diff --git a/code/application/source/cardv/Makefile b/code/application/source/cardv/Makefile index 7ec01bc4d..96f56ea36 100644 --- a/code/application/source/cardv/Makefile +++ b/code/application/source/cardv/Makefile @@ -181,6 +181,8 @@ SRC = \ ./SrcCode/UIApp/Voice/UIAppVoice_CB.c \ ./SrcCode/UIApp/Voice/UIAppVoice_cmd.c \ ./SrcCode/UIApp/Voice/UIAppVoice_Exe.c \ + ./SrcCode/UIApp/Transcode/UIAppTranscode_Exe.c \ + ./SrcCode/UIApp/Transcode/UIAppTranscode_cmd.c \ ./SrcCode/Mode/UIMode.c \ ./SrcCode/Mode/UIModeMain.c \ ./SrcCode/Mode/UIModeMovie.c \ @@ -193,7 +195,8 @@ SRC = \ ./SrcCode/Mode/UIModeUsbPTP.c \ ./SrcCode/Mode/UIMode_cmd.c \ ./SrcCode/Mode/UIModeWifi.c \ - ./SrcCode/Mode/UIModeVoice.c + ./SrcCode/Mode/UIModeVoice.c \ + ./SrcCode/Mode/UIModeTranscode.c #SRC += \ # ./SrcCode/UIApp/AI/yolov5s_postprocess.c \ diff --git a/code/application/source/cardv/SrcCode/Mode/UIModeTranscode.c b/code/application/source/cardv/SrcCode/Mode/UIModeTranscode.c new file mode 100644 index 000000000..46452535e --- /dev/null +++ b/code/application/source/cardv/SrcCode/Mode/UIModeTranscode.c @@ -0,0 +1,77 @@ +#include "PrjInc.h" + +//////////////////////////////////////////////////////////////////////////////// +#include "SysCommon.h" +//#include "AppCommon.h" +//////////////////////////////////////////////////////////////////////////////// +#include "UIApp/AppLib.h" +#include "Mode/UIMode.h" +#include "Mode/UIModeTranscode.h" +#include "UIFrameworkExt.h" +#include "UIWnd/UIFlow.h" +#include "UIApp/Transcode/UIAppTranscode.h" + +/////////////////////////////////////////////////////////////////////////////// +#define __MODULE__ UIModeTranscode +#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 + + +int PRIMARY_MODE_TRANSCODE = -1; ///< UpdFw +int SYS_SUBMODE_TRANSCODE = -1; +void ModeTranscode_Open(void); +void ModeTranscode_Close(void); + +void ModeTranscode_Open(void) +{ + DBG_FUNC_BEGIN("\r\n"); + Ux_SetActiveApp(&CustomTranscodeObjCtrl); + Ux_SendEvent(0, NVTEVT_EXE_OPEN, 0); +#if(UI_FUNC==ENABLE) + if (System_GetState(SYS_STATE_CURRSUBMODE) == SYS_SUBMODE_NORMAL) { + //Ux_OpenWindow((VControl *)(&UIUpdFwWndCtrl), 0); + } else { + SYS_SUBMODE *pCurSubMode = System_GetSubModeCtrl(); + if (pCurSubMode && pCurSubMode->pfSubMode_OnOpen) { + pCurSubMode->pfSubMode_OnOpen(); + } + } +#endif + DBG_FUNC_END("\r\n"); + +} +void ModeTranscode_Close(void) +{ + DBG_FUNC_BEGIN("\r\n"); +#if(UI_FUNC==ENABLE) + if (System_GetState(SYS_STATE_CURRSUBMODE) == SYS_SUBMODE_NORMAL) { + //Ux_CloseWindow((VControl *)(&UIUpdFwWndCtrl), 0); + } else { + SYS_SUBMODE *pCurSubMode = System_GetSubModeCtrl(); + if (pCurSubMode && pCurSubMode->pfSubMode_OnClose) { + pCurSubMode->pfSubMode_OnClose(); + } + } +#endif + + Ux_SendEvent(0, NVTEVT_EXE_CLOSE, 0); + DBG_FUNC_END("\r\n"); + +} + +SYS_MODE gModeTranscode = { + "TRANSCODE", + ModeTranscode_Open, + ModeTranscode_Close, + NULL, + NULL, + NULL, + NULL +}; + +SYS_SUBMODE gSubModeTranscode = { + "SUBTRANSCODE", + NULL, + NULL, +}; diff --git a/code/application/source/cardv/SrcCode/Mode/UIMode_cmd.c b/code/application/source/cardv/SrcCode/Mode/UIMode_cmd.c old mode 100755 new mode 100644 index 16fd6dcc3..a5307629f --- a/code/application/source/cardv/SrcCode/Mode/UIMode_cmd.c +++ b/code/application/source/cardv/SrcCode/Mode/UIMode_cmd.c @@ -201,6 +201,15 @@ static BOOL Cmd_mode_updfw(unsigned char argc, char **argv) return TRUE; } +static BOOL Cmd_mode_transcode(unsigned char argc, char **argv) +{ + + DBG_DUMP("Transcode Mode\r\n"); + Ux_PostEvent(NVTEVT_SYSTEM_MODE, 1, PRIMARY_MODE_TRANSCODE); + + return TRUE; +} + UINT32 g_lviewframeRate = 30, g_lviewTargetRate = (800 * 1024), g_lviewQueueFrame = 2, g_lviewPort = 8192, g_lviewTaskPri = 6, g_hwmemcpy = 1, g_maxJpgSize = 204800, g_reqDelay = 0; static BOOL Cmd_mode_lview(unsigned char argc, char **argv) @@ -286,6 +295,7 @@ SXCMD_ITEM("sleep", Cmd_mode_sleep, "sleep mode") SXCMD_ITEM("lview %", Cmd_mode_lview, "live view mode setting") SXCMD_ITEM("ipcam", Cmd_mode_ipcam, "ipcam mode") SXCMD_ITEM("updfw", Cmd_mode_updfw, "update firmware mode") +SXCMD_ITEM("transcode", Cmd_mode_transcode, "transcode mode") //#NT#2016/05/31#Ben Wang -begin //#NT#Add UVC multimedia function. #if(UVC_MULTIMEDIA_FUNC == ENABLE) diff --git a/code/application/source/cardv/SrcCode/System/SysMain.c b/code/application/source/cardv/SrcCode/System/SysMain.c old mode 100755 new mode 100644 index 9921696cf..702dfd814 --- a/code/application/source/cardv/SrcCode/System/SysMain.c +++ b/code/application/source/cardv/SrcCode/System/SysMain.c @@ -165,6 +165,8 @@ void System_InstallModeObj(void) #if (VOICE_MODE == ENABLE) PRIMARY_MODE_VOICE = System_AddMode(&gModeVoice); #endif + + PRIMARY_MODE_TRANSCODE = System_AddMode(&gModeTranscode); } ///////////////////////////////////////////////////////////////////////////// diff --git a/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode.h b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode.h new file mode 100644 index 000000000..39d2227a6 --- /dev/null +++ b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode.h @@ -0,0 +1,32 @@ + +#ifndef _UIAPPTRANSCODE_H_ +#define _UIAPPTRANSCODE_H_ +#include "PrjInc.h" +#include "UIApp/UIAppCommon.h" + +typedef enum { + NVTEVT_TRANSCODE_EVT_START = APPUSER_TRANSCODE_BASE, + NVTEVT_EXE_TRANSCODE_START = NVTEVT_TRANSCODE_EVT_START, + NVTEVT_EXE_TRANSCODE_REL_BS_BUF, +} +CUSTOM_TRANSCODE_EVENT; + +typedef void (*TRANSCODE_BS_READY_CB)(void* bitstream_va, UINT32 size); + +#define TRANSCODE_DBG_DUMP 0 +#define TRANSCODE_DBG_DUMP_YUV 0 +#define TRANSCODE_DBG_DUMP_BS 0 + +#define TRANSCODE_TARGET_PHOTO_SIZE UIAPP_PHOTO_SIZE_2M +#define TRANSCODE_TARGET_INIT_QUALITY 50 + +typedef struct { + char* filepath; + TRANSCODE_BS_READY_CB bs_ready_cb; +} UIAppTranscode_User_Config; + + + +extern VControl CustomTranscodeObjCtrl; + +#endif diff --git a/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_Exe.c b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_Exe.c new file mode 100644 index 000000000..23da406f8 --- /dev/null +++ b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_Exe.c @@ -0,0 +1,988 @@ +/* + 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" + +#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 = GetPhotoSizeWidth(PHOTO_MAX_CAP_SIZE); + UINT32 max_cap_size_h = 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 = GetPhotoSizeWidth(TRANSCODE_TARGET_PHOTO_SIZE); + UINT32 target_size_h = GetPhotoSizeHeight(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){GetPhotoSizeWidth(TRANSCODE_TARGET_PHOTO_SIZE), GetPhotoSizeHeight(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(); + mem_cfg.pool_info[id].blk_cnt = 1; + 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(); + mem_cfg.pool_info[id].blk_cnt = 1; + 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); + 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) diff --git a/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_cmd.c b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_cmd.c new file mode 100644 index 000000000..918c9cf51 --- /dev/null +++ b/code/application/source/cardv/SrcCode/UIApp/Transcode/UIAppTranscode_cmd.c @@ -0,0 +1,83 @@ +//global debug level: PRJ_DBG_LVL +#include "PrjCfg.h" + +#include "SysCommon.h" +#include "UIApp/UIAppCommon.h" +#include "UIApp/Photo/UIAppPhoto.h" +#include "UIApp/Transcode/UIAppTranscode.h" +#include "UIWnd/UIFlow.h" +#include +#include +#include "kwrap/cmdsys.h" +#include + +//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__ UiAppTranscodeCmd +#define __DBGLVL__ ((THIS_DBGLVL>=PRJ_DBG_LVL)?THIS_DBGLVL:PRJ_DBG_LVL) +#define __DBGFLT__ "*" //*=All, [mark]=CustomClass +#include +/////////////////////////////////////////////////////////////////////////////// + +void transcode_bs_ready_cb(void* bitstream_va, UINT32 size) +{ + DBG_DUMP("bitstream_va = %lx , size = %lx\n", bitstream_va, size); +} + +static BOOL cmd_transcode_start(unsigned char argc, char **argv) +{ + UIAppTranscode_User_Config user_config = {0}; + + DBG_DUMP("transcode start\r\n"); + + if(argc > 0) + user_config.filepath = (char*)argv[0]; + + user_config.bs_ready_cb = transcode_bs_ready_cb; + + Ux_SendEvent(&CustomTranscodeObjCtrl, NVTEVT_EXE_TRANSCODE_START, 1, &user_config); + + return TRUE; +} + +static SXCMD_BEGIN(uitranscode_cmd_tbl, "uitranscode_cmd_tbl") +SXCMD_ITEM("start", cmd_transcode_start, "transcode start") +SXCMD_END() + +static int uitranscode_cmd_showhelp(int (*dump)(const char *fmt, ...)) +{ + UINT32 cmd_num = SXCMD_NUM(uitranscode_cmd_tbl); + UINT32 loop = 1; + + dump("---------------------------------------------------------------------\r\n"); + dump(" %s\n", "uitranscode"); + dump("---------------------------------------------------------------------\r\n"); + + for (loop = 1 ; loop <= cmd_num ; loop++) { + dump("%15s : %s\r\n", uitranscode_cmd_tbl[loop].p_name, uitranscode_cmd_tbl[loop].p_desc); + } + return 0; +} + +MAINFUNC_ENTRY(uitranscode, argc, argv) +{ + UINT32 cmd_num = SXCMD_NUM(uitranscode_cmd_tbl); + UINT32 loop; + int ret; + + if (argc < 2) { + return -1; + } + if (strncmp(argv[1], "?", 2) == 0) { + uitranscode_cmd_showhelp(vk_printk); + return 0; + } + for (loop = 1 ; loop <= cmd_num ; loop++) { + if (strncmp(argv[1], uitranscode_cmd_tbl[loop].p_name, strlen(argv[1])) == 0) { + ret = uitranscode_cmd_tbl[loop].p_func(argc-2, &argv[2]); + return ret; + } + } + return 0; +} diff --git a/code/application/source/cardv/SrcCode/UIWnd/UIFlow.h b/code/application/source/cardv/SrcCode/UIWnd/UIFlow.h old mode 100755 new mode 100644 index 68049d65b..200b9294c --- a/code/application/source/cardv/SrcCode/UIWnd/UIFlow.h +++ b/code/application/source/cardv/SrcCode/UIWnd/UIFlow.h @@ -81,6 +81,9 @@ #include "Mode/UIModeVoice.h" #endif +#include "Mode/UIModeTranscode.h" + + #include "kwrap/task.h" #define TIMER_HALF_SEC 500