/* System Video Callback System Callback for Video Module. @file SysVideo_Exe.c @ingroup mIPRJSYS @note Copyright Novatek Microelectronics Corp. 2010. All rights reserved. */ //////////////////////////////////////////////////////////////////////////////// #include "PrjInc.h" //local debug level: THIS_DBGLVL #define THIS_DBGLVL 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER /////////////////////////////////////////////////////////////////////////////// #define __MODULE__ UIAppTranscode #define __DBGLVL__ ((THIS_DBGLVL>=PRJ_DBG_LVL)?THIS_DBGLVL:PRJ_DBG_LVL) #define __DBGFLT__ "*" //*=All, [mark]=CustomClass #include #include "UIApp/Transcode/UIAppTranscode.h" #include "UIApp/Photo/UIAppPhoto.h" #include "vendor_common.h" #include "FileSysTsk.h" #include "vf_gfx.h" #include "hd_videoenc.h" #if HUNTING_CAMERA_MCU == ENABLE #include "sf_common.h" #endif #define DBGINFO_BUFSIZE() (0x200) #define VDO_YUV_BUFSIZE(w, h, pxlfmt) (ALIGN_CEIL_4((w) * HD_VIDEO_PXLFMT_BPP(pxlfmt) / 8) * (h)) #if TRANSCODE_DBG_DUMP #define TRANSCODE_DUMP(fmtstr, args...) DBG_DUMP(fmtstr, ##args) /* debug dump macro */ #else #define TRANSCODE_DUMP(fmtstr, args...) #endif /******************************************************************************* * structure *******************************************************************************/ typedef struct { HD_COMMON_MEM_VB_BLK blk; UINT32 pa; void* va; UINT32 size; } _UIAppTranscode_Buf; typedef struct { /* internal param */ HD_PATH_ID vdec_path; HD_PATH_ID venc_path; BOOL is_init; /* user param */ UIAppTranscode_User_Config user_config; } _UIAppTranscode_Info; /******************************************************************************* * static variables *******************************************************************************/ static _UIAppTranscode_Info g_transcode_info = {0}; /******************************************************************************* * static functions *******************************************************************************/ static UINT32 _TranscodeExe_Get_Max_Cap_Buf_Size(void) { UINT32 max_cap_size_w = ALIGN_CEIL_64(GetPhotoSizeWidth(PHOTO_MAX_CAP_SIZE)); UINT32 max_cap_size_h = ALIGN_CEIL_64(GetPhotoSizeHeight(PHOTO_MAX_CAP_SIZE)); HD_VIDEO_PXLFMT pxl_fmt = HD_VIDEO_PXLFMT_YUV420; return VDO_YUV_BUFSIZE(max_cap_size_w, max_cap_size_h, pxl_fmt); } static UINT32 _TranscodeExe_Get_Target_Buf_Size(void) { UINT32 target_size_w = ALIGN_CEIL_64(sf_get_screen_nail_width(TRANSCODE_TARGET_PHOTO_SIZE)); UINT32 target_size_h = ALIGN_CEIL_64(sf_get_screen_nail_height(TRANSCODE_TARGET_PHOTO_SIZE)); HD_VIDEO_PXLFMT pxl_fmt = HD_VIDEO_PXLFMT_YUV420; return VDO_YUV_BUFSIZE(target_size_w, target_size_h, pxl_fmt); } static HD_DIM _TranscodeExe_Get_Target_Size(void) { return (HD_DIM){sf_get_screen_nail_width(TRANSCODE_TARGET_PHOTO_SIZE), sf_get_screen_nail_height(TRANSCODE_TARGET_PHOTO_SIZE)}; } static UINT32 _TranscodeExe_Get_Target_Bitrate(void) { return _TranscodeExe_Get_Target_Buf_Size() / 5; } static HD_RESULT _TranscodeExe_CommPool_Init(void) { HD_COMMON_MEM_INIT_CONFIG mem_cfg = {0}; UINT8 id = 0; HD_RESULT ret = HD_OK; /* src image yuv buffer */ mem_cfg.pool_info[id].type = HD_COMMON_MEM_COMMON_POOL; mem_cfg.pool_info[id].blk_size = DBGINFO_BUFSIZE() + _TranscodeExe_Get_Max_Cap_Buf_Size(); #if (HUNTING_CAMERA_MCU == ENABLE) && (SF_UBOOT_UPDATA_FW != ENABLE) if(sf_get_fw_update()) { mem_cfg.pool_info[id].blk_cnt = 0; }else { mem_cfg.pool_info[id].blk_cnt = 1; } #else mem_cfg.pool_info[id].blk_cnt = 1; #endif mem_cfg.pool_info[id].ddr_id = DDR_ID0; /* target size yuv buffer */ id++; mem_cfg.pool_info[id].type = HD_COMMON_MEM_COMMON_POOL; mem_cfg.pool_info[id].blk_size = DBGINFO_BUFSIZE() + _TranscodeExe_Get_Target_Buf_Size(); #if (HUNTING_CAMERA_MCU == ENABLE) && (SF_UBOOT_UPDATA_FW != ENABLE) if(sf_get_fw_update()) { mem_cfg.pool_info[id].blk_cnt = 0; }else { mem_cfg.pool_info[id].blk_cnt = 1; } #else mem_cfg.pool_info[id].blk_cnt = 1; #endif mem_cfg.pool_info[id].ddr_id = DDR_ID0; ret = vendor_common_mem_relayout(&mem_cfg); if (ret != HD_OK) { DBG_ERR("vendor_common_mem_relayout failed(%d)!\n", ret); return ret; } return ret; } static HD_RESULT _TranscodeExe_HDAL_Init(void) { HD_RESULT ret = HD_OK; if(FALSE == g_transcode_info.is_init){ ret = hd_videoenc_init(); if(ret != HD_OK){ DBG_ERR("hd_videoenc_init failed(%d)\n", ret); goto exit; } ret = hd_videodec_init(); if(ret != HD_OK){ DBG_ERR("hd_videodecc_init failed(%d)\n", ret); goto exit; } g_transcode_info.is_init = TRUE; } else{ DBG_WRN("already initialized\n"); } exit: return ret; } static HD_RESULT _TranscodeExe_HDAL_Uninit(void) { HD_RESULT ret = HD_OK; if(TRUE == g_transcode_info.is_init){ ret = hd_videoenc_uninit(); if(ret != HD_OK){ DBG_ERR("hd_videoenc_uninit failed(%d)\n", ret); goto exit; } ret = hd_videodec_uninit(); if(ret != HD_OK){ DBG_ERR("hd_videodecc_uninit failed(%d)\n", ret); goto exit; } g_transcode_info.is_init = FALSE; } else{ DBG_WRN("not initialized yet\n"); } exit: return ret; } static HD_RESULT _TranscodeExe_HDAL_Open(_UIAppTranscode_Info* info) { HD_RESULT ret = HD_OK; if(!g_transcode_info.venc_path){ ret = hd_videoenc_open(HD_VIDEOENC_0_IN_0, HD_VIDEOENC_0_OUT_0, &(info->venc_path)); if(ret != HD_OK){ DBG_ERR("hd_videoenc_open failed(%d)\n", ret); goto exit; } } if(!g_transcode_info.vdec_path){ ret = hd_videodec_open(HD_VIDEODEC_0_IN_0, HD_VIDEODEC_0_OUT_0, &(info->vdec_path)); if(ret != HD_OK){ DBG_ERR("hd_videoenc_open failed(%d)\n", ret); goto exit; } } exit: return ret; } static HD_RESULT _TranscodeExe_HDAL_Close(_UIAppTranscode_Info* info) { HD_RESULT ret = HD_OK; if(info->venc_path){ ret = hd_videoenc_close(info->venc_path); if(ret != HD_OK){ DBG_ERR("hd_videoenc_open failed(%d)\n", ret); goto exit; } info->venc_path = 0; } if(info->vdec_path){ ret = hd_videodec_close(info->vdec_path); if(ret != HD_OK){ DBG_ERR("hd_videodec_close failed(%d)\n", ret); goto exit; } info->vdec_path = 0; } exit: return ret; } static HD_RESULT _TranscodeExe_Get_Common_Buf(_UIAppTranscode_Buf* comm_buf) { comm_buf->blk = hd_common_mem_get_block(HD_COMMON_MEM_COMMON_POOL, comm_buf->size, DDR_ID0); // Get block from mem pool if (comm_buf->blk == HD_COMMON_MEM_VB_INVALID_BLK) { DBG_ERR("hd_common_mem_get_block failed(blk = 0x%x)!\n", comm_buf->blk); return HD_ERR_SYS; } comm_buf->pa = hd_common_mem_blk2pa(comm_buf->blk); // get physical addr if (comm_buf->pa == 0) { DBG_ERR("hd_common_mem_blk2pa failed(blk = 0x%x)\n", comm_buf->blk); return HD_ERR_SYS; } comm_buf->va = hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, comm_buf->pa, comm_buf->size); if (comm_buf->va == 0) { DBG_ERR("hd_common_mem_mmap failed!(pa = %lx)\n", comm_buf->pa); return HD_ERR_SYS; } TRANSCODE_DUMP("get common buffer(blk = %lx , pa = %lx , va = %lx , size = %lx)\r\n", comm_buf->blk, comm_buf->pa, comm_buf->va, comm_buf->size); return HD_OK; } static HD_RESULT _TranscodeExe_Release_Common_Buf(_UIAppTranscode_Buf* comm_buf) { HD_RESULT ret = HD_OK; TRANSCODE_DUMP("release comm buffer (blk = %lx, pa = %lx, va = %lx, size = %lx)\n", comm_buf->blk, comm_buf->pa, comm_buf->va, comm_buf->size ); hd_common_mem_munmap((void*)comm_buf->va, comm_buf->size); ret = hd_common_mem_release_block(comm_buf->blk); if (HD_OK != ret) { DBG_ERR("hd_common_mem_release_block failed(%d)\n", ret); } return ret; } static HD_RESULT _TranscodeExe_Convert_Common_Buf_To_Frame_Buf(_UIAppTranscode_Buf* comm_buf, HD_VIDEO_FRAME* frame) { if(!comm_buf || !frame){ DBG_ERR("comm_buf and frame can't be null!\n"); return HD_ERR_SYS; } frame->sign = MAKEFOURCC('V', 'F', 'R', 'M'); frame->ddr_id = DDR_ID0; frame->pxlfmt = HD_VIDEO_PXLFMT_YUV420; frame->dim.w = ALIGN_CEIL_64(GetPhotoSizeWidth(PHOTO_MAX_CAP_SIZE)); frame->dim.h = ALIGN_CEIL_64(GetPhotoSizeHeight(PHOTO_MAX_CAP_SIZE)); frame->phy_addr[0] = comm_buf->pa; frame->blk = comm_buf->blk; return HD_OK; } static HD_RESULT _TranscodeExe_Set_Decode_Cfg(HD_PATH_ID vdec_path) { HD_RESULT ret = HD_OK; HD_VIDEODEC_PATH_CONFIG path_cfg = {0}; HD_VIDEODEC_IN in_param = {0}; path_cfg.max_mem.codec_type = HD_CODEC_TYPE_JPEG; path_cfg.max_mem.dim.w = GetPhotoSizeWidth(PHOTO_MAX_CAP_SIZE); path_cfg.max_mem.dim.h = GetPhotoSizeHeight(PHOTO_MAX_CAP_SIZE); ret = hd_videodec_set(vdec_path, HD_VIDEODEC_PARAM_PATH_CONFIG, &path_cfg); if (ret != HD_OK) { DBG_ERR("hd_videodec_set HD_VIDEODEC_PARAM_PATH_CONFIG failed!(%d)\n", ret); goto exit; } in_param.codec_type = HD_CODEC_TYPE_JPEG; ret = hd_videodec_set(vdec_path, HD_VIDEODEC_PARAM_IN, &in_param); if (ret != HD_OK) { DBG_ERR("set HD_VIDEODEC_PARAM_IN(%d) !!\r\n\r\n", ret); goto exit; } exit: return ret; } static HD_RESULT _TranscodeExe_Set_Encode_Param(HD_PATH_ID venc_path, HD_DIM target_size, UINT quality) { HD_RESULT ret; HD_VIDEOENC_OUT enc_out = {0}; HD_VIDEOENC_IN enc_in = {0}; enc_out.codec_type = HD_CODEC_TYPE_JPEG; enc_out.jpeg.retstart_interval = 0; enc_out.jpeg.image_quality = quality; TRANSCODE_DUMP("hd_videoenc_set HD_VIDEOENC_PARAM_OUT_ENC_PARAM path_id={%lx} image_quality={%lu}\r\n", venc_path, enc_out.jpeg.image_quality); ret = hd_videoenc_set(venc_path, HD_VIDEOENC_PARAM_OUT_ENC_PARAM, &enc_out); if (ret != HD_OK) { DBG_ERR("set_enc_param_out = %d\r\n", ret); goto exit; } enc_in.dir = HD_VIDEO_DIR_NONE; enc_in.pxl_fmt = HD_VIDEO_PXLFMT_YUV420; enc_in.dim = target_size; enc_in.frc = HD_VIDEO_FRC_RATIO(1,1); TRANSCODE_DUMP("hd_videoenc_set HD_VIDEOENC_PARAM_IN path_id={%lx} dim={%lu, %lu} pxlfmt={%lx}\r\n", venc_path, enc_in.dim, HD_VIDEO_PXLFMT_YUV420); ret = hd_videoenc_set(venc_path, HD_VIDEOENC_PARAM_IN, &enc_in); if(ret != HD_OK){ DBG_ERR("hd_videoenc_set HD_VIDEOENC_PARAM_IN failed(path_id=%lx, ret=%d)!", venc_path, ret); goto exit; } exit: return ret; } static HD_RESULT _TranscodeExe_Set_Encode_Cfg(HD_PATH_ID venc_path, HD_DIM target_size, UINT32 target_bitrate) { HD_RESULT ret; HD_VIDEOENC_PATH_CONFIG enc_path_config = {0}; enc_path_config.max_mem.codec_type = HD_CODEC_TYPE_JPEG; enc_path_config.max_mem.max_dim = target_size; enc_path_config.max_mem.bitrate = target_bitrate; enc_path_config.max_mem.enc_buf_ms = 1500; enc_path_config.max_mem.svc_layer = HD_SVC_DISABLE; enc_path_config.max_mem.ltr = FALSE; enc_path_config.max_mem.rotate = FALSE; enc_path_config.max_mem.source_output = FALSE; enc_path_config.isp_id = 0; TRANSCODE_DUMP("hd_videoenc_set HD_VIDEOENC_PARAM_PATH_CONFIG max_dim={%lu, %lu} bitrate={%lu}\r\n", target_size.w, target_size.h, target_bitrate); ret = hd_videoenc_set(venc_path, HD_VIDEOENC_PARAM_PATH_CONFIG, &enc_path_config); if (ret != HD_OK) { DBG_ERR("hd_videoenc_set HD_VIDEOENC_PARAM_PATH_CONFIG failed(%d)\r\n", ret); goto exit; } exit: return ret; } static HD_RESULT _Transcode_Encode_Get_Enc_Buffer_Info( HD_PATH_ID enc_path, _UIAppTranscode_Buf* buf) { HD_RESULT ret; HD_VIDEOENC_BUFINFO enc_buf_info = {0}; if ((ret = hd_videoenc_get(enc_path, HD_VIDEOENC_PARAM_BUFINFO, &enc_buf_info)) != HD_OK) { DBG_ERR("hd_videoenc_get HD_VIDEOENC_PARAM_BUFINFO failed!(%d)\n", ret); return E_SYS; } buf->pa = enc_buf_info.buf_info.phy_addr; buf->size = enc_buf_info.buf_info.buf_size; buf->va = hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, buf->pa, buf->size); if (buf->va == 0) { DBG_ERR("enc_vir_addr mmap error!!\r\n\r\n"); return E_SYS; } TRANSCODE_DUMP("hd_videoenc_get HD_VIDEOENC_PARAM_BUFINFO blk_size={%lx} pa={%lx} va={%lx}\r\n", buf->size, buf->pa, buf->va); return E_OK; } static HD_RESULT _Transcode_Encode( HD_PATH_ID enc_path, _UIAppTranscode_Buf* hd_enc_buf, HD_VIDEO_FRAME* dst_frame, HD_VIDEOENC_BS* dst_bitstream) { HD_RESULT ret = HD_OK; ret = hd_videoenc_start(enc_path); if (ret != HD_OK) { DBG_ERR("hd_videodec_start(%d)!\n", ret); goto exit; } ret = _Transcode_Encode_Get_Enc_Buffer_Info(enc_path, hd_enc_buf); if (ret != HD_OK) { goto exit; } ret = hd_videoenc_push_in_buf(enc_path, dst_frame, NULL, -1); if (ret != HD_OK) { DBG_ERR("hd_videoenc_push_in_buf failed!(%d)\r\n", ret); goto exit; } ret = hd_videoenc_pull_out_buf(enc_path, dst_bitstream, -1); if (ret != HD_OK) { DBG_ERR("hd_videoenc_pull_out_buf failed!(%d)\r\n", ret); goto exit; } ret = hd_videoenc_stop(enc_path); if (ret != HD_OK) { DBG_ERR("hd_videoenc_stop(%d)!\n", ret); goto exit; } exit: return ret; } static HD_RESULT _TranscodeExe_Decode( HD_PATH_ID vdec_path, FST_FILE fp, _UIAppTranscode_Buf* src_bs_buf, _UIAppTranscode_Buf* src_yuv_buf, HD_VIDEO_FRAME* src_frame) { HD_RESULT ret = HD_OK; HD_VIDEODEC_BS bitstream = {0}; ret = hd_videodec_start(vdec_path); if (ret != HD_OK) { DBG_ERR("hd_videodec_start(%d)!\n", ret); goto exit; } /****************************************** * bitstream buffer ******************************************/ ret = hd_common_mem_alloc("trans_bs_buf", &src_bs_buf->pa, &src_bs_buf->va, src_bs_buf->size, DDR_ID0); if(ret != HD_OK || !src_bs_buf->pa || !src_bs_buf->va){ DBG_ERR("file size is zero!\n"); goto exit; } bitstream.sign = MAKEFOURCC('V','S','T','M'); bitstream.p_next = NULL; bitstream.ddr_id = DDR_ID0; bitstream.vcodec_format = HD_CODEC_TYPE_JPEG; bitstream.timestamp = hd_gettime_us(); bitstream.count = 0; bitstream.phy_addr = src_bs_buf->pa; bitstream.size = src_bs_buf->size; bitstream.blk = -2; /* read bs data */ if(FileSys_ReadFile(fp, src_bs_buf->va, &src_bs_buf->size, 0, NULL) != FST_STA_OK){ goto exit; } ret = hd_common_mem_flush_cache(src_bs_buf->va, src_bs_buf->size); if(ret != HD_OK){ DBG_ERR("hd_common_mem_flush_cache failed(%d)!\n", ret); goto exit; } /****************************************** * yuv buffer ******************************************/ ret = _TranscodeExe_Get_Common_Buf(src_yuv_buf); if(ret != HD_OK){ DBG_ERR("get common buffer failed!(size = %lx)\n", src_yuv_buf->size); goto exit; } ret = _TranscodeExe_Convert_Common_Buf_To_Frame_Buf(src_yuv_buf, src_frame); if(ret != HD_OK){ DBG_ERR("get common buffer failed!(size = %lx)\n", src_yuv_buf->size); goto exit; } /****************************************** * decode ******************************************/ ret = hd_videodec_push_in_buf(vdec_path, &bitstream, src_frame, -1); if(ret != HD_OK){ DBG_ERR("hd_videodec_push_in_buf failed(%d)\n", ret); goto exit; } else{ hd_videodec_release_out_buf(vdec_path, src_frame); } ret = hd_videodec_pull_out_buf(vdec_path, src_frame, 3000); if(ret != HD_OK){ DBG_ERR("hd_videodec_pull_out_buf failed(%d)\n", ret); goto exit; } exit: ret = hd_videodec_stop(vdec_path); if (ret != HD_OK) { DBG_ERR("hd_videodec_start(%d)!\n", ret); } return ret; } static ER _Transcode_Scale_YUV( VF_GFX_SCALE *pscale, const HD_VIDEO_FRAME *psrc, _UIAppTranscode_Buf* dst_yuv_buf, USIZE *pdest_sz, URECT *pdestwin, HD_VIDEO_PXLFMT pxl_fmt) { UINT32 blk_size; UINT32 addr[HD_VIDEO_MAX_PLANE] = {0}; UINT32 loff[HD_VIDEO_MAX_PLANE] = {0}; VF_GFX_DRAW_RECT fill_rect = {0}; HD_RESULT hd_ret; blk_size = VDO_YUV_BUFSIZE(pdest_sz->w, pdest_sz->h, pxl_fmt); if (blk_size > dst_yuv_buf->size) { DBG_ERR("Request blk_size(%d) > pComBufInfo->blk_size(%d)\r\n", blk_size, dst_yuv_buf->size); return E_SYS; } memcpy(&pscale->src_img, psrc, sizeof(HD_VIDEO_FRAME)); addr[0] = dst_yuv_buf->pa; loff[0] = ALIGN_CEIL_4(pdest_sz->w); if(pxl_fmt == HD_VIDEO_PXLFMT_YUV420 ){ addr[1] = addr[0] + loff[0] * pdest_sz->h; loff[1] = ALIGN_CEIL_4(pdest_sz->w); }else{ addr[1] = addr[0] + loff[0] * pdest_sz->h; loff[1] = ALIGN_CEIL_4(pdest_sz->w); addr[2] = addr[0] + loff[0] * pdest_sz->h + (loff[1] * pdest_sz->h)/2; loff[2] = ALIGN_CEIL_4(pdest_sz->w); } if ((hd_ret = vf_init_ex(&(pscale->dst_img), pdest_sz->w, pdest_sz->h, pxl_fmt, loff, addr)) != HD_OK) { DBG_ERR("vf_init_ex dst failed(%d)\r\n", hd_ret); } if ((pdest_sz->w != pdestwin->w ) || (pdest_sz->h != pdestwin->h)) { // clear buffer by black //gximg_fill_data((VDO_FRAME *)&(pscale->dst_img), GXIMG_REGION_MATCH_IMG, COLOR_YUV_BLACK); memcpy((void *)&(fill_rect.dst_img), (void *)&(pscale->dst_img), sizeof(HD_VIDEO_FRAME)); fill_rect.color = COLOR_RGB_BLACK; fill_rect.rect.x = 0; fill_rect.rect.y = 0; fill_rect.rect.w = pdest_sz->w; fill_rect.rect.h = pdest_sz->h; fill_rect.type = HD_GFX_RECT_SOLID; fill_rect.thickness = 0; fill_rect.engine = 0; if ((hd_ret = vf_gfx_draw_rect(&fill_rect)) != HD_OK) { DBG_ERR("vf_gfx_draw_rect failed(%d)\r\n", hd_ret); } } pscale->engine = 0; pscale->src_region.x = 0; pscale->src_region.y = 0; pscale->src_region.w = psrc->dim.w; pscale->src_region.h = psrc->dim.h; pscale->dst_region.x = pdestwin->x; pscale->dst_region.y = pdestwin->y; pscale->dst_region.w = pdestwin->w; pscale->dst_region.h = pdestwin->h; pscale->dst_img.blk = dst_yuv_buf->blk; pscale->quality = HD_GFX_SCALE_QUALITY_BILINEAR; vf_gfx_scale(pscale, 1); pscale->dst_img.count = 0; pscale->dst_img.timestamp = hd_gettime_us(); return E_OK; } static HD_RESULT _TranscodeExe_Scale_Target_Frame( HD_VIDEO_FRAME* in_frame, HD_DIM target_size, _UIAppTranscode_Buf* dst_yuv_buf, HD_VIDEO_FRAME* out_frame) { INT32 ret; VF_GFX_SCALE vf_gfx_scale = {0}; URECT dest_win = {0}; USIZE src_size = {0}, dest_size = {0}; void PhotoExe_Cal_Jpg_Size(USIZE *psrc, USIZE *pdest , URECT *pdestwin); src_size.w = in_frame->dim.w; src_size.h = in_frame->dim.h; dest_size.w = target_size.w; dest_size.h = target_size.h; PhotoExe_Cal_Jpg_Size(&src_size, &dest_size , &dest_win); /* ********************************************** * Padding * 4:3 -> 16:9 left/right * 16:9 -> 4:3 up/down * **********************************************/ TRANSCODE_DUMP("src = {%lu, %lu} , dst = {%lu, %lu} , dst win = {%lu, %lu, %lu, %lu}\n", src_size.w, src_size.h, dest_size.w, dest_size.h, dest_win.x, dest_win.y, dest_win.w, dest_win.h ); ret = _Transcode_Scale_YUV(&vf_gfx_scale, in_frame, dst_yuv_buf, &dest_size, &dest_win, HD_VIDEO_PXLFMT_YUV420); if(ret != E_OK){ return ret; } *out_frame = vf_gfx_scale.dst_img; return E_OK; } static void* _TranscodeExe_Bitsream_pa_to_va( HD_VIDEOENC_BS* bitstream, _UIAppTranscode_Buf* hd_enc_buf) { UINT32 offset = bitstream->video_pack[0].phy_addr - hd_enc_buf->pa; if(bitstream->video_pack[0].phy_addr == 0 || hd_enc_buf->pa == 0 || (bitstream->video_pack[0].phy_addr < hd_enc_buf->pa)){ DBG_ERR("invalid enc phy address(buffer start pa = %lx , bs pa = $lx)\n", hd_enc_buf->pa, bitstream->video_pack[0].phy_addr); return NULL; } else{ return hd_enc_buf->va + offset; } } #if TRANSCODE_DBG_DUMP_YUV static INT32 _TranscodeExe_Dump_Frame( char* filename_prefix, HD_VIDEO_FRAME video_frame) { char filename[128] = {0}; FST_FILE fp = NULL; UINT32 size; void* va; UINT32 offset = 0; sprintf(filename, "A:\\%s_%lux%lu_fmt%lx.dat", filename_prefix, video_frame.dim.w, video_frame.dim.h, video_frame.pxlfmt); fp = FileSys_OpenFile(filename, FST_OPEN_WRITE | FST_CREATE_ALWAYS); if(fp){ size = VDO_YUV_BUFSIZE(video_frame.dim.w, video_frame.dim.h, video_frame.pxlfmt); va = hd_common_mem_mmap(HD_COMMON_MEM_MEM_TYPE_CACHE, video_frame.phy_addr[0], size); if (va == 0) { DBG_ERR("hd_common_mem_mmap error!r\n"); return E_SYS; } hd_common_mem_flush_cache(va, size); size = video_frame.loff[0] * video_frame.ph[0]; FileSys_WriteFile(fp, va, &size, 0, NULL); offset = video_frame.phy_addr[1] - video_frame.phy_addr[0]; size = video_frame.loff[1] * video_frame.ph[1]; FileSys_WriteFile(fp, (UINT8*)va + offset, &size, 0, NULL); FileSys_FlushFile(fp); FileSys_CloseFile(fp); hd_common_mem_munmap(va, size); } return E_OK; } static INT32 _TranscodeExe_Dump_Bitstream( char* filename_prefix, HD_VIDEOENC_BS* dst_bitstream, _UIAppTranscode_Buf* hd_enc_buf) { char filename[128] = {0}; FST_FILE fp = NULL; void* va = _TranscodeExe_Bitsream_pa_to_va(dst_bitstream, hd_enc_buf); if(va == NULL){ return E_SYS; } sprintf(filename, "A:\\%s.jpg", filename_prefix); fp = FileSys_OpenFile(filename, FST_OPEN_WRITE | FST_CREATE_ALWAYS); if(fp){ UINT32 size = dst_bitstream->video_pack[0].size; hd_common_mem_flush_cache(hd_enc_buf->va, hd_enc_buf->size); FileSys_WriteFile(fp, va, &size, 0, NULL); FileSys_FlushFile(fp); FileSys_CloseFile(fp); } return E_OK; } #endif /******************************************************************************* * cmd callback function *******************************************************************************/ INT32 TranscodeExe_Open(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { DBG_FUNC_BEGIN(); HD_RESULT ret = HD_OK; HD_DIM target_size = _TranscodeExe_Get_Target_Size(); UINT target_bitreate = _TranscodeExe_Get_Target_Bitrate(); ret = _TranscodeExe_CommPool_Init(); if(ret != HD_OK) goto exit; ret = _TranscodeExe_HDAL_Init(); if(ret != HD_OK) goto exit; ret = _TranscodeExe_HDAL_Open(&g_transcode_info); if(ret != HD_OK) goto exit; ret = _TranscodeExe_Set_Decode_Cfg(g_transcode_info.vdec_path); if(ret != HD_OK){ goto exit; } ret = _TranscodeExe_Set_Encode_Cfg( g_transcode_info.venc_path, target_size, target_bitreate*2); if(ret != HD_OK){ goto exit; } DBG_FUNC_END() exit: return NVTEVT_CONSUME; } INT32 TranscodeExe_Close(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { DBG_FUNC_BEGIN(); _TranscodeExe_HDAL_Close(&g_transcode_info); _TranscodeExe_HDAL_Uninit(); DBG_FUNC_END(); return NVTEVT_CONSUME; } INT32 TranscodeExe_Start(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { DBG_FUNC_BEGIN(); FST_FILE fp = NULL; FST_FILE_STATUS file_status = {0}; INT32 ret = E_OK; UIAppTranscode_User_Config user_config = {0}; _UIAppTranscode_Buf src_bs_buf = {0}; _UIAppTranscode_Buf src_yuv_buf = {0}; _UIAppTranscode_Buf dst_yuv_buf = {0}; HD_VIDEO_FRAME src_frame = {0}; HD_VIDEO_FRAME dst_frame = {0}; HD_VIDEOENC_BS dst_bitstream = {0}; _UIAppTranscode_Buf hd_enc_buf = {0}; HD_DIM target_size = {0}; if(g_transcode_info.is_init == FALSE){ DBG_ERR("not initialized yet!\n"); ret = E_SYS; goto exit; } if(paramNum == 0){ DBG_ERR("no transcode parameter!\n"); ret = E_SYS; goto exit; } user_config = *((UIAppTranscode_User_Config*) paramArray[0]); if(user_config.filepath == NULL){ DBG_ERR("filepath not found!!\n"); ret = E_SYS; goto exit; } g_transcode_info.user_config = user_config; target_size = _TranscodeExe_Get_Target_Size(); fp = FileSys_OpenFile(user_config.filepath, FST_OPEN_READ); if(fp == NULL){ DBG_ERR("FileSys_OpenFile failed!(%s)\n", user_config.filepath); ret = E_SYS; goto exit; } ret = FileSys_StatFile(fp, &file_status); if(ret != FST_STA_OK){ goto exit; } if(0 == file_status.uiFileSize){ DBG_ERR("file size is zero!\n"); ret = E_SYS; goto exit; } /* assign bs and yuv buffer size */ src_bs_buf.size = ALIGN_CEIL_32(file_status.uiFileSize); src_yuv_buf.size = _TranscodeExe_Get_Max_Cap_Buf_Size(); ret = _TranscodeExe_Decode( g_transcode_info.vdec_path, fp, &src_bs_buf, &src_yuv_buf, &src_frame); if(ret != HD_OK){ goto exit; } ret = FileSys_CloseFile(fp); fp = NULL; if(ret != FST_STA_OK){ goto exit; } #if TRANSCODE_DBG_DUMP_YUV _TranscodeExe_Dump_Frame("src_image", src_frame); #endif dst_yuv_buf.size = _TranscodeExe_Get_Target_Buf_Size(); ret = _TranscodeExe_Get_Common_Buf(&dst_yuv_buf); if(ret != HD_OK){ DBG_ERR("get common buffer failed!(size = %lx)\n", dst_yuv_buf.size); goto exit; } ret = _TranscodeExe_Scale_Target_Frame( &src_frame, target_size, &dst_yuv_buf, &dst_frame); if(ret != HD_OK){ goto exit; } #if TRANSCODE_DBG_DUMP_YUV _TranscodeExe_Dump_Frame("target_image", src_frame); #endif ret = _TranscodeExe_Set_Encode_Param(g_transcode_info.venc_path, target_size, TRANSCODE_TARGET_INIT_QUALITY); if(ret != HD_OK){ goto exit; } ret = _Transcode_Encode(g_transcode_info.venc_path, &hd_enc_buf, &dst_frame, &dst_bitstream); if(ret != HD_OK){ goto exit; } #if TRANSCODE_DBG_DUMP_BS _TranscodeExe_Dump_Bitstream("target_bs", &dst_bitstream, &hd_enc_buf); #endif /**************************************************** * user callback ****************************************************/ if(g_transcode_info.user_config.bs_ready_cb){ void* va = _TranscodeExe_Bitsream_pa_to_va(&dst_bitstream, &hd_enc_buf); g_transcode_info.user_config.bs_ready_cb(va, dst_bitstream.video_pack[0].size); } exit: if(ret != HD_OK){ DBG_ERR("transcode error(%d)!", ret); } if(dst_bitstream.video_pack[0].phy_addr){ hd_videoenc_release_out_buf(g_transcode_info.venc_path, &dst_bitstream); } if(src_frame.phy_addr[0]){ hd_videodec_release_out_buf(g_transcode_info.vdec_path, &src_frame); hd_common_mem_munmap((void*)src_yuv_buf.va, src_yuv_buf.size); src_yuv_buf.va = 0; src_yuv_buf.pa = 0; } else if(src_yuv_buf.va){ _TranscodeExe_Release_Common_Buf(&src_yuv_buf); src_yuv_buf.va = 0; src_yuv_buf.pa = 0; } if(src_bs_buf.va){ hd_common_mem_free(src_bs_buf.pa, src_bs_buf.va); src_bs_buf.pa = 0; src_bs_buf.va = 0; } if(dst_yuv_buf.va){ _TranscodeExe_Release_Common_Buf(&dst_yuv_buf); dst_yuv_buf.va = 0; dst_yuv_buf.pa = 0; } if(hd_enc_buf.va && hd_enc_buf.size){ hd_common_mem_munmap(hd_enc_buf.va, hd_enc_buf.size); hd_enc_buf.va = 0; } if(fp){ FileSys_CloseFile(fp); fp = NULL; } DBG_FUNC_END(); return NVTEVT_CONSUME; } EVENT_ENTRY CustomTranscodeObjCmdMap[] = { {NVTEVT_EXE_OPEN, TranscodeExe_Open }, {NVTEVT_EXE_CLOSE, TranscodeExe_Close }, {NVTEVT_EXE_TRANSCODE_START, TranscodeExe_Start }, {NVTEVT_NULL, 0}, }; CREATE_APP(CustomTranscodeObj, APP_SETUP)