#include "SysCommon.h" #include "AppDisp_PBView.h" #include "PlaybackTsk.h" #include "vf_gfx.h" #include "GxVideo.h" #include #include #include "exif/Exif.h" #include "exif/ExifDef.h" #include "SizeConvert.h" #include "kwrap/perf.h" #include "PlaybackTsk.h" #include "GxVideoFile.h" #include "sys_mempool.h" #include "UIWnd/UIFlow.h" #include "lfqueue/lfqueue.h" /////////////////////////////////////////////////////////////////////////////// #define __MODULE__ PBVIEW #define __DBGLVL__ 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER #define __DBGFLT__ "*" //*=All, [mark]=CustomClass #include /////////////////////////////////////////////////////////////////////////////// #define COLOR_RGB_BLACK 0x00000000 static USIZE aspect_ratio; static ER (*gfpDrawCb)(HD_VIDEO_FRAME *pHdDecVdoFrame, PUSIZE dst_ratio); static UINT32 gPbState = PB_VIEW_STATE_NONE; static HD_VIDEO_FRAME g_LastVdoFrm = {0}; //keep last disp screen #if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together static HD_VIDEO_FRAME g_DispTmpFrm = {0}; // display tmp frame static HD_VIDEO_FRAME g_ThumbFrm[FLOWPB_THUMB_H_NUM2*FLOWPB_THUMB_V_NUM2] = {0}; // thumbnail frame #endif static const char pbview_videoout_task_name[] = "PBView_Vout_Task"; typedef struct { THREAD_HANDLE id; UINT run; UINT is_running; lfqueue_t lfqueue; } PBView_videoout_task_param; typedef struct { HD_PATH_ID path_id; HD_VIDEO_FRAME push_in_frame; /* buffers need to be released after frame pushed */ PBVIEW_HD_COM_BUF relesse_view_buf; PBVIEW_HD_COM_BUF release_2pass_buf; } lfqueue_videoout_param; PBView_videoout_task_param* get_videoout_task_param(void) { static PBView_videoout_task_param* param = NULL; if(param == NULL){ DBG_DUMP("init lfqueue\r\n"); param = (PBView_videoout_task_param*) malloc(sizeof(PBView_videoout_task_param)); memset(param, 0, sizeof(PBView_videoout_task_param)); lfqueue_init(¶m->lfqueue); } return param; } THREAD_RETTYPE _PBView_videoout_task(void) { HD_RESULT ret = HD_OK; PBView_videoout_task_param* task_param = NULL; lfqueue_videoout_param* lfqueue_param = NULL; UINT empty_queue_delay_ms = 1; THREAD_ENTRY(); task_param = get_videoout_task_param(); while(task_param->run) { if(!task_param->is_running) task_param->is_running = 1; /* sleep when queue is empty */ if((lfqueue_param = lfqueue_deq(&task_param->lfqueue)) == NULL){ vos_util_delay_ms(empty_queue_delay_ms); continue; } ret = hd_videoout_push_in_buf( lfqueue_param->path_id, &lfqueue_param->push_in_frame, NULL, 0); if (ret != HD_OK && ret != HD_ERR_OVERRUN){ DBG_ERR("failed to push in buf of videoout\r\n"); } if(lfqueue_param->relesse_view_buf.blk && lfqueue_param->relesse_view_buf.blk!= HD_COMMON_MEM_VB_INVALID_BLK){ hd_common_mem_munmap((void *)lfqueue_param->relesse_view_buf.va, lfqueue_param->relesse_view_buf.blk_size); ret = hd_common_mem_release_block(lfqueue_param->relesse_view_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", lfqueue_param->relesse_view_buf.blk); } } if (lfqueue_param->release_2pass_buf.blk && lfqueue_param->release_2pass_buf.blk!= HD_COMMON_MEM_VB_INVALID_BLK) { hd_common_mem_munmap((void *)lfqueue_param->release_2pass_buf.va, lfqueue_param->release_2pass_buf.blk_size); ret = hd_common_mem_release_block(lfqueue_param->release_2pass_buf.blk); if (ret != HD_OK){ DBG_ERR("release 2-pass blk(0x%x) failed\r\n", lfqueue_param->release_2pass_buf.blk); } } if(lfqueue_param){ free(lfqueue_param); lfqueue_param = NULL; } } task_param->is_running = 0; THREAD_RETURN(0); } ER PBView_videoout_task_create(void) { ER ret = E_OK; const char* task_name = pbview_videoout_task_name; const int priority = 9; const int stack_size = 2048; PBView_videoout_task_param* task_param = get_videoout_task_param(); if(!task_param->id){ if ((task_param->id = vos_task_create(_PBView_videoout_task, 0, task_name, priority, stack_size)) == 0) { DBG_ERR("%s create failed.\r\n", pbview_videoout_task_name); ret |= E_SYS; } else { DBG_DUMP("%s created\r\n", task_name); task_param->run = 1; vos_task_resume(task_param->id); } } return ret; } void PBView_videoout_task_destroy(void) { const UINT timeout = 500; const UINT delay_ms = 1; UINT cnt = 0; PBView_videoout_task_param* task_param = get_videoout_task_param(); task_param->run = 0; while(task_param->is_running && (cnt++ < timeout)) { vos_util_delay_ms(delay_ms); } if(cnt >= timeout){ DBG_ERR("wait PBView_videoout_task finish timeout(over %s ms)\r\n", timeout*delay_ms); vos_task_destroy(task_param->id); } task_param->id = 0; DBG_DUMP("%s destroyed\r\n", pbview_videoout_task_name); } UINT32 PBView_get_hd_phy_addr(void *va) { if (va) { HD_COMMON_MEM_VIRT_INFO vir_meminfo = {0}; vir_meminfo.va = va; if (hd_common_mem_get(HD_COMMON_MEM_PARAM_VIRT_INFO, &vir_meminfo) == HD_OK) { return vir_meminfo.pa; } } return 0; } HD_RESULT PBView_get_hd_common_buf(PPBVIEW_HD_COM_BUF p_hd_view_buf) { // get memory p_hd_view_buf->blk = hd_common_mem_get_block(HD_COMMON_MEM_COMMON_POOL, p_hd_view_buf->blk_size, DDR_ID0); // Get block from mem pool if (p_hd_view_buf->blk == HD_COMMON_MEM_VB_INVALID_BLK) { DBG_ERR("config_vdo_frm: get blk fail, blk(0x%x)\n", p_hd_view_buf->blk ); return HD_ERR_SYS; } p_hd_view_buf->pa = hd_common_mem_blk2pa(p_hd_view_buf->blk); // get physical addr if (p_hd_view_buf->pa == 0) { DBG_ERR("config_vdo_frm: blk2pa fail, blk(0x%x)\n", p_hd_view_buf->blk); return HD_ERR_SYS; } p_hd_view_buf->va = (UINT32)hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, p_hd_view_buf->pa, p_hd_view_buf->blk_size); if (p_hd_view_buf->va == 0) { DBG_ERR("Convert to VA failed for file buffer for decoded buffer!\r\n"); return HD_ERR_SYS; } return HD_OK; } static void PBView_2PassScale(HD_VIDEO_FRAME *pVdoSrc, HD_VIDEO_FRAME *pVdo2PassSrc) { VF_GFX_SCALE gfx_scale = {0}; memcpy((void *)&gfx_scale.src_img, (void *)pVdoSrc, sizeof(HD_VIDEO_FRAME)); memcpy((void *)&gfx_scale.dst_img, (void *)pVdo2PassSrc, sizeof(HD_VIDEO_FRAME)); gfx_scale.src_region.x = 0; gfx_scale.src_region.y = 0; gfx_scale.src_region.w = pVdoSrc->dim.w; gfx_scale.src_region.h = pVdoSrc->dim.h; gfx_scale.dst_region.x = 0; gfx_scale.dst_region.y = 0; gfx_scale.dst_region.w = pVdo2PassSrc->dim.w; gfx_scale.dst_region.h = pVdo2PassSrc->dim.h; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; vf_gfx_scale(&gfx_scale, 0); } #if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together void PBView_DrawSingleView(HD_VIDEO_FRAME *pVdoSrc) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; PBVIEW_HD_COM_BUF hd_2pass_buf = {0}; VF_GFX_SCALE gfx_scale = {0}; HD_VIDEOOUT_IN video_out_param = {0}; HD_VIDEOOUT_WIN_ATTR video_out_win = {0}; UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_VIDEO_FRAME Vdo2PassSrc = {0}, *pVdoNewSrc = NULL; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); ISIZE disp_size = GxVideo_GetDeviceSize(DOUT1); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); ISIZE img_size; BOOL scale_2pass = FALSE; disp_size.w /= 2; // single view only on the right half part of display dst_aspect_ratio.w /= 2; // single view only on the right half part of display // set scaling image info by original image and display aspect ratio if ((pVdoSrc->dim.w * dst_aspect_ratio.h) > (dst_aspect_ratio.w * pVdoSrc->dim.h)) { if ((pVdoSrc->dim.h / 2) > (UINT32)disp_size.h) { scale_2pass = TRUE; img_size.w = pVdoSrc->dim.w / 2; img_size.h = pVdoSrc->dim.h / 2; } else { img_size.w = pVdoSrc->dim.w; img_size.h = pVdoSrc->dim.h; } gfx_scale.engine = 0; gfx_scale.src_region.w = ALIGN_CEIL_4((img_size.h * dst_aspect_ratio.w) / dst_aspect_ratio.h); gfx_scale.src_region.h = img_size.h; gfx_scale.src_region.x = (img_size.w - gfx_scale.src_region.w) / 2; gfx_scale.src_region.y = 0; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = 0; gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } else { if ((pVdoSrc->dim.w / 2) > (UINT32)disp_size.w) { scale_2pass = TRUE; img_size.w = pVdoSrc->dim.w / 2; img_size.h = pVdoSrc->dim.h / 2; } else { img_size.w = pVdoSrc->dim.w; img_size.h = pVdoSrc->dim.h; } gfx_scale.engine = 0; gfx_scale.src_region.w = img_size.w; gfx_scale.src_region.h = ALIGN_CEIL_4((img_size.w * dst_aspect_ratio.h) / dst_aspect_ratio.w); gfx_scale.src_region.x = 0; gfx_scale.src_region.y = (img_size.h - gfx_scale.src_region.h) / 2; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = disp_size.w; // single view is on the right side of display gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } // do 2-pass scaling if necessary if (scale_2pass) { hd_2pass_buf.blk_size = img_size.w * img_size.h * 3 / 2; PBView_get_hd_common_buf(&hd_2pass_buf); pVdoNewSrc = &Vdo2PassSrc; loff[0] = img_size.w; addr[0] = hd_2pass_buf.pa; loff[1] = img_size.w; addr[1] = ALIGN_CEIL_4(addr[0] + img_size.w * img_size.h); ret = vf_init_ex(pVdoNewSrc, img_size.w, img_size.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex: 2-pass src failed\r\n"); return; } pVdoNewSrc->blk = hd_2pass_buf.blk; PBView_2PassScale(pVdoSrc, pVdoNewSrc); } else { pVdoNewSrc = pVdoSrc; } // scale image to display size disp_size.w *= 2; // recall original display width hd_view_buf.blk_size = disp_size.w * disp_size.h * 3 / 2; PBView_get_hd_common_buf(&hd_view_buf); loff[0] = disp_size.w; addr[0] = hd_view_buf.pa; loff[1] = disp_size.w; addr[1] = ALIGN_CEIL_4(addr[0] + disp_size.w * disp_size.h); ret = vf_init_ex(&gfx_scale.dst_img, disp_size.w, disp_size.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); return; } #if 0 // clear buffer VF_GFX_DRAW_RECT draw_rect = {0}; memcpy((void *)&draw_rect.dst_img, (void *)&gfx_scale.dst_img, sizeof(HD_VIDEO_FRAME)); draw_rect.color = COLOR_RGB_BLACK; draw_rect.rect.x = 0; draw_rect.rect.y = 0; draw_rect.rect.w = disp_size.w; draw_rect.rect.h = disp_size.h; draw_rect.type = HD_GFX_RECT_SOLID; draw_rect.thickness = 0; //Don't care for HD_GFX_RECT_SOLID draw_rect.engine = 0; vf_gfx_draw_rect(&draw_rect); #endif memcpy((void *)&gfx_scale.src_img, (void *)pVdoNewSrc, sizeof(HD_VIDEO_FRAME)); vf_gfx_scale(&gfx_scale, 1); gfx_scale.dst_img.blk = hd_view_buf.blk; //must for HD_VIDEOOUT #if 1 // copy left part of display tmp buffer (thumbnail layout) to display buffer VF_GFX_COPY gfx_copy; gfx_copy.src_img = g_DispTmpFrm; gfx_copy.dst_img = gfx_scale.dst_img; //if ((ret = vf_init(&gfx_copy.dst_img, gfx_scale.dst_img.dim.w, gfx_scale.dst_img.dim.h, gfx_scale.dst_img.pxlfmt, gfx_scale.dst_img.loff[0], hd_view_buf.pa, hd_view_buf.blk_size)) != HD_OK) { // DBG_ERR("vf_init fail(%d)\r\n", ret); //} gfx_copy.src_region.x = 0; gfx_copy.src_region.y = 0; gfx_copy.src_region.w = gfx_scale.dst_img.dim.w/2; gfx_copy.src_region.h = gfx_scale.dst_img.dim.h; gfx_copy.dst_pos.x = 0; gfx_copy.dst_pos.y = 0; gfx_copy.colorkey = 0; gfx_copy.alpha = 255; gfx_copy.engine = 0; if ((ret = vf_gfx_copy(&gfx_copy)) != HD_OK) { DBG_ERR("vf_gfx_copy fail(%d)\r\n", ret); } #endif // set video out parameter video_out_param.dim.w = disp_size.w; video_out_param.dim.h = disp_size.h; video_out_param.pxlfmt = HD_VIDEO_PXLFMT_YUV420; video_out_param.dir = SysVideo_GetDirbyID(0); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN failed\r\n"); return; } // set video out window video_out_win.visible = TRUE; video_out_win.layer = HD_LAYER1; video_out_win.rect.x = 0; video_out_win.rect.y = 0; if (disp_rotate) { video_out_win.rect.w = disp_size.h; video_out_win.rect.h = disp_size.w; } else { video_out_win.rect.w = disp_size.w; video_out_win.rect.h = disp_size.h; } ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN_WIN_ATTR, &video_out_win); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN_WIN_ATTR fail\r\n"); } ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } // push in and release buffer ret = hd_videoout_push_in_buf(video_out_path, &gfx_scale.dst_img, NULL, 0); // only support non-blocking mode now if (ret != HD_OK) { DBG_ERR("failed to push in buf of videoout\r\n"); } else { hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK) { DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } memcpy((void *)&g_LastVdoFrm, (void *)&gfx_scale.dst_img, sizeof(HD_VIDEO_FRAME)); } // release 2-pass scaling buffer if necessary if (hd_2pass_buf.blk) { hd_common_mem_munmap((void *)hd_2pass_buf.va, hd_2pass_buf.blk_size); ret = hd_common_mem_release_block(hd_2pass_buf.blk); if (ret != HD_OK) { DBG_ERR("release 2-pass blk(0x%x) failed\r\n", hd_2pass_buf.blk); } } } #elif PLAY_FULL_DISP // image crop for full display void PBView_DrawSingleView(HD_VIDEO_FRAME *pVdoSrc) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; PBVIEW_HD_COM_BUF hd_2pass_buf = {0}; VF_GFX_SCALE gfx_scale = {0}; HD_VIDEOOUT_IN video_out_param = {0}; HD_VIDEOOUT_WIN_ATTR video_out_win = {0}; UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_VIDEO_FRAME Vdo2PassSrc = {0}, *pVdoNewSrc = NULL; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); ISIZE disp_size = GxVideo_GetDeviceSize(DOUT1); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); ISIZE img_size; BOOL scale_2pass = FALSE; // set scaling image info by original image and display aspect ratio if ((pVdoSrc->dim.w * dst_aspect_ratio.h) > (dst_aspect_ratio.w * pVdoSrc->dim.h)) { if ((pVdoSrc->dim.h / 2) > (UINT32)disp_size.h) { scale_2pass = TRUE; img_size.w = pVdoSrc->dim.w / 2; img_size.h = pVdoSrc->dim.h / 2; } else { img_size.w = pVdoSrc->dim.w; img_size.h = pVdoSrc->dim.h; } gfx_scale.engine = 0; gfx_scale.src_region.w = ALIGN_CEIL_4((img_size.h * dst_aspect_ratio.w) / dst_aspect_ratio.h); gfx_scale.src_region.h = img_size.h; gfx_scale.src_region.x = (img_size.w - gfx_scale.src_region.w) / 2; gfx_scale.src_region.y = 0; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = 0; gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } else { if ((pVdoSrc->dim.w / 2) > (UINT32)disp_size.w) { scale_2pass = TRUE; img_size.w = pVdoSrc->dim.w / 2; img_size.h = pVdoSrc->dim.h / 2; } else { img_size.w = pVdoSrc->dim.w; img_size.h = pVdoSrc->dim.h; } gfx_scale.engine = 0; gfx_scale.src_region.w = img_size.w; gfx_scale.src_region.h = ALIGN_CEIL_4((img_size.w * dst_aspect_ratio.h) / dst_aspect_ratio.w); gfx_scale.src_region.x = 0; gfx_scale.src_region.y = (img_size.h - gfx_scale.src_region.h) / 2; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = 0; gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } // do 2-pass scaling if necessary if (scale_2pass) { hd_2pass_buf.blk_size = img_size.w * img_size.h * 3 / 2; PBView_get_hd_common_buf(&hd_2pass_buf); pVdoNewSrc = &Vdo2PassSrc; loff[0] = img_size.w; addr[0] = hd_2pass_buf.pa; loff[1] = img_size.w; addr[1] = ALIGN_CEIL_4(addr[0] + img_size.w * img_size.h); ret = vf_init_ex(pVdoNewSrc, img_size.w, img_size.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex: 2-pass src failed\r\n"); return; } pVdoNewSrc->blk = hd_2pass_buf.blk; PBView_2PassScale(pVdoSrc, pVdoNewSrc); } else { pVdoNewSrc = pVdoSrc; } // scale image to display size hd_view_buf.blk_size = disp_size.w * disp_size.h * 3 / 2; PBView_get_hd_common_buf(&hd_view_buf); loff[0] = disp_size.w; addr[0] = hd_view_buf.pa; loff[1] = disp_size.w; addr[1] = ALIGN_CEIL_4(addr[0] + disp_size.w * disp_size.h); ret = vf_init_ex(&gfx_scale.dst_img, disp_size.w, disp_size.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); return; } memcpy((void *)&gfx_scale.src_img, (void *)pVdoNewSrc, sizeof(HD_VIDEO_FRAME)); vf_gfx_scale(&gfx_scale, 1); gfx_scale.dst_img.blk = hd_view_buf.blk; //must for HD_VIDEOOUT // set video out parameter video_out_param.dim.w = disp_size.w; video_out_param.dim.h = disp_size.h; video_out_param.pxlfmt = HD_VIDEO_PXLFMT_YUV420; video_out_param.dir = SysVideo_GetDirbyID(0); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN failed\r\n"); return; } // set video out window video_out_win.visible = TRUE; video_out_win.layer = HD_LAYER1; video_out_win.rect.x = 0; video_out_win.rect.y = 0; if (disp_rotate) { video_out_win.rect.w = disp_size.h; video_out_win.rect.h = disp_size.w; } else { video_out_win.rect.w = disp_size.w; video_out_win.rect.h = disp_size.h; } ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN_WIN_ATTR, &video_out_win); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN_WIN_ATTR fail\r\n"); } ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } // push in and release buffer ret = hd_videoout_push_in_buf(video_out_path, &gfx_scale.dst_img, NULL, 0); // only support non-blocking mode now if (ret != HD_OK) { DBG_ERR("failed to push in buf of videoout\r\n"); } else { hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK) { DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } memcpy((void *)&g_LastVdoFrm, (void *)&gfx_scale.dst_img, sizeof(HD_VIDEO_FRAME)); } // release 2-pass scaling buffer if necessary if (hd_2pass_buf.blk) { hd_common_mem_munmap((void *)hd_2pass_buf.va, hd_2pass_buf.blk_size); ret = hd_common_mem_release_block(hd_2pass_buf.blk); if (ret != HD_OK) { DBG_ERR("release 2-pass blk(0x%x) failed\r\n", hd_2pass_buf.blk); } } } #else // image full view //PB_GetParam(PBPRMID_INFO_IMG, (UINT32 *)&hd_vdoframe_info); void PBView_Zoom( HD_VIDEO_FRAME *pVdoSrc, HD_IPOINT* target_pos, UINT8 ratio ) { HD_RESULT rst; VF_GFX_COPY vf_gfx_copy_param; UINT32 x_diff, y_diff; HD_VIDEO_FRAME dst = {0}; UINT32 pb_zoom_pa = 0; void* pb_zoom_va = 0; INT32 diff_tmp; if(target_pos->x < 0){ DBG_WRN("target x can't be negative, fix to zero\n"); target_pos->x = 0; } if(target_pos->y < 0){ DBG_WRN("target y can't be negative, fix to zero\n"); target_pos->y = 0; } memcpy(&vf_gfx_copy_param.src_img, pVdoSrc, sizeof(HD_VIDEO_FRAME)); vf_gfx_copy_param.alpha = 255; x_diff = (vf_gfx_copy_param.src_img.dim.w * ratio) / 100; y_diff = (vf_gfx_copy_param.src_img.dim.h * ratio) / 100; vf_gfx_copy_param.src_region.w = vf_gfx_copy_param.src_img.dim.w - x_diff; vf_gfx_copy_param.src_region.h = vf_gfx_copy_param.src_img.dim.h - y_diff; diff_tmp = (target_pos->x + vf_gfx_copy_param.src_region.w) - vf_gfx_copy_param.src_img.dim.w; DBG_DUMP("diff x = %d\n", diff_tmp); if(diff_tmp > 0){ target_pos->x -= diff_tmp; } diff_tmp = (target_pos->y + vf_gfx_copy_param.src_region.h) - vf_gfx_copy_param.src_img.dim.h; DBG_DUMP("diff y = %d\n", diff_tmp); if(diff_tmp > 0){ target_pos->y -= diff_tmp; } vf_gfx_copy_param.src_region.x = target_pos->x; vf_gfx_copy_param.src_region.y = target_pos->y; DBG_DUMP("x = %d y = %d w = %lu h = %lu\n", target_pos->x, target_pos->y, vf_gfx_copy_param.src_region.w, vf_gfx_copy_param.src_region.h); UINT32 size = (vf_gfx_copy_param.src_region.w * vf_gfx_copy_param.src_region.h * 1.5); if(hd_common_mem_alloc("PBZoom", &pb_zoom_pa, &pb_zoom_va, size, DDR_ID0) != HD_OK){ DBG_ERR("get common mem failed\n"); } DBG_DUMP("pa = %lx va = %lx\n", pb_zoom_pa, pb_zoom_va); rst = vf_init( &dst, vf_gfx_copy_param.src_region.w, vf_gfx_copy_param.src_region.h, vf_gfx_copy_param.src_img.pxlfmt, vf_gfx_copy_param.src_region.w, pb_zoom_pa, size ); if(rst != HD_OK){ return; } memcpy(&vf_gfx_copy_param.dst_img, &dst, sizeof(HD_VIDEO_FRAME)); vf_gfx_copy_param.dst_pos.x = 0; vf_gfx_copy_param.dst_pos.y = 0; rst = vf_gfx_copy(&vf_gfx_copy_param); if(rst != HD_OK){ return; } PBView_DrawSingleView(&vf_gfx_copy_param.dst_img); hd_common_mem_free(pb_zoom_pa, pb_zoom_va); } void PBView_DrawSingleView(HD_VIDEO_FRAME *pVdoSrc) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; PBVIEW_HD_COM_BUF hd_2pass_buf = {0}; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; VF_GFX_SCALE gfx_scale = {0}; HD_VIDEOOUT_IN video_out_param={0}; HD_VIDEOOUT_WIN_ATTR video_out_win = {0}; UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); HD_VIDEO_FRAME Vdo2PassSrc = {0}, *pVdoNewSrc = NULL; float SrcImgRatio, Img2PassRatio; UINT32 New2PassImgW, New2PassImgH= 0; SIZECONVERT_INFO CovtInfo = {0}; HD_URECT DstDispRect = {0}; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); Img2PassRatio = (float)PBVIEW_2PASS_W/(float)PBVIEW_2PASS_H; Img2PassRatio = (INT32)(Img2PassRatio*100); SrcImgRatio = (float)pVdoSrc->dim.w/(float)pVdoSrc->dim.h; SrcImgRatio = (INT32)(SrcImgRatio*100); if (SrcImgRatio > Img2PassRatio){ //Source image is 16:9 New2PassImgW = PBVIEW_2PASS_W; New2PassImgH = ALIGN_CEIL_4(PBVIEW_2PASS_W*9/16); }else{ New2PassImgW = PBVIEW_2PASS_W; New2PassImgH = PBVIEW_2PASS_H; } if ((pVdoSrc->dim.w > New2PassImgW) && (pVdoSrc->dim.h > New2PassImgH)){ hd_2pass_buf.blk_size = New2PassImgW*New2PassImgH*3/2; if(PBView_get_hd_common_buf(&hd_2pass_buf) != HD_OK) { goto RELEASE_BLK; } pVdoNewSrc = &Vdo2PassSrc; loff[0] = New2PassImgW; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_2pass_buf.pa; loff[1] = New2PassImgW; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + New2PassImgW*New2PassImgH); ret = vf_init_ex(pVdoNewSrc, New2PassImgW, New2PassImgH, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex: 2-pass src failed\r\n"); return; } pVdoNewSrc->blk = hd_2pass_buf.blk; PBView_2PassScale(pVdoSrc, pVdoNewSrc); }else{ pVdoNewSrc = pVdoSrc; } ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); return; } CovtInfo.uiSrcWidth = pVdoNewSrc->dim.w; CovtInfo.uiSrcHeight = pVdoNewSrc->dim.h; if (disp_rotate) { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.h; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.w; } else { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.w; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.h; } CovtInfo.uiDstWRatio = dst_aspect_ratio.w; CovtInfo.uiDstHRatio = dst_aspect_ratio.h; CovtInfo.alignType = SIZECONVERT_ALIGN_FLOOR_32; DisplaySizeConvert(&CovtInfo); if (CovtInfo.uiOutWidth && CovtInfo.uiOutHeight) { if (disp_rotate) { CovtInfo.uiOutWidth = ALIGN_CEIL_8(CovtInfo.uiOutWidth); CovtInfo.uiOutHeight = ALIGN_CEIL_8(CovtInfo.uiOutHeight); CovtInfo.uiOutX = (p_video_out_syscaps->output_dim.h - CovtInfo.uiOutWidth)>>1; CovtInfo.uiOutY = (p_video_out_syscaps->output_dim.w - CovtInfo.uiOutHeight)>>1; } DstDispRect.x = CovtInfo.uiOutX; DstDispRect.y = CovtInfo.uiOutY; DstDispRect.w = CovtInfo.uiOutWidth; DstDispRect.h = CovtInfo.uiOutHeight; } else { DstDispRect.x = 0; DstDispRect.y = 0; DstDispRect.w = p_video_out_syscaps->output_dim.w; DstDispRect.h = p_video_out_syscaps->output_dim.h; } hd_view_buf.blk_size = DstDispRect.w*DstDispRect.h*3/2; if(PBView_get_hd_common_buf(&hd_view_buf) != HD_OK) { goto RELEASE_BLK; } loff[0] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_view_buf.pa; loff[1] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + DstDispRect.w*DstDispRect.h); ret = vf_init_ex(&gfx_scale.dst_img, DstDispRect.w, DstDispRect.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); return; } memcpy((void *)&gfx_scale.src_img, (void *)pVdoNewSrc, sizeof(HD_VIDEO_FRAME)); gfx_scale.engine = 0; gfx_scale.src_region.x = 0; gfx_scale.src_region.y = 0; gfx_scale.src_region.w = pVdoSrc->dim.w; gfx_scale.src_region.h = pVdoSrc->dim.h; gfx_scale.dst_region.x = 0; // dst frame buffer rather than IDE window. gfx_scale.dst_region.y = 0; // dst frame buffer rather than IDE window. gfx_scale.dst_region.w = DstDispRect.w; gfx_scale.dst_region.h = DstDispRect.h; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; vf_gfx_scale(&gfx_scale, 0); gfx_scale.dst_img.blk = hd_view_buf.blk; //must for HD_VIDEOOUT video_out_param.dim.w = DstDispRect.w; video_out_param.dim.h = DstDispRect.h; video_out_param.pxlfmt = HD_VIDEO_PXLFMT_YUV420; video_out_param.dir = SysVideo_GetDirbyID(0); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN failed\r\n"); return; } #if 0 memset((void *)&video_out_param,0,sizeof(HD_VIDEOOUT_IN)); ret = hd_videoout_get(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_get: HD_VIDEOOUT_PARAM_IN failed\r\n"); return; } #endif video_out_win.visible = TRUE; if (disp_rotate) { video_out_win.rect.x = DstDispRect.y; video_out_win.rect.y = DstDispRect.x; video_out_win.rect.w = DstDispRect.h; video_out_win.rect.h = DstDispRect.w; } else { video_out_win.rect.x = DstDispRect.x; video_out_win.rect.y = DstDispRect.y; video_out_win.rect.w = DstDispRect.w; video_out_win.rect.h = DstDispRect.h; } video_out_win.layer = HD_LAYER1; ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN_WIN_ATTR, &video_out_win); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN_WIN_ATTR fail\r\n"); } ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } #if 0 DBG_ERR("MAKEFOURCC('V','F','R','M') = %d\r\n", MAKEFOURCC('V','F','R','M')); DBG_ERR("gfx_scale.dst_img.sign = %d\r\n", gfx_scale.dst_img.sign); DBG_ERR("gfx_scale.dst_img.ddr_id = %d\r\n", gfx_scale.dst_img.ddr_id); DBG_ERR("gfx_scale.dst_img.pxlfmt = 0x%x\r\n", gfx_scale.dst_img.pxlfmt); DBG_ERR("gfx_scale.dst_img.dim.w = %d\r\n", gfx_scale.dst_img.dim.w); DBG_ERR("gfx_scale.dst_img.dim.h = %d\r\n", gfx_scale.dst_img.dim.h); DBG_ERR("gfx_scale.dst_img.count = %d\r\n", gfx_scale.dst_img.count); DBG_ERR("gfx_scale.dst_img.timestamp = %d\r\n", gfx_scale.dst_img.timestamp); DBG_ERR("gfx_scale.dst_img.pw[HD_VIDEO_PINDEX_Y] = %d\r\n", gfx_scale.dst_img.pw[HD_VIDEO_PINDEX_Y]); DBG_ERR("gfx_scale.dst_img.pw[HD_VIDEO_PINDEX_UV] = %d\r\n", gfx_scale.dst_img.pw[HD_VIDEO_PINDEX_UV]); DBG_ERR("gfx_scale.dst_img.ph[HD_VIDEO_PINDEX_Y] = %d\r\n", gfx_scale.dst_img.ph[HD_VIDEO_PINDEX_Y]); DBG_ERR("gfx_scale.dst_img.ph[HD_VIDEO_PINDEX_UV] = %d\r\n", gfx_scale.dst_img.ph[HD_VIDEO_PINDEX_UV]); DBG_ERR("gfx_scale.dst_img.loff[HD_VIDEO_PINDEX_Y] = %d\r\n", gfx_scale.dst_img.loff[HD_VIDEO_PINDEX_Y]); DBG_ERR("gfx_scale.dst_img.loff[HD_VIDEO_PINDEX_UV] = %d\r\n", gfx_scale.dst_img.loff[HD_VIDEO_PINDEX_UV]); DBG_ERR("gfx_scale.dst_img.phy_addr[HD_VIDEO_PINDEX_Y] = 0x%x\r\n", gfx_scale.dst_img.phy_addr[HD_VIDEO_PINDEX_Y]); DBG_ERR("gfx_scale.dst_img.phy_addr[HD_VIDEO_PINDEX_UV] = 0x%x\r\n", gfx_scale.dst_img.phy_addr[HD_VIDEO_PINDEX_UV]); DBG_ERR("gfx_scale.dst_img.blk = %d\r\n", gfx_scale.dst_img.blk); #endif PBView_videoout_task_param* task_param = get_videoout_task_param(); if(task_param->is_running){ lfqueue_videoout_param* lfqueue_param = (lfqueue_videoout_param*) malloc(sizeof(lfqueue_videoout_param)); memset(lfqueue_param, 0, sizeof(lfqueue_videoout_param)); lfqueue_param->path_id = video_out_path; lfqueue_param->push_in_frame = gfx_scale.dst_img; lfqueue_param->relesse_view_buf = hd_view_buf; lfqueue_param->release_2pass_buf = hd_2pass_buf; while (lfqueue_enq(&task_param->lfqueue, lfqueue_param) == -1) { DBG_ERR("ENQ Full ?\r\n"); } } else{ // push in and release buffer ret = hd_videoout_push_in_buf(video_out_path, &gfx_scale.dst_img, NULL, 0); // only support non-blocking mode now if (ret != HD_OK) { DBG_ERR("failed to push in buf of videoout\r\n"); } else{ memcpy((void *)&g_LastVdoFrm, (void *)&gfx_scale.dst_img, sizeof(HD_VIDEO_FRAME)); } RELEASE_BLK: if(hd_view_buf.blk && hd_view_buf.blk != HD_COMMON_MEM_VB_INVALID_BLK){ hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK) { DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } } // release 2-pass scaling buffer if necessary if (hd_2pass_buf.blk && hd_2pass_buf.blk != HD_COMMON_MEM_VB_INVALID_BLK) { hd_common_mem_munmap((void *)hd_2pass_buf.va, hd_2pass_buf.blk_size); ret = hd_common_mem_release_block(hd_2pass_buf.blk); if (ret != HD_OK) { DBG_ERR("release 2-pass blk(0x%x) failed\r\n", hd_2pass_buf.blk); } } } } #endif static ER PBView_DrawMethod(HD_VIDEO_FRAME *pHdDecVdoFrame, PUSIZE dst_aspect_ratio) { //--------------------Customer Draw Begin------------------------------- PBView_DrawSingleView(pHdDecVdoFrame); //--------------------Customer Draw End--------------------------------- PB_SetPBFlag(PB_SET_FLG_DRAW_END); return E_OK; } static ER PBView_OnSingleDraw(HD_VIDEO_FRAME *pHdDecVdoFrame, PUSIZE dst_aspect_ratio) { return PBView_DrawMethod(pHdDecVdoFrame, dst_aspect_ratio); } static void PBView_DrawThumbView(UINT32 i, HD_VIDEO_FRAME *pVdoSrc, HD_VIDEO_FRAME *pVdoDstDisp, PUSIZE dst_ratio) { UINT32 SrcWidth, SrcHeight; //SrcStart_X, SrcStart_Y UINT32 DstWidth, DstHeight, DstX, DstY; UINT8 ucOrientation; HD_IRECT DstRegion = {0}; PURECT idx_view; UINT32 width_array, height_array; BOOL dec_err_array; BOOL dec_err=TRUE, exif_exist; UINT32 exif_orient = 0; VF_GFX_DRAW_RECT DrawRectDst = {0}; VF_GFX_DRAW_RECT *pDrawRectDst = &DrawRectDst; VF_GFX_SCALE gfx_scale = {0}; HD_VIDEO_FRAME Vdo2PassSrc = {0}, *pVdoNewSrc = NULL; //INT32 i32VdoDstBlk = pVdoDst->blk; PBVIEW_HD_COM_BUF hd_2pass_buf = {0}; UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_RESULT ret = HD_OK; PB_GetParam(PBPRMID_THUMB_RECT, (UINT32 *) &idx_view); PB_GetParam(PBPRMID_THUMB_WIDTH_ARRAY, (UINT32 *) &width_array); PB_GetParam(PBPRMID_THUMB_HEIGHT_ARRAY, (UINT32 *) &height_array); PB_GetParam(PBPRMID_THUMB_DEC_ARRAY, (UINT32 *) &dec_err_array); PB_GetParam(PBPRMID_EXIF_EXIST, (UINT32 *) &exif_exist); PB_GetParam(PBPRMID_EXIF_ORIENT, (UINT32 *) &exif_orient); dec_err = *((((BOOL *)dec_err_array) + i)); SrcWidth = *((((UINT32 *)width_array) + i)); SrcHeight = *((((UINT32 *)height_array) + i)); //SrcStart_X = 0; //SrcStart_Y = 0; DstWidth = (idx_view + i)->w; DstHeight = (idx_view + i)->h; DstX = (idx_view + i)->x; DstY = (idx_view + i)->y; // clear BG if (i == 0) { memcpy((void *)&pDrawRectDst->dst_img, (void *)pVdoDstDisp, sizeof(HD_VIDEO_FRAME)); pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->rect.x = 0; pDrawRectDst->rect.y = 0; pDrawRectDst->rect.w = pVdoDstDisp->dim.w; pDrawRectDst->rect.h = pVdoDstDisp->dim.h; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); } DstRegion.x = DstX; DstRegion.y = DstY; DstRegion.w = DstWidth; DstRegion.h = DstHeight; // decode error if (dec_err == TRUE) { memcpy((void *)&pDrawRectDst->rect, (void *)&DstRegion, sizeof(HD_IRECT)); pDrawRectDst->rect.x = DstX; pDrawRectDst->rect.y = DstY; pDrawRectDst->rect.w = DstWidth; pDrawRectDst->rect.h = DstHeight; pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); } // decode ok else { UINT16 usPBDisplayWidth = pVdoDstDisp->dim.w; PB_KEEPAR ImageRatioTrans; if ((SrcWidth == DstWidth) && (SrcHeight == DstHeight)) { ImageRatioTrans = PB_KEEPAR_NONE; } else { ImageRatioTrans = PB_GetImageRatioTrans(SrcWidth, SrcHeight, DstWidth*dst_ratio->w*pVdoDstDisp->dim.h/pVdoDstDisp->dim.w/dst_ratio->h, DstHeight); } if (ImageRatioTrans == PB_KEEPAR_LETTERBOXING) { UINT32 uiTmpHeight; UINT32 temp; // Clear buffer.. memcpy((void *)&pDrawRectDst->dst_img, (void *)pVdoDstDisp, sizeof(HD_VIDEO_FRAME)); pDrawRectDst->rect.x = DstX; pDrawRectDst->rect.y = DstY; pDrawRectDst->rect.w = DstWidth; pDrawRectDst->rect.h = DstHeight; pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); uiTmpHeight = DstWidth * SrcHeight / SrcWidth * pVdoDstDisp->dim.h / usPBDisplayWidth * dst_ratio->w / dst_ratio->h; temp = ((DstHeight - uiTmpHeight) + 1) & 0xFFFFFFFE; DstHeight = uiTmpHeight; DstRegion.y = DstRegion.y + (temp >> 1); } if (exif_exist) { ucOrientation = exif_orient; } else { ucOrientation = JPEG_EXIF_ORI_DEFAULT; } if (ucOrientation != JPEG_EXIF_ORI_DEFAULT) { if (ucOrientation != JPEG_EXIF_ORI_ROTATE_180) { UINT32 ulTmpWidth; ulTmpWidth = DstHeight * SrcHeight / SrcWidth * usPBDisplayWidth / pVdoDstDisp->dim.h * dst_ratio->h / dst_ratio->w; if (ulTmpWidth > DstWidth) { // Prevent user from setting strange-ratio thumbnail window ulTmpWidth = DstWidth / 2; } DstRegion.x += ((DstWidth - ulTmpWidth) >> 1); DstRegion.w = ulTmpWidth; DstRegion.h = DstHeight; } else { DstRegion.w = DstWidth; DstRegion.h = DstHeight; } } else { DstRegion.w = DstWidth; DstRegion.h = DstHeight; } if ((pVdoSrc->dim.w > PBVIEW_2PASS_W) && (pVdoSrc->dim.h > PBVIEW_2PASS_H)){ hd_2pass_buf.blk_size = PBVIEW_2PASS_W*PBVIEW_2PASS_H*3/2; PBView_get_hd_common_buf(&hd_2pass_buf); pVdoNewSrc = &Vdo2PassSrc; loff[0] = PBVIEW_2PASS_W; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_2pass_buf.pa; loff[1] = PBVIEW_2PASS_W; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + PBVIEW_2PASS_W*PBVIEW_2PASS_H); //ret = vf_init_ex(pVdoNewSrc, PBVIEW_2PASS_W, PBVIEW_2PASS_H, HD_VIDEO_PXLFMT_YUV420, loff, addr); ret = vf_init_ex(pVdoNewSrc, PBVIEW_2PASS_W, (pVdoSrc->dim.h*PBVIEW_2PASS_W)/pVdoSrc->dim.w, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } pVdoNewSrc->blk = hd_2pass_buf.blk; PBView_2PassScale(pVdoSrc, pVdoNewSrc); }else{ pVdoNewSrc = pVdoSrc; } memcpy((void *)&gfx_scale.src_img, (void *)pVdoNewSrc, sizeof(HD_VIDEO_FRAME)); memcpy((void *)&gfx_scale.dst_img, (void *)pVdoDstDisp, sizeof(HD_VIDEO_FRAME)); // display device gfx_scale.src_region.x = 0; gfx_scale.src_region.y = 0; gfx_scale.src_region.w = pVdoNewSrc->dim.w; gfx_scale.src_region.h = pVdoNewSrc->dim.h; gfx_scale.dst_region.x = DstRegion.x; gfx_scale.dst_region.y = DstRegion.y; gfx_scale.dst_region.w = ALIGN_CEIL_4(DstRegion.w); gfx_scale.dst_region.h = ALIGN_CEIL_4(DstRegion.h); gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; vf_gfx_scale(&gfx_scale, 1); #if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together // copy thumbnail image to thumbnail frame buffer VF_GFX_COPY gfx_copy; gfx_copy.src_img = gfx_scale.src_img; //memcpy((void *)&gfx_copy.src_img, (void *)&gfx_scale.src_img, sizeof(HD_VIDEO_FRAME)); if ((ret = vf_init(&gfx_copy.dst_img, gfx_scale.src_img.dim.w, gfx_scale.src_img.dim.h, gfx_scale.src_img.pxlfmt, gfx_scale.src_img.loff[0], mempool_thumb_frame[i], POOL_SIZE_THUMB_FRAME)) != HD_OK) { DBG_ERR("vf_init fail(%d)\r\n", ret); } gfx_copy.src_region.x = 0; gfx_copy.src_region.y = 0; gfx_copy.src_region.w = gfx_scale.src_img.dim.w; gfx_copy.src_region.h = gfx_scale.src_img.dim.h; gfx_copy.dst_pos.x = 0; gfx_copy.dst_pos.y = 0; gfx_copy.colorkey = 0; gfx_copy.alpha = 255; gfx_copy.engine = 0; if ((ret = vf_gfx_copy(&gfx_copy)) != HD_OK) { DBG_ERR("vf_gfx_copy fail(%d)\r\n", ret); } memcpy((void *)&g_ThumbFrm[i], (void *)&gfx_copy.dst_img, sizeof(HD_VIDEO_FRAME)); #endif if (hd_2pass_buf.blk != 0){ ret = hd_common_mem_munmap((void *)hd_2pass_buf.va, hd_2pass_buf.blk_size); if (ret != HD_OK){ DBG_ERR("failed to memory munmap\r\n"); } ret = hd_common_mem_release_block(hd_2pass_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", hd_2pass_buf.blk); } } } } #if PLAY_FULL_DISP // image crop for full display void PBView_DrawErrorView(void) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_VIDEO_FRAME VdoDstDisp = {0}; //Display size VF_GFX_DRAW_RECT DrawRectDst = {0}; VF_GFX_DRAW_RECT *pDrawRectDst = &DrawRectDst; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); UINT32 swap_w_h=0; ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); } //#NT#2021/1/28#Philex Lin-begin // swap Width/Height if panel is rotated if (disp_rotate) { // swap w/h swap_w_h=p_video_out_syscaps->output_dim.w; p_video_out_syscaps->output_dim.w=p_video_out_syscaps->output_dim.h; p_video_out_syscaps->output_dim.h=swap_w_h; } //#NT#2021/1/28#Philex Lin-end hd_view_buf.blk_size = p_video_out_syscaps->output_dim.w*p_video_out_syscaps->output_dim.h*3/2; //YUV420 PBView_get_hd_common_buf(&hd_view_buf); loff[0] = p_video_out_syscaps->output_dim.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_view_buf.pa; loff[1] = p_video_out_syscaps->output_dim.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + p_video_out_syscaps->output_dim.w*p_video_out_syscaps->output_dim.h); ret = vf_init_ex(&VdoDstDisp, p_video_out_syscaps->output_dim.w, p_video_out_syscaps->output_dim.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } VdoDstDisp.blk = hd_view_buf.blk; memcpy((void *)&pDrawRectDst->dst_img, (void *)&VdoDstDisp, sizeof(HD_VIDEO_FRAME)); pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->rect.x = 0; pDrawRectDst->rect.y = 0; pDrawRectDst->rect.w = VdoDstDisp.dim.w; pDrawRectDst->rect.h = VdoDstDisp.dim.h; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } ret = hd_videoout_push_in_buf(video_out_path, &VdoDstDisp, NULL, 0); // only support non-blocking mode now if (ret != HD_OK){ DBG_ERR("failed to push in buf of videoout\r\n"); } ret = hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); if (ret != HD_OK){ DBG_ERR("failed to memory munmap\r\n"); } ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } } #else void PBView_DrawErrorView(void) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_VIDEO_FRAME VdoDstDisp = {0}; //Display size VF_GFX_DRAW_RECT DrawRectDst = {0}; VF_GFX_DRAW_RECT *pDrawRectDst = &DrawRectDst; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); SIZECONVERT_INFO CovtInfo = {0}; HD_URECT DstDispRect = {0}; ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); } CovtInfo.uiSrcWidth = 2560; //hard code CovtInfo.uiSrcHeight = 1440; if (disp_rotate) { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.h; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.w; } else { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.w; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.h; } CovtInfo.uiDstWRatio = dst_aspect_ratio.w; CovtInfo.uiDstHRatio = dst_aspect_ratio.h; CovtInfo.alignType = SIZECONVERT_ALIGN_FLOOR_32; DisplaySizeConvert(&CovtInfo); if (CovtInfo.uiOutWidth && CovtInfo.uiOutHeight) { DstDispRect.x = CovtInfo.uiOutX; DstDispRect.y = CovtInfo.uiOutY; DstDispRect.w = CovtInfo.uiOutWidth; DstDispRect.h = CovtInfo.uiOutHeight; } else { DstDispRect.x = 0; DstDispRect.y = 0; DstDispRect.w = p_video_out_syscaps->output_dim.w; DstDispRect.h = p_video_out_syscaps->output_dim.h; } hd_view_buf.blk_size = DstDispRect.w*DstDispRect.h*3/2; //YUV420 PBView_get_hd_common_buf(&hd_view_buf); loff[0] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_view_buf.pa; loff[1] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + DstDispRect.w*DstDispRect.h); ret = vf_init_ex(&VdoDstDisp, DstDispRect.w, DstDispRect.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } VdoDstDisp.blk = hd_view_buf.blk; memcpy((void *)&pDrawRectDst->dst_img, (void *)&VdoDstDisp, sizeof(HD_VIDEO_FRAME)); pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->rect.x = 0; pDrawRectDst->rect.y = 0; pDrawRectDst->rect.w = VdoDstDisp.dim.w; pDrawRectDst->rect.h = VdoDstDisp.dim.h; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } ret = hd_videoout_push_in_buf(video_out_path, &VdoDstDisp, NULL, 0); // only support non-blocking mode now if (ret != HD_OK){ DBG_ERR("failed to push in buf of videoout\r\n"); } ret = hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); if (ret != HD_OK){ DBG_ERR("failed to memory munmap\r\n"); } ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } } #endif //#NT#2023/11/14#Eric - begin //#NT#Support IVOT_N12144_CO-148_A void PBView_DrawNoFile(void) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_VIDEO_FRAME VdoDstDisp = {0}; //Display size VF_GFX_DRAW_RECT DrawRectDst = {0}; VF_GFX_DRAW_RECT *pDrawRectDst = &DrawRectDst; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); ISIZE disp_size = GxVideo_GetDeviceSize(DOUT1); SIZECONVERT_INFO CovtInfo = {0}; HD_URECT DstDispRect = {0}; ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); } CovtInfo.uiSrcWidth = 2560; //hard code CovtInfo.uiSrcHeight = 1440; if (disp_rotate) { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.h; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.w; } else { CovtInfo.uiDstWidth = p_video_out_syscaps->output_dim.w; CovtInfo.uiDstHeight = p_video_out_syscaps->output_dim.h; } CovtInfo.uiDstWRatio = dst_aspect_ratio.w; CovtInfo.uiDstHRatio = dst_aspect_ratio.h; CovtInfo.alignType = SIZECONVERT_ALIGN_FLOOR_32; DisplaySizeConvert(&CovtInfo); if (CovtInfo.uiOutWidth && CovtInfo.uiOutHeight) { DstDispRect.x = CovtInfo.uiOutX; DstDispRect.y = CovtInfo.uiOutY; DstDispRect.w = CovtInfo.uiOutWidth; DstDispRect.h = CovtInfo.uiOutHeight; } else { DstDispRect.x = 0; DstDispRect.y = 0; DstDispRect.w = p_video_out_syscaps->output_dim.w; DstDispRect.h = p_video_out_syscaps->output_dim.h; } ///hard code DstDispRect.w = disp_size.w; DstDispRect.h = disp_size.h; hd_view_buf.blk_size = DstDispRect.w*DstDispRect.h*3/2; //YUV420 PBView_get_hd_common_buf(&hd_view_buf); loff[0] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_view_buf.pa; loff[1] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + DstDispRect.w*DstDispRect.h); ret = vf_init_ex(&VdoDstDisp, DstDispRect.w, DstDispRect.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } VdoDstDisp.blk = hd_view_buf.blk; memcpy((void *)&pDrawRectDst->dst_img, (void *)&VdoDstDisp, sizeof(HD_VIDEO_FRAME)); pDrawRectDst->color = COLOR_RGB_BLACK; pDrawRectDst->rect.x = 0; pDrawRectDst->rect.y = 0; pDrawRectDst->rect.w = VdoDstDisp.dim.w; pDrawRectDst->rect.h = VdoDstDisp.dim.h; pDrawRectDst->type = HD_GFX_RECT_SOLID; pDrawRectDst->thickness = 0; //Don't care for HD_GFX_RECT_SOLID pDrawRectDst->engine = 0; vf_gfx_draw_rect(pDrawRectDst); ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return; } ret = hd_videoout_push_in_buf(video_out_path, &VdoDstDisp, NULL, 0); // only support non-blocking mode now if (ret != HD_OK){ DBG_ERR("failed to push in buf of videoout\r\n"); } ret = hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); if (ret != HD_OK){ DBG_ERR("failed to memory munmap\r\n"); } ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } } //#NT#2023/11/14#Eric - end #if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together void PBView_DrawThumbFrame(UINT32 idx, UINT32 mode) { HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; ISIZE disp_size = GxVideo_GetDeviceSize(DOUT1); USIZE dst_aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); UINT32 thumb_w, thumb_h, buff_addr; VF_GFX_SCALE gfx_scale = {0}; VF_GFX_COPY gfx_copy; thumb_w = g_ThumbFrm[idx].dim.w; thumb_h = g_ThumbFrm[idx].dim.h; disp_size.w /= 2; // single view only on the right half part of display dst_aspect_ratio.w /= 2; // single view only on the right half part of display // scale and crop image from thumbnail frame to right side of display buffer // the method should be the same as PBView_DrawSingleView except 2 pass scaling if ((thumb_w * dst_aspect_ratio.h) > (dst_aspect_ratio.w * thumb_h)) { gfx_scale.engine = 0; gfx_scale.src_region.w = ALIGN_CEIL_4((thumb_h * dst_aspect_ratio.w) / dst_aspect_ratio.h); gfx_scale.src_region.h = thumb_h; gfx_scale.src_region.x = (thumb_w - gfx_scale.src_region.w) / 2; gfx_scale.src_region.y = 0; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = 0; gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } else { gfx_scale.engine = 0; gfx_scale.src_region.w = thumb_w; gfx_scale.src_region.h = ALIGN_CEIL_4((thumb_w * dst_aspect_ratio.h) / dst_aspect_ratio.w); gfx_scale.src_region.x = 0; gfx_scale.src_region.y = (thumb_h - gfx_scale.src_region.h) / 2; gfx_scale.dst_region.w = disp_size.w; gfx_scale.dst_region.h = disp_size.h; gfx_scale.dst_region.x = disp_size.w; // single view is on the right side of display gfx_scale.dst_region.y = 0; gfx_scale.quality = HD_GFX_SCALE_QUALITY_BILINEAR; } disp_size.w *= 2; // recall original display width // get new display buffer hd_view_buf.blk_size = disp_size.w * disp_size.h * 3 / 2; PBView_get_hd_common_buf(&hd_view_buf); if (mode == THUMB_DRAW_TMP_BUFFER) { // use display tmp buffer // scale image to display tmp buffer firstly, then copy to new display buffer buff_addr = mempool_disp_tmp; } else { // use new display buffer // scale image to new display buffer directly buff_addr = hd_view_buf.pa; } // scale image to display buffer loff[0] = disp_size.w; addr[0] = buff_addr; loff[1] = disp_size.w; addr[1] = ALIGN_CEIL_4(addr[0] + disp_size.w * disp_size.h); ret = vf_init_ex(&gfx_scale.dst_img, disp_size.w, disp_size.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); //return; } memcpy((void *)&gfx_scale.src_img, (void *)&g_ThumbFrm[idx], sizeof(HD_VIDEO_FRAME)); vf_gfx_scale(&gfx_scale, 1); if (mode == THUMB_DRAW_TMP_BUFFER) { // use display tmp buffer // copy whole image from display tmp buffer to new display buffer then push in gfx_copy.src_img = g_DispTmpFrm; if ((ret = vf_init(&gfx_copy.dst_img, disp_size.w, disp_size.h, g_DispTmpFrm.pxlfmt, disp_size.w, hd_view_buf.pa, (disp_size.w*disp_size.h*3)/2)) != HD_OK) { DBG_ERR("vf_init fail(%d)\r\n", ret); } gfx_copy.src_region.w = disp_size.w; // copy whole image } else { // use new display buffer // copy left part of last video frame buffer (thumbnail layout) to new display buffer gfx_copy.src_img = g_LastVdoFrm; if ((ret = vf_init(&gfx_copy.dst_img, disp_size.w, disp_size.h, g_LastVdoFrm.pxlfmt, disp_size.w, hd_view_buf.pa, (disp_size.w*disp_size.h*3)/2)) != HD_OK) { DBG_ERR("vf_init fail(%d)\r\n", ret); } gfx_copy.src_region.w = disp_size.w/2; // copy half image } gfx_copy.src_region.x = 0; gfx_copy.src_region.y = 0; gfx_copy.src_region.h = disp_size.h; gfx_copy.dst_pos.x = 0; gfx_copy.dst_pos.y = 0; gfx_copy.colorkey = 0; gfx_copy.alpha = 255; gfx_copy.engine = 0; if ((ret = vf_gfx_copy(&gfx_copy)) != HD_OK) { DBG_ERR("vf_gfx_copy fail(%d)\r\n", ret); } ret = hd_videoout_start(video_out_path); if (ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); //return; } // push in and release buffer gfx_copy.dst_img.blk = hd_view_buf.blk; ret = hd_videoout_push_in_buf(video_out_path, &gfx_copy.dst_img, NULL, 0); // only support non-blocking mode now if (ret != HD_OK) { DBG_ERR("failed to push in buf of videoout, %d\r\n", ret); } else { hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK) { DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } memcpy((void *)&g_LastVdoFrm, (void *)&gfx_copy.dst_img, sizeof(HD_VIDEO_FRAME)); } } #endif #if PLAY_THUMB_AND_MOVIE // play thumbnail and movie together ER PBView_OnThumbDraw(HD_VIDEO_FRAME *pHdDecVdoFrame, PUSIZE dst_ratio) { ER er; UINT32 uiIdx; UINT32 i, thumb_num=0; HD_RESULT ret = HD_OK; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; HD_VIDEO_FRAME VdoSrc = {0}; HD_VIDEO_FRAME VdoDstDisp = {0}; //Display size UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); HD_URECT DstDispRect = {0}; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); } DstDispRect.x = 0; DstDispRect.y = 0; if (disp_rotate) { DstDispRect.w = p_video_out_syscaps->output_dim.h; DstDispRect.h = p_video_out_syscaps->output_dim.w; } else { DstDispRect.w = p_video_out_syscaps->output_dim.w; DstDispRect.h = p_video_out_syscaps->output_dim.h; } loff[0] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = mempool_disp_tmp; loff[1] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + DstDispRect.w * DstDispRect.h); ret = vf_init_ex(&VdoDstDisp, DstDispRect.w, DstDispRect.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } PB_GetParam(PBPRMID_THUMB_CURR_NUM, (UINT32 *) &thumb_num); for (i = 0; i < thumb_num; i++) { uiIdx = (i & 0x1); if ((er = PB_LockThumb(uiIdx)) != E_OK) { //locked fail indicate skip this draw PB_SetPBFlag(PB_SET_FLG_BROWSER_END); return er; } PB_GetParam(PBPRMID_INFO_IMG, (UINT32 *)&VdoSrc); PBView_DrawThumbView(i, &VdoSrc, &VdoDstDisp, dst_ratio); uiIdx = ((i+1) & 0x1); PB_UnlockThumb(uiIdx); } memcpy((void *)&g_DispTmpFrm, (void *)&VdoDstDisp, sizeof(HD_VIDEO_FRAME)); #if 1 // set vout HD_VIDEOOUT_IN video_out_param={0}; HD_VIDEOOUT_WIN_ATTR video_out_win = {0}; video_out_param.dim.w = DstDispRect.w; video_out_param.dim.h = DstDispRect.h; video_out_param.pxlfmt = HD_VIDEO_PXLFMT_YUV420; video_out_param.dir = SysVideo_GetDirbyID(0); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN failed\r\n"); return E_SYS; } video_out_win.visible = TRUE; if (disp_rotate) { video_out_win.rect.x = DstDispRect.y; video_out_win.rect.y = DstDispRect.x; video_out_win.rect.w = DstDispRect.h; video_out_win.rect.h = DstDispRect.w; } else { video_out_win.rect.x = DstDispRect.x; video_out_win.rect.y = DstDispRect.y; video_out_win.rect.w = DstDispRect.w; video_out_win.rect.h = DstDispRect.h; } video_out_win.layer = HD_LAYER1; ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN_WIN_ATTR, &video_out_win); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN_WIN_ATTR fail\r\n"); } #endif PB_SetPBFlag(PB_SET_FLG_BROWSER_END); return E_OK; } #else ER PBView_OnThumbDraw(HD_VIDEO_FRAME *pHdDecVdoFrame, PUSIZE dst_ratio) { ER er; UINT32 uiIdx; UINT32 i, thumb_num=0; HD_RESULT ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_VIDEOOUT_SYSCAPS video_out_syscaps; HD_VIDEOOUT_SYSCAPS *p_video_out_syscaps = &video_out_syscaps; HD_VIDEO_FRAME VdoSrc = {0}; HD_VIDEO_FRAME VdoDstDisp = {0}; //Display size UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); HD_PATH_ID video_out_ctrl = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_CTRLPATH); HD_URECT DstDispRect = {0}; UINT32 disp_rotate = GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_SWAPXY); ret = hd_videoout_get(video_out_ctrl, HD_VIDEOOUT_PARAM_SYSCAPS, p_video_out_syscaps); if (ret != HD_OK) { DBG_ERR("get video_out_syscaps failed\r\n"); } hd_view_buf.blk_size = p_video_out_syscaps->output_dim.w*p_video_out_syscaps->output_dim.h*3/2; //YUV420 PBView_get_hd_common_buf(&hd_view_buf); DstDispRect.x = 0; DstDispRect.y = 0; if (disp_rotate) { DstDispRect.w = p_video_out_syscaps->output_dim.h; DstDispRect.h = p_video_out_syscaps->output_dim.w; } else { DstDispRect.w = p_video_out_syscaps->output_dim.w; DstDispRect.h = p_video_out_syscaps->output_dim.h; } loff[0] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[0] = hd_view_buf.pa; loff[1] = DstDispRect.w; //Besides rotate panel, the display device don't consider the line offset. addr[1] = ALIGN_CEIL_4(addr[0] + DstDispRect.w * DstDispRect.h); ret = vf_init_ex(&VdoDstDisp, DstDispRect.w, DstDispRect.h, HD_VIDEO_PXLFMT_YUV420, loff, addr); if (ret != HD_OK) { DBG_ERR("vf_init_ex dst failed\r\n"); } VdoDstDisp.blk = hd_view_buf.blk; PB_GetParam(PBPRMID_THUMB_CURR_NUM, (UINT32 *) &thumb_num); for (i = 0; i < thumb_num; i++) { uiIdx = (i & 0x1); if ((er = PB_LockThumb(uiIdx)) != E_OK) { //locked fail indicate skip this draw PB_SetPBFlag(PB_SET_FLG_BROWSER_END); return er; } PB_GetParam(PBPRMID_INFO_IMG, (UINT32 *)&VdoSrc); PBView_DrawThumbView(i, &VdoSrc, &VdoDstDisp, dst_ratio); uiIdx = ((i+1) & 0x1); PB_UnlockThumb(uiIdx); } #if 1 // set vout HD_VIDEOOUT_IN video_out_param={0}; HD_VIDEOOUT_WIN_ATTR video_out_win = {0}; video_out_param.dim.w = DstDispRect.w; video_out_param.dim.h = DstDispRect.h; video_out_param.pxlfmt = HD_VIDEO_PXLFMT_YUV420; video_out_param.dir = SysVideo_GetDirbyID(0); DBG_DUMP("PBView_OnThumbDraw: video_out_param w %d, h %d\r\n", video_out_param.dim.w, video_out_param.dim.h); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN, &video_out_param); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN failed\r\n"); return E_SYS; } video_out_win.visible = TRUE; if (disp_rotate) { video_out_win.rect.x = DstDispRect.y; video_out_win.rect.y = DstDispRect.x; video_out_win.rect.w = DstDispRect.h; video_out_win.rect.h = DstDispRect.w; } else { video_out_win.rect.x = DstDispRect.x; video_out_win.rect.y = DstDispRect.y; video_out_win.rect.w = DstDispRect.w; video_out_win.rect.h = DstDispRect.h; } video_out_win.layer = HD_LAYER1; DBG_DUMP("PBView_OnThumbDraw: video_out x %d, y %d, w %d, h %d\r\n", video_out_win.rect.x, video_out_win.rect.y, video_out_win.rect.w, video_out_win.rect.h); ret = hd_videoout_set(video_out_path, HD_VIDEOOUT_PARAM_IN_WIN_ATTR, &video_out_win); if (ret != HD_OK) { DBG_ERR("hd_videoout_set: HD_VIDEOOUT_PARAM_IN_WIN_ATTR fail\r\n"); } ret = hd_videoout_start(video_out_path); if(ret != HD_OK){ DBG_ERR("hd_videoout_start failed\r\n"); return E_SYS; } #endif VdoDstDisp.blk = hd_view_buf.blk; ret = hd_videoout_push_in_buf(video_out_path, &VdoDstDisp, NULL, 0); // only support non-blocking mode now if (ret != HD_OK){ DBG_ERR("failed to push in buf of videoout\r\n"); }else{ ret = hd_common_mem_munmap((void *)hd_view_buf.va, hd_view_buf.blk_size); if (ret != HD_OK){ DBG_ERR("failed to memory munmap\r\n"); } ret = hd_common_mem_release_block(hd_view_buf.blk); if (ret != HD_OK){ DBG_ERR("release blk(0x%x) failed\r\n", hd_view_buf.blk); } memcpy((void *)&g_LastVdoFrm, (void *)&VdoDstDisp, sizeof(HD_VIDEO_FRAME)); } PB_SetPBFlag(PB_SET_FLG_BROWSER_END); return E_OK; } #endif void PBView_OnDrawCB(PB_VIEW_STATE view_state, HD_VIDEO_FRAME *pHdDecVdoFrame) { UINT32 uiFileNum = 0; UINT32 u32CurrPbStatus = 0; PB_GetParam(PBPRMID_TOTAL_FILE_COUNT, &uiFileNum); PB_GetParam(PBPRMID_PLAYBACK_STATUS, &u32CurrPbStatus); if ((uiFileNum == 0) || (u32CurrPbStatus != PB_STA_DONE)){ PBView_DrawErrorView(); PB_SetPBFlag(PB_SET_FLG_DRAW_END); return; } if (view_state == PB_VIEW_STATE_SINGLE) { gfpDrawCb = PBView_OnSingleDraw; } else if (view_state == PB_VIEW_STATE_THUMB) { gfpDrawCb = PBView_OnThumbDraw; } gPbState = view_state; aspect_ratio = GxVideo_GetDeviceAspect(DOUT1); if (gPbState == PB_VIEW_STATE_THUMB) { gfpDrawCb(0, &aspect_ratio); }else{ gfpDrawCb(pHdDecVdoFrame, &aspect_ratio); } } #if _TODO //refer to NA51055-840 JIRA and using new method void PBView_KeepLastView(void) { HD_RESULT hd_ret = HD_OK; PBVIEW_HD_COM_BUF hd_view_buf = {0}; HD_COMMON_MEM_DDR_ID ddr_id = 0; VF_GFX_COPY copy_param; HD_PATH_ID video_out_path = (HD_PATH_ID)GxVideo_GetDeviceCtrl(DOUT1, DISPLAY_DEVCTRL_PATH); hd_view_buf.blk_size = g_LastVdoFrm.dim.w*g_LastVdoFrm.loff[0]*3/2; if ((hd_ret = hd_common_mem_alloc("NVTMPP_TEMP", &hd_view_buf.pa, (void **)&hd_view_buf.va, hd_view_buf.blk_size, ddr_id)) != HD_OK) { DBG_ERR("hd_common_mem_alloc fail(%d)\r\n", hd_ret); return; } copy_param.src_img = g_LastVdoFrm; if ((hd_ret = vf_init(&(copy_param.dst_img), g_LastVdoFrm.dim.w, g_LastVdoFrm.dim.h, g_LastVdoFrm.pxlfmt, g_LastVdoFrm.loff[0], hd_view_buf.pa, hd_view_buf.blk_size)) != HD_OK) { DBG_ERR("vf_init fail(%d)\r\n", hd_ret); return; } copy_param.src_region.x = 0; copy_param.src_region.y = 0; copy_param.src_region.w = g_LastVdoFrm.dim.w; copy_param.src_region.h = g_LastVdoFrm.dim.h; copy_param.dst_pos.x = 0; copy_param.dst_pos.y = 0; copy_param.colorkey = 0; copy_param.alpha = 255; copy_param.engine = 0; if ((hd_ret = vf_gfx_copy(©_param)) != HD_OK) { DBG_ERR("vf_gfx_copy fail(%d)\r\n", hd_ret); } copy_param.dst_img.blk = -2; if ((hd_ret = hd_videoout_push_in_buf(video_out_path, &(copy_param.dst_img), NULL, 500)) != HD_OK) { DBG_ERR("hd_videoout_push_in_buf fail(%d)\r\n", hd_ret); } } #endif