diff --git a/bin/e_player b/bin/e_player index 59cdcde..976e62b 100755 Binary files a/bin/e_player and b/bin/e_player differ 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 01cf598..a5cf2e1 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 47d1b33..a3766de 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 @@ -fc6846865270cca1350150fd2ee30cce /home/hyx/work/0212/demo/release/e_player-single-00-70-1.0.84.tar +69abcb73eeff987b2759c8906bd77c27 /home/hyx/work/0212/demo/release/e_player-single-00-70-1.0.84.tar diff --git a/src/display/fbdev.c b/src/display/fbdev.c index c030e62..c191991 100644 --- a/src/display/fbdev.c +++ b/src/display/fbdev.c @@ -24,6 +24,7 @@ #include "filter/qua_mm_filter.h" #include "quagl/qua_gl.h" +extern qua_mm_tde_device_t *g_tde_device_for_hole; extern qua_mm_system_ops_t *g_sys_ops; extern int g_screen_rotation; @@ -49,16 +50,38 @@ void fbdev_init(void) fbdev_get_info(&vinfo, &finfo); fb_surface.data = fbp; fb_surface.phy_addr = finfo.smem_start; - fb_surface.width = vinfo.xres_virtual; - fb_surface.height = vinfo.yres_virtual; - fb_surface.stride = vinfo.xres_virtual; + fb_surface.width = vinfo.xres; + fb_surface.height = vinfo.yres; + fb_surface.stride = finfo.line_length / 4; fb_surface.format = QUA_PIXEL_FMT_RGB_8888; fb_surface.crop_x = 0; fb_surface.crop_y = 0; fb_surface.crop_w = vinfo.xres; fb_surface.crop_h = vinfo.yres; - printf("fbdev_init: %dx%d smem_start=0x%lx\n", vinfo.xres, vinfo.yres, (unsigned long)finfo.smem_start); - lvgl_surface = fb_surface; + printf("设备信息: vinfo.xres:%d,vinfo.yres:%d \n", vinfo.xres, vinfo.yres); + if (g_screen_rotation == 1) + { + lvgl_surface.phy_addr = finfo.smem_start + (finfo.smem_len / 2); + lvgl_surface.data = fbp + (finfo.smem_len / 2); + lvgl_surface.width = vinfo.yres; + lvgl_surface.height = vinfo.xres; + lvgl_surface.stride = vinfo.yres; + lvgl_surface.format = QUA_PIXEL_FMT_RGB_8888; + lvgl_surface.crop_x = 0; + lvgl_surface.crop_y = 0; + lvgl_surface.crop_w = vinfo.yres; + lvgl_surface.crop_h = vinfo.xres; + } + else + { + lvgl_surface = fb_surface; + if (vinfo.xres > vinfo.yres) + { + lvgl_surface.stride = finfo.line_length / 4; + } + } + printf("fbdev_init: xres=%d, yres=%d, line_length=%d, smem_len=%d, smem_start=0x%lx\n", + vinfo.xres, vinfo.yres, finfo.line_length, finfo.smem_len, finfo.smem_start); } void fbdev_exit(void) @@ -75,10 +98,11 @@ void *fbdev_req_mem(int size) int ret = posix_memalign(&buf, 64, size); if (ret != 0 || buf == NULL) { - printf("fbdev_req_mem malloc failed: ret=%d\n", ret); + LV_LOG_ERROR("fbdev_req_mem malloc failed: ret=%d\n", ret); return NULL; } memset(buf, 0, size); + return buf; } @@ -89,13 +113,20 @@ int fbdev_get_actual_height(void) void fbdev_set_hole(int x, int y, int width, int height) { + if (hole_rect.x_pos == x && + hole_rect.y_pos == y && + hole_rect.width == width && + hole_rect.height == height) + { + return; + } + hole_rect.x_pos = x; hole_rect.y_pos = y; hole_rect.width = width; hole_rect.height = height; - // printf("刷新屏幕挖孔区域 \n"); - fbdev_draw_hole(); // 播放视频打洞使用 + fbdev_draw_hole(); fbdev_pan_disp(); } @@ -109,9 +140,16 @@ void fbdev_set_statusbar(int x, int y, int width, int height) static void fbdev_draw_hole() { + QUA_S32 ret; + QUA_TDE_HANDLE handle; + qua_tde2_surface_t hole_surface = {}; + if (hole_rect.width == 0 || hole_rect.height == 0) return; + if (g_tde_device_for_hole == NULL) + return; + qua_tde2_rect_t tmp_rect = hole_rect; QUA_S32 new_y = statusbar_rect.y_pos + statusbar_rect.height; if (new_y > tmp_rect.y_pos) @@ -120,15 +158,36 @@ static void fbdev_draw_hole() tmp_rect.y_pos = new_y; } - fb_surface.crop_x = tmp_rect.x_pos; - fb_surface.crop_y = tmp_rect.y_pos; - fb_surface.crop_w = tmp_rect.width; - fb_surface.crop_h = tmp_rect.height; - qua_gl_fill(&fb_surface, 0); - fb_surface.crop_x = 0; - fb_surface.crop_y = 0; - fb_surface.crop_w = fb_surface.width; - fb_surface.crop_h = fb_surface.height; + hole_surface.phy_addr = lvgl_surface.phy_addr; + hole_surface.color_fmt = QUA_TDE2_COLOR_FMT_ARGB8888; + hole_surface.width = lvgl_surface.width; + hole_surface.height = lvgl_surface.height; + hole_surface.stride = finfo.line_length; + hole_surface.alpha_max255 = QUA_TRUE; + hole_surface.fbc_compress = QUA_FALSE; + + if (g_tde_device_for_hole->qua_tde2_begin_job == NULL || + g_tde_device_for_hole->qua_tde2_quick_fill == NULL || + g_tde_device_for_hole->qua_tde2_end_job == NULL) + return; + + handle = g_tde_device_for_hole->qua_tde2_begin_job(); + if (handle == QUA_FAILURE) + { + return; + } + + ret = g_tde_device_for_hole->qua_tde2_quick_fill(handle, &hole_surface, &tmp_rect, 0x000000FF); + if (ret != QUA_SUCCESS) + { + return; + } + + ret = g_tde_device_for_hole->qua_tde2_end_job(handle, QUA_FALSE, QUA_TRUE, 5000); + if (ret != QUA_SUCCESS) + { + return; + } } /** @@ -140,15 +199,14 @@ static void fbdev_draw_hole() void fbdev_flush(lv_display_t *drv, const lv_area_t *area, uint8_t *color_p) { - static int flush_cnt = 0; - if (flush_cnt < 3) { printf("[fbdev_flush] #%d area=[%d,%d,%d,%d]\n", flush_cnt, area->x1, area->y1, area->x2, area->y2); fflush(stdout); flush_cnt++; } if (fbp == NULL || finfo.line_length == 0) { lv_display_flush_ready(drv); return; } - if (area->x2 < 0 || + if (fbp == NULL || + area->x2 < 0 || area->y2 < 0 || area->x1 > (int32_t)vinfo.xres - 1 || area->y1 > (int32_t)vinfo.yres - 1) @@ -157,21 +215,147 @@ void fbdev_flush(lv_display_t *drv, const lv_area_t *area, uint8_t *color_p) return; } - /* 拷贝 LVGL buffer 到 FB(会导致视频 VO_BUSY,但先让图片显示) */ - int32_t act_x1 = area->x1 < 0 ? 0 : area->x1; - int32_t act_y1 = area->y1 < 0 ? 0 : area->y1; - int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2; - int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2; + int32_t act_x1 = LV_MAX(area->x1, 0); + int32_t act_y1 = LV_MAX(area->y1, 0); + int32_t act_x2 = LV_MIN(area->x2, (int32_t)vinfo.xres - 1); + int32_t act_y2 = LV_MIN(area->y2, (int32_t)vinfo.yres - 1); - int32_t w = (act_x2 - act_x1 + 1); - uint32_t *fbp32 = (uint32_t *)fbp; - uint32_t *color_p32 = (uint32_t *)color_p; + int32_t w = act_x2 - act_x1 + 1; + int32_t h = act_y2 - act_y1 + 1; - for (int32_t y = act_y1; y <= act_y2; y++) + if (w <= 0 || h <= 0) { - uint32_t *fb_line = fbp32 + (y * vinfo.xres) + act_x1; - uint32_t *color_line = color_p32 + ((y - area->y1) * (area->x2 - area->x1 + 1)) + (act_x1 - area->x1); - memcpy(fb_line, color_line, w * sizeof(uint32_t)); + lv_display_flush_ready(drv); + return; + } + + lv_display_rotation_t rotation = lv_display_get_rotation(drv); + + if (rotation == LV_DISPLAY_ROTATION_180) + { + for (int32_t y = 0; y < h; y++) + { + for (int32_t x = 0; x < w; x++) + { + uint32_t src_idx = (y * w + x) * 4; + + int32_t dst_x = vinfo.xres - 1 - (act_x1 + x); + int32_t dst_y = vinfo.yres - 1 - (act_y1 + y); + + if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres && + dst_y >= 0 && dst_y < (int32_t)vinfo.yres) + { + + uint8_t *dst_pixel = (uint8_t *)fbp + + (dst_y + vinfo.yoffset) * finfo.line_length + + (dst_x + vinfo.xoffset) * 4; + + dst_pixel[0] = color_p[src_idx + 0]; + dst_pixel[1] = color_p[src_idx + 1]; + dst_pixel[2] = color_p[src_idx + 2]; + dst_pixel[3] = color_p[src_idx + 3]; + } + } + } + } + else if (rotation == LV_DISPLAY_ROTATION_90) + { + for (int32_t y = 0; y < h; y++) + { + for (int32_t x = 0; x < w; x++) + { + uint32_t src_idx = (y * w + x) * 4; + + int32_t dst_x = act_y1 + y; + int32_t dst_y = vinfo.yres - 1 - (act_x1 + x); + + if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres && + dst_y >= 0 && dst_y < (int32_t)vinfo.yres) + { + + uint8_t *dst_pixel = (uint8_t *)fbp + + (dst_y + vinfo.yoffset) * finfo.line_length + + (dst_x + vinfo.xoffset) * 4; + + dst_pixel[0] = color_p[src_idx + 0]; + dst_pixel[1] = color_p[src_idx + 1]; + dst_pixel[2] = color_p[src_idx + 2]; + dst_pixel[3] = color_p[src_idx + 3]; + } + } + } + } + else if (rotation == LV_DISPLAY_ROTATION_270) + { + for (int32_t y = 0; y < h; y++) + { + for (int32_t x = 0; x < w; x++) + { + uint32_t src_idx = (y * w + x) * 4; + + int32_t dst_x = vinfo.xres - 1 - (act_y1 + y); + int32_t dst_y = act_x1 + x; + + if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres && + dst_y >= 0 && dst_y < (int32_t)vinfo.yres) + { + + uint8_t *dst_pixel = (uint8_t *)fbp + + (dst_y + vinfo.yoffset) * finfo.line_length + + (dst_x + vinfo.xoffset) * 4; + + dst_pixel[0] = color_p[src_idx + 0]; + dst_pixel[1] = color_p[src_idx + 1]; + dst_pixel[2] = color_p[src_idx + 2]; + dst_pixel[3] = color_p[src_idx + 3]; + } + } + } + } + else + { + uint32_t line_offset = (act_y1 + vinfo.yoffset) * finfo.line_length + (act_x1 + vinfo.xoffset) * 4; + if (line_offset >= finfo.smem_len) + { + lv_display_flush_ready(drv); + return; + } + + uint8_t *fb_line = ((uint8_t *)fbp) + line_offset; + + uint32_t refresh_area = w * h; + uint32_t screen_area = vinfo.xres * vinfo.yres; + + if (refresh_area < screen_area / 4) + { + for (int32_t y = 0; y < h; y++) + { + if ((uint8_t *)fb_line - (uint8_t *)fbp + w * 4 > finfo.smem_len) + break; + + memcpy(fb_line, color_p, w * 4); + fb_line += finfo.line_length; + color_p += w * 4; + } + } + else + { + uint32_t fb_pitch = finfo.line_length / 4; + uint32_t lvgl_pitch = w; + + uint32_t *fb_ptr = (uint32_t *)fb_line; + uint32_t *lvgl_ptr = (uint32_t *)color_p; + + for (int32_t y = 0; y < h; y++) + { + if ((uint8_t *)fb_ptr - (uint8_t *)fbp + w * 4 > finfo.smem_len) + break; + + memcpy(fb_ptr, lvgl_ptr, w * 4); + fb_ptr += fb_pitch; + lvgl_ptr += lvgl_pitch; + } + } } if (lv_display_flush_is_last(drv)) diff --git a/src/display/fbdev_10xd.c b/src/display/fbdev_10xd.c index 1dcf1c8..0b82c50 100644 --- a/src/display/fbdev_10xd.c +++ b/src/display/fbdev_10xd.c @@ -142,9 +142,9 @@ static QUA_S32 init_fyfb() qua_fb_alpha_t alpha; alpha.alpha_enable = QUA_TRUE; - alpha.alpha_channel = QUA_TRUE; + alpha.alpha_channel = QUA_FALSE; alpha.alpha0 = 0; - alpha.alpha1 = 128; + alpha.alpha1 = 0; alpha.global_alpha = 128; alpha.reserved = 0; if (fb_device->put_alpha(fb_device, &alpha) != QUA_SUCCESS) @@ -159,9 +159,7 @@ static QUA_S32 init_fyfb() printf("map failed\n"); goto map_failed; } - /* FB 底层保持黑色背景(图片将通过 fbdev_load_images 函数加载) */ memset(pShowScreen, 0x00, finfo.smem_len); - printf("[init_fyfb] FB initialized (images will be loaded via fbdev_load_images)\n"); fb_device->compress(fb_device, QUA_TRUE); return QUA_SUCCESS; map_failed: @@ -232,33 +230,19 @@ int fbdev_pan_disp(void) { qua_mm_fb_device_t *fb_dev = (qua_mm_fb_device_t *)g_fb_device; static int is_first_frame = 1; - static int pan_cnt = 0; - if (pan_cnt < 3) { printf("[fbdev_pan_disp] called #%d first=%d fb_dev=%p\n", pan_cnt, is_first_frame, fb_dev); fflush(stdout); pan_cnt++; } if (fb_dev == NULL) return -1; if (is_first_frame) { -#ifdef CONFIG_XOS_PLAY_BOOTANIMATION - int status = qua_request_bootanimation(QUA_BOOTANIMAION_CMD_QUERY_STATUS); - if (status >= QUA_BOOTANIMAION_STATUS_UNKNOWN && status < QUA_BOOTANIMAION_STATUS_BOOT_FINISH) - { - return -1; - } -#else if (g_vo_device == NULL) return -1; qua_vo_pub_attr_t dev_attr = { .bg_color = 0, .intf_type = QUA_VO_INTF_LCD, - // #ifdef CONFIG_XOS_LCM_800x1280 .intf_sync = QUA_VO_OUTPUT_800x1280_60, - // #else - // .intf_sync = QUA_VO_OUTPUT_1024x600_60, - // #endif - .intf_type = QUA_VO_INTF_LCD, }; QUA_S32 ret = g_vo_device->set_public_attr(vo_num, &dev_attr); @@ -272,12 +256,12 @@ int fbdev_pan_disp(void) { return ret; } -#endif - if (fb_dev->show(fb_dev, QUA_TRUE) != QUA_SUCCESS) - { - printf("show failed\n"); - return -1; - } + + if (fb_dev->show(fb_dev, QUA_TRUE) != QUA_SUCCESS) + { + printf("show failed\n"); + return -1; + } is_first_frame = 0; } @@ -285,8 +269,7 @@ int fbdev_pan_disp(void) if (fb_dev->render == NULL) return -1; - QUA_S32 render_ret = fb_dev->render(fb_dev, &vinfo); - return render_ret; + return fb_dev->render(fb_dev, &vinfo); } #endif diff --git a/src/e_player_list.c b/src/e_player_list.c index b13ee2b..762be17 100644 --- a/src/e_player_list.c +++ b/src/e_player_list.c @@ -326,61 +326,13 @@ void video_player_set_hole(VideoPlayer *video_player) if (!video_player) return; - // 根据屏幕旋转调整挖洞区域坐标 + // 直接使用视频区域,不做坐标转换 + // 因为 QuaPlayer 库已经处理了旋转后的实际显示位置 int x = video_player->area.x; int y = video_player->area.y; int width = video_player->area.width; int height = video_player->area.height; - // 获取实际屏幕尺寸 - int actual_scr_width, actual_scr_height; - if (g_screen_rotation == 1 || g_screen_rotation == 3) - { // 90度或270度旋转 - actual_scr_width = GET_SCR_HEIGHT(); - actual_scr_height = GET_SCR_WIDTH(); - } - else - { // 0度或180度旋转 - actual_scr_width = GET_SCR_WIDTH(); - actual_scr_height = GET_SCR_HEIGHT(); - } - - // 根据旋转角度调整坐标 - switch (g_screen_rotation) - { - case 1: // 90度旋转:(x,y) -> (y, height-1-(x+width-1), width, height) -> (height, width) - { - int temp_x = y; - int temp_y = actual_scr_height - 1 - (x + width - 1); - int temp_width = height; - int temp_height = width; - x = temp_x; - y = temp_y; - width = temp_width; - height = temp_height; - } - break; - case 2: // 180度旋转:(x,y) -> (width-1-(x+width-1), height-1-(y+height-1)) = (width-x-width, height-y-height) - x = actual_scr_width - (x + width); - y = actual_scr_height - (y + height); - break; - case 3: // 270度旋转:(x,y) -> (width-1-(y+height-1), x, height, width) -> (height, width) - { - int temp_x = actual_scr_width - 1 - (y + height - 1); - int temp_y = x; - int temp_width = height; - int temp_height = width; - x = temp_x; - y = temp_y; - width = temp_width; - height = temp_height; - } - break; - case 0: // 0度,无旋转 - default: - break; - } - if (video_player->display_idx == 0) { LOGD("设置视频挖洞区域。x=%d,y=%d,w=%d,h=%d", x, y, width, height); @@ -550,13 +502,7 @@ static int play_video(VideoPlayer *video_player, const MediaPath *media_path) } if (player) { - // LOGI("diaplayer name %s", video_player->display); qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_DISPLAY_ID, (QUA_VOID_PTR)video_player->display); - // 设置视频旋转角度 - // qua_rotate_t rotate = 2; - // qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_ROTATE, (QUA_VOID_PTR)&rotate); - qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_ROTATE, (QUA_VOID_PTR)&g_screen_rotation); - xos_player_set_volume(player, 0); qua_mm_player_set_loop(player, QUA_FALSE); video_player->player = player; @@ -606,8 +552,6 @@ static int play_video(VideoPlayer *video_player, const MediaPath *media_path) chn_rect.width = GET_SCR_WIDTH(); chn_rect.height = GET_SCR_HEIGHT(); qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_DISPLAY_RECT, (QUA_VOID_PTR)&chn_rect); - - // video 大小 qua_mm_player_set_parameter(player, KEY_PARAMETER_VO_CHN_RECT, (QUA_VOID_PTR)&rect); ret = qua_mm_player_prepare(player); diff --git a/src/main.c b/src/main.c index 204a08f..3aeda78 100755 --- a/src/main.c +++ b/src/main.c @@ -109,10 +109,22 @@ int main(int argc, char **argv) lv_obj_clear_flag(tag_gif, LV_OBJ_FLAG_HIDDEN); lv_gif_restart(tag_gif); - /* 创建 02.gif 小动画 - 右下角,缩小到 120x120 减少负载 */ + /* 创建 02.gif 小动画 - 根据旋转调整位置 */ lv_obj_t *small_gif = lv_gif_create(disp.root_obj); lv_gif_set_src(small_gif, "A:usrdata/pic/02.gif"); - lv_obj_set_pos(small_gif, 800 - 150, 1280 - 150); /* 右下角:(680, 1160) */ + + // 根据屏幕旋转调整小动画位置 + extern int g_screen_rotation; + int small_x = 800 - 150; + int small_y = 1280 - 150; + + if (g_screen_rotation == 2) { + // 180度旋转:右下角变成左上角 + small_x = 0; + small_y = 0; + } + + lv_obj_set_pos(small_gif, small_x, small_y); lv_obj_set_size(small_gif, 150, 150); lv_obj_clear_flag(small_gif, LV_OBJ_FLAG_HIDDEN); lv_gif_restart(small_gif); @@ -124,6 +136,12 @@ int main(int argc, char **argv) area.y = 0; area.width = 800; area.height = 640; + + // 根据屏幕旋转调整视频区域 + if (g_screen_rotation == 2) { + // 180度旋转:视频应该显示在上半部分 + area.y = 640; // 设置到下半部分,旋转后会显示在上半部分 + } video_player_set_size(video_player,area);