diff options
-rw-r--r-- | dce_rpc.h | 15 | ||||
-rw-r--r-- | libdce.c | 298 | ||||
-rw-r--r-- | libdce.h | 1 | ||||
-rw-r--r-- | packages/codec_engine/Makefile.am | 1 | ||||
-rw-r--r-- | packages/codec_engine/ti/sdo/ce/video2/viddec2.h | 399 | ||||
-rw-r--r-- | packages/xdais/Makefile.am | 1 | ||||
-rw-r--r-- | packages/xdais/ti/xdais/dm/ividdec2.h | 632 |
7 files changed, 1289 insertions, 58 deletions
@@ -42,13 +42,14 @@ * possibly we should define a special ioctl and msg to handle this case. */ -#define DCE_DEVICE_NAME "rpmsg-dce" #define MAX_NAME_LENGTH 32 #define MAX_INPUT_BUF 2 // Need to confirm for interlaced YUVs for Encoders #define MAX_OUTPUT_BUF 2 -#define MAX_TOTAl_BUF (MAX_INPUT_BUF + MAX_OUTPUT_BUF) +#define MAX_OUTPUT_BUFPTRS 2//To take care bufs and bufSizes in viddec2 case +#define MAX_TOTAL_BUF (MAX_INPUT_BUF + MAX_OUTPUT_BUF + MAX_OUTPUT_BUFPTRS) +#define MAX_INSTANCES 4 /* Message-Ids: */ //#define DCE_RPC_CONNECT (0x80000000 | 00) Connect not needed anymore. @@ -65,9 +66,17 @@ typedef enum dce_rpc_call { typedef enum dce_codec_type { OMAP_DCE_VIDENC2 = 1, - OMAP_DCE_VIDDEC3 = 2 + OMAP_DCE_VIDDEC3 = 2, + OMAP_DCE_VIDDEC2 = 3 } dce_codec_type; +typedef enum dce_core_type { + INVALID_CORE = -1, + IPU = 0, + DSP = 1, + MAX_REMOTEDEVICES +}dce_core_type; + /* Structures of RPC */ typedef struct dce_connect { uint32_t chipset_id; @@ -48,11 +48,12 @@ /********************* GLOBALS ***********************/ /* Hande used for Remote Communication */ -MmRpc_Handle MmRpcHandle = NULL; +MmRpc_Handle MmRpcHandle[MAX_REMOTEDEVICES] = { NULL}; +Engine_Handle gEngineHandle[MAX_INSTANCES][MAX_REMOTEDEVICES] = { NULL}; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -static int __ClientCount = 0; +static int __ClientCount[MAX_REMOTEDEVICES] = {0}; int dce_debug = DCE_DEBUG_LEVEL; - +const String DCE_DEVICE_NAME[MAX_REMOTEDEVICES]= {"rpmsg-dce","rpmsg-dce-dsp"}; /****************** INLINE FUNCTIONS ********************/ static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry) @@ -110,32 +111,73 @@ void dce_free(void *ptr) memplugin_free(ptr); } +static int __inline getCoreIndexFromName(String name) +{ + if(name == NULL) + return INVALID_CORE; + + if(!strcmp(name,"ivahd_vidsvr")) + return IPU; + else if(!strcmp(name, "dsp_vidsvr")) + return DSP; + else + return INVALID_CORE; +} + +static int __inline getCoreIndexFromCodec(int codec_id) +{ + if(codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3) + return IPU; + else if(codec_id == OMAP_DCE_VIDDEC2) + return DSP; + else + return INVALID_CORE; +} +static int __inline getCoreIndexFromEngine(Engine_Handle engine) +{ + int i; + int core = INVALID_CORE; + + for(i = 0; i < MAX_INSTANCES ; i++){ + if(engine == gEngineHandle[i][IPU]){ + core = IPU; + break; + } + else if(engine == gEngineHandle[i][DSP]){ + core = DSP; + break; + } + } + return core; +} /*=====================================================================================*/ /** dce_ipc_init : Initialize MmRpc. This function is called within Engine_open(). * * @ return : Error Status. */ -static int dce_ipc_init(void) +static int dce_ipc_init(int core) { MmRpc_Params args; dce_error_status eError = DCE_EOK; DEBUG(" >> dce_ipc_init\n"); - __ClientCount++; - /* Check if already Initialized */ - if (__ClientCount > 1) { - goto EXIT; - } - /* Create remote server insance */ - MmRpc_Params_init(&args); + __ClientCount[core]++; - eError = MmRpc_create(DCE_DEVICE_NAME, &args, &MmRpcHandle); + if(__ClientCount[core] > MAX_INSTANCES){ + eError = DCE_EXDM_UNSUPPORTED; + return eError; + } + if(__ClientCount[core] > 1){ + goto EXIT; + } - _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, __ClientCount--); + MmRpc_Params_init(&args); - DEBUG("open(/dev/" DCE_DEVICE_NAME ") -> 0x%x\n", (int)MmRpcHandle); + eError = MmRpc_create(DCE_DEVICE_NAME[core], &args, &MmRpcHandle[core]); + _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, __ClientCount[core]--); + DEBUG("open(/dev/%s]) -> 0x%x\n",DCE_DEVICE_NAME[core], (int)MmRpcHandle[core]); EXIT: return (eError); @@ -145,18 +187,17 @@ EXIT: /** dce_ipc_deinit : DeInitialize MmRpc. This function is called within * Engine_close(). */ -static void dce_ipc_deinit() +static void dce_ipc_deinit(int core) { - __ClientCount--; - if( __ClientCount > 0 ) { + __ClientCount[core]--; + if( __ClientCount[core] > 0 ) { goto EXIT; - } - - if( MmRpcHandle != NULL ) { - MmRpc_delete(&MmRpcHandle); - } - MmRpcHandle = NULL; + } + if( MmRpcHandle[core] != NULL ) { + MmRpc_delete(&MmRpcHandle[core]); + MmRpcHandle[core] = NULL; + } EXIT: return; } @@ -177,13 +218,15 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec) dce_engine_open *engine_open_msg = NULL; Engine_Attrs *engine_attrs = NULL; Engine_Handle engine_handle = NULL; + int coreIdx = INVALID_CORE; _ASSERT(name != '\0', DCE_EINVALID_INPUT); pthread_mutex_lock(&mutex); - + coreIdx = getCoreIndexFromName(name); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); /* Initialize IPC. In case of Error Deinitialize them */ - _ASSERT(dce_ipc_init() == DCE_EOK, DCE_EIPC_CREATE_FAIL); + _ASSERT(dce_ipc_init(coreIdx) == DCE_EOK, DCE_EIPC_CREATE_FAIL); INFO(">> Engine_open Params::name = %s size = %d\n", name, strlen(name)); /* Allocate Shared memory for the engine_open rpc msg structure*/ @@ -207,9 +250,10 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec) sizeof(MemHeader), memplugin_share(engine_open_msg)); /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&engine_handle)); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, (int32_t *)(&engine_handle)); + gEngineHandle[__ClientCount[coreIdx] - 1][coreIdx] = engine_handle; - /* In case of Error, the Application will get a NULL Engine Handle */ + /* In case of Error, the Application will get a NULL Engine Handle */ _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, engine_handle = NULL); if( ec ) { @@ -237,8 +281,9 @@ Void Engine_close(Engine_Handle engine) MmRpc_FxnCtx fxnCtx; int32_t fxnRet; dce_error_status eError = DCE_EOK; + int32_t coreIdx = INVALID_CORE; - pthread_mutex_lock(&mutex); + pthread_mutex_lock(&mutex); _ASSERT(engine != NULL, DCE_EINVALID_INPUT); @@ -246,13 +291,15 @@ Void Engine_close(Engine_Handle engine) Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_ENGINE_CLOSE, 1, 0, NULL); Fill_MmRpc_fxnCtx_Scalar_Params(fxnCtx.params, sizeof(Engine_Handle), (int32_t)engine); - /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet); + coreIdx = getCoreIndexFromEngine(engine); + _ASSERT(coreIdx != INVALID_CORE,DCE_EINVALID_INPUT); + /* Invoke the Remote function through MmRpc */ + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, &fxnRet); _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); EXIT: - dce_ipc_deinit(); + dce_ipc_deinit(coreIdx); pthread_mutex_unlock(&mutex); @@ -279,6 +326,7 @@ static void *create(Engine_Handle engine, String name, void *params, dce_codec_t dce_error_status eError = DCE_EOK; void *codec_handle = NULL; char *codec_name = NULL; + int coreIdx = INVALID_CORE; _ASSERT(name != '\0', DCE_EINVALID_INPUT); _ASSERT(engine != NULL, DCE_EINVALID_INPUT); @@ -299,8 +347,9 @@ static void *create(Engine_Handle engine, String name, void *params, dce_codec_t Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[3]), GetSz(params), P2H(params), sizeof(MemHeader), memplugin_share(params)); /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, (int32_t *)(&codec_handle)); - + coreIdx = getCoreIndexFromCodec(codec_id); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, (int32_t *)(&codec_handle)); /* In case of Error, the Application will get a NULL Codec Handle */ _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CALL_FAIL, codec_handle = NULL); @@ -329,6 +378,7 @@ static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dc MmRpc_FxnCtx fxnCtx; int32_t fxnRet; dce_error_status eError = DCE_EOK; + int coreIdx = INVALID_CORE; _ASSERT(codec != NULL, DCE_EINVALID_INPUT); _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT); @@ -345,7 +395,9 @@ static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dc sizeof(MemHeader), memplugin_share(status)); /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet); + coreIdx = getCoreIndexFromCodec(codec_id); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, &fxnRet); _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); @@ -378,6 +430,7 @@ static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_co void * *version_buf = NULL; int32_t fxnRet; dce_error_status eError = DCE_EOK; + int coreIdx = INVALID_CORE; _ASSERT(codec != NULL, DCE_EINVALID_INPUT); _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT); @@ -387,6 +440,8 @@ static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_co version_buf = (void * *)(&(((IVIDDEC3_Status *)status)->data.buf)); } else if( codec_id == OMAP_DCE_VIDENC2 ) { version_buf = (void * *)(&(((IVIDENC2_Status *)status)->data.buf)); + }else if( codec_id == OMAP_DCE_VIDDEC2 ) { + version_buf = (void * *)(&(((IVIDDEC2_Status *)status)->data.buf)); } _ASSERT(*version_buf != NULL, DCE_EINVALID_INPUT); @@ -400,10 +455,14 @@ static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_co sizeof(MemHeader), memplugin_share(status)); /* Address Translation needed for buffer for version Info */ - Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 3, MmRpc_OFFSET((int32_t)status, (int32_t)version_buf), (size_t)P2H(*version_buf), memplugin_share(*version_buf)); + Fill_MmRpc_fxnCtx_Xlt_Array(fxnCtx.xltAry, 3, + MmRpc_OFFSET((int32_t)status, (int32_t)version_buf), + (size_t)P2H(*version_buf), memplugin_share(*version_buf)); /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet); + coreIdx = getCoreIndexFromCodec(codec_id); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, &fxnRet); _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); @@ -417,7 +476,8 @@ typedef enum process_call_params { INBUFS_INDEX, OUTBUFS_INDEX, INARGS_INDEX, - OUTARGS_INDEX + OUTARGS_INDEX, + OUTBUFS_PTR_INDEX } process_call_params; #define LUMA_BUF 0 @@ -441,10 +501,14 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs, void *inArgs, void *outArgs, dce_codec_type codec_id) { MmRpc_FxnCtx fxnCtx; - MmRpc_Xlt xltAry[MAX_TOTAl_BUF]; + MmRpc_Xlt xltAry[MAX_TOTAL_BUF]; int fxnRet, count, total_count, numInBufs = 0, numOutBufs = 0; dce_error_status eError = DCE_EOK; - void * *data_buf = NULL; + void **data_buf = NULL; + void **buf_arry = NULL; + void **bufSize_arry = NULL; + int numXltAry, numParams; + int coreIdx = INVALID_CORE; #ifdef BUILDOS_ANDROID int32_t inbuf_offset[MAX_INPUT_BUF]; @@ -459,14 +523,28 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs, if( codec_id == OMAP_DCE_VIDDEC3 ) { numInBufs = ((XDM2_BufDesc *)inBufs)->numBufs; numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs; + numXltAry = numInBufs + numOutBufs; + numParams = 6; } else if( codec_id == OMAP_DCE_VIDENC2 ) { numInBufs = ((IVIDEO2_BufDesc *)inBufs)->numPlanes; numOutBufs = ((XDM2_BufDesc *)outBufs)->numBufs; + numXltAry = numInBufs + numOutBufs; + numParams = 6; + }else if( codec_id == OMAP_DCE_VIDDEC2 ) { + numInBufs = ((XDM1_BufDesc *)inBufs)->numBufs; + numOutBufs = ((XDM_BufDesc *)outBufs)->numBufs; + numXltAry = numInBufs + numOutBufs + MAX_OUTPUT_BUFPTRS;/* 2 extra needed for bufs and bufSizes */ + numParams = 7; + } + else{ + eError = DCE_EXDM_UNSUPPORTED; + return eError; } + /* marshall function arguments into the send buffer */ /* Approach [2] as explained in "Notes" used for process */ - Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, 6, numInBufs + numOutBufs, xltAry); + Fill_MmRpc_fxnCtx(&fxnCtx, DCE_RPC_CODEC_PROCESS, numParams, numXltAry, xltAry); Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_ID_INDEX]), sizeof(int32_t), codec_id); Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[CODEC_HANDLE_INDEX]), sizeof(int32_t), (int32_t)codec); @@ -490,34 +568,60 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs, /* for the actual data. the offset within the input buffer is provided */ /* via memheader offset field. Hence the buf ptr needs to be advanced with the offset */ inbuf_offset[count] = P2H(*data_buf)->offset; - Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), - (size_t)P2H(*data_buf), (size_t)memplugin_share((void *)*data_buf)); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, + MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf),(size_t)P2H(*data_buf), + (size_t)memplugin_share((void *)*data_buf)); + *data_buf += inbuf_offset[count]; #else - Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), - (size_t)*data_buf, (size_t)*data_buf); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, + MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), + (size_t)*data_buf, (size_t)*data_buf); #endif } else if( codec_id == OMAP_DCE_VIDENC2 ) { data_buf = (void * *)(&(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].buf)); - Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), - (size_t)*data_buf, (size_t)*data_buf); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, + MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), + (size_t)*data_buf, (size_t)*data_buf); + + } else if( codec_id == OMAP_DCE_VIDDEC2 ) { + data_buf = (void * *)(&(((XDM1_BufDesc *)inBufs)->descs[count].buf)); +#ifdef BUILDOS_ANDROID + /* the decoder input buffer filled by the parsers, have an offset */ + /* for the actual data. the offset within the input buffer is provided */ + /* via memheader offset field. Hence the buf ptr needs to be advanced with the offset */ + inbuf_offset[count] = P2H(*data_buf)->offset; + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, + MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf),(size_t)P2H(*data_buf), + (size_t)memplugin_share((void *)*data_buf)); + + *data_buf += inbuf_offset[count]; +#else + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), INBUFS_INDEX, + MmRpc_OFFSET((int32_t)inBufs, (int32_t)data_buf), + (size_t)*data_buf, (size_t)*data_buf); +#endif } - } +} /* Output Buffers */ for( count = 0; count < numOutBufs; count++, total_count++ ) { + if(codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3) { if(((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) { /* Either Encode usecase or MultiPlanar Buffers for Decode usecase */ data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf)); - Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, MmRpc_OFFSET((int32_t)outBufs, (int32_t)data_buf), - (size_t)*data_buf, (size_t)*data_buf); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, + MmRpc_OFFSET((int32_t)outBufs, (int32_t)data_buf), + (size_t)*data_buf, (size_t)*data_buf); } #if defined(BUILDOS_LINUX) || defined(BUILDOS_ANDROID) else { /* SinglePlanar Buffers for Decode usecase*/ data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf)); - Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, MmRpc_OFFSET((int32_t)outBufs, (int32_t)data_buf), - (size_t)*data_buf, (size_t)*data_buf); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, + MmRpc_OFFSET((int32_t)outBufs, (int32_t)data_buf), + (size_t)*data_buf, (size_t)*data_buf); + if( count == CHROMA_BUF ) { if(((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW || ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) { @@ -529,10 +633,40 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs, } } #endif - } + }else if(codec_id == OMAP_DCE_VIDDEC2) { + if(count == LUMA_BUF) { + buf_arry = (void * *)(&(((XDM_BufDesc *)outBufs)->bufs)); + + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, + MmRpc_OFFSET((int32_t)outBufs, (int32_t)buf_arry), + (size_t)P2H(*buf_arry), (size_t)memplugin_share(*buf_arry)); + + total_count++; + + bufSize_arry = (void * *)(&(((XDM_BufDesc *)outBufs)->bufSizes)); + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, + MmRpc_OFFSET((int32_t)outBufs, (int32_t)bufSize_arry), + (size_t)P2H(*bufSize_arry), (size_t)memplugin_share(*bufSize_arry)); + + total_count++; + } + + Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[OUTBUFS_PTR_INDEX]), GetSz(*buf_arry), P2H(*buf_arry), + sizeof(MemHeader), memplugin_share(*buf_arry)); + + data_buf = (void * *)(&(((XDM_BufDesc *)outBufs)->bufs[count])); + + Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_PTR_INDEX, + MmRpc_OFFSET((int32_t)*buf_arry, (int32_t)data_buf), (size_t)*data_buf, (size_t)*data_buf); + + } + +} /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet); + coreIdx = getCoreIndexFromCodec(codec_id); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, &fxnRet); _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); @@ -543,6 +677,10 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs, /* restore the actual buf ptr before returing to the mmf */ data_buf = (void * *)(&(((XDM2_BufDesc *)inBufs)->descs[count].buf)); *data_buf -= inbuf_offset[count]; + }else if( codec_id == OMAP_DCE_VIDDEC2 ) { + /* restore the actual buf ptr before returing to the mmf */ + data_buf = (void * *)(&(((XDM1_BufDesc *)inBufs)->descs[count].buf)); + *data_buf -= inbuf_offset[count]; } } @@ -565,6 +703,7 @@ static void delete(void *codec, dce_codec_type codec_id) MmRpc_FxnCtx fxnCtx; int32_t fxnRet; dce_error_status eError = DCE_EOK; + int coreIdx = INVALID_CORE; _ASSERT(codec != NULL, DCE_EINVALID_INPUT); @@ -574,7 +713,9 @@ static void delete(void *codec, dce_codec_type codec_id) Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[1]), sizeof(int32_t), (int32_t)codec); /* Invoke the Remote function through MmRpc */ - eError = MmRpc_call(MmRpcHandle, &fxnCtx, &fxnRet); + coreIdx = getCoreIndexFromCodec(codec_id); + _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); + eError = MmRpc_call(MmRpcHandle[coreIdx], &fxnCtx, &fxnRet); _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); @@ -582,7 +723,7 @@ EXIT: return; } -/*************** Deocder Codec Engine Functions ***********************/ +/*************** Decoder Codec Engine Functions ***********************/ VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name, VIDDEC3_Params *params) { @@ -678,4 +819,51 @@ Void VIDENC2_delete(VIDENC2_Handle codec) delete(codec, OMAP_DCE_VIDENC2); DEBUG("<<"); } +/*************** Decoder Codec Engine Functions ***********************/ +VIDDEC2_Handle VIDDEC2_create(Engine_Handle engine, String name, + VIDDEC2_Params *params) +{ + VIDDEC2_Handle codec; + + DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params); + codec = create(engine, name, params, OMAP_DCE_VIDDEC2); + DEBUG("<< codec=%p", codec); + return (codec); +} +XDAS_Int32 VIDDEC2_control(VIDDEC2_Handle codec, VIDDEC2_Cmd id, + VIDDEC2_DynamicParams *dynParams, VIDDEC2_Status *status) +{ + XDAS_Int32 ret; + + DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p", + codec, id, dynParams, status); + if( id == XDM_GETVERSION ) { + ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC2); + } else { + ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC2); + } + DEBUG("<< ret=%d", ret); + return (ret); +} + +XDAS_Int32 VIDDEC2_process(VIDDEC2_Handle codec, + XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, + VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs) +{ + XDAS_Int32 ret; + + DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p", + codec, inBufs, outBufs, inArgs, outArgs); + ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC2); + DEBUG("<< ret=%d", ret); + return (ret); +} + + +Void VIDDEC2_delete(VIDDEC2_Handle codec) +{ + DEBUG(">> codec=%p", codec); + delete(codec, OMAP_DCE_VIDDEC2); + DEBUG("<<"); +} @@ -38,6 +38,7 @@ #include <ti/sdo/ce/Engine.h> #include <ti/sdo/ce/video3/viddec3.h> #include <ti/sdo/ce/video2/videnc2.h> +#include <ti/sdo/ce/video2/viddec2.h> #if defined(BUILDOS_LINUX) /* avoid some messy stuff in xdc/std.h which leads to gcc issues */ diff --git a/packages/codec_engine/Makefile.am b/packages/codec_engine/Makefile.am index 7a6c170..61e8d58 100644 --- a/packages/codec_engine/Makefile.am +++ b/packages/codec_engine/Makefile.am @@ -8,6 +8,7 @@ nobase_pkg_include_HEADERS = \ ti/sdo/ce/ServerDefs.h \ ti/sdo/ce/video3/viddec3.h \ ti/sdo/ce/video2/videnc2.h \ + ti/sdo/ce/video2/viddec2.h \ ti/sdo/ce/Server.h \ ti/sdo/ce/skel.h \ ti/sdo/ce/node/node.h \ diff --git a/packages/codec_engine/ti/sdo/ce/video2/viddec2.h b/packages/codec_engine/ti/sdo/ce/video2/viddec2.h new file mode 100644 index 0000000..955c274 --- /dev/null +++ b/packages/codec_engine/ti/sdo/ce/video2/viddec2.h @@ -0,0 +1,399 @@ +/* + * Copyright 2013 by Texas Instruments Incorporated. + * + */ + +/* + * Copyright (c) 2013, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/* + * ======== viddec2.h ======== + */ +/** + * @file ti/sdo/ce/video2/viddec2.h + * + * @brief The VIDDEC2 video decoder interface. Provides the user an + * interface to create and interact with XDAIS algorithms that are + * compliant with the XDM-defined IVIDDEC2 video decoder + * interface. + */ +/** + * @defgroup ti_sdo_ce_video2_VIDDEC2 VIDDEC2 - Video Decoder Interface + * + * This is the VIDDEC2 video decoder interface. Several of the data + * types in this API are specified by the XDM interface; please see + * the XDM documentation for those details. + */ + +#ifndef ti_sdo_ce_video2_VIDDEC2_ +#define ti_sdo_ce_video2_VIDDEC2_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <ti/xdais/dm/xdm.h> +#include <ti/xdais/dm/ividdec2.h> + +#include <ti/sdo/ce/Engine.h> +#include <ti/sdo/ce/visa.h> +#include <ti/sdo/ce/skel.h> + +/** @ingroup ti_sdo_ce_video2_VIDDEC2 */ +/*@{*/ + +typedef IVIDDEC2_Status VIDDEC2_Status; /**< @copydoc IVIDDEC2_Status */ + +#define VIDDEC2_EOK IVIDDEC2_EOK /**< @copydoc IVIDDEC2_EOK */ +#define VIDDEC2_EFAIL IVIDDEC2_EFAIL /**< @copydoc IVIDDEC2_EFAIL */ + +/**< @copydoc IVIDDEC2_EUNSUPPORTED */ +#define VIDDEC2_EUNSUPPORTED IVIDDEC2_EUNSUPPORTED + +#define VIDDEC2_ETIMEOUT VISA_ETIMEOUT /**< @copydoc VISA_ETIMEOUT */ +#define VIDDEC2_FOREVER VISA_FOREVER /**< @copydoc VISA_FOREVER */ + +/** + * @brief The VISA type + */ +#define VIDDEC2_VISATYPE "ti.sdo.ce.video2.IVIDDEC2" + +/** + * @brief Name of stub functions. Use this name when registering the + * VIDDEC2_STUBS functions with Engine_addStubFxns. + * + * @sa Engine_addStubFxns + */ +#define VIDDEC2_STUBSNAME "VIDDEC2_STUBS" + + +/** + * @brief Opaque handle to a VIDDEC2 codec. + */ +typedef VISA_Handle VIDDEC2_Handle; + +/** + * @brief This structure defines the parameters necessary to create an + * instance of a video decoder object. + */ +typedef struct IVIDDEC2_Params VIDDEC2_Params; + +/** + * @copydoc IVIDDEC2_InArgs + */ +typedef IVIDDEC2_InArgs VIDDEC2_InArgs; + +/** + * @copydoc IVIDDEC2_OutArgs + */ +typedef IVIDDEC2_OutArgs VIDDEC2_OutArgs; + +/** + * @copydoc IVIDDEC2_Cmd + */ +typedef IVIDDEC2_Cmd VIDDEC2_Cmd; + +/** + * @copydoc IVIDDEC2_DynamicParams + */ +typedef IVIDDEC2_DynamicParams VIDDEC2_DynamicParams; + +/** @cond INTERNAL */ + +/** + * @brief An implementation of the skel interface; the skeleton side + * of the stubs. + */ +extern SKEL_Fxns VIDDEC2_SKEL; + +/** + * @brief Implementation of the IVIDDEC2 interface that is run remotely. + */ +extern IVIDDEC2_Fxns VIDDEC2_STUBS; + +/** @endcond */ + +/** + * @brief Definition of IVIDDEC2 codec class configurable parameters + * + * @sa VISA_getCodecClassConfig() + */ +typedef struct IVIDDEC2_CodecClassConfig { + Bool manageInBufsCache [ XDM_MAX_IO_BUFFERS ]; + Bool manageOutBufsCache [ XDM_MAX_IO_BUFFERS ]; +} IVIDDEC2_CodecClassConfig; + + +/* + * ======== VIDDEC2_create ======== + */ +/** + * @brief Create an instance of a video decoder algorithm. + * + * Instance handles must not be concurrently accessed by multiple threads; + * each thread must either obtain its own handle (via VIDDEC2_create()) or + * explicitly serialize access to a shared handle. + * + * @param[in] e Handle to an opened engine. + * @param[in] name String identifier of the type of video decoder + * to create. + * @param[in] params Creation parameters. + * + * @retval NULL An error has occurred. + * @retval non-NULL The handle to the newly created video decoder + * instance. + * + * @remarks @c params is optional. If it's not supplied, codec-specific + * default params will be used. + * + * @remark Depending on the configuration of the engine opened, this + * call may create a local or remote instance of the video + * decoder. + * + * @codecNameRemark + * + * @sa Engine_open() + * @sa VIDDEC2_delete() + */ +extern VIDDEC2_Handle VIDDEC2_create(Engine_Handle e, String name, + VIDDEC2_Params *params); + + +/* + * ======== VIDDEC2_process ======== + */ +/** + * @brief Execute the process() method in this instance of a video + * decoder algorithm. + * + * @param[in] handle Handle to a created video decoder instance. + * @param[in] inBufs A buffer descriptor containing input buffers. + * @param[out] outBufs A buffer descriptor containing output buffers. + * @param[in] inArgs Input Arguments. + * @param[out] outArgs Output Arguments. + * + * @pre @c handle is a valid (non-NULL) video decoder handle + * and the video decoder is in the created state. + * + * @retval #VIDDEC2_EOK Success. + * @retval #VIDDEC2_EFAIL Failure. + * @retval #VIDDEC2_EUNSUPPORTED Unsupported request. + * + * @remark Since the VIDDEC2 decoder contains support for asynchronous + * buffer submission and retrieval, this API becomes known as + * synchronous in nature. + * + * @remark This is a blocking call, and will return after the data + * has been decoded. + * + * @remark The buffers supplied to VIDDEC2_process() may have constraints + * put on them. For example, in dual-processor, shared memory + * architectures, where the codec is running on a remote + * processor, the buffers may need to be physically contiguous. + * Additionally, the remote processor may place restrictions on + * buffer alignment. + * + * @sa VIDDEC2_create() + * @sa VIDDEC2_delete() + * @sa VIDDEC2_control() + * @sa VIDDEC2_processAsync() + * @sa VIDDEC2_processWait() + * @sa IVIDDEC2_Fxns::process() - the reflected algorithm interface, + * which may contain further usage + * details. + */ +extern Int32 VIDDEC2_process(VIDDEC2_Handle handle, XDM1_BufDesc *inBufs, + XDM_BufDesc *outBufs, VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs); + + +/* + * ======== VIDDEC2_control ======== + */ +/** + * @brief Execute the control() method in this instance of a video + * decoder algorithm. + * + * @param[in] handle Handle to a created video decoder instance. + * @param[in] id Command id for xDM control operation. + * @param[in] params Runtime control parameters used for decoding. + * @param[out] status Status info upon completion of decode operation. + * + * @pre @c handle is a valid (non-NULL) video decoder handle + * and the video decoder is in the created state. + * + * @retval #VIDDEC2_EOK Success. + * @retval #VIDDEC2_EFAIL Failure. + * @retval #VIDDEC2_EUNSUPPORTED Unsupported request. + * + * @remark This is a blocking call, and will return after the control + * command has been executed. + * + * @remark If an error is returned, @c status->extendedError may + * indicate further details about the error. See + * #VIDDEC2_Status::extendedError for details. + * + * @sa VIDDEC2_create() + * @sa VIDDEC2_delete() + * @sa IVIDDEC2_Fxns::process() + */ +extern Int32 VIDDEC2_control(VIDDEC2_Handle handle, VIDDEC2_Cmd id, + VIDDEC2_DynamicParams *params, VIDDEC2_Status *status); + + +/* + * ======== VIDDEC2_delete ======== + */ +/** + * @brief Delete the instance of a video decoder algorithm. + * + * @param[in] handle Handle to a created video decoder instance. + * + * @remark Depending on the configuration of the engine opened, this + * call may delete a local or remote instance of the video + * decoder. + * + * @pre @c handle is a valid (non-NULL) handle which is + * in the created state. + * + * @post All resources allocated as part of the VIDDEC2_create() + * operation (memory, DMA channels, etc.) are freed. + * + * @sa VIDDEC2_create() + */ +extern Void VIDDEC2_delete(VIDDEC2_Handle handle); + + +/* + * ======== VIDDEC2_processAsync ======== + */ +/** + * @brief Perform asynchronous submission to this instance of a video + * decoder algorithm. + * + * @param[in] handle Handle to a created video decoder instance. + * @param[in] inBufs A buffer descriptor containing input buffers. + * @param[out] outBufs A buffer descriptor containing output buffers. + * @param[in] inArgs Input Arguments. + * @param[out] outArgs Output Arguments. + * + * @pre @c handle is a valid (non-NULL) video decoder handle + * and the video decoder is in the created state. + * + * @retval #VIDDEC2_EOK Success. + * @retval #VIDDEC2_EFAIL Failure. + * @retval #VIDDEC2_EUNSUPPORTED Unsupported request. + * + * @remark This API is the asynchronous counterpart to the process() + * method. It allows for buffer and argument submission without + * waiting for retrieval. A response is retrieved using the + * VIDDEC2_processWait() API. + * + * @remark The buffers supplied to VIDDEC2_processAsync() may have + * constraints put on them. For example, in dual-processor, + * shared memory architectures, where the codec is running on a + * remote processor, the buffers may need to be physically + * contiguous. Additionally, the remote processor may place + * restrictions on buffer alignment. + * + * @sa VIDDEC2_create() + * @sa VIDDEC2_delete() + * @sa VIDDEC2_control() + * @sa VIDDEC2_process() + * @sa VIDDEC2_processWait() + * @sa IVIDDEC2_Fxns::process() + */ +extern XDAS_Int32 VIDDEC2_processAsync(VIDDEC2_Handle handle, + XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, + VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs); + + +/* + * ======== VIDDEC2_processWait ======== + */ +/** + * @brief Wait for a return message from a previous invocation of + * VIDDEC2_processAsync() in this instance of an video decoder + * algorithm. + * + * @param[in] handle Handle to a created video decoder instance. + * @param[in] inBufs A buffer descriptor containing input buffers. + * @param[out] outBufs A buffer descriptor containing output buffers. + * @param[in] inArgs Input Arguments. + * @param[out] outArgs Output Arguments. + * @param[in] timeout Amount of "time" to wait (from 0 -> VIDDEC2_FOREVER) + * + * @pre @c handle is a valid (non-NULL) video decoder handle + * and the video decoder is in the created state. + * + * @retval #VIDDEC2_EOK Success. + * @retval #VIDDEC2_EFAIL Failure. + * @retval #VIDDEC2_EUNSUPPORTED Unsupported request. + * @retval #VIDDEC2_ETIMEOUT Operation timed out. + * + * @remark This is a blocking call, and will return after the data + * has been decoded. + * + * @remark "Polling" is supported by using a timeout of 0. Waiting + * forever is supported by using a timeout of VIDDEC2_EFOREVER. + * + * @remark There must have previously been an invocation of the + * VIDDEC2_processAsync() API. + * + * @remark The buffers supplied to VIDDEC2_processAsync() may have + * constraints put on them. For example, in dual-processor, + * shared memory architectures, where the codec is running on a + * remote processor, the buffers may need to be physically + * contiguous. Additionally, the remote processor may place + * restrictions on buffer alignment. + * + * @sa VIDDEC2_create() + * @sa VIDDEC2_delete() + * @sa VIDDEC2_control() + * @sa VIDDEC2_process() + * @sa VIDDEC2_processAsync() + */ +extern XDAS_Int32 VIDDEC2_processWait(VIDDEC2_Handle handle, + XDM1_BufDesc *inBufs, XDM_BufDesc *outBufs, + VIDDEC2_InArgs *inArgs, VIDDEC2_OutArgs *outArgs, UInt timeout); + + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif +/* + * @(#) ti.sdo.ce.video2; 1, 0, 3,3; 6-13-2013 00:20:38; /db/atree/library/trees/ce/ce-w08/src/ xlibrary + + */ diff --git a/packages/xdais/Makefile.am b/packages/xdais/Makefile.am index 6aac227..0c5d9cc 100644 --- a/packages/xdais/Makefile.am +++ b/packages/xdais/Makefile.am @@ -4,6 +4,7 @@ pkg_includedir = $(includedir)/dce nobase_pkg_include_HEADERS = \ ti/xdais/dm/ividenc2.h \ + ti/xdais/dm/ividdec2.h \ ti/xdais/dm/ividdec3.h \ ti/xdais/dm/ivideo.h \ ti/xdais/dm/xdm.h \ diff --git a/packages/xdais/ti/xdais/dm/ividdec2.h b/packages/xdais/ti/xdais/dm/ividdec2.h new file mode 100644 index 0000000..60137e6 --- /dev/null +++ b/packages/xdais/ti/xdais/dm/ividdec2.h @@ -0,0 +1,632 @@ +/* + * Copyright (c) 2006-2012, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * @file ti/xdais/dm/ividdec2.h + * + * @brief This header defines all types, constants, and functions + * shared by all implementations of the video decoder + * algorithms. + */ +/** + * @defgroup ti_xdais_dm_IVIDDEC2 IVIDDEC2 - XDM Video Decoder Interface + * + * This is the XDM IVIDDEC2 video decoder interface. + */ + +#ifndef ti_xdais_dm_IVIDDEC2_ +#define ti_xdais_dm_IVIDDEC2_ + +#include <ti/xdais/ialg.h> +#include <ti/xdais/xdas.h> +#include "xdm.h" +#include "ivideo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup ti_xdais_dm_IVIDDEC2 */ +/*@{*/ + +/** + * @brief Maximum I/O Buffers. + * + * @remarks This IVIDDEC2-specific definition has been replaced with + * IVIDEO2_MAX_IO_BUFFERS. It has been kept for backward + * compatibility, but users are encouraged to use + * IVIDEO2_MAX_IO_BUFFERS instead. + * + * @sa IVIDEO2_MAX_IO_BUFFERS + */ +#define IVIDDEC2_MAX_IO_BUFFERS IVIDEO2_MAX_IO_BUFFERS + +#define IVIDDEC2_EOK XDM_EOK /**< @copydoc XDM_EOK */ +#define IVIDDEC2_EFAIL XDM_EFAIL /**< @copydoc XDM_EFAIL */ +#define IVIDDEC2_EUNSUPPORTED XDM_EUNSUPPORTED /**< @copydoc XDM_EUNSUPPORTED */ + +/** + * @brief This must be the first field of all IVIDDEC2 + * instance objects. + */ +typedef struct IVIDDEC2_Obj { + struct IVIDDEC2_Fxns *fxns; +} IVIDDEC2_Obj; + + +/** + * @brief Opaque handle to an IVIDDEC2 object + */ +typedef struct IVIDDEC2_Obj *IVIDDEC2_Handle; + + +/** + * @brief Video decoder output frame order + * + * @enumWarning + * + * @sa IVIDDEC2_DynamicParams::frameOrder + */ +typedef enum { + IVIDDEC2_DISPLAY_ORDER = 0, /**< The decoder provides decoded output in + * in the actual order of displaying the + * output buffer. The codec assumes the + * responsibility of reordering the frames. + * + * @remarks The output buffer will be + * delayed by one frame, + * regardless of whether the frame + * contains I/P or I/P/B frames. + * + * @remarks This is the default mode. + * + * @remarks This mode is required to be + * supported by all video decoder + * codecs. + */ + IVIDDEC2_DECODE_ORDER = 1, /**< The decoder provides decoded output in the + * the order of decoding. There will be no + * delay in the output buffers. + * + * @remarks It is the application's + * responsibility to handle the + * frame re-ordering. + * + * @remarks This mode is optional. If it + * is not supported by the + * decoder, IVIDDEC_EUNSUPPORTED + * will be returned. + */ + + /** Default setting. */ + IVIDDEC2_FRAMEORDER_DEFAULT = IVIDDEC2_DISPLAY_ORDER +} IVIDDEC2_FrameOrder; + + +/** + * @brief Defines the creation time parameters for + * all IVIDDEC2 instance objects. + * + * @extensibleStruct + */ +typedef struct IVIDDEC2_Params { + XDAS_Int32 size; /**< @sizeField */ + XDAS_Int32 maxHeight; /**< Maximum video height in pixels. */ + XDAS_Int32 maxWidth; /**< Maximum video width in pixels. */ + XDAS_Int32 maxFrameRate; /**< Maximum frame rate in fps * 1000. + * For example, if max frame rate is 30 + * frames per second, set this field + * to 30000. + */ + XDAS_Int32 maxBitRate; /**< Maximum bit rate, bits per second. + * For example, if bit rate is 10 Mbps, set + * this field to 10000000 + */ + XDAS_Int32 dataEndianness; /**< Endianness of output data. + * + * @sa XDM_DataFormat + */ + XDAS_Int32 forceChromaFormat;/**< @copydoc XDM_ChromaFormat + * + * @sa XDM_ChromaFormat + */ +} IVIDDEC2_Params; + + +/** + * @brief This structure defines the codec parameters that can be + * modified after creation via control() calls. + * + * @remarks It is not necessary that a given implementation support all + * dynamic parameters to be configurable at run time. If a + * particular algorithm does not support run-time updates to + * a parameter that the application is attempting to change + * at runtime, it may indicate this as an error. + * + * @extensibleStruct + * + * @sa IVIDDEC2_Fxns::control() + */ +typedef struct IVIDDEC2_DynamicParams { + XDAS_Int32 size; /**< @sizeField */ + XDAS_Int32 decodeHeader; /**< @copydoc XDM_DecMode + * + * @sa XDM_DecMode + */ + XDAS_Int32 displayWidth; /**< Pitch. If set to zero, use the decoded + * image width. Else, use given display + * width in pixels. + */ + XDAS_Int32 frameSkipMode; /**< @copydoc IVIDEO_FrameSkip + * + * @sa IVIDEO_FrameSkip + */ + XDAS_Int32 frameOrder; /**< @copydoc IVIDDEC2_FrameOrder + * + * @sa IVIDDEC2_FrameOrder + */ + XDAS_Int32 newFrameFlag; /**< Flag to indicate that the algorithm should + * start a new frame. + * + * @remarks Valid values are XDAS_TRUE + * and XDAS_FALSE. + * + * @remarks This is useful for error + * recovery, for example when the + * end of frame cannot be detected + * by the codec but is known to the + * application. + */ + XDAS_Int32 mbDataFlag; /**< Flag to indicate that the algorithm should + * generate MB Data in addition to decoding + * the data. + * + * @remarks Valid values are XDAS_TRUE + * and XDAS_FALSE. + * + * @sa IVIDDEC2_OutArgs::mbDataBuf + */ +} IVIDDEC2_DynamicParams; + + +/** + * @brief Defines the input arguments for all IVIDDEC2 instance + * process function. + * + * @extensibleStruct + * + * @sa IVIDDEC2_Fxns::process() + */ +typedef struct IVIDDEC2_InArgs { + XDAS_Int32 size; /**< @sizeField */ + XDAS_Int32 numBytes; /**< Size of input data in bytes, provided + * to the algorithm for decoding. + */ + XDAS_Int32 inputID; /**< The decoder will attach + * this ID with the corresponding output + * frames. + * + * @remarks This is useful when frames + * require re-ordering (e.g. B frames). + * + * @remarks When there is no re-ordering, + * IVIDDEC2_OutArgs#outputID will be same + * as this inputID field. + * + * @remarks Zero (0) is not a supported + * inputID. This value is + * reserved for cases when there + * is no output buffer provided in + * IVIDDEC2_OutArgs::displayBufs. + * + * @sa IVIDDEC2_OutArgs::outputID. + */ +} IVIDDEC2_InArgs; + + +/** + * @brief Defines instance status parameters. + * + * @extensibleStruct + * + * @remarks All fields correspond to latest IVIDDEC2_Fxns::process() call + * on the particular instance of the decoder. + * + * @sa IVIDDEC2_Fxns::control() + */ +typedef struct IVIDDEC2_Status { + XDAS_Int32 size; /**< @sizeField */ + XDAS_Int32 extendedError; /**< @extendedErrorField */ + XDM1_SingleBufDesc data; /**< Buffer descriptor for data passing. + * + * @remarks If this field is not used, + * the application <b>must</b> + * set @c data.buf to NULL. + * + * @remarks This buffer can be used as + * either input or output, + * depending on the command. + * + * @remarks The buffer will be provided + * by the application, and + * returned to the application + * upon return of the + * IVIDDEC2_Fxns.control() + * call. The algorithm must + * not retain a pointer to this + * data. + * + * @sa #XDM_GETVERSION + */ + XDAS_Int32 maxNumDisplayBufs; /**< The maximum number of buffers that will + * be required by the codec. + * + * @remarks The maximum number of buffers + * can be IVIDEO2_MAX_IO_BUFFERS. + */ + XDAS_Int32 outputHeight; /**< Output height in pixels. */ + XDAS_Int32 outputWidth; /**< Output width in pixels. */ + XDAS_Int32 frameRate; /**< Average frame rate in fps * 1000. + * For example, if average frame rate is 30 + * frames per second, this field should be + * 30000. + */ + XDAS_Int32 bitRate; /**< Average bit rate, in bits per second. */ + XDAS_Int32 contentType; /**< @copydoc IVIDEO_ContentType + * + * @sa IVIDEO_ContentType + */ + XDAS_Int32 outputChromaFormat; /**< @copydoc XDM_ChromaFormat + * + * @sa XDM_ChromaFormat + */ + XDM_AlgBufInfo bufInfo; /**< Input and output buffer information. + * + * @sa XDM_AlgBufInfo + */ +} IVIDDEC2_Status; + + +/** + * @brief Defines the run time output arguments for + * all IVIDDEC2 instance objects. + * + * @extensibleStruct + * + * @sa IVIDDEC2_Fxns::process() + */ +typedef struct IVIDDEC2_OutArgs { + XDAS_Int32 size; /**< @sizeField */ + XDAS_Int32 bytesConsumed; /**< Number of bytes consumed during the + * process() call. + */ + + XDAS_Int32 outputID[IVIDEO2_MAX_IO_BUFFERS]; /**< Output ID corresponding + * to displayBufs[]. + * + * @remarks A value of zero (0) indicates + * an invalid ID. The first zero + * entry in array will indicate + * end of valid outputIDs within + * the array. Hence the + * application can stop reading the + * array when it encounters the + * first zero entry. + * + * @sa IVIDDEC2_OutArgs#displayBufs + * @sa IVIDDEC2_InArgs#inputID + */ + IVIDEO1_BufDesc decodedBufs; /**< The decoder fills this structure with + * buffer pointers to the decoded frame. + * Related information fields for the + * decoded frame are also populated. + * + * When frame decoding is not complete, as + * indicated by @c outBufsInUseFlag, + * the frame data in this structure will be + * incomplete. However, the algorithm will + * provide incomplete decoded frame data + * in case application may choose to use + * it for error recovery purposes. + * + * @sa IVIDDEC2_OutArgs#outBufsInUseFlag + */ + IVIDEO1_BufDesc displayBufs[IVIDEO2_MAX_IO_BUFFERS]; /**< Array + * containing display frames + * corresponding to valid ID entries + * in the @c outputID[] array. + * + * @remarks The + * @c displayBufs[].bufDesc[].bufSize + * fields returned correspond to + * the actual size of the + * memory buffers. Other fields + * (e.g. pitch, width, height, + * chroma) can be used to determine + * the contents in those buffers. + * + * @remarks Entries in the array + * corresponding to invalid + * ID values (zero) in + * @c outputID[] will set + * zero value for the following + * fields in the IVIDEO1_BufDesc + * structure: @c numBufs, + * @c frameWidth, @c frameHeight, + * and @c framePitch. + * + * @remarks Implied by the previous remark, + * as this array corresponds to + * buffer IDs indicated by + * @c outputID[], elements of + * this array are undefined if + * the corresponding @c outputID[] + * element is zero (0). + */ + XDAS_Int32 outputMbDataID; /**< Output ID corresponding with the MB Data + * + * @remarks This will be set to zero when + * there is no MB Data Buffer + */ + XDM1_SingleBufDesc mbDataBuf; /**< The decoder populates the last buffer + * among the buffers supplied within + * outBufs->bufs[] with the decoded MB data + * generated by the ECD module. The pointer + * buffer along with the buffer size is + * output via this buffer descriptor. + */ + XDAS_Int32 freeBufID[IVIDEO2_MAX_IO_BUFFERS]; /**< This is an + * array of inputID's corresponding to the + * buffers that have been unlocked in the + * current process call. + * + * @remarks Buffers returned to the + * application for display (via + * IVIDDEC2_OutArgs#displayBufs) + * continue to be owned by the + * algorithm until they are + * released - indicated by + * the ID being returned in this + * @c freeBuf array. + * + * @remarks The buffers released by the + * algorithm are indicated by + * their non-zero ID (previously + * provided via + * IVIDDEC2_InArgs#inputID). + * + * @remarks A value of zero (0) indicates + * an invalid ID. The first zero + * entry in array will indicate + * end of valid freeBufIDs within + * the array. Hence the + * application can stop searching + * the array when it encounters the + * first zero entry. + * + * @remarks If no buffer was unlocked in + * the process call, + * @c freeBufID[0] will + * have a value of zero. + * + * @sa IVIDDEC2_InArgs#inputID + * @sa IVIDDEC2_OutArgs#displayBufs + */ + XDAS_Int32 outBufsInUseFlag; /**< Flag to indicate that the @c outBufs + * provided with the process() call are in + * use. No outBufs are required to be + * supplied with the next process() call. + * + * @remarks Valid values are XDAS_TRUE + * and XDAS_FALSE. + */ + +} IVIDDEC2_OutArgs; + + +/** + * @brief Defines the control commands for the IVIDDEC2 module. + * + * @remarks This ID can be extended in IMOD interface for + * additional controls. + * + * @sa XDM_CmdId + * + * @sa IVIDDEC2_Fxns::control() + */ +typedef IALG_Cmd IVIDDEC2_Cmd; + + +/** + * @brief Defines all of the operations on IVIDDEC2 objects + */ +typedef struct IVIDDEC2_Fxns { + IALG_Fxns ialg; /**< XDAIS algorithm interface. + * + * @sa IALG_Fxns + */ + +/** + * @brief Basic video decoding call + * + * @param[in] handle Handle to an algorithm instance. + * @param[in,out] inBufs Input buffer descriptors. + * @param[in,out] outBufs Output buffer descriptors. The algorithm + * may modify the output buffer pointers. + * @param[in] inArgs Input arguments. This is a required + * parameter. + * @param[out] outArgs Ouput results. This is a required parameter. + * + * @remarks process() is a blocking call. When process() returns, the + * algorithm's processing is complete. + * + * @remarks process() enables codecs to support error resiliency and + * error concealment. As a result, even if #IVIDDEC2_EFAIL + * is returned from process() because the encoded buffer has + * an error, it's possible that decoded buffers + * (@c outArgs->decodedBufs) and display buffers + * (@c outArgs->displayBufs) could still be returned. + * The codec can indicate that buffers are available by + * <i>not</i> setting the #XDM_ISFATALERROR bit + * in the respective @c displayBufs and @c decodedBufs + * @c extendedError field if the buffers contain valid data. + * + * @remarks By extension then, if the @c outArgs->decodedBufs and + * @c outArgs->displayBufs buffers are <i>not</i> valid, even + * if the codec's process() call returns IVIDDEC2_EFAIL, it must + * also be sure to set the #XDM_ISFATALERROR bit in the + * respective @c extendedError fields. Failure to do so may + * result in applications accessing these buffers and causing + * system instability. + * + * @pre @c inBufs->numBufs will indicate the total number of input + * buffers supplied for input frame, and conditionally, the + * encoders MB data buffer. + * + * @pre If IVIDDEC2_DynamicParams::mbDataFlag was set to #XDAS_FALSE + * in a previous control() call, the application only needs to + * provide buffers for reconstruction frames. + * + * @pre If IVIDDEC2_DynamicParams::mbDataFlag was set to #XDAS_TRUE + * in a previous control() call, + * @c outBufs->bufs[outBufs->numBufs - 1] is a buffer descriptor + * into which the algorithm will write MB data for each macro + * block. The size of the MB data buffer will vary based on the + * decoder type. H.264 may generate N264 bytes per MB, while + * Mpeg2 may generate NMP2 bytes. The exact size of the buffers + * should be obtained by calling the algorithm's control() method + * with XDM_GETBUFINFO. + * + * @pre @c inArgs must not be NULL, and must point to a valid + * IVIDDEC2_InArgs structure. + * + * @pre @c outArgs must not be NULL, and must point to a valid + * IVIDDEC2_OutArgs structure. + * + * @pre @c inBufs must not be NULL, and must point to a valid + * XDM1_BufDesc structure. + * + * @pre @c inBufs->descs[0].buf must not be NULL, and must point to + * a valid buffer of data that is at least + * @c inBufs->descs[0].bufSize bytes in length. + * + * @pre @c outBufs must not be NULL, and must point to a valid + * XDM_BufDesc structure. + * + * @pre @c outBufs->buf[0] must not be NULL, and must point to + * a valid buffer of data that is at least + * @c outBufs->bufSizes[0] bytes in length. + * + * @pre The buffers in @c inBufs and @c outBufs are physically + * contiguous and owned by the calling application. + * + * @post The algorithm <b>must not</b> modify the contents of @c inArgs. + * + * @post The algorithm <b>must not</b> modify the contents of + * @c inBufs, with the exception of @c inBufs.bufDesc[].accessMask. + * That is, the data and buffers pointed to by these parameters + * must be treated as read-only. + * + * @post The algorithm <b>must</b> modify the contents of + * @c inBufs->descs[].accessMask and appropriately indicate the + * mode in which each of the buffers in @c inBufs were read. + * For example, if the algorithm only read from + * @c inBufs.descs[0].buf using the algorithm processor, it + * could utilize #XDM_SETACCESSMODE_READ to update the appropriate + * @c accessMask fields. + * The application <i>may</i> utilize these + * returned values to appropriately manage cache. + * + * @post The buffers in @c inBufs are + * owned by the calling application. + * + * @retval IVIDDEC2_EOK @copydoc IVIDDEC2_EOK + * @retval IVIDDEC2_EFAIL @copydoc IVIDDEC2_EFAIL + * See IVIDDEC2_Status#extendedError + * for more detailed further error + * conditions. + * @retval IVIDDEC2_EUNSUPPORTED @copydoc IVIDDEC2_EUNSUPPORTED + */ + XDAS_Int32 (*process)(IVIDDEC2_Handle handle, XDM1_BufDesc *inBufs, + XDM_BufDesc *outBufs, IVIDDEC2_InArgs *inArgs, + IVIDDEC2_OutArgs *outArgs); + + +/** + * @brief Control behavior of an algorithm. + * + * @param[in] handle Handle to an algorithm instance. + * @param[in] id Command id. See #XDM_CmdId. + * @param[in] params Dynamic parameters. This is a required + * parameter. + * @param[out] status Output results. This is a required parameter. + * + * @pre @c handle must be a valid algorithm instance handle. + * + * @pre @c params must not be NULL, and must point to a valid + * IVIDDEC2_DynamicParams structure. + * + * @pre @c status must not be NULL, and must point to a valid + * IVIDDEC2_Status structure. + * + * @pre If a buffer is provided in the @c status->data field, + * it must be physically contiguous and owned by the calling + * application. + * + * @post The algorithm <b>must not</b> modify the contents of @c params. + * That is, the data pointed to by this parameter must be + * treated as read-only. + * + * @post If a buffer was provided in the @c status->data field, + * it is owned by the calling application. + * + * @retval IVIDDEC2_EOK @copydoc IVIDDEC2_EOK + * @retval IVIDDEC2_EFAIL @copydoc IVIDDEC2_EFAIL + * See IVIDDEC2_Status#extendedError + * for more detailed further error + * conditions. + * @retval IVIDDEC2_EUNSUPPORTED @copydoc IVIDDEC2_EUNSUPPORTED + */ + XDAS_Int32 (*control)(IVIDDEC2_Handle handle, IVIDDEC2_Cmd id, + IVIDDEC2_DynamicParams *params, IVIDDEC2_Status *status); + +} IVIDDEC2_Fxns; + + +/*@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* ti_xdais_dm_IVIDDEC2_ */ |