summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dce_priv.h6
-rw-r--r--dce_rpc.h6
-rw-r--r--libdce.c672
-rw-r--r--test_qnx/dce_enc_test/dce_enc_test.c766
-rw-r--r--test_qnx/dce_enc_test/dce_enc_test.use44
-rw-r--r--test_qnx/dce_test/dce_test.c460
-rw-r--r--test_qnx/dce_test/dce_test.use25
7 files changed, 1546 insertions, 433 deletions
diff --git a/dce_priv.h b/dce_priv.h
index 5e2fba1..198c689 100644
--- a/dce_priv.h
+++ b/dce_priv.h
@@ -57,19 +57,19 @@ extern int dce_debug;
57#ifdef BUILDOS_QNX 57#ifdef BUILDOS_QNX
58#include <sys/slog.h> 58#include <sys/slog.h>
59#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \ 59#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \
60 slogf(42, _SLOG_INFO, "%s:%d:\t%s\terror: " FMT, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ 60 slogf(42, _SLOG_INFO, "%s:%d:\t%s\t" FMT, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
61} while( 0 ) 61} while( 0 )
62 62
63#elif defined BUILDOS_LINUX 63#elif defined BUILDOS_LINUX
64#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \ 64#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \
65 printf("%s:%d:\t%s\t Error: "FMT,__FILE__, __LINE__,__FUNCTION__ ,##__VA_ARGS__); \ 65 printf("%s:%d:\t%s\t" FMT,__FILE__, __LINE__,__FUNCTION__ ,##__VA_ARGS__); \
66}while( 0 ) 66}while( 0 )
67 67
68#elif defined BUILDOS_ANDROID 68#elif defined BUILDOS_ANDROID
69#include <utils/Log.h> 69#include <utils/Log.h>
70#define LOG_TAG "libdce" 70#define LOG_TAG "libdce"
71#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \ 71#define TRACE(lvl,FMT, ...) do if ((lvl) <= dce_debug) { \
72 ALOGE("%s:%d:\t%s\t Error: "FMT,__FILE__, __LINE__,__FUNCTION__ ,##__VA_ARGS__); \ 72 ALOGE("%s:%d:\t%s\t" FMT,__FILE__, __LINE__,__FUNCTION__ ,##__VA_ARGS__); \
73}while( 0 ) 73}while( 0 )
74#endif 74#endif
75 75
diff --git a/dce_rpc.h b/dce_rpc.h
index d1307ce..dcbeaf7 100644
--- a/dce_rpc.h
+++ b/dce_rpc.h
@@ -63,6 +63,12 @@ typedef enum dce_rpc_call {
63 DCE_RPC_CODEC_DELETE 63 DCE_RPC_CODEC_DELETE
64} dce_rpc_call; 64} dce_rpc_call;
65 65
66//Enumeration for dce function callback
67typedef enum dce_callback_rpc_call {
68 DCE_CALLBACK_RPC_GET_DATAFXN = 0,
69 DCE_CALLBACK_RPC_PUT_DATAFXN,
70 DCE_CALLBACK_RPC_GET_BUFFERFXN
71} dce_callback_rpc_call;
66 72
67typedef enum dce_codec_type { 73typedef enum dce_codec_type {
68 OMAP_DCE_VIDENC2 = 1, 74 OMAP_DCE_VIDENC2 = 1,
diff --git a/libdce.c b/libdce.c
index 108d8f3..82eaf46 100644
--- a/libdce.c
+++ b/libdce.c
@@ -35,6 +35,7 @@
35#include <stdio.h> 35#include <stdio.h>
36#include <pthread.h> 36#include <pthread.h>
37#include <errno.h> 37#include <errno.h>
38#include <semaphore.h>
38 39
39/* IPC Headers */ 40/* IPC Headers */
40#include <ti/ipc/mm/MmRpc.h> 41#include <ti/ipc/mm/MmRpc.h>
@@ -45,23 +46,72 @@
45#include "dce_priv.h" 46#include "dce_priv.h"
46#include "memplugin.h" 47#include "memplugin.h"
47 48
48
49/***************** GLOBALS ***************************/ 49/***************** GLOBALS ***************************/
50/* Handle used for Remote Communication */ 50/* Handle used for Remote Communication */
51MmRpc_Handle MmRpcHandle[MAX_REMOTEDEVICES] = { NULL}; 51MmRpc_Handle MmRpcHandle[MAX_REMOTEDEVICES] = { NULL};
52Engine_Handle gEngineHandle[MAX_INSTANCES][MAX_REMOTEDEVICES] = { {NULL, NULL}}; 52Engine_Handle gEngineHandle[MAX_INSTANCES][MAX_REMOTEDEVICES] = { {NULL, NULL}};
53MmRpc_Handle MmRpcCallbackHandle = NULL;
54static int MmRpcCallback_count = 0;
53 55
54#ifdef BUILDOS_LINUX 56#ifdef BUILDOS_LINUX
55pthread_mutex_t ipc_mutex; 57pthread_mutex_t ipc_mutex;
58pthread_mutex_t dce_callback_mutex;
56#else 59#else
57pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER; 60pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER;
61static pthread_mutex_t dce_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
58#endif 62#endif
59 63
60static int __ClientCount[MAX_REMOTEDEVICES] = {0}; 64static int __ClientCount[MAX_REMOTEDEVICES] = {0};
61int dce_debug = DCE_DEBUG_LEVEL; 65int dce_debug = DCE_DEBUG_LEVEL;
62const String DCE_DEVICE_NAME[MAX_REMOTEDEVICES]= {"rpmsg-dce","rpmsg-dce-dsp"}; 66const String DCE_DEVICE_NAME[MAX_REMOTEDEVICES]= {"rpmsg-dce","rpmsg-dce-dsp"};
67const String DCE_CALLBACK_NAME = "dce-callback";
68
69typedef struct {
70 XDAS_UInt32 codec_handle;
71 XDM_DataSyncHandle local_dataSyncHandle;
72 XDM_DataSyncDesc *local_dataSyncDesc;
73 XDAS_Int32 getDataFlag;
74 XDM_DataSyncGetFxn (*local_get_DataFxn) (XDM_DataSyncHandle, XDM_DataSyncDesc*);
75 XDAS_Int32 putDataFlag;
76 XDM_DataSyncGetFxn (*local_put_DataFxn) (XDM_DataSyncHandle, XDM_DataSyncDesc*);
77 XDAS_Int32 getBufferFlag;
78 pthread_t getDataFxn_thread;
79 pthread_t putDataFxn_thread;
80 sem_t sem_dec_row_mode;
81 sem_t sem_enc_row_mode;
82 int row_mode;
83 int first_control;
84 int receive_numBlocks;
85 int total_numBlocks;
86} CallbackFlag;
87
88static CallbackFlag callbackmsg[MAX_INSTANCES];
63 89
64/***************** INLINE FUNCTIONS ******************/ 90/***************** INLINE FUNCTIONS ******************/
91static inline int get_callback(Uint32 codec)
92{
93 int i;
94 for (i = 0; i < MAX_INSTANCES; i++) {
95 if( callbackmsg[i].codec_handle == codec ) {
96 return i;
97 }
98 }
99 return -1;
100}
101
102static inline int update_clients_table(Engine_Handle engine, int core)
103{
104 int i;
105 for(i = 0; i < MAX_INSTANCES; i++)
106 {
107 if( gEngineHandle[i][core] == 0 ) {
108 gEngineHandle[i][core] = engine;
109 return i;
110 }
111 }
112 return -1;
113}
114
65static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry) 115static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry)
66{ 116{
67 fxnCtx->fxn_id = fxn_id; 117 fxnCtx->fxn_id = fxn_id;
@@ -106,12 +156,12 @@ static inline void Fill_MmRpc_fxnCtx_Xlt_Array(MmRpc_Xlt *mmrpc_xlt, int index,
106 156
107static int __inline getCoreIndexFromName(String name) 157static int __inline getCoreIndexFromName(String name)
108{ 158{
109 if(name == NULL) 159 if( name == NULL )
110 return INVALID_CORE; 160 return INVALID_CORE;
111 161
112 if(!strcmp(name,"ivahd_vidsvr")) 162 if( !strcmp(name,"ivahd_vidsvr") )
113 return IPU; 163 return IPU;
114 else if(!strcmp(name, "dsp_vidsvr")) 164 else if( !strcmp(name, "dsp_vidsvr") )
115 return DSP; 165 return DSP;
116 else 166 else
117 return INVALID_CORE; 167 return INVALID_CORE;
@@ -119,9 +169,9 @@ static int __inline getCoreIndexFromName(String name)
119 169
120static int __inline getCoreIndexFromCodec(int codec_id) 170static int __inline getCoreIndexFromCodec(int codec_id)
121{ 171{
122 if(codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3) 172 if( codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3 )
123 return IPU; 173 return IPU;
124 else if(codec_id == OMAP_DCE_VIDDEC2) 174 else if( codec_id == OMAP_DCE_VIDDEC2 )
125 return DSP; 175 return DSP;
126 else 176 else
127 return INVALID_CORE; 177 return INVALID_CORE;
@@ -132,16 +182,15 @@ static int __inline getCoreIndexFromEngine(Engine_Handle engine, int *tabIdx)
132 int i; 182 int i;
133 int core = INVALID_CORE; 183 int core = INVALID_CORE;
134 184
135
136 *tabIdx = -1; 185 *tabIdx = -1;
137 186
138 for(i = 0; i < MAX_INSTANCES ; i++) { 187 for(i = 0; i < MAX_INSTANCES ; i++) {
139 if(engine == gEngineHandle[i][IPU]) { 188 if( engine == gEngineHandle[i][IPU] ) {
140 core = IPU; 189 core = IPU;
141 *tabIdx = i; 190 *tabIdx = i;
142 break; 191 break;
143 } 192 }
144 else if(engine == gEngineHandle[i][DSP]) { 193 else if( engine == gEngineHandle[i][DSP] ) {
145 *tabIdx = i; 194 *tabIdx = i;
146 core = DSP; 195 core = DSP;
147 break; 196 break;
@@ -167,6 +216,175 @@ void dce_free(void *ptr)
167 memplugin_free(ptr); 216 memplugin_free(ptr);
168} 217}
169 218
219/* dce_callback_putDataFxn is a callback function that runs on different Thread id. */
220/* It is an infinite loop notifying client when partial output data is available when outputDataMode = IVIDEO_ROWMODE. */
221int dce_callback_putDataFxn(void *codec)
222{
223 MmRpc_FxnCtx fxnCtx;
224 int32_t fxnRet;
225 int32_t return_callback;
226 dce_error_status eError = DCE_EOK;
227 XDM_DataSyncHandle *codec_handle = (XDM_DataSyncHandle *) codec;
228 int id;
229
230 DEBUG("======================START======================== codec_handle 0x%x", (unsigned int) *codec_handle);
231
232 id = get_callback((Uint32) *codec_handle);
233 if( id < 0 ) {
234 ERROR("Cannot find the entry in callbackmsg");
235 } else {
236 (callbackmsg[id]).local_dataSyncHandle = *codec_handle;
237 /* This is called from VIDDEC3_process, so we can start telling client to get the output data and provide the numBlocks info. */
238 /* Call the callback function specified in the dynParams->putDataFxn */
239 while (1) {
240 if( (callbackmsg[id]).putDataFlag == 1 ) {
241 DEBUG("lock (callbackmsg[%d]).putDataFxn_thread 0x%x (callbackmsg[%d]).local_dataSyncHandle 0x%x",
242 id, (callbackmsg[id]).putDataFxn_thread, id, (unsigned int) (callbackmsg[id]).local_dataSyncHandle);
243 pthread_mutex_lock(&dce_callback_mutex);
244 if( (callbackmsg[id]).row_mode ) {
245 /* Marshall function arguments into the send callback information to codec for put_DataFxn */
246 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_CALLBACK_RPC_PUT_DATAFXN, 2, 0, NULL);
247 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), (int32_t) (callbackmsg[id]).local_dataSyncHandle);
248 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[1]), GetSz((callbackmsg[id]).local_dataSyncDesc), (void *) P2H((callbackmsg[id]).local_dataSyncDesc),
249 sizeof(MemHeader), memplugin_share((callbackmsg[id]).local_dataSyncDesc));
250
251 DEBUG("Calling MmRpc_call on MmRpcCallbackHandle %p", MmRpcCallbackHandle);
252 eError = MmRpc_call(MmRpcCallbackHandle, &fxnCtx, &fxnRet);
253 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
254
255 /* When this return it means that Codec has called DCE Server with putDataFxn callback that has the numBlock information. */
256 /* At this point, codec should have filled the outputBuffer pointer that is passed in VIDDEC3_process. */
257 DEBUG("From codec (callbackmsg[%d]).local_dataSyncHandle %p (callbackmsg[%d]).local_dataSyncDesc->numBlocks %d ",
258 id, (callbackmsg[id]).local_dataSyncHandle, id, (int32_t) (callbackmsg[id]).local_dataSyncDesc->numBlocks);
259
260 if( (callbackmsg[id]).local_dataSyncDesc->numBlocks ) {
261 (callbackmsg[id]).receive_numBlocks += (callbackmsg[id]).local_dataSyncDesc->numBlocks;
262 return_callback = (int32_t) ((callbackmsg[id]).local_put_DataFxn)((callbackmsg[id]).local_dataSyncHandle, (callbackmsg[id]).local_dataSyncDesc);
263 if( return_callback < 0 ) {
264 /* dce_callback_putDataFxn getting no output data saved when calling the callback. Ignore and continue. */
265 ERROR("Received return_callback %d when asking client to save the output Data of (callbackmsg[%d]).numBlock %d",
266 return_callback, id, (callbackmsg[id]).local_dataSyncDesc->numBlocks);
267 }
268
269 DEBUG("(callbackmsg[%d]).local_dataSyncHandle %p (callbackmsg[%d]).receive_numBlocks %d >= (callbackmsg[%d]).total_numBlocks %d (callbackmsg[%d]).putDataFlag %d",
270 id, (callbackmsg[id]).local_dataSyncHandle, id, (callbackmsg[id]).receive_numBlocks, id, (callbackmsg[id]).total_numBlocks, id, (callbackmsg[id]).putDataFlag);
271 } else {
272 /* dce_callback_putDataFxn getting 0 numBlocks from DCE server. Need to stop the loop as it indicates VIDDEC3_process will be returned*/
273 DEBUG("dce_callback_putDataFxn is getting (callbackmsg[%d]).numBlock %d when calling putDataFxn callback",
274 id, (callbackmsg[id]).local_dataSyncDesc->numBlocks);
275 (callbackmsg[id]).putDataFlag = 0;
276 }
277
278 DEBUG("unlock (callbackmsg[%d]).putDataFxn_thread 0x%x (callbackmsg[%d]).local_dataSyncHandle %p",
279 id, (callbackmsg[id]).putDataFxn_thread, id, (callbackmsg[id]).local_dataSyncHandle);
280 pthread_mutex_unlock(&dce_callback_mutex);
281 }
282 } else if( (callbackmsg[id]).putDataFlag == 2 ) {
283 /* Receive an indication to clean up and exit the thread. */
284 DEBUG("CLEAN UP indication due to (callbackmsg[%d]).putDataFlag %d is set.", id, (callbackmsg[id]).putDataFlag);
285 pthread_exit(0);
286 } else {
287 DEBUG("Do nothing (callbackmsg[%d]).local_dataSyncHandle 0x%x because (callbackmsg[%d]).putDataFlag %d is not 1.",
288 id, (unsigned int)(callbackmsg[id]).local_dataSyncHandle, id, (callbackmsg[id]).putDataFlag);
289 if ((callbackmsg[id]).receive_numBlocks) {
290 (callbackmsg[id]).receive_numBlocks = 0;
291 DEBUG("Signal sem_dec_row_mode as VIDDEC3_process might wait before returning to client.");
292 sem_post(&((callbackmsg[id]).sem_dec_row_mode));
293 }
294 sem_wait(&((callbackmsg[id]).sem_dec_row_mode));
295 }
296 }
297 }
298
299EXIT:
300
301 DEBUG("======================END======================== codec_handle 0x%x", (unsigned int) *codec_handle);
302 return (0);
303}
304
305
306/* dce_callback_getDataFxn is running on different Thread id. */
307/* It is an infinite loop request to client for more input data when inputDataMode = IVIDEO_ROWMODE. */
308int dce_callback_getDataFxn(void *codec)
309{
310 MmRpc_FxnCtx fxnCtx;
311 int32_t fxnRet;
312 int32_t return_callback;
313 dce_error_status eError = DCE_EOK;
314 XDM_DataSyncHandle *codec_handle = (XDM_DataSyncHandle *) codec;
315 int id;
316
317 DEBUG("======================START========================");
318 DEBUG(" >> dce_callback_getDataFxn codec_handle 0x%x", (unsigned int) *codec_handle);
319
320 id = get_callback((Uint32) *codec_handle);
321 if( id < 0 ) {
322 ERROR("Cannot find the entry in callbackmsg");
323 } else {
324 (callbackmsg[id]).local_dataSyncHandle = *codec_handle;
325 /* This is called from VIDENC2_process, so we can start request client to fill in input and provide the row information written. */
326 /* Call the callback function specified in the dynParams->getDataFxn */
327 while( 1 ) {
328 if( (callbackmsg[id]).getDataFlag == 1 ) {
329 DEBUG("lock (callbackmsg[%d]).getDataFxn_thread 0x%x (callbackmsg[%d]).local_dataSyncHandle %p",
330 id, (callbackmsg[id]).getDataFxn_thread, id, (callbackmsg[id]).local_dataSyncHandle);
331 pthread_mutex_lock(&dce_callback_mutex);
332 if( (callbackmsg[id]).row_mode ) {
333 /* Calling client callback function to pass data received from IVA-HD codec */
334 return_callback = (int32_t) ((callbackmsg[id]).local_get_DataFxn)((callbackmsg[id]).local_dataSyncHandle, (callbackmsg[id]).local_dataSyncDesc);
335 if( return_callback < 0 ) {
336 /* dce_callback_getDataFxn getting error when calling the callback. Ignore and re-try. */
337 ERROR("dce_callback_getDataFxn is getting return_callback %d when calling getDataFxn callback. Retry callback for more data.", return_callback);
338 } else {
339 (callbackmsg[id]).receive_numBlocks += (callbackmsg[id]).local_dataSyncDesc->numBlocks;
340
341 if( (callbackmsg[id]).local_dataSyncDesc->numBlocks ) {
342 /* Marshall function arguments into the send callback information to codec for get_dataFxn */
343 Fill_MmRpc_fxnCtx(&fxnCtx, DCE_CALLBACK_RPC_GET_DATAFXN, 2, 0, NULL);
344 Fill_MmRpc_fxnCtx_Scalar_Params(&(fxnCtx.params[0]), sizeof(int32_t), (int32_t) (callbackmsg[id]).local_dataSyncHandle);
345 Fill_MmRpc_fxnCtx_OffPtr_Params(&(fxnCtx.params[1]), GetSz((callbackmsg[id]).local_dataSyncDesc), (void *) P2H((callbackmsg[id]).local_dataSyncDesc),
346 sizeof(MemHeader), memplugin_share((callbackmsg[id]).local_dataSyncDesc));
347
348 eError = MmRpc_call(MmRpcCallbackHandle, &fxnCtx, &fxnRet);
349 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
350
351 DEBUG("(callbackmsg[%d]).local_dataSyncHandle %p (callbackmsg[%d]).receive_numBlocks %d >= (callbackmsg[%d]).total_numBlocks %d",
352 id, (callbackmsg[id]).local_dataSyncHandle, id, (callbackmsg[id]).receive_numBlocks, id, (callbackmsg[id]).total_numBlocks);
353
354 if( (callbackmsg[id]).receive_numBlocks >= (callbackmsg[id]).total_numBlocks ) {
355 /* one full frame has been sent to codec. Need to stop the callback call to client. */
356 /* it will be resumed once VIDENC2_process for the next one. */
357 (callbackmsg[id]).receive_numBlocks = 0;
358 (callbackmsg[id]).getDataFlag = 0;
359 DEBUG("Setting the (callbackmsg[%d]).getDataFlag to 0 to stop calling client to fill", id);
360 }
361 } else {
362 /* dce_callback_getDataFxn getting 0 numBlocks when calling the callback. Ignore and re-try. */
363 DEBUG("Received dataSyncDesc->numBlocks == 0 meaning the callback thread has no data -ignore.");
364 }
365 }
366 DEBUG("unlock (callbackmsg[%d]).getDataFxn_thread 0x%x (callbackmsg[%d]).local_dataSyncHandle %p",
367 id, (callbackmsg[id]).getDataFxn_thread, id, (callbackmsg[id]).local_dataSyncHandle);
368 pthread_mutex_unlock(&dce_callback_mutex);
369 }
370 } else if( (callbackmsg[id]).getDataFlag == 2 ) {
371 /* Receive an indication to clean up and exit the thread. */
372 DEBUG("CLEAN UP indication due to (callbackmsg[%d]).getDataFlag %d is set.", id, (callbackmsg[id]).getDataFlag);
373 pthread_exit(0);
374 } else {
375 DEBUG("Do nothing (callbackmsg[%d]).local_dataSyncHandle 0x%x because msg-getDataFlag %d is not 1.",
376 id, (unsigned int)(callbackmsg[id]).local_dataSyncHandle, (callbackmsg[id]).getDataFlag);
377 sem_wait(&((callbackmsg[id]).sem_enc_row_mode));
378 }
379 }
380 }
381
382EXIT:
383 DEBUG(" << dce_callback_getDataFxn COMPLETE");
384 DEBUG("======================END========================");
385 return (0);
386}
387
170/*=====================================================================================*/ 388/*=====================================================================================*/
171/** dce_ipc_init : Initialize MmRpc. This function is called within Engine_open(). 389/** dce_ipc_init : Initialize MmRpc. This function is called within Engine_open().
172 * 390 *
@@ -180,7 +398,7 @@ int dce_ipc_init(int core)
180 DEBUG(" >> dce_ipc_init\n"); 398 DEBUG(" >> dce_ipc_init\n");
181 399
182 /*First check if maximum clients are already using ipc*/ 400 /*First check if maximum clients are already using ipc*/
183 if(__ClientCount[core] >= MAX_INSTANCES) { 401 if( __ClientCount[core] >= MAX_INSTANCES ) {
184 eError = DCE_EXDM_UNSUPPORTED; 402 eError = DCE_EXDM_UNSUPPORTED;
185 return (eError); 403 return (eError);
186 } 404 }
@@ -188,7 +406,7 @@ int dce_ipc_init(int core)
188 /* Create remote server insance */ 406 /* Create remote server insance */
189 __ClientCount[core]++; 407 __ClientCount[core]++;
190 408
191 if(__ClientCount[core] > 1) { 409 if( __ClientCount[core] > 1 ) {
192 goto EXIT; 410 goto EXIT;
193 } 411 }
194 412
@@ -208,13 +426,13 @@ EXIT:
208 */ 426 */
209void dce_ipc_deinit(int core, int tableIdx) 427void dce_ipc_deinit(int core, int tableIdx)
210{ 428{
211 if(__ClientCount[core] == 0) { 429 if( __ClientCount[core] == 0 ) {
212 DEBUG("Nothing to be done: a spurious call\n"); 430 DEBUG("Nothing to be done: a spurious call\n");
213 return; 431 return;
214 } 432 }
215 __ClientCount[core]--; 433 __ClientCount[core]--;
216 434
217 if (tableIdx >= 0) 435 if ( tableIdx >= 0 )
218 gEngineHandle[tableIdx][core] = 0; 436 gEngineHandle[tableIdx][core] = 0;
219 437
220 if( __ClientCount[core] > 0 ) { 438 if( __ClientCount[core] > 0 ) {
@@ -230,21 +448,6 @@ EXIT:
230 return; 448 return;
231} 449}
232 450
233static inline int update_clients_table(Engine_Handle engine, int core)
234{
235 int i;
236 for(i = 0; i < MAX_INSTANCES; i++)
237 {
238 if(gEngineHandle[i][core] == 0) {
239 gEngineHandle[i][core] = engine;
240 return i;
241 }
242 }
243 return -1;
244}
245
246
247
248/*===============================================================*/ 451/*===============================================================*/
249/** Engine_open : Open Codec Engine. 452/** Engine_open : Open Codec Engine.
250 * 453 *
@@ -264,7 +467,7 @@ Engine_Handle Engine_open(String name, Engine_Attrs *attrs, Engine_Error *ec)
264 int coreIdx = INVALID_CORE; 467 int coreIdx = INVALID_CORE;
265 int tabIdx = -1; 468 int tabIdx = -1;
266 469
267 470 DEBUG("START Engine_open ipc_mutex 0x%x", (unsigned int) &ipc_mutex);
268 /*Acquire permission to use IPC*/ 471 /*Acquire permission to use IPC*/
269 pthread_mutex_lock(&ipc_mutex); 472 pthread_mutex_lock(&ipc_mutex);
270 473
@@ -317,6 +520,7 @@ EXIT:
317 } 520 }
318 /*Relinquish IPC*/ 521 /*Relinquish IPC*/
319 pthread_mutex_unlock(&ipc_mutex); 522 pthread_mutex_unlock(&ipc_mutex);
523 DEBUG("END Engine_open ipc_mutex 0x%x", (unsigned int) &ipc_mutex);
320 524
321 return ((Engine_Handle)engine_handle); 525 return ((Engine_Handle)engine_handle);
322} 526}
@@ -352,7 +556,7 @@ Void Engine_close(Engine_Handle engine)
352 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); 556 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
353 557
354EXIT: 558EXIT:
355 if(coreIdx != INVALID_CORE) 559 if( coreIdx != INVALID_CORE )
356 dce_ipc_deinit(coreIdx, tableIdx); 560 dce_ipc_deinit(coreIdx, tableIdx);
357 561
358 /*Relinquish IPC*/ 562 /*Relinquish IPC*/
@@ -383,10 +587,6 @@ static void *create(Engine_Handle engine, String name, void *params, dce_codec_t
383 char *codec_name = NULL; 587 char *codec_name = NULL;
384 int coreIdx = INVALID_CORE; 588 int coreIdx = INVALID_CORE;
385 589
386
387 /*Acquire permission to use IPC*/
388 pthread_mutex_lock(&ipc_mutex);
389
390 _ASSERT(name != '\0', DCE_EINVALID_INPUT); 590 _ASSERT(name != '\0', DCE_EINVALID_INPUT);
391 _ASSERT(engine != NULL, DCE_EINVALID_INPUT); 591 _ASSERT(engine != NULL, DCE_EINVALID_INPUT);
392 _ASSERT(params != NULL, DCE_EINVALID_INPUT); 592 _ASSERT(params != NULL, DCE_EINVALID_INPUT);
@@ -416,8 +616,6 @@ static void *create(Engine_Handle engine, String name, void *params, dce_codec_t
416 616
417EXIT: 617EXIT:
418 memplugin_free(codec_name); 618 memplugin_free(codec_name);
419 /*Relinquish IPC*/
420 pthread_mutex_unlock(&ipc_mutex);
421 return ((void *)codec_handle); 619 return ((void *)codec_handle);
422} 620}
423 621
@@ -443,10 +641,6 @@ static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dc
443 dce_error_status eError = DCE_EOK; 641 dce_error_status eError = DCE_EOK;
444 int coreIdx = INVALID_CORE; 642 int coreIdx = INVALID_CORE;
445 643
446
447 /*Acquire permission to use IPC*/
448 pthread_mutex_lock(&ipc_mutex);
449
450 _ASSERT(codec != NULL, DCE_EINVALID_INPUT); 644 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
451 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT); 645 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
452 _ASSERT(status != NULL, DCE_EINVALID_INPUT); 646 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
@@ -469,16 +663,14 @@ static XDAS_Int32 control(void *codec, int id, void *dynParams, void *status, dc
469 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); 663 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
470 664
471EXIT: 665EXIT:
472 /*Relinquish IPC*/
473 pthread_mutex_unlock(&ipc_mutex);
474 return (fxnRet); 666 return (fxnRet);
475 667
476} 668}
477 669
478/*===============================================================*/ 670/*===============================================================*/
479/** get_version : Codec control call to get the codec version. This call has been made 671/** get_version : Codec control call to get the codec version. This call has been made
480 * separate from control call because it involves an additional version 672 * separate from control call because it involves an additional version
481 * buffer translation. 673 * buffer translation.
482 * 674 *
483 * @ param codec [in] : Codec Handle obtained in create() call. 675 * @ param codec [in] : Codec Handle obtained in create() call.
484 * @ param id [in] : Command id for XDM control operation. 676 * @ param id [in] : Command id for XDM control operation.
@@ -501,10 +693,6 @@ static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_co
501 dce_error_status eError = DCE_EOK; 693 dce_error_status eError = DCE_EOK;
502 int coreIdx = INVALID_CORE; 694 int coreIdx = INVALID_CORE;
503 695
504
505 /*Acquire permission to use IPC*/
506 pthread_mutex_lock(&ipc_mutex);
507
508 _ASSERT(codec != NULL, DCE_EINVALID_INPUT); 696 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
509 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT); 697 _ASSERT(dynParams != NULL, DCE_EINVALID_INPUT);
510 _ASSERT(status != NULL, DCE_EINVALID_INPUT); 698 _ASSERT(status != NULL, DCE_EINVALID_INPUT);
@@ -540,8 +728,6 @@ static XDAS_Int32 get_version(void *codec, void *dynParams, void *status, dce_co
540 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); 728 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
541 729
542EXIT: 730EXIT:
543 /*Relinquish IPC*/
544 pthread_mutex_unlock(&ipc_mutex);
545 return (fxnRet); 731 return (fxnRet);
546} 732}
547 733
@@ -590,10 +776,6 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
590 int32_t outbuf_offset[MAX_OUTPUT_BUF]; 776 int32_t outbuf_offset[MAX_OUTPUT_BUF];
591#endif 777#endif
592 778
593
594 /*Acquire permission to use IPC*/
595 pthread_mutex_lock(&ipc_mutex);
596
597 _ASSERT(codec != NULL, DCE_EINVALID_INPUT); 779 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
598 _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT); 780 _ASSERT(inBufs != NULL, DCE_EINVALID_INPUT);
599 _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT); 781 _ASSERT(outBufs != NULL, DCE_EINVALID_INPUT);
@@ -661,8 +843,8 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
661 (size_t)*data_buf, (size_t)*data_buf); 843 (size_t)*data_buf, (size_t)*data_buf);
662#ifdef BUILDOS_LINUX 844#ifdef BUILDOS_LINUX
663 /*Single planar input buffer for Encoder. No adjustments needed for Multiplanar case*/ 845 /*Single planar input buffer for Encoder. No adjustments needed for Multiplanar case*/
664 if(count == CHROMA_BUF && codec_id == OMAP_DCE_VIDENC2 && ((IVIDEO2_BufDesc *)inBufs)->planeDesc[LUMA_BUF].buf == ((IVIDEO2_BufDesc *)inBufs)->planeDesc[CHROMA_BUF].buf){ 846 if( count == CHROMA_BUF && codec_id == OMAP_DCE_VIDENC2 && ((IVIDEO2_BufDesc *)inBufs)->planeDesc[LUMA_BUF].buf == ((IVIDEO2_BufDesc *)inBufs)->planeDesc[CHROMA_BUF].buf ) {
665 if(((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].memType == XDM_MEMTYPE_RAW || 847 if( ((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].memType == XDM_MEMTYPE_RAW ||
666 ((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].memType == XDM_MEMTYPE_TILEDPAGE ) 848 ((IVIDEO2_BufDesc *)inBufs)->planeDesc[count].memType == XDM_MEMTYPE_TILEDPAGE )
667 *data_buf += ((IVIDEO2_BufDesc *)inBufs)->planeDesc[LUMA_BUF].bufSize.bytes; 849 *data_buf += ((IVIDEO2_BufDesc *)inBufs)->planeDesc[LUMA_BUF].bufSize.bytes;
668 else 850 else
@@ -675,8 +857,8 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
675 857
676 /* Output Buffers */ 858 /* Output Buffers */
677 for( count = 0; count < numOutBufs; count++, total_count++ ) { 859 for( count = 0; count < numOutBufs; count++, total_count++ ) {
678 if(codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3) { 860 if( codec_id == OMAP_DCE_VIDENC2 || codec_id == OMAP_DCE_VIDDEC3 ) {
679 if(((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) { 861 if( ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].buf != ((XDM2_BufDesc *)outBufs)->descs[CHROMA_BUF].buf ) {
680 /* Either Encode usecase or MultiPlanar Buffers for Decode usecase */ 862 /* Either Encode usecase or MultiPlanar Buffers for Decode usecase */
681 data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf)); 863 data_buf = (void * *)(&(((XDM2_BufDesc *)outBufs)->descs[count].buf));
682#ifdef BUILDOS_ANDROID 864#ifdef BUILDOS_ANDROID
@@ -701,7 +883,7 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
701 (size_t)*data_buf, (size_t)*data_buf); 883 (size_t)*data_buf, (size_t)*data_buf);
702 884
703 if( count == CHROMA_BUF ) { 885 if( count == CHROMA_BUF ) {
704 if(((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW || 886 if( ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_RAW ||
705 ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) { 887 ((XDM2_BufDesc *)outBufs)->descs[count].memType == XDM_MEMTYPE_TILEDPAGE ) {
706 *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.bytes; 888 *data_buf += ((XDM2_BufDesc *)outBufs)->descs[LUMA_BUF].bufSize.bytes;
707 } else { 889 } else {
@@ -711,8 +893,8 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
711 } 893 }
712 } 894 }
713#endif 895#endif
714 } else if(codec_id == OMAP_DCE_VIDDEC2) { 896 } else if( codec_id == OMAP_DCE_VIDDEC2 ) {
715 if(count == LUMA_BUF) { 897 if( count == LUMA_BUF ) {
716 buf_arry = (void * *)(&(((XDM_BufDesc *)outBufs)->bufs)); 898 buf_arry = (void * *)(&(((XDM_BufDesc *)outBufs)->bufs));
717 899
718 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX, 900 Fill_MmRpc_fxnCtx_Xlt_Array(&(fxnCtx.xltAry[total_count]), OUTBUFS_INDEX,
@@ -764,8 +946,6 @@ static XDAS_Int32 process(void *codec, void *inBufs, void *outBufs,
764 eError = (dce_error_status)(fxnRet); 946 eError = (dce_error_status)(fxnRet);
765 947
766EXIT: 948EXIT:
767 /*Relinquish IPC*/
768 pthread_mutex_unlock(&ipc_mutex);
769 return (eError); 949 return (eError);
770} 950}
771 951
@@ -783,10 +963,6 @@ static void delete(void *codec, dce_codec_type codec_id)
783 dce_error_status eError = DCE_EOK; 963 dce_error_status eError = DCE_EOK;
784 int coreIdx = INVALID_CORE; 964 int coreIdx = INVALID_CORE;
785 965
786
787 /*Acquire permission to use IPC*/
788 pthread_mutex_lock(&ipc_mutex);
789
790 _ASSERT(codec != NULL, DCE_EINVALID_INPUT); 966 _ASSERT(codec != NULL, DCE_EINVALID_INPUT);
791 coreIdx = getCoreIndexFromCodec(codec_id); 967 coreIdx = getCoreIndexFromCodec(codec_id);
792 _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT); 968 _ASSERT(coreIdx != INVALID_CORE, DCE_EINVALID_INPUT);
@@ -801,8 +977,6 @@ static void delete(void *codec, dce_codec_type codec_id)
801 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL); 977 _ASSERT(eError == DCE_EOK, DCE_EIPC_CALL_FAIL);
802 978
803EXIT: 979EXIT:
804 /*Relinquish IPC*/
805 pthread_mutex_unlock(&ipc_mutex);
806 return; 980 return;
807} 981}
808 982
@@ -810,27 +984,110 @@ EXIT:
810VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name, 984VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name,
811 VIDDEC3_Params *params) 985 VIDDEC3_Params *params)
812{ 986{
813 VIDDEC3_Handle codec; 987 VIDDEC3_Handle codec = NULL;
988 MmRpc_Params args;
989 dce_error_status eError = DCE_EOK;
990 int id;
991
992 /*Acquire permission to use IPC*/
993 pthread_mutex_lock(&ipc_mutex);
994
995 id = get_callback(0);
996 if (id < 0) {
997 /* This is depended on the MAX_INSTANCE, by default it handles only 4 instances of codec instance (full frame or low latency) */
998 ERROR("Failed because too many codec clients, Max is %d. MAX_INSTANCES default needs to be changed if required.", MAX_INSTANCES);
999 goto EXIT;
1000 } else { /* Found empty array to be populated */
1001 if( params->outputDataMode == IVIDEO_NUMROWS ) {
1002 (callbackmsg[id]).row_mode = 1;
1003 (callbackmsg[id]).first_control = TRUE;
1004 (callbackmsg[id]).total_numBlocks = params->maxHeight / 16;
1005 DEBUG("callbackmsg[%d]->total_numBlocks %d", id, (callbackmsg[id]).total_numBlocks);
1006
1007 (callbackmsg[id]).local_dataSyncDesc = memplugin_alloc(sizeof(XDM_DataSyncDesc), 1, DEFAULT_REGION, 0, IPU);
1008 DEBUG("Checking local_dataSyncDesc %p local_put_DataFxn %p local_dataSyncHandle %p",
1009 (callbackmsg[id]).local_dataSyncDesc, (callbackmsg[id]).local_put_DataFxn, (callbackmsg[id]).local_dataSyncHandle);
1010 if( (callbackmsg[id]).local_dataSyncDesc == NULL ) {
1011 goto EXIT;
1012 }
1013
1014 /* Create sem_dec_row_mode */
1015 sem_init(&((callbackmsg[id]).sem_dec_row_mode), 0, 0);
1016
1017 DEBUG("MmRpcCallbackHandle 0x%x MmRpcCallback_count %d", (int)MmRpcCallbackHandle, MmRpcCallback_count);
1018 if( !MmRpcCallbackHandle ) {
1019 /* Need to create another MmRpcHandle for codec callback */
1020 MmRpc_Params_init(&args);
1021 eError = MmRpc_create(DCE_CALLBACK_NAME, &args, &MmRpcCallbackHandle);
1022 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, MmRpcCallbackHandle = NULL);
1023 DEBUG("open(/dev/%s]) -> 0x%x\n", DCE_CALLBACK_NAME, (int)MmRpcCallbackHandle);
1024 }
1025 MmRpcCallback_count++;
1026 } else if( params->outputDataMode == IVIDEO_ENTIREFRAME ) {
1027 (callbackmsg[id]).row_mode = 0; /* full frame; the other parameters are not used in full frame mode */
1028 } else {
1029 ERROR("outputDataMode %d is not supported.", params->outputDataMode);
1030 goto EXIT;
1031 }
1032 DEBUG("Checking row_mode %d first_control %d",
1033 (callbackmsg[id]).row_mode, (callbackmsg[id]).first_control);
1034 }
814 1035
815 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params); 1036 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
816 codec = create(engine, name, params, OMAP_DCE_VIDDEC3); 1037 codec = create(engine, name, params, OMAP_DCE_VIDDEC3);
817 DEBUG("<< codec=%p", codec); 1038 DEBUG("<< codec=%p", codec);
1039
1040 if( params->outputDataMode == IVIDEO_NUMROWS ) {
1041 (callbackmsg[id]).codec_handle = (XDAS_UInt32) codec;
1042 DEBUG("Saving the codec %p to (callbackmsg[%d]).codec_handle = 0x%x", codec, id, (unsigned int) (callbackmsg[id]).codec_handle);
1043 }
1044
1045EXIT:
1046 /*Relinquish IPC*/
1047 pthread_mutex_unlock(&ipc_mutex);
818 return (codec); 1048 return (codec);
819} 1049}
820 1050
821XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id, 1051XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd cmd_id,
822 VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status) 1052 VIDDEC3_DynamicParams *dynParams, VIDDEC3_Status *status)
823{ 1053{
824 XDAS_Int32 ret; 1054 XDAS_Int32 ret;
1055 int id;
825 1056
826 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p", 1057 /*Acquire permission to use IPC*/
827 codec, id, dynParams, status); 1058 pthread_mutex_lock(&ipc_mutex);
828 if( id == XDM_GETVERSION ) { 1059
1060 id = get_callback((Uint32) codec);
1061 if( id < 0 ) {
1062 DEBUG("Could not find the entry; control on full frame mode");
1063 } else {
1064 DEBUG("Checking codec_handle 0x%x row_mode %d first_control %d",
1065 (unsigned int) (callbackmsg[id]).codec_handle, (callbackmsg[id]).row_mode, (callbackmsg[id]).first_control);
1066 if( (callbackmsg[id]).row_mode && (callbackmsg[id]).first_control ) {
1067 /* dynParams has the function callback; store the information as it will get overwritten by the M4 codec for their own callback Fxn. */
1068 (callbackmsg[id]).local_put_DataFxn = (void*) dynParams->putDataFxn;
1069 (callbackmsg[id]).local_dataSyncHandle = dynParams->putDataHandle;
1070 (callbackmsg[id]).first_control = FALSE;
1071 DEBUG("Set callback pointer local_get_dataFxn %p local_dataSyncHandle %p",
1072 (callbackmsg[id]).local_put_DataFxn, (callbackmsg[id]).local_dataSyncHandle);
1073 }
1074
1075 if( cmd_id == XDM_FLUSH ) {
1076 DEBUG("FLUSH HAS BEEN ORDERED");
1077 }
1078 }
1079
1080 DEBUG(">> codec=%p, cmd_id=%d, dynParams=%p, status=%p",
1081 codec, cmd_id, dynParams, status);
1082 if( cmd_id == XDM_GETVERSION ) {
829 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3); 1083 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDDEC3);
830 } else { 1084 } else {
831 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDDEC3); 1085 ret = control(codec, cmd_id, dynParams, status, OMAP_DCE_VIDDEC3);
832 } 1086 }
1087 DEBUG("dynParams->putDataFxn %p", dynParams->putDataFxn);
833 DEBUG("<< ret=%d", ret); 1088 DEBUG("<< ret=%d", ret);
1089 /*Relinquish IPC*/
1090 pthread_mutex_unlock(&ipc_mutex);
834 return (ret); 1091 return (ret);
835} 1092}
836 1093
@@ -838,19 +1095,110 @@ XDAS_Int32 VIDDEC3_process(VIDDEC3_Handle codec,
838 XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs, 1095 XDM2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
839 VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs) 1096 VIDDEC3_InArgs *inArgs, VIDDEC3_OutArgs *outArgs)
840{ 1097{
841 XDAS_Int32 ret; 1098 XDAS_Int32 ret;
1099 pthread_attr_t attr;
1100 int id;
842 1101
843 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p", 1102 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
844 codec, inBufs, outBufs, inArgs, outArgs); 1103 codec, inBufs, outBufs, inArgs, outArgs);
1104
1105 /*Acquire permission to use IPC*/
1106 pthread_mutex_lock(&ipc_mutex);
1107 id = get_callback((Uint32) codec);
1108 if( id < 0 ) {
1109 DEBUG("Received VIDDEC3_process for ENTIRE/FULL FRAME decoding.");
1110 } else {
1111 pthread_mutex_lock(&dce_callback_mutex);
1112 DEBUG("Checking row_mode %d SETTING (callbackmsg[id]).putDataFlag = 0", (callbackmsg[id]).row_mode);
1113 if( (callbackmsg[id]).row_mode ) {
1114 (callbackmsg[id]).putDataFlag = 0;
1115 DEBUG("Checking callbackmsg[%d]->putDataFxn_thread %p", id, (void*) (callbackmsg[id]).putDataFxn_thread);
1116 if( !(callbackmsg[id]).putDataFxn_thread ) {
1117 /* Need to start a new thread for the callback handling to request for data - process call will be synchronous. */
1118 pthread_attr_init(&attr);
1119 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1120 if( pthread_create(&((callbackmsg[id]).putDataFxn_thread), &attr, (void*)dce_callback_putDataFxn, (void*) &codec) ) {
1121 pthread_mutex_unlock(&ipc_mutex);
1122 return DCE_EXDM_FAIL;
1123 }
1124 }
1125 DEBUG("Checking thread callbackmsg[%d]->putDataFxn_thread %p", id, (void*) (callbackmsg[id]).putDataFxn_thread);
1126
1127 /* Start the callback to get putDataFxn from codec to client. */
1128 (callbackmsg[id]).putDataFlag = 1;
1129 sem_post(&((callbackmsg[id]).sem_dec_row_mode));
1130
1131 DEBUG("Start the callback to client callbackmsg[%d]->putDataFlag %d on callbackmsg[%d]->local_dataSyncHandle 0x%x",
1132 id, (callbackmsg[id]).putDataFlag, id, (unsigned int) (callbackmsg[id]).local_dataSyncHandle);
1133 }
1134 pthread_mutex_unlock(&dce_callback_mutex);
1135 }
1136
845 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3); 1137 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDDEC3);
846 DEBUG("<< ret=%d", ret); 1138 DEBUG("<< ret=%d", ret);
1139
1140 if( (callbackmsg[id]).row_mode ) {
1141 DEBUG("(callbackmsg[%d]).receive_numBlocks %d >= (callbackmsg[%d]).total_numBlocks %d",
1142 id, (callbackmsg[id]).receive_numBlocks, id, (callbackmsg[id]).total_numBlocks);
1143
1144 if( (callbackmsg[id]).receive_numBlocks >= (callbackmsg[id]).total_numBlocks ) {
1145 DEBUG("Stop the callback to client callbackmsg[%d]->putDataFlag %d reach full frame (callbackmsg[%d]).receive_numBlocks %d",
1146 id, (callbackmsg[id]).putDataFlag, id, (callbackmsg[id]).receive_numBlocks);
1147 (callbackmsg[id]).putDataFlag = 0;
1148 if ((callbackmsg[id]).receive_numBlocks) {
1149 DEBUG("Waiting for dce_callback_putDataFxn to be in waiting case.");
1150 sem_wait(&((callbackmsg[id]).sem_dec_row_mode));
1151 }
1152 }
1153 }
1154
1155 /*Relinquish IPC*/
1156 pthread_mutex_unlock(&ipc_mutex);
847 return (ret); 1157 return (ret);
848} 1158}
849 1159
850Void VIDDEC3_delete(VIDDEC3_Handle codec) 1160Void VIDDEC3_delete(VIDDEC3_Handle codec)
851{ 1161{
1162 void *res;
1163 int id;
1164
852 DEBUG(">> codec=%p", codec); 1165 DEBUG(">> codec=%p", codec);
1166
1167 /*Acquire permission to use IPC*/
1168 pthread_mutex_lock(&ipc_mutex);
1169
1170 id = get_callback((Uint32) codec);
1171 if( id < 0 ) {
1172 DEBUG("Delete decode instance in full frame mode");
1173 } else {
1174 if( (callbackmsg[id]).row_mode ) {
1175 MmRpcCallback_count--;
1176 /* Exit the callback thread to request to client */
1177 (callbackmsg[id]).putDataFlag = 2;
1178 DEBUG("Exit the callback to client callbackmsg[%d]->getDataFlag %d callbackmsg[%d]->getDataFxn_thread %p",
1179 id, (callbackmsg[id]).putDataFlag, id, (void*) ((callbackmsg[id]).putDataFxn_thread));
1180 sem_post(&((callbackmsg[id]).sem_dec_row_mode));
1181
1182 pthread_join((callbackmsg[id]).putDataFxn_thread, (void*) &res);
1183 DEBUG("PTHREAD_JOIN res %d", (int) res);
1184
1185 /* Clean up the allocation earlier. */
1186 memplugin_free((callbackmsg[id]).local_dataSyncDesc);
1187
1188 /* Destroy sem_dec_row_mode */
1189 sem_destroy(&((callbackmsg[id]).sem_dec_row_mode));
1190
1191 DEBUG("Checking on MmRpcCallback_count %d MmRpcCallbackHandle 0x%x", MmRpcCallback_count, (unsigned int) MmRpcCallbackHandle);
1192 if( MmRpcCallback_count == 0 && MmRpcCallbackHandle != NULL ) {
1193 MmRpc_delete(&MmRpcCallbackHandle);
1194 MmRpcCallbackHandle = NULL;
1195 }
1196 }
1197 }
1198
853 delete(codec, OMAP_DCE_VIDDEC3); 1199 delete(codec, OMAP_DCE_VIDDEC3);
1200 /*Relinquish IPC*/
1201 pthread_mutex_unlock(&ipc_mutex);
854 DEBUG("<<"); 1202 DEBUG("<<");
855} 1203}
856 1204
@@ -858,27 +1206,101 @@ Void VIDDEC3_delete(VIDDEC3_Handle codec)
858VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name, 1206VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name,
859 VIDENC2_Params *params) 1207 VIDENC2_Params *params)
860{ 1208{
861 VIDENC2_Handle codec; 1209 VIDENC2_Handle codec = NULL;
1210 MmRpc_Params args;
1211 dce_error_status eError = DCE_EOK;
1212 int id;
1213
1214 /*Acquire permission to use IPC*/
1215 pthread_mutex_lock(&ipc_mutex);
1216
1217 id = get_callback(0);
1218 if( id < 0 ) {
1219 /* This is depended on the MAX_INSTANCE, by default it handles only 4 instances of codec instance (full frame or low latency) */
1220 ERROR("Failed because too many codec clients, Max is %d. MAX_INSTANCES default needs to be changed if required.", MAX_INSTANCES);
1221 goto EXIT;
1222 } else { /* Found empty array to be populated */
1223 if( params->inputDataMode == IVIDEO_NUMROWS ) {
1224 (callbackmsg[id]).row_mode = 1;
1225 (callbackmsg[id]).first_control = TRUE;
1226 (callbackmsg[id]).total_numBlocks = params->maxHeight / 16;
1227 DEBUG("callbackmsg[%d]->total_numBlocks %d", id, (callbackmsg[id]).total_numBlocks);
1228
1229 /* Create sem_dec_row_mode */
1230 sem_init(&((callbackmsg[id]).sem_enc_row_mode), 0, 0);
1231
1232 (callbackmsg[id]).local_dataSyncDesc = memplugin_alloc(sizeof(XDM_DataSyncDesc), 1, DEFAULT_REGION, 0, IPU);
1233 DEBUG("Checking local_dataSyncDesc %p local_get_DataFxn %p local_dataSyncHandle %p",
1234 (callbackmsg[id]).local_dataSyncDesc, (callbackmsg[id]).local_get_DataFxn, (callbackmsg[id]).local_dataSyncHandle);
1235 if( (callbackmsg[id]).local_dataSyncDesc == NULL ) {
1236 goto EXIT;
1237 }
1238
1239 if( !MmRpcCallbackHandle ) {
1240 /* Need to create another MmRpcHandle for codec callback */
1241 MmRpc_Params_init(&args);
1242 eError = MmRpc_create(DCE_CALLBACK_NAME, &args, &MmRpcCallbackHandle);
1243 _ASSERT_AND_EXECUTE(eError == DCE_EOK, DCE_EIPC_CREATE_FAIL, MmRpcCallbackHandle = NULL);
1244 DEBUG("open(/dev/%s]) -> 0x%x\n", DCE_CALLBACK_NAME, (int)MmRpcCallbackHandle);
1245 }
1246 MmRpcCallback_count++;
1247 } else if( params->inputDataMode == IVIDEO_ENTIREFRAME ) {
1248 (callbackmsg[id]).row_mode = 0; /* full frame; the other parameters are not used in full frame mode */
1249 } else {
1250 ERROR("inputDataMode %d is not supported.", params->inputDataMode);
1251 goto EXIT;
1252 }
1253 DEBUG("Checking row_mode %d first_control %d", (callbackmsg[id]).row_mode, (callbackmsg[id]).first_control);
1254 }
862 1255
863 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params); 1256 DEBUG(">> engine=%p, name=%s, params=%p", engine, name, params);
864 codec = create(engine, name, params, OMAP_DCE_VIDENC2); 1257 codec = create(engine, name, params, OMAP_DCE_VIDENC2);
865 DEBUG("<< codec=%p", codec); 1258 DEBUG("<< codec=%p", codec);
1259
1260 if( params->inputDataMode == IVIDEO_NUMROWS ) {
1261 (callbackmsg[id]).codec_handle = (XDAS_UInt32) codec;
1262 }
1263
1264EXIT:
1265 /*Relinquish IPC*/
1266 pthread_mutex_unlock(&ipc_mutex);
866 return (codec); 1267 return (codec);
867} 1268}
868 1269
869XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id, 1270XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd cmd_id,
870 VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status) 1271 VIDENC2_DynamicParams *dynParams, VIDENC2_Status *status)
871{ 1272{
872 XDAS_Int32 ret; 1273 XDAS_Int32 ret;
1274 int id;
873 1275
874 DEBUG(">> codec=%p, id=%d, dynParams=%p, status=%p", 1276 /*Acquire permission to use IPC*/
875 codec, id, dynParams, status); 1277 pthread_mutex_lock(&ipc_mutex);
876 if( id == XDM_GETVERSION ) { 1278
1279 id = get_callback((Uint32) codec);
1280 if( id < 0 ) {
1281 DEBUG("Could not find the entry in callbackmsg array; might not be rowmode; should be full frame mode");
1282 } else {
1283 DEBUG("Checking row_mode %d first_control %d", (callbackmsg[id]).row_mode, (callbackmsg[id]).first_control);
1284 if( (callbackmsg[id]).row_mode && (callbackmsg[id]).first_control ) {
1285 /* dynParams has the function callback; store the information as it will get overwritten by the M4 codec for their own callback Fxn. */
1286 (callbackmsg[id]).local_get_DataFxn = (void*) dynParams->getDataFxn;
1287 (callbackmsg[id]).local_dataSyncHandle = dynParams->getDataHandle;
1288 (callbackmsg[id]).first_control = FALSE;
1289 DEBUG("Set callback pointer local_get_dataFxn %p local_dataSyncHandle %p", (callbackmsg[id]).local_get_DataFxn, (callbackmsg[id]).local_dataSyncHandle);
1290 }
1291 }
1292
1293 DEBUG(">> codec=%p, cmd_id=%d, dynParams=%p, status=%p",
1294 codec, cmd_id, dynParams, status);
1295 if( cmd_id == XDM_GETVERSION ) {
877 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDENC2); 1296 ret = get_version(codec, dynParams, status, OMAP_DCE_VIDENC2);
878 } else { 1297 } else {
879 ret = control(codec, id, dynParams, status, OMAP_DCE_VIDENC2); 1298 ret = control(codec, cmd_id, dynParams, status, OMAP_DCE_VIDENC2);
880 } 1299 }
1300
881 DEBUG("<< ret=%d", ret); 1301 DEBUG("<< ret=%d", ret);
1302 /*Relinquish IPC*/
1303 pthread_mutex_unlock(&ipc_mutex);
882 return (ret); 1304 return (ret);
883} 1305}
884 1306
@@ -886,19 +1308,99 @@ XDAS_Int32 VIDENC2_process(VIDENC2_Handle codec,
886 IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs, 1308 IVIDEO2_BufDesc *inBufs, XDM2_BufDesc *outBufs,
887 VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs) 1309 VIDENC2_InArgs *inArgs, VIDENC2_OutArgs *outArgs)
888{ 1310{
889 XDAS_Int32 ret; 1311 XDAS_Int32 ret = 0;
1312 pthread_attr_t attr;
1313 int id;
890 1314
891 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p", 1315 DEBUG(">> codec=%p, inBufs=%p, outBufs=%p, inArgs=%p, outArgs=%p",
892 codec, inBufs, outBufs, inArgs, outArgs); 1316 codec, inBufs, outBufs, inArgs, outArgs);
1317
1318 /*Acquire permission to use IPC*/
1319 pthread_mutex_lock(&ipc_mutex);
1320
1321 id = get_callback((Uint32) codec);
1322 if( id < 0 ) {
1323 DEBUG("Received VIDENC2_process for ENTIRE FRAME encoding because no entry found in callbackmsg");
1324 } else {
1325 DEBUG("Checking row_mode %d", (callbackmsg[id]).row_mode);
1326 if( (callbackmsg[id]).row_mode ) {
1327 (callbackmsg[id]).getDataFlag = 0;
1328 DEBUG("Checking callbackmsg[%d]->getDataFxn_thread 0x%x", id, (callbackmsg[id]).getDataFxn_thread);
1329 if( !(callbackmsg[id]).getDataFxn_thread ) {
1330 /* Need to start a new thread for the callback handling to request for data - process call will be synchronous. */
1331 pthread_attr_init(&attr);
1332 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1333 if( pthread_create(&((callbackmsg[id]).getDataFxn_thread), &attr, (void*)dce_callback_getDataFxn, (void*) &codec) ) {
1334 pthread_mutex_unlock(&ipc_mutex);
1335 return DCE_EXDM_FAIL;
1336 }
1337 }
1338 DEBUG("Create thread callbackmsg[%d]->getDataFxn_thread 0x%x", id, (unsigned int) (callbackmsg[id]).getDataFxn_thread);
1339
1340 /* Start the callback to request to client */
1341 (callbackmsg[id]).getDataFlag = 1;
1342 sem_post(&((callbackmsg[id]).sem_enc_row_mode));
1343 DEBUG("Start the callback to client (callbackmsg[%d]).getDataFlag %d on (callbackmsg[%d]).local_dataSyncHandle 0x%x",
1344 id, (callbackmsg[id]).getDataFlag, id, (unsigned int) (callbackmsg[id]).local_dataSyncHandle);
1345 }
1346 }
1347
893 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2); 1348 ret = process(codec, inBufs, outBufs, inArgs, outArgs, OMAP_DCE_VIDENC2);
894 DEBUG("<< ret=%d", ret); 1349 DEBUG("<< ret=%d", ret);
1350
1351 if( (callbackmsg[id]).row_mode ) {
1352 /* Stop the callback to request to client */
1353 DEBUG("Stop the callback to client callbackmsg[%d]->getDataFlag %d", id, (callbackmsg[id]).getDataFlag);
1354 (callbackmsg[id]).getDataFlag = 0;
1355 }
1356
1357 /*Relinquish IPC*/
1358 pthread_mutex_unlock(&ipc_mutex);
895 return (ret); 1359 return (ret);
896} 1360}
897 1361
898Void VIDENC2_delete(VIDENC2_Handle codec) 1362Void VIDENC2_delete(VIDENC2_Handle codec)
899{ 1363{
1364 void *res;
1365 int id;
1366
900 DEBUG(">> codec=%p", codec); 1367 DEBUG(">> codec=%p", codec);
1368
1369 /*Acquire permission to use IPC*/
1370 pthread_mutex_lock(&ipc_mutex);
1371
1372 id = get_callback((Uint32) codec);
1373 if( id < 0 ) {
1374 DEBUG("Delete encode instance in full frame mode");
1375 } else {
1376 if( (callbackmsg[id]).row_mode ) {
1377 MmRpcCallback_count--;
1378 /* Exit the callback thread to request to client */
1379 (callbackmsg[id]).getDataFlag = 2;
1380 DEBUG("Exit the callback to client (callbackmsg[%d]).getDataFlag %d (callbackmsg[%d]).getDataFxn_thread 0x%x",
1381 id, (callbackmsg[id]).getDataFlag, id, (unsigned int) (callbackmsg[id]).getDataFxn_thread);
1382 sem_post(&((callbackmsg[id]).sem_enc_row_mode));
1383
1384 pthread_join((callbackmsg[id]).getDataFxn_thread, (void*) &res);
1385 DEBUG("PTHREAD_JOIN res %d", (int) res);
1386
1387 /* Clean up the allocation earlier. */
1388 memplugin_free((callbackmsg[id]).local_dataSyncDesc);
1389
1390 /* Destroy sem_dec_row_mode */
1391 sem_destroy(&((callbackmsg[id]).sem_enc_row_mode));
1392
1393 DEBUG("Check on MmRpcCallback_count %d", MmRpcCallback_count);
1394 if( MmRpcCallback_count == 0 && MmRpcCallbackHandle != NULL ) {
1395 MmRpc_delete(&MmRpcCallbackHandle);
1396 MmRpcCallbackHandle = NULL;
1397 }
1398 }
1399 }
1400
901 delete(codec, OMAP_DCE_VIDENC2); 1401 delete(codec, OMAP_DCE_VIDENC2);
1402 /*Relinquish IPC*/
1403 pthread_mutex_unlock(&ipc_mutex);
902 DEBUG("<<"); 1404 DEBUG("<<");
903} 1405}
904 1406
diff --git a/test_qnx/dce_enc_test/dce_enc_test.c b/test_qnx/dce_enc_test/dce_enc_test.c
index dc399fb..616859e 100644
--- a/test_qnx/dce_enc_test/dce_enc_test.c
+++ b/test_qnx/dce_enc_test/dce_enc_test.c
@@ -53,7 +53,12 @@
53#include "ti/shmemallocator/SharedMemoryAllocatorUsr.h" 53#include "ti/shmemallocator/SharedMemoryAllocatorUsr.h"
54 54
55#define PRINT_DEBUG 55#define PRINT_DEBUG
56//#define PRINT_DEBUG_LOW
57
56//#define H264_DEBUG 58//#define H264_DEBUG
59//#define DUMPINPUTDATA
60//#define DUMPOUTPUTDATA
61//#define ROWMODE_INPUTDUMP
57 62
58#define ERROR(FMT, ...) printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 63#define ERROR(FMT, ...) printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
59// enable below to print debug information 64// enable below to print debug information
@@ -62,6 +67,13 @@
62#else 67#else
63#define DEBUG(FMT, ...) 68#define DEBUG(FMT, ...)
64#endif 69#endif
70
71#ifdef PRINT_DEBUG_LOW
72#define DEBUGLOW(FMT, ...) printf("%s:%d:\t%s\tdebug: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
73#else
74#define DEBUGLOW(FMT, ...)
75#endif
76
65#define INFO(FMT, ...) printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 77#define INFO(FMT, ...) printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
66#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 78#define MIN(a, b) (((a) < (b)) ? (a) : (b))
67 79
@@ -74,6 +86,26 @@
74// Getting codec version through XDM_GETVERSION 86// Getting codec version through XDM_GETVERSION
75#define GETVERSION 87#define GETVERSION
76 88
89#ifdef GETVERSION
90#define VERSION_SIZE 128
91#endif
92
93/* ************************************************************************* */
94/* utilities to allocate/manage 2d input buffers */
95
96typedef struct InputBuffer InputBuffer;
97
98struct InputBuffer {
99 char *buf; /* virtual address for local access, 4kb stride */
100 SSPtr y, uv; /* physical addresses of Y and UV for remote access */
101 InputBuffer *next; /* next free buffer */
102 bool tiler;
103 uint32_t len;
104 shm_buf shmBuf;
105};
106
107static InputBuffer *head = NULL;
108
77enum { 109enum {
78 IVAHD_H264_ENCODE, 110 IVAHD_H264_ENCODE,
79 IVAHD_MPEG4_ENCODE, 111 IVAHD_MPEG4_ENCODE,
@@ -114,8 +146,30 @@ IMPEG4ENC_DynamicParams *mpeg4enc_dynParams = NULL;
114IMPEG4ENC_Status *mpeg4enc_status = NULL; 146IMPEG4ENC_Status *mpeg4enc_status = NULL;
115 147
116unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ 148unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */
149int endOfFile = 0;
150char *in_pattern, *out_pattern;
151int in_cnt = 0, out_cnt = 0;
152InputBuffer *buf = NULL;
117static int input_offset = 0; 153static int input_offset = 0;
118 154
155#ifdef ROWMODE_INPUTDUMP
156FILE *inputDump;
157char Buff1[100];
158static int GlobalCount1 = 0;
159static int read_input_count = 0;
160#endif
161
162#ifdef DUMPOUTPUTDATA
163FILE *outputDump;
164#endif
165
166// This global only used in low latency IVIDEO_NUMROWS
167static int numBlock = 10;
168static int input_y_offset = 0;
169static int input_uv_offset = 0;
170static int dest_y_offset = 0;
171static int dest_uv_offset = 0;
172
119static void *tiler_alloc(int width, int height) 173static void *tiler_alloc(int width, int height)
120{ 174{
121 int dimensions; 175 int dimensions;
@@ -196,18 +250,136 @@ static void free_nonTiler(void *shmBuf)
196 SHM_release(shmBuf); 250 SHM_release(shmBuf);
197} 251}
198 252
199/* ************************************************************************* */ 253void input_free(void)
200/* utilities to allocate/manage 2d input buffers */ 254{
255 InputBuffer *buf = head;
201 256
202typedef struct InputBuffer InputBuffer; 257 while((buf=head)) {
258 DEBUG("input_free: %p", buf);
259 if( buf->tiler ) {
260 MemMgr_Free(buf->buf);
261 } else {
262 SHM_release(&buf->shmBuf);
263 }
264 head = buf->next;
265 free(buf);
266 }
267}
203 268
204struct InputBuffer { 269int input_allocate(IVIDEO2_BufDesc *inBufs, int cnt,
205 char *buf; /* virtual address for local access, 4kb stride */ 270 int width, int height)
206 SSPtr y, uv; /* physical addresses of Y and UV for remote access */ 271{
207 InputBuffer *next; /* next free buffer */ 272 inBufs->imagePitch[0] = 4096;
208 bool tiler; 273 inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILED8;
209 uint32_t len; 274 inBufs->planeDesc[0].bufSize.tileMem.width = width;
210}; 275 inBufs->planeDesc[0].bufSize.tileMem.height = height;
276
277 inBufs->secondFieldOffsetWidth[1] = 1;
278 inBufs->secondFieldOffsetHeight[1] = 0;
279
280 inBufs->imagePitch[1] = 4096;
281 inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILED16;
282 inBufs->planeDesc[1].bufSize.tileMem.width = width; /* UV interleaved width is same a Y */
283 inBufs->planeDesc[1].bufSize.tileMem.height = height / 2;
284
285 // INPUT BUFFER MUST BE in NV12.
286 while( cnt ) {
287 InputBuffer *buf = calloc(sizeof(InputBuffer), 1);
288 if( buf == NULL ) {
289 input_free();
290 return (-ENOMEM);
291 }
292
293 DEBUG(" ----------------- create input TILER buf 0x%x --------------------", (unsigned int)buf);
294
295 buf->buf = tiler_alloc(width, height);
296 if( buf->buf ) {
297 buf->y = (SSPtr) buf->buf;
298 buf->uv = (SSPtr)(buf->buf + (height * 4096));
299
300 DEBUG("INPUT TILER cnt=%d buf=%p, buf->buf=%p y=%08x, uv=%08x", cnt, buf, buf->buf, buf->y, buf->uv);
301
302 buf->tiler = TRUE;
303 buf->next = head;
304 head = buf;
305 } else {
306 ERROR("DCE_ENCODE_TEST_FAIL: TILER ALLOCATION FAILED");
307 free(buf);
308 return (-ENOMEM);
309 }
310 cnt--;
311 }
312
313 return (0);
314}
315
316int input_allocate_nonTiler(IVIDEO2_BufDesc *inBufs, int cnt,
317 int width, int height)
318{
319 int err = 0;
320
321 inBufs->imagePitch[0] = width;
322 inBufs->planeDesc[0].memType = XDM_MEMTYPE_RAW;
323 inBufs->planeDesc[0].bufSize.bytes = width * height;
324 inBufs->secondFieldOffsetWidth[1] = 1;
325 inBufs->secondFieldOffsetHeight[1] = 0;
326
327 inBufs->imagePitch[1] = width;
328 inBufs->planeDesc[1].memType = XDM_MEMTYPE_RAW;
329 inBufs->planeDesc[1].bufSize.bytes = width * height / 2;
330
331 while( cnt ) {
332 InputBuffer *buf = calloc(sizeof(InputBuffer), 1);
333 if( buf == NULL ) {
334 input_free();
335 return (-ENOMEM);
336 }
337
338 DEBUG(" ----------------- create NON INPUT TILER buf 0x%x --------------------", (unsigned int)buf);
339
340 err = allocate_nonTiler(&buf->shmBuf, width * height * 3/2);
341 if( err < 0 ) {
342 ERROR("DCE_ENCODE_TEST_FAIL: NON-TILER ALLOCATION FAILED");
343 free(buf);
344 return (-ENOMEM);
345 }
346 else
347 {
348 buf->buf = (char*)buf->shmBuf.vir_addr;
349 buf->y = (SSPtr)buf->shmBuf.vir_addr;
350 buf->uv = (SSPtr)buf->shmBuf.vir_addr + (height * width);
351
352 DEBUG("INPUT NON TILER buf=%p, buf->buf=%p y=%08x, uv=%08x", buf, buf->buf, buf->y, buf->uv);
353 }
354
355 buf->next = head;
356 buf->tiler = FALSE;
357 head = buf;
358
359 cnt--;
360 }
361
362 return (0);
363}
364
365InputBuffer *input_get(void)
366{
367 InputBuffer *buf = head;
368
369 if( buf ) {
370 head = buf->next;
371 }
372 DEBUG("input_get: %p buf->next %p", buf, buf->next);
373 DEBUG("input_get TEST buf->buf: %p", buf->buf);
374 return (buf);
375}
376
377void input_release(InputBuffer *buf)
378{
379 DEBUG("input_release: %p", buf);
380 buf->next = head;
381 head = buf;
382}
211 383
212/* ************************************************************************* */ 384/* ************************************************************************* */
213 385
@@ -232,20 +404,120 @@ static const char *get_path(const char *pattern, int cnt)
232 return (path); 404 return (path);
233} 405}
234 406
235//#define DUMPINPUTDATA 407int read_partial_input(const char *pattern, int cnt, char *input, int rowmode, int numBlock)
236//#define DUMPOUTPUTDATA 408{
409 int sz = 0, n = 0, num_planes, i, buf_height;
410 char *input_y = (char *) ((int) input + dest_y_offset);
411 char *input_uv = (char *) ((int) input + dest_uv_offset);
237 412
238#ifdef DUMPINPUTDATA 413 const char *path = get_path(pattern, cnt);
239FILE *inputDump; 414 if( path == NULL ) {
415 return (sz);
416 }
417
418 int fd = open(path, O_RDONLY);
419 if( fd < 0 ) {
420 ERROR("open input file failed");
421 return (-1);
422 }
423
424#ifdef ROWMODE_INPUTDUMP
425 ++read_input_count;
240#endif 426#endif
241 427
242#ifdef DUMPOUTPUTDATA 428 // For rowmode, filling the input in NV12 format per numBlock.
243FILE *outputDump; 429 // For numBlock = 1, that means application has written (provided)
430 // width * 16 (luma pixels) of input data in input buffer & width * 8 (chroma pixels).
431 for( num_planes = 0; num_planes < 2; num_planes++ ) {
432 if( num_planes ) { //UV location - num_plane = 1
433 buf_height = numBlock * 16 / 2;
434 } else { //Y location - num_plane = 0
435 buf_height = numBlock * 16;
436 }
437
438 for( i = 0; i < buf_height; i++ ) {
439 if( num_planes ) { // UV location - num_plane = 1
440 if( dest_uv_offset < (width * height * 1.5) ) {
441 lseek(fd, input_uv_offset, SEEK_SET);
442 n = read(fd, input_uv , width);
443 if( n ) {
444 sz += n;
445 input_uv_offset += n;
446 } else {
447 close(fd);
448 DEBUGLOW("Reading REACH EOF - return -1");
449 endOfFile = 1;
450 return (-1); //Cannot read anymore input
451 }
452
453 if( tiler ) {
454 input_uv = (char *) ((int)input_uv + 4096);
455 dest_uv_offset += 4096;
456 } else {
457 input_uv = (char *) ((int)input_uv + width);
458 dest_uv_offset += width;
459 }
460 } else {
461 //DEBUGLOW("dest_uv_offset %d >= width * height * 1.5 %d", (int)dest_uv_offset, (int) (width * height * 1.5));
462 }
463 } else { // Y location - num_plane = 0
464 if( dest_y_offset < (width * height) ) {
465 lseek(fd, input_y_offset, SEEK_SET);
466 n = read(fd, input_y , width);
467 if( n ) {
468 sz += n;
469 input_y_offset += n;
470 } else {
471 close(fd);
472 DEBUGLOW("Reading REACH EOF - return -1");
473 endOfFile = 1;
474 return (-1); //Cannot read anymore input
475 }
476
477 if( tiler ) {
478 input_y = (char *) ((int)input_y + 4096);
479 dest_y_offset += 4096;
480 } else {
481 input_y = (char *) ((int)input_y + width);
482 dest_y_offset += width;
483 }
484 } else {
485 //DEBUGLOW("dest_y_offset %d >= width * height %d", dest_y_offset, width * height);
486 }
487 }
488 }
489 }
490
491#ifdef ROWMODE_INPUTDUMP
492 if ( read_input_count % 68 == 0 ) {
493 //Dump the file
494 if( inputDump == NULL ) {
495 if( GlobalCount1 <= 50 ) {
496 sprintf(Buff1, "/tmp/dceinputdump%d.bin", GlobalCount1);
497 inputDump = fopen(Buff1, "wb+");
498 if( inputDump == NULL ) {
499 ERROR("Opening input Dump /tmp/dceinputdump%d.bin file FAILED", GlobalCount1);
500 } else {
501 GlobalCount1++;
502 fwrite(input, 1, width * height * 3 / 2, inputDump);
503 DEBUGLOW("Dumping input file of NV12 format with read data of %d inside buffersize = %d", n, width * height * 3 / 2);
504 fflush(inputDump);
505 fclose(inputDump);
506 inputDump = NULL;
507 }
508 }
509 }
510 }
244#endif 511#endif
512 DEBUGLOW("read_partial_input close fd");
513 close(fd);
245 514
515 DEBUGLOW("sz=%d", sz);
516 return (sz);
517}
246 518
247/* helper to read one frame NV12 of input */ 519/* helper to read one frame NV12 of input */
248int read_input(const char *pattern, int cnt, char *input) 520int read_input(const char *pattern, int cnt, char *input, int rowmode)
249{ 521{
250 int sz = 0, n = 0, num_planes, i, buf_height; 522 int sz = 0, n = 0, num_planes, i, buf_height;
251 523
@@ -255,23 +527,19 @@ int read_input(const char *pattern, int cnt, char *input)
255 } 527 }
256 528
257 int fd = open(path, O_RDONLY); 529 int fd = open(path, O_RDONLY);
258
259 //DEBUG("Open file fd %d errno %d", fd, errno);
260 if( fd < 0 ) { 530 if( fd < 0 ) {
261 DEBUG("open input file failed"); 531 DEBUG("open input file failed");
262 return (-1); 532 return (-1);
263 } 533 }
264 534
265 sz = width * height * 3 / 2;
266
267 // Filling the input in NV12 format; where 535 // Filling the input in NV12 format; where
268 // Luma has size of Stride "4096" * height for TILER or width * height 536 // Luma has size of Stride "4096" * height for TILER or width * height
269 // and Chroma has size of Stride "4096 * height / 2 for TILER or 537 // and Chroma has size of Stride "4096 * height / 2 for TILER or
270 // width * height / 2 538 // width * height / 2
271 for( num_planes = 0; num_planes < 2; num_planes++ ) { 539 for( num_planes = 0; num_planes < 2; num_planes++ ) {
272 if( num_planes ) { //UV location 540 if( num_planes ) { //UV location - num_plane = 1
273 buf_height = height / 2; 541 buf_height = height / 2;
274 } else { //Y location 542 } else { //Y location - num_plane = 0
275 buf_height = height; 543 buf_height = height;
276 } 544 }
277 545
@@ -279,10 +547,12 @@ int read_input(const char *pattern, int cnt, char *input)
279 lseek(fd, input_offset, SEEK_SET); 547 lseek(fd, input_offset, SEEK_SET);
280 n = read(fd, input, width); 548 n = read(fd, input, width);
281 if( n ) { 549 if( n ) {
550 sz += n;
282 input_offset += n; 551 input_offset += n;
283 } else { 552 } else {
284 close(fd); 553 close(fd);
285 DEBUG("Reading REACH EOF - return -1"); 554 DEBUG("Reading REACH EOF - return -1");
555 endOfFile = 1;
286 return (-1); //Cannot read anymore input 556 return (-1); //Cannot read anymore input
287 } 557 }
288 558
@@ -294,6 +564,7 @@ int read_input(const char *pattern, int cnt, char *input)
294 } 564 }
295 } 565 }
296 566
567 DEBUG("read_input close fd");
297 close(fd); 568 close(fd);
298 569
299 DEBUG("sz=%d", sz); 570 DEBUG("sz=%d", sz);
@@ -341,12 +612,43 @@ uint64_t mark_microsecond(uint64_t *last)
341 } 612 }
342 return (t1); 613 return (t1);
343} 614}
344
345#endif 615#endif
346 616
347#ifdef GETVERSION 617/* Function callback for low latency encoder with NUMROWS*/
348#define VERSION_SIZE 128 618/* Client is expected to fill the dataSyncDesc information especially numBlocks for codec to continue */
349#endif 619/* numBlocks is filled based on the input data being filled into the input buffer that was passed in VIDENC2_process */
620/* The return value of this function is NULL when okay; if there is a problem return value < 0, then LIBDCE will always retry */
621XDAS_Int32 H264E_MPU_GetDataFxn(XDM_DataSyncHandle dataSyncHandle, XDM_DataSyncDesc *dataSyncDesc)
622{
623 int n;
624
625 DEBUGLOW("-----------------------START--------------------------------");
626 //sleep(1); //instrument a 1s delay on the MPU side to get numblocks.
627 //DEBUGLOW("After 1sec Received H264E_MPU_GetDataFxn 0x%x", (unsigned int)dataSyncHandle);
628 // Need to read and write the amount put into the inputBuffer.
629 // Need to write numBlock into the inputBuffer and update the data here to be passed down to M4.
630
631 // Set NumBlock to be equal height/(16 * 2); eg. 1088 / (16 * 2) = 34 rows; meaning 34*16 height of data each time.
632 numBlock = ALIGN2(height, 4) / (16 * 2);
633
634 DEBUGLOW("Before read_partial_input numBlock %d buf->buf %p input_y_offset %d input_uv_offset %d dest_y_offset %d dest_uv_offset %d", numBlock, buf->buf, input_y_offset, input_uv_offset, dest_y_offset, dest_uv_offset);
635 n = read_partial_input(in_pattern, in_cnt, buf->buf, TRUE, numBlock);
636 DEBUGLOW("After read_partial_input buf->buf %p input_y_offset %d input_uv_offset %d dest_y_offset %d dest_uv_offset %d", buf->buf, input_y_offset, input_uv_offset, dest_y_offset, dest_uv_offset);
637 if( n > 0) {
638 if (dataSyncHandle == codec) {
639 dataSyncDesc->size = sizeof(XDM_DataSyncDesc); // Size of this structure
640 dataSyncDesc->scatteredBlocksFlag = XDAS_FALSE; // Flag indicates whether the individual data blocks may be scatttered in memory.
641 dataSyncDesc->baseAddr = (XDAS_Int32*) buf->buf;
642 dataSyncDesc->numBlocks = numBlock;
643 dataSyncDesc->varBlockSizesFlag = XDAS_FALSE;
644 dataSyncDesc->blockSizes= NULL;
645 DEBUGLOW("H264E_MPU_GetDataFxn dataSyncDesc->size %d dataSyncDesc->baseAddr 0x%x dataSyncDesc->numBlocks %d", (unsigned int)dataSyncDesc->size, (unsigned int)dataSyncDesc->baseAddr, (unsigned int)dataSyncDesc->numBlocks);
646 }
647 }
648 DEBUGLOW("read_partial_input is returning size of %d", n);
649 DEBUGLOW("-----------------------END--------------------------------");
650 return (0);
651}
350 652
351/* encoder body */ 653/* encoder body */
352int main(int argc, char * *argv) 654int main(int argc, char * *argv)
@@ -357,21 +659,18 @@ int main(int argc, char * *argv)
357 char *output_mvbuf = NULL; 659 char *output_mvbuf = NULL;
358 shm_buf output_mvbuf_nonTiler; 660 shm_buf output_mvbuf_nonTiler;
359 shm_buf output_nonTiler; 661 shm_buf output_nonTiler;
360 shm_buf input_nonTiler;
361 int output_size = 0; 662 int output_size = 0;
362 int mvbufinfo_size = 0; 663 int mvbufinfo_size = 0;
363 char *in_pattern, *out_pattern;
364 int in_cnt = 0, out_cnt = 0;
365 InputBuffer *buf = NULL;
366 char profile[10]; 664 char profile[10];
367 int profile_value; 665 int profile_value;
368 int level; 666 int level;
369 int eof = 0;
370 char vid_codec[10]; 667 char vid_codec[10];
371 char tilerbuffer[10]; 668 char tilerbuffer[10];
372 unsigned int codec_switch = 0; 669 unsigned int codec_switch = 0;
373 int bytesGenerated = 0; 670 int bytesGenerated = 0;
374 int frames_to_write = 0; 671 int frames_to_write = 0;
672 char row_mode[10];
673 int datamode;
375 674
376#ifdef PROFILE_TIME 675#ifdef PROFILE_TIME
377 uint64_t init_start_time = 0; 676 uint64_t init_start_time = 0;
@@ -394,12 +693,12 @@ int main(int argc, char * *argv)
394 argv++; 693 argv++;
395 } 694 }
396 695
397 if( argc != 10 ) { 696 if( argc != 11 ) {
398 printf("usage: %s width height frames_to_write inpattern outpattern codec baseline/high level buffertype\n", argv[0]); 697 printf("usage: %s width height frames_to_write inpattern outpattern codec baseline/high level buffertype mode\n", argv[0]);
399 printf("example: %s 1920 1088 300 in.yuv out.h264 h264 baseline 10 tiler\n", argv[0]); 698 printf("example: %s 1920 1088 300 in.yuv out.h264 h264 baseline 10 tiler numrow/slice/fixed/full\n", argv[0]);
400 printf("example: %s 176 144 300 in.yuv out.m4v mpeg4 simple/baseline 0 non-tiler\n", argv[0]); 699 printf("example: %s 176 144 300 in.yuv out.m4v mpeg4 simple/baseline 0 non-tiler full\n", argv[0]);
401 printf("example: %s 176 144 300 in.yuv out.m4v h263 simple/baseline 0 tiler\n", argv[0]); 700 printf("example: %s 176 144 300 in.yuv out.m4v h263 simple/baseline 0 tiler full\n", argv[0]);
402 printf("Currently supported codecs: h264 or mpeg4 or h263\n"); 701 printf("Currently supported codecs: h264 or mpeg4 or h263 full\n");
403 printf("Run this command for help on the use case: use dce_enc_test\n"); 702 printf("Run this command for help on the use case: use dce_enc_test\n");
404 return (1); 703 return (1);
405 } 704 }
@@ -413,9 +712,11 @@ int main(int argc, char * *argv)
413 strcpy(profile, argv[7]); 712 strcpy(profile, argv[7]);
414 level = atoi(argv[8]); 713 level = atoi(argv[8]);
415 strcpy(tilerbuffer, argv[9]); 714 strcpy(tilerbuffer, argv[9]);
715 strcpy(row_mode, argv[10]);
416 716
417 printf("Selected codec: %s\n", vid_codec); 717 printf("Selected codec: %s\n", vid_codec);
418 printf("Selected buffer: %s\n", tilerbuffer); 718 printf("Selected buffer: %s\n", tilerbuffer);
719 printf("Encode mode: %s\n", row_mode);
419 720
420 enum { 721 enum {
421 DCE_ENC_TEST_H264 = 1, 722 DCE_ENC_TEST_H264 = 1,
@@ -518,6 +819,27 @@ int main(int argc, char * *argv)
518 return (1); 819 return (1);
519 } 820 }
520 821
822 if((!(strcmp(row_mode, "full")))) {
823 datamode = IVIDEO_ENTIREFRAME;
824 } else if ((!(strcmp(row_mode, "numrow")))) {
825 datamode = IVIDEO_NUMROWS;
826 } else if ((!(strcmp(row_mode, "slice")))) {
827 datamode = IVIDEO_SLICEMODE;
828 ERROR("SLICE mode is not supported.");
829 goto shutdown;
830 } else if ((!(strcmp(row_mode, "fixed")))) {
831 datamode = IVIDEO_FIXEDLENGTH;
832 ERROR("FIXED LENGTH mode is not supported.");
833 goto shutdown;
834 } else {
835 ERROR("WRONG argument mode %s", row_mode);
836 goto shutdown;
837 }
838
839 if( (codec_switch != DCE_ENC_TEST_H264) && (datamode != IVIDEO_ENTIREFRAME) ) {
840 ERROR("WRONG argument codec type %s mode %s", vid_codec, row_mode);
841 goto shutdown;
842 }
521 DEBUG("width=%d, height=%d", width, height); 843 DEBUG("width=%d, height=%d", width, height);
522 844
523 /* output buffer parameters is aligned */ 845 /* output buffer parameters is aligned */
@@ -528,13 +850,13 @@ int main(int argc, char * *argv)
528 case DCE_ENC_TEST_H264 : 850 case DCE_ENC_TEST_H264 :
529 case DCE_ENC_TEST_MPEG4 : 851 case DCE_ENC_TEST_MPEG4 :
530 case DCE_ENC_TEST_H263 : 852 case DCE_ENC_TEST_H263 :
531 num_buffers = 1; 853 num_buffers = 2;
532 break; 854 break;
533 default : 855 default :
534 ERROR("Unrecognized codec to encode"); 856 ERROR("Unrecognized codec to encode");
535 } 857 }
536 858
537 DEBUG("width=%d, height=%d, num_buffers=%d", 859 DEBUG("After alignment width=%d, height=%d, num_buffers=%d",
538 width, height, num_buffers); 860 width, height, num_buffers);
539 861
540#ifdef PROFILE_TIME 862#ifdef PROFILE_TIME
@@ -550,104 +872,6 @@ int main(int argc, char * *argv)
550 DEBUG("Engine_open successful engine=%p", engine); 872 DEBUG("Engine_open successful engine=%p", engine);
551 873
552/* 874/*
553 * inBufs handling
554 */
555 DEBUG("input buffer configuration width %d height %d", width, height);
556 inBufs = dce_alloc(sizeof(IVIDEO2_BufDesc));
557
558 DEBUG("Input allocate through tiler");
559
560#ifdef PROFILE_TIME
561 uint64_t alloc_time_start = mark_microsecond(NULL);
562#endif
563
564 inBufs->numPlanes = 2;
565 inBufs->imageRegion.topLeft.x = 0;
566 inBufs->imageRegion.topLeft.y = 0;
567 inBufs->imageRegion.bottomRight.x = width;
568
569 inBufs->topFieldFirstFlag = 0; //Only valid for interlace content.
570 inBufs->contentType = IVIDEO_PROGRESSIVE;
571
572 inBufs->activeFrameRegion.topLeft.x = 0;
573 inBufs->activeFrameRegion.topLeft.y = 0;
574 inBufs->activeFrameRegion.bottomRight.x = width;
575 inBufs->activeFrameRegion.bottomRight.y = height;
576
577 inBufs->imageRegion.bottomRight.y = height;
578 inBufs->chromaFormat = XDM_YUV_420SP;
579
580 inBufs->secondFieldOffsetWidth[0] = 0;
581 inBufs->secondFieldOffsetHeight[0] = 0;
582
583 if( !(strcmp(tilerbuffer, "tiler")) ) {
584 DEBUG("Input allocate through TILER 2D");
585 tiler = 1;
586
587 inBufs->imagePitch[0] = 4096;
588 inBufs->planeDesc[0].memType = XDM_MEMTYPE_TILED8;
589 inBufs->planeDesc[0].bufSize.tileMem.width = width;
590 inBufs->planeDesc[0].bufSize.tileMem.height = height;
591
592 inBufs->secondFieldOffsetWidth[1] = 1;
593 inBufs->secondFieldOffsetHeight[1] = 0;
594
595 inBufs->imagePitch[1] = 4096;
596 inBufs->planeDesc[1].memType = XDM_MEMTYPE_TILED16;
597 inBufs->planeDesc[1].bufSize.tileMem.width = width; /* UV interleaved width is same a Y */
598 inBufs->planeDesc[1].bufSize.tileMem.height = height / 2;
599
600 // INPUT BUFFER MUST BE TILED NV12. Encoder codec doesn't support non TILED input buffer.
601 buf = calloc(sizeof(InputBuffer), 1);
602 DEBUG(" ----------------- create INPUT TILER buf 0x%x --------------------", (unsigned int)buf);
603 buf->buf = tiler_alloc(width, height);
604 if( buf->buf ) {
605 buf->y = (SSPtr)buf->buf;
606 buf->uv = (SSPtr)buf->buf + (height * 4096);
607
608 DEBUG("INPUT TILER buf=%p, buf->buf=%p y=%08x, uv=%08x", buf, buf->buf, buf->y, buf->uv);
609 } else {
610 ERROR("DCE_ENCODE_TEST_FAIL: TILER ALLOCATION FAILED");
611 goto shutdown;
612 }
613 } else {
614 DEBUG("Input allocate through NON-TILER");
615 tiler = 0;
616
617 inBufs->imagePitch[0] = width;
618 inBufs->planeDesc[0].memType = XDM_MEMTYPE_RAW;
619 inBufs->planeDesc[0].bufSize.bytes = width * height;
620 inBufs->secondFieldOffsetWidth[1] = 1;
621 inBufs->secondFieldOffsetHeight[1] = 0;
622
623 inBufs->imagePitch[1] = width;
624 inBufs->planeDesc[1].memType = XDM_MEMTYPE_RAW;
625 inBufs->planeDesc[1].bufSize.bytes = width * height / 2;
626 buf = calloc(sizeof(InputBuffer), 1);
627 DEBUG(" ----------------- create NON INPUT TILER buf 0x%x --------------------", (unsigned int)buf);
628 err = allocate_nonTiler(&input_nonTiler, width * height * 3/2);
629 if( err < 0 ) {
630 ERROR("DCE_ENCODE_TEST_FAIL: NON-TILER ALLOCATION FAILED");
631 free(buf);
632 goto shutdown;
633 }
634 else
635 {
636 buf->buf = (char*)input_nonTiler.vir_addr;
637 buf->y = (SSPtr)input_nonTiler.vir_addr;
638 buf->uv = (SSPtr)input_nonTiler.vir_addr + (height * width);
639
640 DEBUG("INPUT NON TILER buf=%p, buf->buf=%p y=%08x, uv=%08x", buf, buf->buf, buf->y, buf->uv);
641 }
642 }
643
644#ifdef PROFILE_TIME
645 input_alloc_time = mark_microsecond(&alloc_time_start);
646#endif
647
648 DEBUG("input buffer configuration num_buffers %d width %d height %d", num_buffers, width, height);
649
650/*
651 * inArgs and outArgs configuration for static parameter passed during codec creation. 875 * inArgs and outArgs configuration for static parameter passed during codec creation.
652 */ 876 */
653 switch( codec_switch ) { 877 switch( codec_switch ) {
@@ -690,7 +914,15 @@ int main(int argc, char * *argv)
690 params->operatingMode = IVIDEO_ENCODE_ONLY; //IVIDEO_OperatingMode 914 params->operatingMode = IVIDEO_ENCODE_ONLY; //IVIDEO_OperatingMode
691 params->profile = profile_value; 915 params->profile = profile_value;
692 params->level = level; 916 params->level = level;
693 params->inputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode 917
918 if (datamode == IVIDEO_NUMROWS) {
919 params->inputDataMode = IVIDEO_NUMROWS;
920 params->numInputDataUnits = 1;
921 } else {
922 params->inputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
923 params->numInputDataUnits = 1;
924 }
925
694 params->outputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode 926 params->outputDataMode = IVIDEO_ENTIREFRAME; //IVIDEO_DataMode
695 params->numInputDataUnits = 1; 927 params->numInputDataUnits = 1;
696 params->numOutputDataUnits = 1; 928 params->numOutputDataUnits = 1;
@@ -698,7 +930,7 @@ int main(int argc, char * *argv)
698 params->metadataType[1] = IVIDEO_METADATAPLANE_NONE; 930 params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
699 params->metadataType[2] = IVIDEO_METADATAPLANE_NONE; 931 params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
700 932
701 DEBUG("dce_alloc VIDENC2_Params successful params=%p", params); 933 DEBUG("dce_alloc VIDENC2_Params successful params=%p inputDataMode(2=IVIDEO_NUMROWS) %d", params, params->inputDataMode);
702 934
703 switch( codec_switch ) { 935 switch( codec_switch ) {
704 case DCE_ENC_TEST_H264 : 936 case DCE_ENC_TEST_H264 :
@@ -980,7 +1212,14 @@ int main(int argc, char * *argv)
980 dynParams->ignoreOutbufSizeFlag = XDAS_FALSE; // If this is XDAS_TRUE then getBufferFxn and getBufferHandle needs to be set. 1212 dynParams->ignoreOutbufSizeFlag = XDAS_FALSE; // If this is XDAS_TRUE then getBufferFxn and getBufferHandle needs to be set.
981 dynParams->putDataFxn = NULL; 1213 dynParams->putDataFxn = NULL;
982 dynParams->putDataHandle = NULL; 1214 dynParams->putDataHandle = NULL;
983 dynParams->getDataFxn = NULL; 1215
1216 if (datamode == IVIDEO_NUMROWS) {
1217 dynParams->getDataFxn = (XDM_DataSyncGetFxn) H264E_MPU_GetDataFxn;
1218 DEBUGLOW("dynParams->getDataFxn %p", dynParams->getDataFxn);
1219 } else {
1220 dynParams->getDataFxn = NULL;
1221 }
1222
984 dynParams->getDataHandle = NULL; 1223 dynParams->getDataHandle = NULL;
985 dynParams->getBufferFxn = NULL; 1224 dynParams->getBufferFxn = NULL;
986 dynParams->getBufferHandle = NULL; 1225 dynParams->getBufferHandle = NULL;
@@ -1096,7 +1335,6 @@ int main(int argc, char * *argv)
1096 err = VIDENC2_control(codec, XDM_GETVERSION, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status); 1335 err = VIDENC2_control(codec, XDM_GETVERSION, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status);
1097 DEBUG("VIDENC2_control IH264ENC_Status XDM_GETVERSION h264enc_status->data.buf = %s", (((VIDENC2_Status *)h264enc_status)->data.buf)); 1336 DEBUG("VIDENC2_control IH264ENC_Status XDM_GETVERSION h264enc_status->data.buf = %s", (((VIDENC2_Status *)h264enc_status)->data.buf));
1098#endif 1337#endif
1099
1100 h264enc_status = (IH264ENC_Status *) status; 1338 h264enc_status = (IH264ENC_Status *) status;
1101 err = VIDENC2_control(codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status); 1339 err = VIDENC2_control(codec, XDM_SETPARAMS, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status);
1102 DEBUG("dce_alloc IH264ENC_Status successful h264enc_status=%p", h264enc_status); 1340 DEBUG("dce_alloc IH264ENC_Status successful h264enc_status=%p", h264enc_status);
@@ -1158,7 +1396,64 @@ int main(int argc, char * *argv)
1158 // XDM_GETBUFINFO 1396 // XDM_GETBUFINFO
1159 // Send Control cmd XDM_GETBUFINFO to get min output and output size 1397 // Send Control cmd XDM_GETBUFINFO to get min output and output size
1160 err = VIDENC2_control(codec, XDM_GETBUFINFO, dynParams, status); 1398 err = VIDENC2_control(codec, XDM_GETBUFINFO, dynParams, status);
1161 DEBUG("VIDENC2_control - XDM_GETBUFINFO err %d status numOutBuf %d OutBufSize %d MVBufInfo %d", err, status->bufInfo.minNumOutBufs, status->bufInfo.minOutBufSize[0].bytes, status->bufInfo.minOutBufSize[1].bytes); 1399 DEBUG("VIDENC2_control - XDM_GETBUFINFO err %d status numInBuf %d minInBufSize[0] %d minInBufSize[1] %d", err, status->bufInfo.minNumInBufs, status->bufInfo.minInBufSize[0].bytes, status->bufInfo.minInBufSize[1].bytes);
1400 num_buffers = status->bufInfo.minNumInBufs;
1401
1402/*
1403 * inBufs handling
1404 */
1405 DEBUG("input buffer configuration width %d height %d", width, height);
1406 inBufs = dce_alloc(sizeof(IVIDEO2_BufDesc));
1407
1408 DEBUG("Input inBufs 0x%x allocate through dce_alloc", (unsigned int) inBufs);
1409
1410#ifdef PROFILE_TIME
1411 uint64_t alloc_time_start = mark_microsecond(NULL);
1412#endif
1413
1414 inBufs->numPlanes = 2;
1415 inBufs->imageRegion.topLeft.x = 0;
1416 inBufs->imageRegion.topLeft.y = 0;
1417 inBufs->imageRegion.bottomRight.x = width;
1418
1419 inBufs->topFieldFirstFlag = 0; //Only valid for interlace content.
1420 inBufs->contentType = IVIDEO_PROGRESSIVE;
1421
1422 inBufs->activeFrameRegion.topLeft.x = 0;
1423 inBufs->activeFrameRegion.topLeft.y = 0;
1424 inBufs->activeFrameRegion.bottomRight.x = width;
1425 inBufs->activeFrameRegion.bottomRight.y = height;
1426
1427 inBufs->imageRegion.bottomRight.y = height;
1428 inBufs->chromaFormat = XDM_YUV_420SP;
1429
1430 inBufs->secondFieldOffsetWidth[0] = 0;
1431 inBufs->secondFieldOffsetHeight[0] = 0;
1432
1433 if( !(strcmp(tilerbuffer, "tiler")) ) {
1434 DEBUG("Input allocate through TILER 2D");
1435 tiler = 1;
1436 input_allocate(inBufs, num_buffers, width, height);
1437 } else {
1438 DEBUG("Input allocate through NON-TILER");
1439 tiler = 0;
1440 input_allocate_nonTiler(inBufs, num_buffers, width, height);
1441 }
1442
1443#ifdef PROFILE_TIME
1444 input_alloc_time = mark_microsecond(&alloc_time_start);
1445#endif
1446
1447 if (datamode == IVIDEO_NUMROWS) {
1448 if( tiler ) {
1449 input_uv_offset = input_y_offset + (4096 * height);
1450 } else {
1451 input_uv_offset = input_y_offset + (width * height);
1452 }
1453 DEBUG("input_y_offset %d input_uv_offset %d ", input_y_offset, input_uv_offset);
1454 }
1455
1456 DEBUG("input buffer configuration num_buffers %d width %d height %d", num_buffers, width, height);
1162 1457
1163/* 1458/*
1164 * outBufs handling 1459 * outBufs handling
@@ -1226,15 +1521,39 @@ int main(int argc, char * *argv)
1226/* 1521/*
1227 * codec process 1522 * codec process
1228 */ 1523 */
1229 while( inBufs->numPlanes && outBufs->numBufs ) { 1524 while ( !endOfFile) {
1230 int n; 1525 int n = 0;
1231 DEBUG("Looping on reading input inBufs->numPlanes %d outBufs->numBufs %d", inBufs->numPlanes, outBufs->numBufs); 1526 buf = input_get();
1527 DEBUG("input_get buf %p", buf);
1528 if( !buf ) {
1529 ERROR("DCE_TEST_FAIL: out of buffers");
1530 goto shutdown;
1531 }
1232 1532
1233 //Read the NV12 frame to input buffer to be encoded. 1533 if (datamode == IVIDEO_ENTIREFRAME) {
1234 n = read_input(in_pattern, in_cnt, buf->buf); 1534 //Read the NV12 frame to input buffer to be encoded.
1535 n = read_input(in_pattern, in_cnt, buf->buf, FALSE);
1536 } else if (datamode == IVIDEO_NUMROWS) {
1537 int cnt = 0;
1538 //Check if input has reached EOF - from the current input_uv_offset + 1 full frame
1539 const char *path = get_path(in_pattern, cnt);
1540 int fd = open(path, O_RDONLY);
1541 DEBUGLOW("CHECK Position %d", input_uv_offset - 1 + (width * height / 2));
1542 lseek(fd, input_uv_offset - 1 + (width * height / 2), SEEK_SET);
1543 char temp_buf[100];
1544 n = read(fd, temp_buf, sizeof(temp_buf));
1545 DEBUGLOW("CHECK on the next input full frame n %d", n);
1546 if (!n) {
1547 DEBUGLOW("CHECK - next input full frame is Empty as n is %d - REACH EOF", n);
1548 endOfFile = 1;
1549 n = -1;
1550 }
1551 } else {
1552 ERROR("NOT SUPPORTED MODE");
1553 goto shutdown;
1554 }
1235 1555
1236 if( n && (n != -1) ) { 1556 if( n && (n != -1) ) {
1237 eof = 0;
1238 inBufs->planeDesc[0].buf = (XDAS_Int8 *)buf->y; 1557 inBufs->planeDesc[0].buf = (XDAS_Int8 *)buf->y;
1239 inBufs->planeDesc[1].buf = (XDAS_Int8 *)buf->uv; 1558 inBufs->planeDesc[1].buf = (XDAS_Int8 *)buf->uv;
1240 DEBUG("inBufs->planeDesc[0].buf %p inBufs->planeDesc[1].buf %p", inBufs->planeDesc[0].buf, inBufs->planeDesc[1].buf); 1559 DEBUG("inBufs->planeDesc[0].buf %p inBufs->planeDesc[1].buf %p", inBufs->planeDesc[0].buf, inBufs->planeDesc[1].buf);
@@ -1242,95 +1561,28 @@ int main(int argc, char * *argv)
1242 in_cnt++; 1561 in_cnt++;
1243 1562
1244 /* 1563 /*
1245 * Input buffer has data to be encoded. 1564 * Input buffer has data to be encoded.
1246 */ 1565 */
1247 inArgs->inputID = (XDAS_Int32)buf; 1566 inArgs->inputID = (XDAS_Int32)buf;
1248 if( codec_switch == DCE_ENC_TEST_H264 ) { 1567 if( codec_switch == DCE_ENC_TEST_H264 ) {
1249 h264enc_inArgs = (IH264ENC_InArgs *) inArgs; 1568 h264enc_inArgs = (IH264ENC_InArgs *) inArgs;
1250 DEBUG("TEST inArgs->inputID %d h264enc_inArgs->videnc2InArgs.inputID %d", inArgs->inputID, h264enc_inArgs->videnc2InArgs.inputID); 1569 DEBUG("inArgs->inputID 0x%x h264enc_inArgs->videnc2InArgs.inputID %d", inArgs->inputID, h264enc_inArgs->videnc2InArgs.inputID);
1251 } else if( (codec_switch == DCE_ENC_TEST_MPEG4) || (codec_switch == DCE_ENC_TEST_H263) ) { 1570 } else if( (codec_switch == DCE_ENC_TEST_MPEG4) || (codec_switch == DCE_ENC_TEST_H263) ) {
1252 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) inArgs; 1571 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) inArgs;
1253 DEBUG("TEST inArgs->inputID %d mpeg4enc_inArgs->videnc2InArgs.inputID %d", inArgs->inputID, mpeg4enc_inArgs->videnc2InArgs.inputID); 1572 DEBUG("inArgs->inputID 0x%x mpeg4enc_inArgs->videnc2InArgs.inputID %d", inArgs->inputID, mpeg4enc_inArgs->videnc2InArgs.inputID);
1254 } 1573 }
1255 } else if( n == -1 ) { 1574 } else if( (n == -1) && (endOfFile) ) {
1256 1575
1257 // Set EOF as 1 to ensure flush completes
1258 eof = 1;
1259 in_cnt++; 1576 in_cnt++;
1260 1577
1261 DEBUG("n == -1 - go to shutdown"); 1578 DEBUG("n == -1 and IT IS EOF - go to shutdown");
1262
1263 goto shutdown; 1579 goto shutdown;
1264
1265 switch( codec_switch ) {
1266 case DCE_ENC_TEST_H264 :
1267 DEBUG("Calling VIDENC2_control XDM_FLUSH h264enc_dynParams %p h264enc_status %p", h264enc_dynParams, h264enc_status);
1268 err = VIDENC2_control(codec, XDM_FLUSH, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status);
1269 break;
1270 case DCE_ENC_TEST_MPEG4 :
1271 case DCE_ENC_TEST_H263 :
1272 DEBUG("Calling VIDENC2_control XDM_FLUSH mpeg4enc_dynParams %p mpeg4enc_status %p", mpeg4enc_dynParams, mpeg4enc_status);
1273 err = VIDENC2_control(codec, XDM_FLUSH, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) mpeg4enc_status);
1274 break;
1275 default :
1276 ERROR("Unrecognized codec to encode");
1277 }
1278
1279 /* We have sent the XDM_FLUSH, call VIDENC2_process until we get
1280 * an error of XDM_EFAIL which tells us there are no more buffers
1281 * at codec level.
1282 */
1283
1284 inArgs->inputID = 0;
1285 if( codec_switch == DCE_ENC_TEST_H264 ) {
1286 h264enc_inArgs = (IH264ENC_InArgs *) inArgs;
1287 } else if( (codec_switch == DCE_ENC_TEST_MPEG4) || (codec_switch == DCE_ENC_TEST_H263) ) {
1288 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) inArgs;
1289 }
1290 inBufs->planeDesc[0].buf = NULL;
1291 inBufs->planeDesc[0].bufSize.bytes = 0;
1292 inBufs->planeDesc[1].buf = NULL;
1293 inBufs->planeDesc[1].bufSize.bytes = 0;
1294 outBufs->descs[0].buf = NULL;
1295 outBufs->descs[1].buf = NULL;
1296 } else { 1580 } else {
1297 /* end of input.. (n == 0) */ 1581 /* end of input.. (n == 0) */
1298 inBufs->numPlanes = 0; 1582 inBufs->numPlanes = 0;
1299 eof = 1; 1583 DEBUG("n == 0 and NOT slice mode - go to shutdown");
1300 DEBUG("n == 0 - go to shutdown");
1301 1584
1302 goto shutdown; 1585 goto shutdown;
1303
1304 switch( codec_switch ) {
1305 case DCE_ENC_TEST_H264 :
1306 DEBUG("Calling VIDENC2_control XDM_FLUSH h264enc_dynParams %p h264enc_status %p", h264enc_dynParams, h264enc_status);
1307 err = VIDENC2_control(codec, XDM_FLUSH, (VIDENC2_DynamicParams *) h264enc_dynParams, (VIDENC2_Status *) h264enc_status);
1308 break;
1309 case DCE_ENC_TEST_MPEG4 :
1310 case DCE_ENC_TEST_H263 :
1311 DEBUG("Calling VIDENC2_control XDM_FLUSH mpeg4enc_dynParams %p mpeg4enc_status %p", mpeg4enc_dynParams, mpeg4enc_status);
1312 err = VIDENC2_control(codec, XDM_FLUSH, (VIDENC2_DynamicParams *) mpeg4enc_dynParams, (VIDENC2_Status *) mpeg4enc_status);
1313 break;
1314 default :
1315 ERROR("Unrecognized codec to encode");
1316 }
1317
1318 /* We have sent the XDM_FLUSH, call VIDENC2_process until we get
1319 * an error of XDM_EFAIL which tells us there are no more buffers
1320 * at codec level.
1321 */
1322
1323 inArgs->inputID = 0;
1324 if( codec_switch == DCE_ENC_TEST_H264 ) {
1325 h264enc_inArgs = (IH264ENC_InArgs *) inArgs;
1326 } else if( (codec_switch == DCE_ENC_TEST_MPEG4) || (codec_switch == DCE_ENC_TEST_H263) ) {
1327 mpeg4enc_inArgs = (IMPEG4ENC_InArgs *) inArgs;
1328 }
1329 inBufs->planeDesc[0].buf = NULL;
1330 inBufs->planeDesc[0].bufSize.bytes = 0;
1331 inBufs->planeDesc[1].buf = NULL;
1332 inBufs->planeDesc[1].bufSize.bytes = 0;
1333 outBufs->descs[0].buf = NULL;
1334 } 1586 }
1335 1587
1336#ifdef DUMPINPUTDATA 1588#ifdef DUMPINPUTDATA
@@ -1338,14 +1590,12 @@ int main(int argc, char * *argv)
1338 1590
1339 //Dump the file 1591 //Dump the file
1340 if( inputDump == NULL ) { 1592 if( inputDump == NULL ) {
1341
1342 if( GlobalCount1 <= 50 ) { 1593 if( GlobalCount1 <= 50 ) {
1343 DEBUG("[DCE_ENC_TEST] GlobalCount1 %d\n", GlobalCount1); 1594 sprintf(Buff1, "/tmp/dceinputdump%d.bin", GlobalCount1);
1344 sprintf(Buff1, "/sd/dce_enc_dump/dceinputdump%d.bin", GlobalCount1);
1345 inputDump = fopen(Buff1, "wb+"); 1595 inputDump = fopen(Buff1, "wb+");
1346 //DEBUG("input data dump file open %p errno %d", inputDump, errno); 1596 //DEBUG("input data dump file open %p errno %d", inputDump, errno);
1347 if( inputDump == NULL ) { 1597 if( inputDump == NULL ) {
1348 DEBUG("Opening input Dump /sd/dce_enc_dump/dceinputdump.bin file FAILED"); 1598 DEBUG("Opening input Dump /tmp/dceinputdump%d.bin file FAILED", GlobalCount1);
1349 } else { 1599 } else {
1350 GlobalCount1++; 1600 GlobalCount1++;
1351 //DEBUG("Before Input [%p]\n", input); 1601 //DEBUG("Before Input [%p]\n", input);
@@ -1357,11 +1607,11 @@ int main(int argc, char * *argv)
1357 inputDump = NULL; 1607 inputDump = NULL;
1358 } 1608 }
1359 } 1609 }
1360 //DEBUG("input data dump file open %p Successful", inputDump);
1361 } 1610 }
1362#endif 1611#endif
1363 1612
1364 int iters = 0; 1613 int iters = 0;
1614 int i = 0;
1365 1615
1366 do { 1616 do {
1367 1617
@@ -1384,13 +1634,20 @@ int main(int argc, char * *argv)
1384 codec_process_time = mark_microsecond(NULL); 1634 codec_process_time = mark_microsecond(NULL);
1385#endif 1635#endif
1386 1636
1637 if (datamode == IVIDEO_NUMROWS) {
1638 dest_y_offset = 0;
1639 if(tiler) {
1640 dest_uv_offset = 4096 * height;
1641 } else {
1642 dest_uv_offset = width * height;
1643 }
1644 }
1645
1387 if( codec_switch == DCE_ENC_TEST_H264 ) { 1646 if( codec_switch == DCE_ENC_TEST_H264 ) {
1388 err = VIDENC2_process(codec, inBufs, outBufs, (VIDENC2_InArgs *) h264enc_inArgs, (VIDENC2_OutArgs *) h264enc_outArgs); 1647 err = VIDENC2_process(codec, inBufs, outBufs, (VIDENC2_InArgs *) h264enc_inArgs, (VIDENC2_OutArgs *) h264enc_outArgs);
1389 DEBUG("[DCE_ENC_TEST] VIDENC2_process - err %d", err); 1648 DEBUG("[DCE_ENC_TEST] VIDENC2_process - err %d", err);
1390 1649
1391 if( err == DCE_EXDM_FAIL ) { 1650 if( err == DCE_EXDM_FAIL ) {
1392 int i = 0;
1393
1394 for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) { 1651 for( i=0; i < IH264ENC_EXTERROR_NUM_MAXWORDS; i++ ) {
1395 DEBUG("DETAIL EXTENDED ERROR h264enc_outArgs->extErrorCode[%d]=%08x", i, (uint)h264enc_outArgs->extErrorCode[i]); 1652 DEBUG("DETAIL EXTENDED ERROR h264enc_outArgs->extErrorCode[%d]=%08x", i, (uint)h264enc_outArgs->extErrorCode[i]);
1396 } 1653 }
@@ -1407,7 +1664,7 @@ int main(int argc, char * *argv)
1407 ERROR("extendedError: %08x", h264enc_outArgs->videnc2OutArgs.extendedError); 1664 ERROR("extendedError: %08x", h264enc_outArgs->videnc2OutArgs.extendedError);
1408 ERROR("DCE_ENCODE_TEST_FAIL: CODEC FATAL ERROR"); 1665 ERROR("DCE_ENCODE_TEST_FAIL: CODEC FATAL ERROR");
1409 goto shutdown; 1666 goto shutdown;
1410 } else if( eof ) { 1667 } else if( endOfFile ) {
1411 ERROR("Codec_process returned err=%d, extendedError=%08x", err, h264enc_outArgs->videnc2OutArgs.extendedError); 1668 ERROR("Codec_process returned err=%d, extendedError=%08x", err, h264enc_outArgs->videnc2OutArgs.extendedError);
1412 DEBUG("-------------------- Flush completed------------------------"); 1669 DEBUG("-------------------- Flush completed------------------------");
1413 } else { 1670 } else {
@@ -1434,7 +1691,7 @@ int main(int argc, char * *argv)
1434 ERROR("extendedError: %08x", mpeg4enc_outArgs->videnc2OutArgs.extendedError); 1691 ERROR("extendedError: %08x", mpeg4enc_outArgs->videnc2OutArgs.extendedError);
1435 ERROR("DCE_ENCODE_TEST_FAIL: CODEC FATAL ERROR"); 1692 ERROR("DCE_ENCODE_TEST_FAIL: CODEC FATAL ERROR");
1436 goto shutdown; 1693 goto shutdown;
1437 } else if( eof ) { 1694 } else if( endOfFile ) {
1438 ERROR("Codec_process returned err=%d, extendedError=%08x", err, mpeg4enc_outArgs->videnc2OutArgs.extendedError); 1695 ERROR("Codec_process returned err=%d, extendedError=%08x", err, mpeg4enc_outArgs->videnc2OutArgs.extendedError);
1439 DEBUG("-------------------- Flush completed------------------------"); 1696 DEBUG("-------------------- Flush completed------------------------");
1440 } else { 1697 } else {
@@ -1479,11 +1736,11 @@ int main(int argc, char * *argv)
1479 if( outputDump == NULL ) { 1736 if( outputDump == NULL ) {
1480 if( GlobalCount2 <= 50 ) { 1737 if( GlobalCount2 <= 50 ) {
1481 DEBUG("DCE_ENC_TEST GlobalCount2 %d\n", GlobalCount2); 1738 DEBUG("DCE_ENC_TEST GlobalCount2 %d\n", GlobalCount2);
1482 sprintf(Buff2, "/sd/dce_enc_dump/dceoutputdump%d.bin", GlobalCount2); 1739 sprintf(Buff2, "/tmp/dceoutputdump%d.bin", GlobalCount2);
1483 outputDump = fopen(Buff2, "wb+"); 1740 outputDump = fopen(Buff2, "wb+");
1484 //DEBUG("output data dump file open %p errno %d", outputDump, errno); 1741 //DEBUG("output data dump file open %p errno %d", outputDump, errno);
1485 if( outputDump == NULL ) { 1742 if( outputDump == NULL ) {
1486 DEBUG("Opening output Dump /sd/dce_enc_dump/dceoutputdump.bin file FAILED"); 1743 DEBUG("Opening output Dump /tmp/dceoutputdump%d.bin file FAILED", GlobalCount2);
1487 } else { 1744 } else {
1488 GlobalCount2++; 1745 GlobalCount2++;
1489 fwrite(output, 1, bytesGenerated, outputDump); 1746 fwrite(output, 1, bytesGenerated, outputDump);
@@ -1504,15 +1761,34 @@ int main(int argc, char * *argv)
1504 } 1761 }
1505 } 1762 }
1506 1763
1764 for( i=0; outArgs->freeBufID[i]; i++ ) {
1765 DEBUG("freeBufID[%d] = %d", i, outArgs->freeBufID[i]);
1766 buf = (InputBuffer *)outArgs->freeBufID[i];
1767 input_release(buf);
1768 }
1769
1507 ++iters; // Guard for infinite VIDENC2_PROCESS loop when codec never return XDM_EFAIL 1770 ++iters; // Guard for infinite VIDENC2_PROCESS loop when codec never return XDM_EFAIL
1508 } while( eof && (err != XDM_EFAIL) && (iters < 100)); // Multiple VIDENC2_process when eof until err == XDM_EFAIL 1771 } while( endOfFile && (err != XDM_EFAIL) && (iters < 100)); // Multiple VIDENC2_process when endOfFile until err == XDM_EFAIL
1509 1772
1773 if (datamode == IVIDEO_NUMROWS) {
1774 // Reset to the next frame; when VIDENC2_process return; 1 input frame should be encoded.
1775 if( tiler ) {
1776 input_y_offset += (4096 * height/2);
1777 input_uv_offset += (4096 * height);
1778 } else {
1779 input_y_offset += (width * height/2);
1780 input_uv_offset += (width * height);
1781 }
1782 DEBUG("input_y_offset %d input_uv_offset %d", input_y_offset, input_uv_offset);
1783 }
1510 } 1784 }
1511 1785
1512shutdown: 1786shutdown:
1513 1787
1514 printf("\nDeleting encoder codec...\n"); 1788 printf("\nDeleting encoder codec 0x%x...\n", (unsigned int) codec);
1515 VIDENC2_delete(codec); 1789 if( codec ) {
1790 VIDENC2_delete(codec);
1791 }
1516 1792
1517out: 1793out:
1518 if( engine ) { 1794 if( engine ) {
@@ -1562,19 +1838,9 @@ out:
1562 } 1838 }
1563 } 1839 }
1564 1840
1565 printf("\nFreeing buf %p...\n", buf); 1841 printf("\nFreeing input...\n");
1566 if( buf ) { 1842 input_free();
1567 if( buf->buf ) { 1843
1568 if( tiler ) {
1569 printf("\nFreeing buf->buf %p...\n", buf->buf);
1570 MemMgr_Free(buf->buf);
1571 } else {
1572 printf("\nFreeing input_nonTiler %p...\n", &input_nonTiler);
1573 free_nonTiler(&input_nonTiler);
1574 }
1575 }
1576 free(buf);
1577 }
1578 printf("DCE ENC test completed...\n"); 1844 printf("DCE ENC test completed...\n");
1579 1845
1580 return (0); 1846 return (0);
diff --git a/test_qnx/dce_enc_test/dce_enc_test.use b/test_qnx/dce_enc_test/dce_enc_test.use
index aadf40a..92d543a 100644
--- a/test_qnx/dce_enc_test/dce_enc_test.use
+++ b/test_qnx/dce_enc_test/dce_enc_test.use
@@ -39,9 +39,9 @@ Options:
39 39
40Examples: 40Examples:
411. Encoding h.264 411. Encoding h.264
42 dce_enc_test width height inpattern outpattern codec profile level 42 dce_enc_test width height inpattern outpattern codec profile level buffertype mode
43 example to encode H.264 QCIF with Profile baseline and Level 1.0 43 example to encode H.264 QCIF with Profile baseline and Level 1.0; nontiler; full frame.
44 dce_enc_test 176 144 inputfile.yuv outputfile.h264 h264 baseline 10 44 dce_enc_test 176 144 inputfile.yuv outputfile.h264 h264 baseline 10 nontiler full
45 45
46 Acceptable input value for profile: 46 Acceptable input value for profile:
47 baseline 47 baseline
@@ -65,10 +65,20 @@ Examples:
65 50 - Level 5.0 65 50 - Level 5.0
66 51 - Level 5.1 66 51 - Level 5.1
67 67
68 Acceptable input value for buffertype:
69 tiler (beware of ERRATA i878)
70 nontiler
71
72 Acceptable input value for mode:
73 numrow
74 slice
75 fixed
76 full
77
682. encoding Mpeg4 782. encoding Mpeg4
69 dce_enc_test width height inpattern outpattern codec profile 0 79 dce_enc_test width height inpattern outpattern codec profile 0 buffertype mode
70 example to encode MPEG4 QCIF with profile simple level 0 80 example to encode MPEG4 QCIF with profile simple level 0; nontiler; full frame.
71 dce_enc_test 176 144 inputfile.yuv outputfile.mpeg4 mpeg4 0 0 81 dce_enc_test 176 144 inputfile.yuv outputfile.mpeg4 mpeg4 0 0 nontiler full
72 82
73 Acceptable input value for profile: 83 Acceptable input value for profile:
74 0 - MPEG4 SIMPLE PROFILE LEVEL 0 84 0 - MPEG4 SIMPLE PROFILE LEVEL 0
@@ -80,10 +90,17 @@ Examples:
80 5 - MPEG4 SIMPLE PROFILE LEVEL 5 90 5 - MPEG4 SIMPLE PROFILE LEVEL 5
81 6 - MPEG4 SIMPLE PROFILE LEVEL 6 91 6 - MPEG4 SIMPLE PROFILE LEVEL 6
82 92
93 Acceptable input value for buffertype:
94 tiler (beware of ERRATA i878)
95 nontiler
96
97 Acceptable input value for mode:
98 full
99
833. Encoding H.263 1003. Encoding H.263
84 dce_enc_test width height inpattern outpattern codec profile 0 101 dce_enc_test width height inpattern outpattern codec profile 0 buffertype mode
85 example to encode H.263 QCIF with profile simple level 0 102 example to encode H.263 QCIF with profile simple level 0; nontiler; full frame.
86 dce_enc_test 176 144 inputfile.yuv outputfile.h263 h263 0 0 103 dce_enc_test 176 144 inputfile.yuv outputfile.h263 h263 0 0 nontiler full
87 104
88 Acceptable input value for profile: 105 Acceptable input value for profile:
89 10 - H.263 BASELINE PROFILE LEVEL 10 106 10 - H.263 BASELINE PROFILE LEVEL 10
@@ -95,4 +112,11 @@ Examples:
95 60 - H.263 BASELINE PROFILE LEVEL 60 112 60 - H.263 BASELINE PROFILE LEVEL 60
96 70 - H.263 BASELINE PROFILE LEVEL 70 113 70 - H.263 BASELINE PROFILE LEVEL 70
97 114
98Currently supported codecs: h264 and mpeg4 115 Acceptable input value for buffertype:
116 tiler (beware of ERRATA i878)
117 nontiler
118
119 Acceptable input value for mode:
120 full
121
122Currently supported codecs: h264, mpeg4 and h263
diff --git a/test_qnx/dce_test/dce_test.c b/test_qnx/dce_test/dce_test.c
index 7e60dd0..3852b8d 100644
--- a/test_qnx/dce_test/dce_test.c
+++ b/test_qnx/dce_test/dce_test.c
@@ -63,6 +63,8 @@
63#include "ti/shmemallocator/SharedMemoryAllocatorUsr.h" 63#include "ti/shmemallocator/SharedMemoryAllocatorUsr.h"
64 64
65#define PRINT_DEBUG 65#define PRINT_DEBUG
66//#define PRINT_DEBUG_LOW
67
66#define ERROR(FMT, ...) printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 68#define ERROR(FMT, ...) printf("%s:%d:\t%s\terror: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
67// enable below to print debug information 69// enable below to print debug information
68#ifdef PRINT_DEBUG 70#ifdef PRINT_DEBUG
@@ -70,6 +72,13 @@
70#else 72#else
71#define DEBUG(FMT, ...) 73#define DEBUG(FMT, ...)
72#endif 74#endif
75
76#ifdef PRINT_DEBUG_LOW
77#define DEBUGLOW(FMT, ...) printf("%s:%d:\t%s\tdebug: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
78#else
79#define DEBUGLOW(FMT, ...)
80#endif
81
73#define INFO(FMT, ...) printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 82#define INFO(FMT, ...) printf("%s:%d:\t%s\tinfo: " FMT "\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
74#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 83#define MIN(a, b) (((a) < (b)) ? (a) : (b))
75 84
@@ -82,6 +91,8 @@
82// Getting codec version through XDM_GETVERSION 91// Getting codec version through XDM_GETVERSION
83#define GETVERSION 92#define GETVERSION
84 93
94#define STRIDE 4096
95
85enum { 96enum {
86 IVAHD_AVC1_DECODE, 97 IVAHD_AVC1_DECODE,
87 IVAHD_H264_DECODE, 98 IVAHD_H264_DECODE,
@@ -94,12 +105,20 @@ enum {
94 IVAHD_JPEGV_DECODE 105 IVAHD_JPEGV_DECODE
95}; 106};
96 107
108// Used when datamode == IVIDEO_NUMROWS
109static int numBlock = 2;
110static int output_y_offset = 0;
111static int output_uv_offset = 0;
112static int numRow_y_offset = 0;
113static int numRow_uv_offset = 0;
114char *out_pattern;
115char *outBuf_lowlatency;
116
97/* 117/*
98 * A very simple VIDDEC3 client which will decode h264 frames (one per file), 118 * A very simple VIDDEC3 client which will decode h264 frames (one per file),
99 * and write out raw (unstrided) nv12 frames (one per file). 119 * and write out raw (unstrided) nv12 frames (one per file).
100 */ 120 */
101 121int orig_width, orig_height, width, height, frames_to_write, padded_width, padded_height, num_buffers, tiler;
102int width, height, frames_to_write, padded_width, padded_height, num_buffers, tiler;
103Engine_Handle engine = NULL; 122Engine_Handle engine = NULL;
104VIDDEC3_Handle codec = NULL; 123VIDDEC3_Handle codec = NULL;
105VIDDEC3_Params *params = NULL; 124VIDDEC3_Params *params = NULL;
@@ -129,6 +148,7 @@ IJPEGVDEC_Status *mjpeg_status = NULL;
129IMPEG2VDEC_Params *mpeg2_params = NULL; 148IMPEG2VDEC_Params *mpeg2_params = NULL;
130IMPEG2VDEC_DynamicParams *mpeg2_dynParams = NULL; 149IMPEG2VDEC_DynamicParams *mpeg2_dynParams = NULL;
131IMPEG2VDEC_Status *mpeg2_status = NULL; 150IMPEG2VDEC_Status *mpeg2_status = NULL;
151int out_cnt = 0;
132 152
133unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ 153unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */
134static int input_offset = 0; 154static int input_offset = 0;
@@ -218,7 +238,7 @@ get_mem_type (uint32_t paddr)
218/* list of free buffers, not locked by codec! */ 238/* list of free buffers, not locked by codec! */
219static OutputBuffer *head = NULL; 239static OutputBuffer *head = NULL;
220 240
221#if 0 241#if 0 // OLD implementation when using DCE RLS 3.x
222/*! @brief Start address of DDR region for 1GB RAM */ 242/*! @brief Start address of DDR region for 1GB RAM */
223#define DDR_1G_ADDRESS_START 0x80000000 243#define DDR_1G_ADDRESS_START 0x80000000
224/*! @brief End address of DDR region for 1GB RAM */ 244/*! @brief End address of DDR region for 1GB RAM */
@@ -386,8 +406,8 @@ int output_allocate_nonTiler(XDM2_BufDesc *outBufs, int cnt,
386 406
387 if((y_type < 0) || (uv_type < 0)) { 407 if((y_type < 0) || (uv_type < 0)) {
388 DEBUG("non TILER buffer address translation buf->y %x buf->uv %x", buf->y, buf->uv); 408 DEBUG("non TILER buffer address translation buf->y %x buf->uv %x", buf->y, buf->uv);
389 //buf->y = SysLinkMemUtils_translateAddr(buf->y); 409 //buf->y = SysLinkMemUtils_translateAddr(buf->y); // Old Implementation when using DCE 3.x
390 //buf->uv = SysLinkMemUtils_translateAddr(buf->uv); 410 //buf->uv = SysLinkMemUtils_translateAddr(buf->uv); // Old Implementation when using DCE 3.x
391 y_type = XDM_MEMTYPE_RAW; 411 y_type = XDM_MEMTYPE_RAW;
392 uv_type = XDM_MEMTYPE_RAW; 412 uv_type = XDM_MEMTYPE_RAW;
393 DEBUG("buf->y %x buf->uv %x", buf->y, buf->uv); 413 DEBUG("buf->y %x buf->uv %x", buf->y, buf->uv);
@@ -495,12 +515,143 @@ int read_input(const char *pattern, int cnt, char *input)
495 return (sz); 515 return (sz);
496} 516}
497 517
518//#define DUMP_PARTIAL_OUTPUT
519
520// Used when outputDataMode = IVIDEO_NUMROWS
521#ifdef DUMP_PARTIAL_OUTPUT
522static int GlobalFileCount = 0;
523#endif
524static int total_numRows = 0;
525//Create 2 temp buffers for Y and UV
526char *y_buffer = NULL;
527int y_buffer_offset = 0;
528char *orig_y_buffer = NULL;
529char *uv_buffer = NULL;
530int uv_buffer_offset = 0;
531char *orig_uv_buffer = NULL;
532
533/* helper to write partial data into output file based on numRows (1 numRows = 16 row of height for luma and 8 row of height for chroma */
534int write_partial_output(const char *pattern, char *y, char *uv, int stride, int numRows)
535{
536 DEBUGLOW("write_partial_output pattern %s y 0x%x uv 0x%x numRow_y_offset %d numRow_uv_offset %d orig_width %d numRows %d",
537 pattern, (unsigned int) y, (unsigned int) uv, numRow_y_offset, numRow_uv_offset, orig_width, numRows);
538
539 int sz = 0, i;
540
541#ifdef DUMP_PARTIAL_OUTPUT
542 int size;
543 FILE *fp = NULL;
544
545 DEBUGLOW("write_partial_output total_numRows %d y_buffer 0x%x y_buffer_offset 0x%x uv_buffer 0x%x uv_buffer_offset 0x%x",
546 total_numRows, (unsigned int) y_buffer, (unsigned int) y_buffer_offset, (unsigned int) uv_buffer, (unsigned int)uv_buffer_offset);
547
548 char Buff1[100];
549 sprintf(Buff1, "/tmp/dec_y_dump%d.bin", GlobalFileCount);
550 fp = fopen(Buff1,"wb+");
551 if(fp == NULL)
552 ERROR(">> error in file create ");
553#endif
554
555 DEBUGLOW("write_partial_output y_buffer 0x%x y_buffer_offset 0x%x y 0x%x numRow_y_offset %d stride %d orig_width %d",
556 (unsigned int) y_buffer, (unsigned int) y_buffer_offset, (unsigned int) y, numRow_y_offset, stride, orig_width);
557
558 DEBUGLOW("memcpy y_buffer dst 0x%x src 0x%x size %d", (unsigned int) y_buffer + y_buffer_offset, (unsigned int) y + (numRow_y_offset * stride), orig_width);
559
560 for ( i = 0; i < (numRows * 16 ); i++) {
561 memcpy(y_buffer + y_buffer_offset, y + (numRow_y_offset * stride), orig_width);
562
563#ifdef DUMP_PARTIAL_OUTPUT
564 size = fwrite(y_buffer + y_buffer_offset, 1, orig_width, fp);
565 if(size)
566 DEBUGLOW(">> dumped size = %d in file %s", orig_width, Buff1);
567 else
568 ERROR(">> writing % size", size);
569#endif
570
571 y_buffer_offset += orig_width;
572 sz += orig_width;
573 numRow_y_offset++;
574 }
575
576#ifdef DUMP_PARTIAL_OUTPUT
577 fclose(fp);
578
579 char Buff2[100];
580 sprintf(Buff2, "/tmp/dce_uv_dump%d.bin", GlobalFileCount);
581 fp = fopen(Buff2,"wb+");
582 if(fp == NULL)
583 ERROR(">> error in file create ");
584#endif
585
586 DEBUGLOW("write_partial_output uv_buffer 0x%x uv_buffer_offset 0x%x uv 0x%x numRow_uv_offset %d stride %d orig_width %d",
587 (unsigned int) uv_buffer, (unsigned int) uv_buffer_offset, (unsigned int) uv, numRow_uv_offset, stride, orig_width);
588
589 DEBUGLOW("memcpy uv_buffer dst 0x%x src 0x%x size %d", (unsigned int) uv_buffer + uv_buffer_offset, (unsigned int) uv + (numRow_uv_offset * stride), orig_width);
590
591 for ( i = 0; i < (numRows * 8 ); i++) {
592 memcpy(uv_buffer + uv_buffer_offset, uv + (numRow_uv_offset * stride), orig_width);
593
594#ifdef DUMP_PARTIAL_OUTPUT
595 size = fwrite(uv_buffer + uv_buffer_offset, 1, orig_width, fp);
596 if(size)
597 DEBUGLOW(">> dumped size = %d in file %s", orig_width, Buff2);
598 else
599 ERROR(">> writing % size", size);
600#endif
601
602 uv_buffer_offset += orig_width;
603 sz += orig_width;
604 numRow_uv_offset++;
605 }
606
607#ifdef DUMP_PARTIAL_OUTPUT
608 fclose(fp);
609 GlobalFileCount++;
610#endif
611
612 total_numRows += numRows;
613 DEBUGLOW("total_numRows %d height / 16 = %d", total_numRows, height / 16);
614
615 if (total_numRows == (height / 16)) {
616 // Meaning 1 full frame has been reached. Need to write the temp y_buffer and uv_buffer to file.
617 if( out_cnt < frames_to_write ) {
618 DEBUGLOW("write_partial_output writing the output file");
619
620 FILE* fd = fopen(pattern,"ab+");
621 if( fd < 0 ) {
622 ERROR("could open output file: %s (%d)", pattern, errno);
623 return (0);
624 }
625
626 fwrite(y_buffer, 1, orig_width * orig_height, fd);
627 DEBUGLOW("write_partial_output writing %d size from Y_buffer 0x%x", orig_width * orig_height, (unsigned int) y_buffer);
628 fwrite(uv_buffer, 1, orig_width * orig_height/2, fd);
629 DEBUGLOW("write_partial_output writing %d size from UV_buffer 0x%x", orig_width * orig_height/2, (unsigned int) uv_buffer);
630
631 fclose(fd);
632 }
633
634 out_cnt++;
635 numRow_y_offset = 0;
636 numRow_uv_offset = 0;
637 y_buffer_offset = 0;
638 uv_buffer_offset = 0;
639 total_numRows = 0;
640 }
641
642 DEBUGLOW("write_partial_output is returning size of %d", sz);
643 return (sz);
644}
645
646
498/* helper to write one frame of output */ 647/* helper to write one frame of output */
499int write_output(const char *pattern, int cnt, char *y, char *uv, int stride) 648int write_output(const char *pattern, int cnt, char *y, char *uv, int stride)
500{ 649{
501 int sz = 0, n = 0, i; 650 int sz = 0, n = 0, i;
502 const char *path = get_path(pattern, cnt); 651 const char *path = get_path(pattern, cnt);
503 652
653 DEBUG("write_output y 0x%x uv 0x%x", (unsigned int) y, (unsigned int) uv);
654
504 if( path == NULL ) { 655 if( path == NULL ) {
505 return (sz); 656 return (sz);
506 } 657 }
@@ -512,9 +663,9 @@ int write_output(const char *pattern, int cnt, char *y, char *uv, int stride)
512 return (0); 663 return (0);
513 } 664 }
514 665
515 for( i = 0; i < height; i++ ) { 666 for( i = 0; i < orig_height; i++ ) {
516 char *p = y; 667 char *p = y;
517 int len = width; 668 int len = orig_width;
518 669
519 while( len && ((n = write(fd, p, len)) > 0)) { 670 while( len && ((n = write(fd, p, len)) > 0)) {
520 sz += n; 671 sz += n;
@@ -530,9 +681,9 @@ int write_output(const char *pattern, int cnt, char *y, char *uv, int stride)
530 } 681 }
531 682
532 if( n >= 0 ) { 683 if( n >= 0 ) {
533 for( i = 0; i < height / 2; i++ ) { 684 for( i = 0; i < orig_height / 2; i++ ) {
534 char *p = uv; 685 char *p = uv;
535 int len = width; 686 int len = orig_width;
536 687
537 while( len && ((n = write(fd, p, len)) > 0)) { 688 while( len && ((n = write(fd, p, len)) > 0)) {
538 sz += n; 689 sz += n;
@@ -588,14 +739,73 @@ FILE *inputDump;
588#define VERSION_SIZE 128 739#define VERSION_SIZE 128
589#endif 740#endif
590 741
742/* Function callback for low latency decoder with NUMROWS*/
743/* Client is expected to read the dataSyncDesc information especially numBlocks for decoded output that is ready. */
744/* numBlocks is filled based on the output data being filled into the output buffer that was passed in VIDDEC3_process */
745/* The return value of this function is NULL when okay; if there is a problem return value < 0, then LIBDCE will print and Error and continue. */
746/* It is up to client to stop when client is not able to read/save the decoded output from output buffer pointer. */
747XDAS_Int32 H264D_MPU_PutDataFxn(XDM_DataSyncHandle dataSyncHandle, XDM_DataSyncDesc *dataSyncDesc)
748{
749 int numRows;
750
751 DEBUGLOW("-----------------------H264D_MPU_PutDataFxn START--------------------------------dataSyncHandle 0x%x dataSyncDesc->numBlocks %d ",
752 (unsigned int)dataSyncHandle, dataSyncDesc->numBlocks);
753 //Need to read the information in dataSyncDesc->numBlocks which specifies how many numBlocks that are ready in
754 //the output buffer pointer. Only write that much.
755 numRows = dataSyncDesc->numBlocks;
756
757 // This callback should be called when libdce is getting the putDataFxn on the 2nd MmRpc instances.
758 // At this point application/client receive information that numRows is ready in output buffers.
759 // Call the write_partial_output to write the available output YUV NV12 (1 numBlock = 16 row of height on luma section and 8 row of heigh on chroma section.
760
761 if (outBuf_lowlatency) {
762 DEBUGLOW("H264D_MPU_PutDataFxn tiler %d", tiler);
763 if( tiler ) {
764 DEBUGLOW("TILER outArgs->outputID[%d] 0x%x", 0, outArgs->outputID[0]);
765
766 /* calculate offset to region of interest */
767 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
768
769 DEBUGLOW("r->topLeft.y 0x%x r->topLeft.x 0x%x", r->topLeft.y, r->topLeft.x);
770
771 int yoff = (r->topLeft.y * STRIDE) + r->topLeft.x;
772 int uvoff = (r->topLeft.y * (STRIDE / 2)) + (STRIDE * padded_height) + r->topLeft.x;
773
774 DEBUGLOW("outBuf_lowlatency 0x%x yoff 0x%x uvoff 0x%x numRow_y_offset %d", (unsigned int) outBuf_lowlatency, yoff, uvoff, numRow_y_offset);
775 DEBUGLOW("H264D_MPU_PutDataFxn TILER getting partial output buffer on outBuf_lowlatency : (%p) y 0x%x uv 0x%x",
776 outBuf_lowlatency, (unsigned int) outBuf_lowlatency + yoff, (unsigned int) outBuf_lowlatency + uvoff);
777 write_partial_output(out_pattern, outBuf_lowlatency + yoff, outBuf_lowlatency + uvoff, STRIDE, numRows);
778 } else {
779 DEBUGLOW("NONTILER outArgs->outputID[%d] 0x%x", 0, outArgs->outputID[0]);
780
781 /* calculate offset to region of interest */
782 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
783
784 DEBUGLOW("r->topLeft.y 0x%x r->topLeft.x 0x%x", r->topLeft.y, r->topLeft.x);
785
786 int yoff = (r->topLeft.y * padded_width) + r->topLeft.x;
787 int uvoff = (r->topLeft.y * (padded_width / 2)) + (padded_height * padded_width) + r->topLeft.x;
788
789 DEBUGLOW("outBuf_lowlatency 0x%x yoff 0x%x uvoff 0x%x numRow_y_offset %d", (unsigned int) outBuf_lowlatency, yoff, uvoff, numRow_y_offset);
790 DEBUGLOW("H264D_MPU_PutDataFxn nonTILER getting partial output buffer on outBuf_lowlatency : (%p) y 0x%x uv 0x%x",
791 outBuf_lowlatency, (unsigned int) outBuf_lowlatency + yoff, (unsigned int) outBuf_lowlatency + uvoff);
792 write_partial_output(out_pattern, outBuf_lowlatency + yoff, outBuf_lowlatency + uvoff, padded_width, numRows);
793 }
794 }
795
796 DEBUGLOW("-----------------------H264D_MPU_PutDataFxn END--------------------------------");
797 return (0);
798}
799
800
591/* decoder body */ 801/* decoder body */
592int main(int argc, char * *argv) 802int main(int argc, char * *argv)
593{ 803{
594 Engine_Error ec; 804 Engine_Error ec;
595 XDAS_Int32 err; 805 XDAS_Int32 err;
596 char *input = NULL; 806 char *input = NULL;
597 char *in_pattern, *out_pattern, *frameData; 807 char *in_pattern, *frameData;
598 int in_cnt = 0, out_cnt = 0; 808 int in_cnt = 0;
599 int oned, stride; 809 int oned, stride;
600 unsigned int frameCount = 0; 810 unsigned int frameCount = 0;
601 FILE *frameFile; 811 FILE *frameFile;
@@ -605,8 +815,10 @@ int main(int argc, char * *argv)
605 char *temp_data = NULL; 815 char *temp_data = NULL;
606 char vid_codec[10]; 816 char vid_codec[10];
607 char tilerbuffer[10]; 817 char tilerbuffer[10];
818 char row_mode[10];
608 unsigned int codec_switch = 0; 819 unsigned int codec_switch = 0;
609 Bool outBufsInUse = FALSE; 820 Bool outBufsInUse = FALSE;
821 int datamode;
610 822
611#ifdef PROFILE_TIME 823#ifdef PROFILE_TIME
612 uint64_t init_start_time = 0; 824 uint64_t init_start_time = 0;
@@ -616,7 +828,7 @@ int main(int argc, char * *argv)
616#endif 828#endif
617 829
618#if 0 830#if 0
619 int loop = 0; 831 volatile int loop = 0;
620 832
621 while( loop == 0 ) { 833 while( loop == 0 ) {
622 loop = 0; 834 loop = 0;
@@ -632,21 +844,21 @@ int main(int argc, char * *argv)
632 oned = FALSE; 844 oned = FALSE;
633 } 845 }
634 846
635 if( argc != 9 ) { 847 if( argc != 10 ) {
636 printf("usage: %s width height frames_to_write framefile inpattern outpattern codec tilerbuffer\n", argv[0]); 848 printf("usage: %s width height frames_to_write framefile inpattern outpattern codec tilerbuffer mode\n", argv[0]);
637 printf("example: %s 320 240 30 frame.txt in.h264 out.yuv h264 tiler\n", argv[0]); 849 printf("example: %s 320 240 30 frame.txt in.h264 out.yuv h264 tiler numrow/slice/fixed/full\n", argv[0]);
638 printf("example: %s 640 480 30 frame.txt in.m4v out.yuv mpeg4 nontiler\n", argv[0]); 850 printf("example: %s 640 480 30 frame.txt in.m4v out.yuv mpeg4 nontiler full\n", argv[0]);
639 printf("example: %s 720 480 30 frame.txt in.vc1 out.yuv vc1ap tiler\n", argv[0]); 851 printf("example: %s 720 480 30 frame.txt in.vc1 out.yuv vc1ap tiler full\n", argv[0]);
640 printf("example: %s 320 240 30 frame.txt in.vc1 out.yuv vc1smp nontiler\n", argv[0]); 852 printf("example: %s 320 240 30 frame.txt in.vc1 out.yuv vc1smp nontiler full\n", argv[0]);
641 printf("example: %s 1280 720 30 frame.txt in.bin out.yuv mjpeg tiler\n", argv[0]); 853 printf("example: %s 1280 720 30 frame.txt in.bin out.yuv mjpeg tiler full\n", argv[0]);
642 printf("example: %s 1920 1088 30 frame.txt in.bin out.yuv mpeg2 nontiler\n", argv[0]); 854 printf("example: %s 1920 1088 30 frame.txt in.bin out.yuv mpeg2 nontiler full\n", argv[0]);
643 printf("Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2\n"); 855 printf("Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2\n");
644 return (1); 856 return (1);
645 } 857 }
646 858
647 /* error checking? */ 859 // Extracting the input parameters
648 width = atoi(argv[1]); 860 orig_width = atoi(argv[1]);
649 height = atoi(argv[2]); 861 orig_height = atoi(argv[2]);
650 frames_to_write = atoi(argv[3]); 862 frames_to_write = atoi(argv[3]);
651 frameData = argv[4]; 863 frameData = argv[4];
652 in_pattern = argv[5]; 864 in_pattern = argv[5];
@@ -655,9 +867,14 @@ int main(int argc, char * *argv)
655 strcpy(vid_codec, temp_data); 867 strcpy(vid_codec, temp_data);
656 temp_data = argv[8]; 868 temp_data = argv[8];
657 strcpy(tilerbuffer, temp_data); 869 strcpy(tilerbuffer, temp_data);
870 temp_data = argv[9];
871 strcpy(row_mode, temp_data);
658 872
659 printf("Selected codec: %s\n", vid_codec); 873 printf("Selected codec: %s\n", vid_codec);
660 printf("Selected buffer: %s\n", tilerbuffer); 874 printf("Selected buffer: %s\n", tilerbuffer);
875 printf("Decode mode: %s\n", row_mode);
876 printf("in_pattern: %s\n", in_pattern);
877 printf("out_pattern: %s\n", out_pattern);
661 878
662 if( frames_to_write == -1 ) { 879 if( frames_to_write == -1 ) {
663 /* Default : 30 frames to write into output file */ 880 /* Default : 30 frames to write into output file */
@@ -676,7 +893,6 @@ int main(int argc, char * *argv)
676 if((!(strcmp(vid_codec, "h264")))) { 893 if((!(strcmp(vid_codec, "h264")))) {
677 ivahd_decode_type = IVAHD_H264_DECODE; 894 ivahd_decode_type = IVAHD_H264_DECODE;
678 codec_switch = DCE_TEST_H264; 895 codec_switch = DCE_TEST_H264;
679
680 } else if((!(strcmp(vid_codec, "mpeg4")))) { 896 } else if((!(strcmp(vid_codec, "mpeg4")))) {
681 ivahd_decode_type = IVAHD_MP4V_DECODE; 897 ivahd_decode_type = IVAHD_MP4V_DECODE;
682 codec_switch = DCE_TEST_MPEG4; 898 codec_switch = DCE_TEST_MPEG4;
@@ -702,6 +918,28 @@ int main(int argc, char * *argv)
702 return (1); 918 return (1);
703 } 919 }
704 920
921 if((!(strcmp(row_mode, "full")))) {
922 datamode = IVIDEO_ENTIREFRAME;
923 } else if ((!(strcmp(row_mode, "numrow")))) {
924 datamode = IVIDEO_NUMROWS;
925 } else if ((!(strcmp(row_mode, "slice")))) {
926 datamode = IVIDEO_SLICEMODE;
927 ERROR("SLICE mode is not supported.");
928 goto shutdown;
929 } else if ((!(strcmp(row_mode, "fixed")))) {
930 datamode = IVIDEO_FIXEDLENGTH;
931 ERROR("FIXED LENGTH mode is not supported.");
932 goto shutdown;
933 } else {
934 ERROR("WRONG argument mode %s", row_mode);
935 goto shutdown;
936 }
937
938 if( (ivahd_decode_type != IVAHD_H264_DECODE) && (datamode != IVIDEO_ENTIREFRAME) ) {
939 ERROR("WRONG argument codec type %s mode %s", vid_codec, row_mode);
940 goto shutdown;
941 }
942
705 DEBUG("Storing frame size data"); 943 DEBUG("Storing frame size data");
706 frameFile = fopen(frameData, "rb"); 944 frameFile = fopen(frameData, "rb");
707 DEBUG("frameFile open %p errno %d", frameFile, errno); 945 DEBUG("frameFile open %p errno %d", frameFile, errno);
@@ -723,11 +961,11 @@ int main(int argc, char * *argv)
723 } 961 }
724 } 962 }
725 963
726 DEBUG("Num Frames is %d width=%d, height=%d", frameCount, width, height); 964 DEBUG("Num Frames is %d orig_width=%d, orig_height=%d width=%d height=%d", frameCount, orig_width, orig_height, width, height);
727 965
728 /* calculate output buffer parameters: */ 966 /* calculate output buffer parameters: */
729 width = ALIGN2(width, 4); /* round up to MB */ 967 width = ALIGN2(orig_width, 4); /* round up to MB */
730 height = ALIGN2(height, 4); /* round up to MB */ 968 height = ALIGN2(orig_height, 4); /* round up to MB */
731 969
732 switch( codec_switch ) { 970 switch( codec_switch ) {
733 case DCE_TEST_H264 : 971 case DCE_TEST_H264 :
@@ -741,7 +979,7 @@ int main(int argc, char * *argv)
741 case DCE_TEST_MPEG4 : 979 case DCE_TEST_MPEG4 :
742 padded_width = ALIGN2(width + PADX_MPEG4, 7); 980 padded_width = ALIGN2(width + PADX_MPEG4, 7);
743 padded_height = height + PADY_MPEG4; 981 padded_height = height + PADY_MPEG4;
744 num_buffers = 8; 982 num_buffers = 4;
745 break; 983 break;
746 case DCE_TEST_VC1SMP : 984 case DCE_TEST_VC1SMP :
747 case DCE_TEST_VC1AP : 985 case DCE_TEST_VC1AP :
@@ -767,8 +1005,8 @@ int main(int argc, char * *argv)
767 stride = 4096; 1005 stride = 4096;
768 } 1006 }
769 1007
770 DEBUG("padded_width=%d, padded_height=%d, stride=%d, num_buffers=%d", 1008 DEBUG("width=%d, height=%dpadded_width=%d, padded_height=%d, stride=%d, num_buffers=%d",
771 padded_width, padded_height, stride, num_buffers); 1009 width, height, padded_width, padded_height, stride, num_buffers);
772#ifdef PROFILE_TIME 1010#ifdef PROFILE_TIME
773 init_start_time = mark_microsecond(NULL); 1011 init_start_time = mark_microsecond(NULL);
774#endif 1012#endif
@@ -790,12 +1028,24 @@ int main(int argc, char * *argv)
790 } 1028 }
791 params->size = sizeof(IH264VDEC_Params); 1029 params->size = sizeof(IH264VDEC_Params);
792 params->maxBitRate = 10000000; 1030 params->maxBitRate = 10000000;
793 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO; 1031 if (datamode == IVIDEO_NUMROWS) {
794 params->numOutputDataUnits = 0; 1032 // Constraint: display order not being same as decode order with IVIDDEC3_Params::outputDataMode = IVIDEO_NUMROWS, is an erroneous situation
1033 params->displayDelay = IVIDDEC3_DECODE_ORDER;
1034 DEBUG("low latency with IVIDDEC3_DECODE_ORDER");
1035 // If outputDataMode == IVIDEO_NUMROWS, then it defines the frequency
1036 // at which decoder should inform to application about data availability.
1037 // For example, numOutputDataUnits = 2 means that after every 2MB row (2*16 lines)
1038 // availability in display buffer, decoder should inform to application.
1039 params->numOutputDataUnits = numBlock;
1040 } else if (datamode == IVIDEO_ENTIREFRAME) {
1041 params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
1042 params->numOutputDataUnits = 0;
1043 }
795 params->maxWidth = width; 1044 params->maxWidth = width;
1045
796 break; 1046 break;
797 case DCE_TEST_MPEG4 : 1047 case DCE_TEST_MPEG4 :
798 params = dce_alloc(sizeof(IMPEG4VDEC_Params)); 1048 params = dce_alloc(sizeof(IMPEG4VDEC_Params));
799 if( !params ) { 1049 if( !params ) {
800 ERROR("DCE_TEST_FAIL: Parameter memory allocation failed"); 1050 ERROR("DCE_TEST_FAIL: Parameter memory allocation failed");
801 goto out; 1051 goto out;
@@ -852,13 +1102,18 @@ int main(int argc, char * *argv)
852 params->dataEndianness = XDM_BYTE; 1102 params->dataEndianness = XDM_BYTE;
853 params->forceChromaFormat = XDM_YUV_420SP; 1103 params->forceChromaFormat = XDM_YUV_420SP;
854 params->operatingMode = IVIDEO_DECODE_ONLY; 1104 params->operatingMode = IVIDEO_DECODE_ONLY;
855 //params->displayDelay = IVIDDEC3_DECODE_ORDER;
856 params->displayBufsMode = IVIDDEC3_DISPLAYBUFS_EMBEDDED; 1105 params->displayBufsMode = IVIDDEC3_DISPLAYBUFS_EMBEDDED;
857 params->inputDataMode = IVIDEO_ENTIREFRAME; 1106 params->inputDataMode = IVIDEO_ENTIREFRAME;
858 params->metadataType[0] = IVIDEO_METADATAPLANE_NONE; 1107 params->metadataType[0] = IVIDEO_METADATAPLANE_NONE;
859 params->metadataType[1] = IVIDEO_METADATAPLANE_NONE; 1108 params->metadataType[1] = IVIDEO_METADATAPLANE_NONE;
860 params->metadataType[2] = IVIDEO_METADATAPLANE_NONE; 1109 params->metadataType[2] = IVIDEO_METADATAPLANE_NONE;
861 params->outputDataMode = IVIDEO_ENTIREFRAME; 1110
1111 if (datamode == IVIDEO_NUMROWS) {
1112 params->outputDataMode = IVIDEO_NUMROWS;
1113 } else if (datamode == IVIDEO_ENTIREFRAME) {
1114 params->outputDataMode = IVIDEO_ENTIREFRAME;
1115 }
1116
862 params->numInputDataUnits = 0; 1117 params->numInputDataUnits = 0;
863 params->errorInfoMode = IVIDEO_ERRORINFO_OFF; 1118 params->errorInfoMode = IVIDEO_ERRORINFO_OFF;
864 1119
@@ -952,6 +1207,11 @@ int main(int argc, char * *argv)
952 case DCE_TEST_H264 : 1207 case DCE_TEST_H264 :
953 dynParams = dce_alloc(sizeof(IH264VDEC_DynamicParams)); 1208 dynParams = dce_alloc(sizeof(IH264VDEC_DynamicParams));
954 dynParams->size = sizeof(IH264VDEC_DynamicParams); 1209 dynParams->size = sizeof(IH264VDEC_DynamicParams);
1210 if (datamode == IVIDEO_NUMROWS) {
1211 dynParams->putDataFxn = (XDM_DataSyncPutFxn) H264D_MPU_PutDataFxn;
1212 dynParams->putDataHandle = codec;
1213 DEBUG("dynParams->putDataFxn %p dynParams->putDataHandle 0x%x", dynParams->putDataFxn, (unsigned int) dynParams->putDataHandle);
1214 }
955 break; 1215 break;
956 case DCE_TEST_MPEG4 : 1216 case DCE_TEST_MPEG4 :
957 dynParams = dce_alloc(sizeof(IMPEG4VDEC_DynamicParams)); 1217 dynParams = dce_alloc(sizeof(IMPEG4VDEC_DynamicParams));
@@ -991,8 +1251,9 @@ int main(int argc, char * *argv)
991#ifdef GETVERSION 1251#ifdef GETVERSION
992 // Allocating memory to store the Codec version information from Codec. 1252 // Allocating memory to store the Codec version information from Codec.
993 char *codec_version = NULL; 1253 char *codec_version = NULL;
1254 DEBUG("Codec version Size %d ", sizeof(VERSION_SIZE));
994 codec_version = dce_alloc(VERSION_SIZE); 1255 codec_version = dce_alloc(VERSION_SIZE);
995 DEBUG("codec_version 0x%x", codec_version); 1256 DEBUG("codec_version 0x%x", (unsigned int) codec_version);
996#endif 1257#endif
997 1258
998 switch( codec_switch ) { 1259 switch( codec_switch ) {
@@ -1144,10 +1405,11 @@ int main(int argc, char * *argv)
1144 1405
1145 DEBUG("VIDDEC3_control XDM_SETPARAMS successful"); 1406 DEBUG("VIDDEC3_control XDM_SETPARAMS successful");
1146 1407
1147 DEBUG("input buffer configuration width %d height %d", width, height); 1408 DEBUG("input buffer configuration orig_width %d orig_height %d width %d height %d", orig_width, orig_height, width, height);
1409
1148 inBufs = dce_alloc(sizeof(XDM2_BufDesc)); 1410 inBufs = dce_alloc(sizeof(XDM2_BufDesc));
1149 inBufs->numBufs = 1; 1411 inBufs->numBufs = 1;
1150 input = dce_alloc(width * height); 1412 input = dce_alloc(orig_width * orig_height);
1151 inBufs->descs[0].buf = (XDAS_Int8 *)input; 1413 inBufs->descs[0].buf = (XDAS_Int8 *)input;
1152 inBufs->descs[0].memType = XDM_MEMTYPE_RAW; 1414 inBufs->descs[0].memType = XDM_MEMTYPE_RAW;
1153 1415
@@ -1174,6 +1436,27 @@ int main(int argc, char * *argv)
1174 padded_width, padded_height, stride); 1436 padded_width, padded_height, stride);
1175 } 1437 }
1176 1438
1439 if (datamode == IVIDEO_NUMROWS) {
1440 y_buffer = dce_alloc(width * height);
1441 if (!y_buffer) {
1442 ERROR("Failed to allocate luma buffer for temporary Y buffer on Low Latency case");
1443 goto shutdown;
1444 }
1445 orig_y_buffer = y_buffer;
1446 uv_buffer = dce_alloc(width * height/2);
1447 if (!uv_buffer) {
1448 ERROR("Failed to allocate chroma buffer for temporary UV buffer on Low Latency case");
1449 goto shutdown;
1450 }
1451 orig_uv_buffer = uv_buffer;
1452
1453 if (tiler) {
1454 output_uv_offset = output_y_offset + (4096 * height);
1455 } else {
1456 output_uv_offset = output_y_offset + (width * height);
1457 }
1458 }
1459
1177#ifdef PROFILE_TIME 1460#ifdef PROFILE_TIME
1178 output_alloc_time = mark_microsecond(&alloc_time_start); 1461 output_alloc_time = mark_microsecond(&alloc_time_start);
1179#endif 1462#endif
@@ -1344,20 +1627,28 @@ int main(int argc, char * *argv)
1344 fflush(inputDump); 1627 fflush(inputDump);
1345 fclose(inputDump); 1628 fclose(inputDump);
1346 inputDump = NULL; 1629 inputDump = NULL;
1347 #endif 1630#endif
1348 1631
1349 int iters = 0; 1632 int iters = 0;
1350 1633
1351 do { 1634 do {
1352 DEBUG("Calling VIDDEC3_process inArgs->inputID=%x inBufs->descs[0].buf %p inBufs->descs.bufSize %d input %p", 1635 DEBUG("Calling VIDDEC3_process inArgs->inputID=%d inBufs->descs[0].buf %p inBufs->descs.bufSize %d input %p",
1353 inArgs->inputID, inBufs->descs[0].buf, (int) inBufs->descs[0].bufSize.bytes, input); 1636 inArgs->inputID, inBufs->descs[0].buf, (int) inBufs->descs[0].bufSize.bytes, input);
1354#ifdef PROFILE_TIME 1637#ifdef PROFILE_TIME
1355 codec_process_time = mark_microsecond(NULL); 1638 codec_process_time = mark_microsecond(NULL);
1356#endif 1639#endif
1640
1641 if (datamode == IVIDEO_NUMROWS) {
1642 outBuf_lowlatency = (Char*) outBufs->descs[0].buf;
1643 DEBUG("Before calling VIDDEC3_process checking outBufs %p outBufs->descs[0].buf %p outBuf_lowlatency %p",
1644 outBufs, outBufs->descs[0].buf, outBuf_lowlatency);
1645 }
1646
1357 err = VIDDEC3_process(codec, inBufs, outBufs, inArgs, outArgs); 1647 err = VIDDEC3_process(codec, inBufs, outBufs, inArgs, outArgs);
1358#ifdef PROFILE_TIME 1648#ifdef PROFILE_TIME
1359 INFO("processed returned in: %llu us", (uint64_t) mark_microsecond(&codec_process_time)); 1649 INFO("processed returned in: %llu us", (uint64_t) mark_microsecond(&codec_process_time));
1360#endif 1650#endif
1651 DEBUG("VIDDEC3_process complete");
1361 if( err == DCE_EXDM_FAIL ) { 1652 if( err == DCE_EXDM_FAIL ) {
1362 if( XDM_ISFATALERROR(outArgs->extendedError)) { 1653 if( XDM_ISFATALERROR(outArgs->extendedError)) {
1363 ERROR("process returned error: %d\n", err); 1654 ERROR("process returned error: %d\n", err);
@@ -1400,51 +1691,62 @@ int main(int argc, char * *argv)
1400 goto shutdown; 1691 goto shutdown;
1401 } 1692 }
1402 1693
1403 /* 1694 if (datamode == IVIDEO_ENTIREFRAME) {
1404 * Handling of output data from codec 1695 /*
1405 */ 1696 * Handling of output data from codec
1406 if( tiler ) { 1697 */
1407 for( i = 0; outArgs->outputID[i]; i++ ) { 1698 DEBUG("low latency check outArgs->outputID[0] %p", (void*) outArgs->outputID[0]);
1408 /* calculate offset to region of interest */ 1699 if( tiler ) {
1409 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion); 1700 for( i = 0; outArgs->outputID[i]; i++ ) {
1701 /* calculate offset to region of interest */
1702 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
1703
1704 int yoff = (r->topLeft.y * stride) + r->topLeft.x;
1705 int uvoff = (r->topLeft.y * stride / 2) + (stride * padded_height) + r->topLeft.x;
1410 1706
1411 int yoff = (r->topLeft.y * stride) + r->topLeft.x; 1707 /* get the output buffer and write it to file */
1412 int uvoff = (r->topLeft.y * stride / 2) + (stride * padded_height) + r->topLeft.x; 1708 buf = (OutputBuffer *)outArgs->outputID[i];
1709 DEBUG("pop: %d (%p)", out_cnt, buf);
1413 1710
1414 /* get the output buffer and write it to file */ 1711 DEBUG("TILER buf->buf %p yoff 0x%x uvoff 0x%x", buf->buf, yoff, uvoff);
1415 buf = (OutputBuffer *)outArgs->outputID[i];
1416 DEBUG("pop: %d (%p)", out_cnt, buf);
1417 1712
1418 if( out_cnt < frames_to_write ) { // write first 30 frames to output file out_cnt < 300 1713 if( out_cnt < frames_to_write ) { // write first 30 frames to output file out_cnt < 300
1419 write_output(out_pattern, out_cnt++, buf->buf + yoff, 1714 write_output(out_pattern, out_cnt++, buf->buf + yoff,
1420 buf->buf + uvoff, stride); 1715 buf->buf + uvoff, stride);
1421 } else { 1716 } else {
1422 out_cnt++; 1717 out_cnt++;
1718 }
1423 } 1719 }
1424 } 1720 } else {
1425 } else { 1721 for( i = 0; outArgs->outputID[i]; i++ ) {
1426 for( i = 0; outArgs->outputID[i]; i++ ) { 1722 /* calculate offset to region of interest */
1427 /* calculate offset to region of interest */ 1723 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion);
1428 XDM_Rect *r = &(outArgs->displayBufs.bufDesc[0].activeFrameRegion); 1724
1725 int yoff = (r->topLeft.y * padded_width) + r->topLeft.x;
1726 int uvoff = (r->topLeft.y * padded_width / 2) + (padded_height * padded_width) + r->topLeft.x;
1429 1727
1430 int yoff = (r->topLeft.y * padded_width) + r->topLeft.x; 1728 /* get the output buffer and write it to file */
1431 int uvoff = (r->topLeft.y * padded_width / 2) + (padded_height * padded_width) + r->topLeft.x; 1729 buf = (OutputBuffer *)outArgs->outputID[i];
1730 DEBUG("pop: %d (%p)", out_cnt, buf);
1432 1731
1433 /* get the output buffer and write it to file */ 1732 DEBUG("NONTILER buf->buf %p yoff 0x%x uvoff 0x%x", buf->buf, yoff, uvoff);
1434 buf = (OutputBuffer *)outArgs->outputID[i];
1435 DEBUG("pop: %d (%p)", out_cnt, buf);
1436 1733
1437 if( out_cnt < frames_to_write ) { // write first frames_to_write frames to output file as 1734 if( out_cnt < frames_to_write ) { // write first frames_to_write frames to output file as
1438 write_output(out_pattern, out_cnt++, buf->buf + yoff, 1735 write_output(out_pattern, out_cnt++, buf->buf + yoff,
1439 buf->buf + uvoff, padded_width); 1736 buf->buf + uvoff, padded_width);
1440 } else { 1737 } else {
1441 out_cnt++; 1738 out_cnt++;
1739 }
1442 } 1740 }
1443 } 1741 }
1444 } 1742 }
1445 1743
1744 if (datamode == IVIDEO_NUMROWS) {
1745 DEBUG("Check outArgs->freeBufID[0] %p", (void*) outArgs->freeBufID[0]);
1746 }
1747
1446 for( i = 0; outArgs->freeBufID[i]; i++ ) { 1748 for( i = 0; outArgs->freeBufID[i]; i++ ) {
1447 DEBUG("freeBufID[%d] = %d", i, outArgs->freeBufID[i]); 1749 DEBUG("freeBufID[%d] = %p", i, (void*) outArgs->freeBufID[i]);
1448 buf = (OutputBuffer *)outArgs->freeBufID[i]; 1750 buf = (OutputBuffer *)outArgs->freeBufID[i];
1449 output_release(buf); 1751 output_release(buf);
1450 } 1752 }
@@ -1463,8 +1765,10 @@ int main(int argc, char * *argv)
1463 1765
1464shutdown: 1766shutdown:
1465 1767
1466 printf("\nDeleting codec...\n"); 1768 printf("\nDeleting codec 0x%x...\n", (unsigned int) codec);
1467 VIDDEC3_delete(codec); 1769 if( codec ) {
1770 VIDDEC3_delete(codec);
1771 }
1468 1772
1469out: 1773out:
1470 if( engine ) { 1774 if( engine ) {
@@ -1495,6 +1799,16 @@ out:
1495 dce_free(input); 1799 dce_free(input);
1496 } 1800 }
1497 1801
1802 if (datamode == IVIDEO_NUMROWS) {
1803 if (y_buffer) {
1804 dce_free(y_buffer);
1805 }
1806
1807 if (uv_buffer) {
1808 dce_free(uv_buffer);
1809 }
1810 }
1811
1498 output_free(); 1812 output_free();
1499 1813
1500 fclose(frameFile); 1814 fclose(frameFile);
diff --git a/test_qnx/dce_test/dce_test.use b/test_qnx/dce_test/dce_test.use
index 45165a0..627c979 100644
--- a/test_qnx/dce_test/dce_test.use
+++ b/test_qnx/dce_test/dce_test.use
@@ -12,27 +12,28 @@ Options:
12 12
13Examples: 13Examples:
141. decoding h.264 141. decoding h.264
15 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 15 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler numrow/slice/fixed/full
16 dce_test 320 240 30 framesize.txt inputfile.h264 outputfile.yuv h264 tiler 16 dce_test 320 240 30 framesize.txt inputfile.h264 outputfile.yuv h264 tiler full
17 dce_test 320 240 30 framesize.txt inputfile.h264 low_numrow.yuv h264 tiler numrow
17 18
182. decoding mpeg4 192. decoding mpeg4
19 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 20 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler full
20 dce_test 640 480 30 framesize.txt inputfile.m4v outputfile.yuv mpeg4 nontiler 21 dce_test 640 480 30 framesize.txt inputfile.m4v outputfile.yuv mpeg4 nontiler full
21 22
223. decoding vc1ap 233. decoding vc1ap
23 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 24 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler full
24 dce_test 720 480 30 framesize.txt inputfile.vc1 outputfile.yuv vc1ap tiler 25 dce_test 720 480 30 framesize.txt inputfile.vc1 outputfile.yuv vc1ap tiler full
25 26
264. decoding vc1smp 274. decoding vc1smp
27 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 28 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler full
28 dce_test 320 240 30 framesize.txt inputfile.vc1 outputfile.yuv vc1smp nontiler 29 dce_test 320 240 30 framesize.txt inputfile.vc1 outputfile.yuv vc1smp nontiler full
29 30
305. decoding mjpeg 315. decoding mjpeg
31 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 32 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler full
32 dce_test 1280 720 30 framesize.txt inputfile.bin outputfile.yuv mjpeg tiler 33 dce_test 1280 720 30 framesize.txt inputfile.bin outputfile.yuv mjpeg tiler full
33 34
346. decoding mpeg2 356. decoding mpeg2
35 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler 36 dce_test width height frames_to_write framesize inpattern outpattern codec tiler/nontiler full
36 dce_test 1920 1088 30 framesize.txt inputfile.bin outputfile.yuv mpeg2 nontiler 37 dce_test 1920 1088 30 framesize.txt inputfile.bin outputfile.yuv mpeg2 nontiler full
37 38
38Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2 39Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2