lv_demo_video.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-03-09 Rbb666 First version
  9. */
  10. #include <rtthread.h>
  11. #include <lcd_port.h>
  12. #include "lvgl.h"
  13. #include "drv_jpeg.h"
  14. #include "lv_demo_video.h"
  15. #include "ui_helpers.h"
  16. #include "ui_anim.h"
  17. #include "player.h"
  18. #define JPEG_WIDTH 400
  19. #define JPEG_HEIGHT 240
  20. #define DCODE_BUFFER_SIZE (35 * 1024)
  21. #define MY_CLASS &lv_media_class
  22. lv_obj_t *win_obj;
  23. lv_obj_t *avi_obj;
  24. lv_obj_t *file_explorer_panel;
  25. lv_obj_t *file_ImgButton;
  26. lv_obj_t *ui_ImgButton1;
  27. lv_obj_t *ui_ImgButton2;
  28. lv_obj_t *ui_ImgButton3;
  29. lv_obj_t *ui_Indicator_Left;
  30. lv_obj_t *ui_Audio_Wave;
  31. const lv_obj_class_t lv_media_class =
  32. {
  33. .width_def = LV_SIZE_CONTENT,
  34. .height_def = LV_SIZE_CONTENT,
  35. .instance_size = sizeof(lv_media_obj_t),
  36. .base_class = &lv_obj_class
  37. };
  38. static rt_bool_t btn_state_change = RT_FALSE;
  39. static rt_bool_t play_state_change = RT_FALSE;
  40. static uint16_t lv_show_buffer[JPEG_WIDTH * JPEG_HEIGHT] BSP_ALIGN_VARIABLE(16);
  41. struct player v_player;
  42. static void func_button_create(lv_obj_t *parent);
  43. void lv_media_set_state(lv_obj_t *obj, lv_mdeia_state_t state)
  44. {
  45. lv_media_obj_t *media = (lv_media_obj_t *)obj;
  46. media->state = state;
  47. }
  48. lv_mdeia_state_t lv_media_get_state(lv_obj_t *obj, lv_mdeia_state_t state)
  49. {
  50. LV_ASSERT_OBJ(obj, MY_CLASS);
  51. lv_media_obj_t *media = (lv_media_obj_t *)obj;
  52. return media->state;
  53. }
  54. void lv_media_set_fn(lv_obj_t *obj, char *fn)
  55. {
  56. LV_ASSERT_OBJ(obj, MY_CLASS);
  57. lv_media_obj_t *fd = (lv_media_obj_t *)obj;
  58. uint16_t fn_len = strlen(fn);
  59. if ((!fn) || (fn_len == 0)) return;
  60. if (fd->cur_fn)
  61. {
  62. lv_mem_free(fd->cur_fn);
  63. fd->cur_fn = NULL;
  64. }
  65. fd->cur_fn = lv_mem_alloc(fn_len + 1);
  66. LV_ASSERT_MALLOC(fd->cur_fn);
  67. if (fd->cur_fn == NULL) return;
  68. strcpy(fd->cur_fn, fn);
  69. }
  70. char *lv_media_get_fn(lv_obj_t *obj)
  71. {
  72. LV_ASSERT_OBJ(obj, MY_CLASS);
  73. lv_media_obj_t *media = (lv_media_obj_t *)obj;
  74. return media->cur_fn;
  75. }
  76. static void file_explorer_event_cb(lv_event_t *e)
  77. {
  78. lv_event_code_t code = lv_event_get_code(e);
  79. lv_obj_t *file_explorer = lv_event_get_target(e);
  80. lv_obj_t *file = lv_event_get_user_data(e);
  81. if (code == LV_EVENT_VALUE_CHANGED)
  82. {
  83. const char *path = lv_file_explorer_get_current_path(file_explorer);
  84. const char *fn = lv_file_explorer_get_selected_file_name(file_explorer);
  85. uint16_t path_len = strlen(path);
  86. uint16_t fn_len = strlen(fn);
  87. if ((path_len + fn_len) <= LV_FILE_EXPLORER_PATH_MAX_LEN)
  88. {
  89. char sel_fn[LV_FILE_EXPLORER_PATH_MAX_LEN];
  90. strcpy(sel_fn, path);
  91. strcat(sel_fn, fn);
  92. if (strstr(sel_fn, ".avi") == NULL)
  93. return;
  94. lv_media_set_fn(file, sel_fn);
  95. /* send event to take back file panel */
  96. lv_event_send(file_ImgButton, LV_EVENT_RELEASED, NULL);
  97. player_control(&v_player, PLAYER_CMD_INIT, sel_fn);
  98. /* delete button */
  99. lv_obj_del(file_ImgButton);
  100. lv_obj_del_delayed(file_explorer_panel, 1000);
  101. func_button_create(win_obj);
  102. }
  103. }
  104. }
  105. #define set_pause_picture lv_imgbtn_set_src(ui_ImgButton2, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_pause_png, NULL)
  106. #define set_play_picture lv_imgbtn_set_src(ui_ImgButton2, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_run_png, NULL)
  107. void Button_event(lv_event_t *e)
  108. {
  109. lv_event_code_t event_code = lv_event_get_code(e);
  110. lv_obj_t *target = lv_event_get_target(e);
  111. if (target == file_ImgButton)
  112. {
  113. if (event_code == LV_EVENT_RELEASED)
  114. {
  115. btn_state_change = !btn_state_change;
  116. btn_state_change == LV_FILE_EXPLORER_OPEN ? \
  117. roll_out_Animation(file_explorer_panel, 0) : \
  118. take_back_Animation(file_explorer_panel, 0);
  119. \
  120. }
  121. }
  122. // pause
  123. if (target == ui_ImgButton2)
  124. {
  125. if (event_code == LV_EVENT_RELEASED)
  126. {
  127. play_state_change = !play_state_change;
  128. play_state_change == LV_MUSIC_PLAY ? \
  129. player_control(&v_player, PLAYER_CMD_PLAY, RT_NULL), set_play_picture : \
  130. player_control(&v_player, PLAYER_CMD_STOP, RT_NULL), set_pause_picture;
  131. \
  132. }
  133. }
  134. // next
  135. if (target == ui_ImgButton1)
  136. {
  137. if (event_code == LV_EVENT_RELEASED)
  138. {
  139. if (v_player.status == PLAYER_STOP)
  140. player_control(&v_player, PLAYER_CMD_PLAY, RT_NULL);
  141. player_control(&v_player, PLAYER_CMD_NEXT, RT_NULL);
  142. }
  143. }
  144. // prev
  145. if (target == ui_ImgButton3)
  146. {
  147. if (event_code == LV_EVENT_RELEASED)
  148. {
  149. if (v_player.status == PLAYER_STOP)
  150. player_control(&v_player, PLAYER_CMD_PLAY, RT_NULL);
  151. player_control(&v_player, PLAYER_CMD_LAST, RT_NULL);
  152. }
  153. }
  154. }
  155. static void slider_event_cb(lv_event_t *event)
  156. {
  157. int16_t volume;
  158. lv_obj_t *slider = lv_event_get_target(event);
  159. volume = lv_slider_get_value(slider);
  160. player_control(&v_player, PLAYER_CMD_SET_VOL, &volume);
  161. }
  162. static lv_obj_t *lv_media_page_create(lv_obj_t *parent)
  163. {
  164. LV_LOG_INFO("begin");
  165. lv_obj_t *obj = lv_obj_class_create_obj(MY_CLASS, parent);
  166. lv_obj_class_init_obj(obj);
  167. return obj;
  168. }
  169. void file_explorer_create(lv_obj_t *parent)
  170. {
  171. lv_obj_set_style_border_width(lv_scr_act(), 0, LV_STATE_DEFAULT);
  172. lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_STATE_DEFAULT);
  173. lv_obj_set_size(parent, LCD_WIDTH, LCD_HEIGHT);
  174. lv_obj_center(parent);
  175. file_explorer_panel = lv_file_explorer_create(parent);
  176. lv_obj_set_size(file_explorer_panel, 370, 200);
  177. lv_obj_center(file_explorer_panel);
  178. lv_file_explorer_set_sort(file_explorer_panel, LV_EXPLORER_SORT_NONE);
  179. lv_file_explorer_open_dir(file_explorer_panel, "/");
  180. lv_obj_add_event_cb(file_explorer_panel, file_explorer_event_cb, LV_EVENT_VALUE_CHANGED, parent);
  181. }
  182. static void file_ImgButton_create(lv_obj_t *parent)
  183. {
  184. LV_IMG_DECLARE(file_icon);
  185. file_ImgButton = lv_imgbtn_create(parent);
  186. lv_imgbtn_set_src(file_ImgButton, LV_IMGBTN_STATE_RELEASED, NULL, &file_icon, NULL);
  187. lv_obj_set_size(file_ImgButton, 62, 62);
  188. lv_obj_align(file_ImgButton, LV_ALIGN_TOP_RIGHT, 0, 0);
  189. lv_obj_add_event_cb(file_ImgButton, Button_event, LV_EVENT_ALL, NULL);
  190. }
  191. static void func_button_create(lv_obj_t *parent)
  192. {
  193. ui_ImgButton3 = lv_imgbtn_create(parent);
  194. lv_imgbtn_set_src(ui_ImgButton3, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_prev_png, NULL);
  195. lv_obj_set_width(ui_ImgButton3, 35);
  196. lv_obj_set_height(ui_ImgButton3, 35);
  197. lv_obj_set_x(ui_ImgButton3, 220);
  198. lv_obj_set_y(ui_ImgButton3, -69);
  199. lv_obj_set_align(ui_ImgButton3, LV_ALIGN_CENTER);
  200. ui_ImgButton1 = lv_imgbtn_create(parent);
  201. lv_imgbtn_set_src(ui_ImgButton1, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_next_png, NULL);
  202. lv_obj_set_width(ui_ImgButton1, 35);
  203. lv_obj_set_height(ui_ImgButton1, 35);
  204. lv_obj_set_x(ui_ImgButton1, 220);
  205. lv_obj_set_y(ui_ImgButton1, 56);
  206. lv_obj_set_align(ui_ImgButton1, LV_ALIGN_CENTER);
  207. ui_ImgButton2 = lv_imgbtn_create(parent);
  208. lv_imgbtn_set_src(ui_ImgButton2, LV_IMGBTN_STATE_RELEASED, NULL, &ui_img_pause_png, NULL);
  209. lv_obj_set_width(ui_ImgButton2, 35);
  210. lv_obj_set_height(ui_ImgButton2, 35);
  211. lv_obj_set_x(ui_ImgButton2, 220);
  212. lv_obj_set_y(ui_ImgButton2, -7);
  213. lv_obj_set_align(ui_ImgButton2, LV_ALIGN_CENTER);
  214. btn1_comein_Animation(ui_ImgButton1, 0);
  215. btn2_comein_Animation(ui_ImgButton2, 0);
  216. btn3_comein_Animation(ui_ImgButton3, 0);
  217. lv_obj_add_event_cb(ui_ImgButton1, Button_event, LV_EVENT_ALL, NULL);
  218. lv_obj_add_event_cb(ui_ImgButton2, Button_event, LV_EVENT_ALL, NULL);
  219. lv_obj_add_event_cb(ui_ImgButton3, Button_event, LV_EVENT_ALL, NULL);
  220. }
  221. static void sound_slider_create(lv_obj_t *parent)
  222. {
  223. ui_Indicator_Left = lv_slider_create(parent);
  224. lv_slider_set_range(ui_Indicator_Left, -16, 16);
  225. lv_slider_set_mode(ui_Indicator_Left, LV_SLIDER_MODE_SYMMETRICAL);
  226. lv_obj_set_width(ui_Indicator_Left, 20);
  227. lv_obj_set_height(ui_Indicator_Left, 200);
  228. lv_obj_set_align(ui_Indicator_Left, LV_ALIGN_LEFT_MID);
  229. lv_obj_set_style_radius(ui_Indicator_Left, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  230. lv_obj_set_style_bg_color(ui_Indicator_Left, lv_color_hex(0x272A33), LV_PART_MAIN | LV_STATE_DEFAULT);
  231. lv_obj_set_style_bg_opa(ui_Indicator_Left, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  232. lv_obj_set_style_bg_main_stop(ui_Indicator_Left, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  233. lv_obj_set_style_bg_grad_stop(ui_Indicator_Left, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  234. lv_obj_set_style_border_width(ui_Indicator_Left, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  235. lv_obj_set_style_pad_left(ui_Indicator_Left, 2, LV_PART_MAIN | LV_STATE_DEFAULT);
  236. lv_obj_set_style_pad_right(ui_Indicator_Left, 2, LV_PART_MAIN | LV_STATE_DEFAULT);
  237. lv_obj_set_style_pad_top(ui_Indicator_Left, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  238. lv_obj_set_style_pad_bottom(ui_Indicator_Left, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  239. lv_obj_set_style_radius(ui_Indicator_Left, 4, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  240. lv_obj_set_style_bg_color(ui_Indicator_Left, lv_color_hex(0xFFFFFF), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  241. lv_obj_set_style_bg_opa(ui_Indicator_Left, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  242. lv_obj_set_style_bg_main_stop(ui_Indicator_Left, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  243. lv_obj_set_style_bg_grad_stop(ui_Indicator_Left, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  244. lv_obj_set_style_bg_img_src(ui_Indicator_Left, &ui_img_indicator_ver_png, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  245. lv_obj_set_style_bg_color(ui_Indicator_Left, lv_color_hex(0xFFFFFF), LV_PART_KNOB | LV_STATE_DEFAULT);
  246. lv_obj_set_style_bg_opa(ui_Indicator_Left, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  247. lv_obj_add_event_cb(ui_Indicator_Left, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
  248. }
  249. static void lv_audio_wave_create(lv_obj_t *parent)
  250. {
  251. ui_Audio_Wave = lv_slider_create(parent);
  252. lv_slider_set_value(ui_Audio_Wave, 0, LV_ANIM_OFF);
  253. if (lv_slider_get_mode(ui_Audio_Wave) == LV_SLIDER_MODE_RANGE) lv_slider_set_left_value(ui_Audio_Wave, 0, LV_ANIM_OFF);
  254. lv_obj_set_width(ui_Audio_Wave, 310);
  255. lv_obj_set_height(ui_Audio_Wave, 10);
  256. lv_obj_set_align(ui_Audio_Wave, LV_ALIGN_BOTTOM_MID);
  257. lv_obj_set_style_bg_color(ui_Audio_Wave, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  258. lv_obj_set_style_bg_opa(ui_Audio_Wave, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  259. lv_obj_set_style_bg_main_stop(ui_Audio_Wave, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  260. lv_obj_set_style_bg_grad_stop(ui_Audio_Wave, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  261. lv_obj_set_style_bg_img_src(ui_Audio_Wave, &ui_img_audio_wave_1_png, LV_PART_MAIN | LV_STATE_DEFAULT);
  262. lv_obj_set_style_bg_img_opa(ui_Audio_Wave, 50, LV_PART_MAIN | LV_STATE_DEFAULT);
  263. lv_obj_set_style_bg_color(ui_Audio_Wave, lv_color_hex(0xFFFFFF), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  264. lv_obj_set_style_bg_opa(ui_Audio_Wave, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  265. lv_obj_set_style_bg_main_stop(ui_Audio_Wave, 0, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  266. lv_obj_set_style_bg_grad_stop(ui_Audio_Wave, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  267. lv_obj_set_style_bg_img_src(ui_Audio_Wave, &ui_img_audio_wave_1_png, LV_PART_INDICATOR | LV_STATE_DEFAULT);
  268. lv_obj_set_style_bg_color(ui_Audio_Wave, lv_color_hex(0xFFFFFF), LV_PART_KNOB | LV_STATE_DEFAULT);
  269. lv_obj_set_style_bg_opa(ui_Audio_Wave, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  270. }
  271. void set_audio_wave_value(int32_t value)
  272. {
  273. lv_slider_set_value(ui_Audio_Wave, value, LV_ANIM_OFF);
  274. }
  275. static void lv_avi_window_create(lv_obj_t *parent)
  276. {
  277. avi_obj = lv_img_create(parent);
  278. lv_obj_set_size(avi_obj, JPEG_WIDTH, JPEG_HEIGHT);
  279. lv_obj_align(avi_obj, LV_ALIGN_CENTER, 0, 0);
  280. }
  281. void lv_avi_player_draw(int32_t x, int32_t y, const void *pInBuffer, int32_t xSize, int32_t ySize)
  282. {
  283. static lv_img_dsc_t img_dsc =
  284. {
  285. .header.always_zero = 0,
  286. .header.w = JPEG_WIDTH,
  287. .header.h = JPEG_HEIGHT,
  288. .header.cf = LV_IMG_CF_TRUE_COLOR,
  289. .data_size = JPEG_WIDTH * JPEG_HEIGHT * sizeof(lv_color16_t),
  290. .data = NULL,
  291. };
  292. uint16_t *fbp16 = (uint16_t *)lv_show_buffer;
  293. long int location = 0;
  294. location = x + y * JPEG_WIDTH;
  295. rt_memcpy(&fbp16[location], pInBuffer, (ySize * JPEG_WIDTH * sizeof(lv_color16_t)));
  296. if (y == JPEG_HEIGHT - 16)
  297. {
  298. img_dsc.data_size = ySize * xSize * sizeof(lv_color16_t);
  299. img_dsc.data = (const uint8_t *)fbp16;
  300. lv_img_set_src(avi_obj, &img_dsc);
  301. }
  302. }
  303. static void auto_run_video_timer_cb(lv_timer_t *timer)
  304. {
  305. /* send event to take back file panel */
  306. lv_event_send(file_ImgButton, LV_EVENT_RELEASED, NULL);
  307. player_control(&v_player, PLAYER_CMD_INIT, v_player.video_list[0]);
  308. /* delete button */
  309. lv_obj_del(file_ImgButton);
  310. lv_obj_del_delayed(file_explorer_panel, 1000);
  311. func_button_create(win_obj);
  312. lv_timer_del(timer);
  313. }
  314. void lv_video_gui_init(void)
  315. {
  316. win_obj = lv_media_page_create(lv_scr_act());
  317. lv_avi_window_create(win_obj);
  318. file_explorer_create(win_obj);
  319. file_ImgButton_create(win_obj);
  320. sound_slider_create(win_obj);
  321. lv_audio_wave_create(win_obj);
  322. lv_timer_t *t = lv_timer_create(auto_run_video_timer_cb, 2000, NULL);
  323. lv_timer_ready(t);
  324. }
  325. static uint8_t jpeg_outbuffer[DCODE_BUFFER_SIZE] BSP_ALIGN_VARIABLE(8);
  326. static decode_drv_t decode;
  327. int player_init(void)
  328. {
  329. v_player.decode = &decode;
  330. v_player.decode->jpeg_out_buf = &jpeg_outbuffer;
  331. v_player.decode->decode_read = lv_avi_player_draw;
  332. player_start(&v_player);
  333. return 0;
  334. }
  335. INIT_APP_EXPORT(player_init);