diff --git a/README.md b/README.md deleted file mode 100644 index bc03853..0000000 --- a/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# eplayer demo - FB+视频共存问题 - -## 问题与根因 - -FB 和视频无法共存:`compress(TRUE)` 下 render 阻塞,`compress(FALSE)` 下视频返回 VO_BUSY。 - -根因: `rootfs_overlay/qua/ko/loadko.sh` 中 `insmod fhfb.ko fbc=0` 禁用了 FB 压缩,且 `fhfb.ko` 是旧版不支持 fbc。 - -## 修改点 - -### 内核层 - -1. 替换 fhfb.ko — 用 SDK 新版替换 `rootfs_overlay/qua/ko/fhfb.ko`(旧版 md5:`96d321` → 新版 md5:`58050d`) -2. loadko.sh 启用 fbc — `fbc=0` → `fbc=3000`,`vram0_size=4000`,`fhfb0_fbc=1` - -### 应用层 - -3. e_logger.c — 修复 `log_print` 死锁(持有 mutex 后调用 `log_init` 再次加锁) -4. fbdev_10xd.c — `compress(TRUE)` 前加载 `bk.rgba` 全屏铺底 + `tag.rgba` 底部 alpha 叠加 -5. fbdev.c — 跳过 LVGL memcpy,仅做挖洞 + render -6. main.c — 视频区域改为顶部,LVGL root 设为透明 - -## 关键时序 - -mmap → 写入图片 → compress(TRUE) → VO enable → show(TRUE) → render → 挖洞 → 播视频 - -> 图片必须在 `compress(TRUE)` 之前写入 FB buffer。 - -## 素材 - -素材需预转换(PNG/JPG → raw BGRA): - -python3 -c " -from PIL import Image -import struct -img = Image.open('/path/to/bk1.jpg').convert('RGBA') -print(f'Size: {img.size}') -with open('/path/to/bk1.rgba', 'wb') as f: - for y in range(img.height): - for x in range(img.width): - r, g, b, a = img.getpixel((x, y)) - f.write(struct.pack('BBBB', b, g, r, a)) -print('Done') -" - -> 设备上 crc32 与 zlib 冲突,无法用 libpng,需预转换 raw 格式。 diff --git a/bin/e_player b/bin/e_player index a9b4710..a24e229 100755 Binary files a/bin/e_player and b/bin/e_player differ diff --git a/lv_conf.h b/lv_conf.h index 1fe612d..ce62b9a 100755 --- a/lv_conf.h +++ b/lv_conf.h @@ -91,7 +91,7 @@ #endif #endif /*LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN*/ -#define LV_DEF_REFR_PERIOD 33 /**< [ms] 33ms (30fps),优化后支持 tag.gif + 02.gif + 03.gif + 视频长时间稳定运行 */ +#define LV_DEF_REFR_PERIOD 150 /**< [ms] 33ms (30fps),优化后支持 tag.gif + 02.gif + 03.gif + 视频长时间稳定运行 */ #define LV_DPI_DEF 130 /**< [px/inch] */ diff --git a/release/e_player-single-00-70-1.0.84.tar b/release/e_player-single-00-70-1.0.84.tar index d1720c7..359a68a 100644 Binary files a/release/e_player-single-00-70-1.0.84.tar and b/release/e_player-single-00-70-1.0.84.tar differ diff --git a/release/e_player-single-00-70-1.0.84.tar.md5 b/release/e_player-single-00-70-1.0.84.tar.md5 index 43edd8e..dc7df55 100644 --- a/release/e_player-single-00-70-1.0.84.tar.md5 +++ b/release/e_player-single-00-70-1.0.84.tar.md5 @@ -1 +1 @@ -d7d8bda7fec96e0cb0b071e56df40841 /home/hyx/work/0212/demo/release/e_player-single-00-70-1.0.84.tar +1191545f9e16f1a3cb238f5c529dc0a7 /home/hyx/work/MC3302_push/0212/demo/release/e_player-single-00-70-1.0.84.tar diff --git a/src/e_player_list.c b/src/e_player_list.c index 85be66f..32358df 100644 --- a/src/e_player_list.c +++ b/src/e_player_list.c @@ -504,7 +504,11 @@ static int play_video(VideoPlayer *video_player, const MediaPath *media_path) { qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_DISPLAY_ID, (QUA_VOID_PTR)video_player->display); qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_ROTATE, (QUA_VOID_PTR)&g_screen_rotation); - xos_player_set_volume(player, 0); + // 设置音频轨道类型为音乐 + qua_audio_track_type_t track_type = QUA_AUDIO_TRACK_TYPE_MUSIC; + qua_mm_player_set_parameter(player, KEY_PARAMETER_AO_TRACK_TYPE, (QUA_VOID_PTR)&track_type); + + xos_player_set_volume(player, 80); // 设置音量为80 (范围通常是0-100) qua_mm_player_set_loop(player, QUA_FALSE); video_player->player = player; } diff --git a/src/e_port_disp.c b/src/e_port_disp.c index fa33c69..c9e5959 100755 --- a/src/e_port_disp.c +++ b/src/e_port_disp.c @@ -30,7 +30,7 @@ static disp_handle_t front_disp; static disp_handle_t back_disp; // 屏幕旋转 -int g_screen_rotation = 2; +int g_screen_rotation = 0; qua_mm_system_ops_t *g_sys_ops = NULL; qua_mm_tde_device_t *g_tde_device_for_hole = NULL; diff --git a/src/main.c b/src/main.c index 33101cc..3536a45 100755 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -101,56 +102,72 @@ int main(int argc, char **argv) disp_handle_t disp = get_front_display(); - /* 创建 tag.gif 全屏背景动画 */ - lv_obj_t *tag_gif = lv_gif_create(disp.root_obj); - lv_gif_set_src(tag_gif, "A:usrdata/pic/tag.gif"); - lv_obj_set_pos(tag_gif, 0, 0); /* 全屏 */ - lv_obj_set_size(tag_gif, 800, 1280); - lv_obj_clear_flag(tag_gif, LV_OBJ_FLAG_HIDDEN); - lv_gif_restart(tag_gif); - - /* 创建 02.gif 小动画 - 根据旋转调整位置 */ - lv_obj_t *small_gif = lv_gif_create(disp.root_obj); - lv_gif_set_src(small_gif, "A:usrdata/pic/02.gif"); - - // 根据屏幕旋转调整小动画位置 extern int g_screen_rotation; - int small_x, small_y; - if (g_screen_rotation == 2) { - // 180度旋转:显示系统已旋转,逻辑坐标需要反向 - // 要显示在左上角,逻辑坐标应该是右下角 - small_x = 800 - 280; // 520,为280宽度留出空间 - small_y = 1280 - 280; // 1000,为280高度留出空间 - printf("[DEBUG] Rotation 2: position (%d, %d) will display at top-left\n", small_x, small_y); - } else { - // 不旋转:右下角位置 - small_x = 800 - 280 - 20; // 500,右下角留20像素边距 - small_y = 1280 - 280 - 20; // 980,右下角留20像素边距 - printf("[DEBUG] No rotation: position (%d, %d) at bottom-right\n", small_x, small_y); - } - - lv_obj_set_pos(small_gif, small_x, small_y); - lv_obj_set_size(small_gif, 280, 280); // 增加尺寸到280x280 - lv_obj_clear_flag(small_gif, LV_OBJ_FLAG_HIDDEN); - lv_gif_restart(small_gif); - - printf("[DEBUG] GIF position: (%d, %d), size: 280x280\n", small_x, small_y); + /* 创建 bk.jpg 背景图片 */ + lv_obj_t *bk_img = lv_image_create(disp.root_obj); + lv_image_set_src(bk_img, "A:data/pic/bk.jpeg"); + lv_obj_set_pos(bk_img, 0, 0); + lv_obj_set_size(bk_img, 800, 1280); + lv_obj_clear_flag(bk_img, LV_OBJ_FLAG_HIDDEN); + printf("[INFO] bk.jpg loaded at (0, 0), size: 800x1280\n"); - /* 创建 03.gif 在 02.gif 正上方 */ - lv_obj_t *third_gif = lv_gif_create(disp.root_obj); - lv_gif_set_src(third_gif, "A:usrdata/pic/03.gif"); - - // 计算 03.gif 位置:在 02.gif 正上方 - int third_x = small_x; // X 坐标相同 - int third_y = small_y - 280 - 20; // Y 坐标在 02.gif 上方,间距20像素 - - printf("[DEBUG] 03.gif position: (%d, %d), size: 280x280\n", third_x, third_y); - - lv_obj_set_pos(third_gif, third_x, third_y); - lv_obj_set_size(third_gif, 280, 280); - lv_obj_clear_flag(third_gif, LV_OBJ_FLAG_HIDDEN); - lv_gif_restart(third_gif); + /* 创建 tag.png 图片 */ + lv_obj_t *tag_img = lv_image_create(disp.root_obj); + lv_image_set_src(tag_img, "A:data/pic/tag.png"); + lv_obj_set_pos(tag_img, 0, 0); + lv_obj_set_size(tag_img, 800, 1280); + lv_obj_clear_flag(tag_img, LV_OBJ_FLAG_HIDDEN); + printf("[INFO] tag.png loaded at (0, 0), size: 800x1280\n"); + + /* 创建底部细条状态栏 */ + lv_obj_t *status_bar = lv_obj_create(disp.root_obj); + lv_obj_set_pos(status_bar, 320, 1240); + lv_obj_set_size(status_bar, 160, 24); + lv_obj_set_style_bg_color(status_bar, lv_color_make(0, 0, 0), LV_PART_MAIN); + lv_obj_set_style_bg_opa(status_bar, 100, LV_PART_MAIN); + lv_obj_set_style_border_width(status_bar, 0, LV_PART_MAIN); + lv_obj_set_style_radius(status_bar, 12, LV_PART_MAIN); + lv_obj_clear_flag(status_bar, LV_OBJ_FLAG_HIDDEN); + + /* 在线状态绿点 */ + lv_obj_t *online_dot = lv_obj_create(status_bar); + lv_obj_set_pos(online_dot, 10, 4); + lv_obj_set_size(online_dot, 16, 16); + lv_obj_set_style_bg_color(online_dot, lv_color_make(0, 255, 0), LV_PART_MAIN); + lv_obj_set_style_bg_opa(online_dot, 255, LV_PART_MAIN); + lv_obj_set_style_border_width(online_dot, 0, LV_PART_MAIN); + lv_obj_set_style_radius(online_dot, 8, LV_PART_MAIN); + lv_obj_clear_flag(online_dot, LV_OBJ_FLAG_HIDDEN); + + /* 时间显示标签 */ + lv_obj_t *time_label = lv_label_create(status_bar); + lv_obj_set_pos(time_label, 32, 2); + lv_obj_set_size(time_label, 80, 20); + lv_obj_set_style_text_color(time_label, lv_color_make(255, 255, 255), LV_PART_MAIN); + lv_obj_set_style_text_font(time_label, &lv_font_montserrat_22, LV_PART_MAIN); + lv_label_set_text(time_label, "00:00"); + lv_obj_clear_flag(time_label, LV_OBJ_FLAG_HIDDEN); + + /* 更新时间线程 */ + pthread_t time_tid; + static volatile bool time_running = true; + void *time_update_thread(void *arg) { + (void)arg; + while (time_running) { + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + char time_str[16]; + strftime(time_str, sizeof(time_str), "%H:%M", tm_info); + lv_label_set_text(time_label, time_str); + sleep(60); + } + return NULL; + } + pthread_create(&time_tid, NULL, time_update_thread, NULL); + pthread_detach(time_tid); + + printf("[INFO] status bar created at bottom\n"); //创建视频播放器 VideoPlayer *video_player=video_player_init(0); @@ -162,8 +179,7 @@ int main(int argc, char **argv) // 根据屏幕旋转调整视频区域 if (g_screen_rotation == 2) { - // 180度旋转:视频应该显示在上半部分 - area.y = 640; // 设置到下半部分,旋转后会显示在上半部分 + area.y = 640; } video_player_set_size(video_player,area); @@ -176,12 +192,12 @@ int main(int argc, char **argv) } memset(media_path, 0, sizeof(MediaPath)); - safe_strcpy(media_path->path, "/usrdata/downloads/lemon.MOV", MAX_URL_LEN); + safe_strcpy(media_path->path, "/data/downloads/lemon.MOV", MAX_URL_LEN); safe_strcpy(media_path->item_id, "", MAX_ID_LEN); safe_strcpy(media_path->deviceId, "700000000010", MAX_DEVICE_ID); safe_strcpy(media_path->downloadUrl, "", MAX_URL_LEN); - safe_strcpy(media_path->file_name, "/usrdata/downloads/lemon.MOV", MAX_NAME_LEN); + safe_strcpy(media_path->file_name, "/data/downloads/lemon.MOV", MAX_NAME_LEN); media_path->type = 1; // 视频 diff --git a/tag.png b/tag.png deleted file mode 100644 index 9f34c2b..0000000 Binary files a/tag.png and /dev/null differ