diff options
author | Buddy Liong | 2015-11-24 16:32:11 -0600 |
---|---|---|
committer | Buddy Liong | 2016-03-01 17:11:16 -0600 |
commit | 4cde6d994029b7a442bc2e32f161ca3aa284f6fa (patch) | |
tree | fa0c79a6f6fea7f64dcb512f11395a83eabe94a9 | |
parent | e05d0b506a8f5e9218449d3952ee6c1d327fddb5 (diff) | |
download | repo-libdce-4cde6d994029b7a442bc2e32f161ca3aa284f6fa.tar.gz repo-libdce-4cde6d994029b7a442bc2e32f161ca3aa284f6fa.tar.xz repo-libdce-4cde6d994029b7a442bc2e32f161ca3aa284f6fa.zip |
H.264 low latency with IVIDEO_NUMROWS
H.264 codec user guide describes the functionality of low latency.
This functionality allows user to encode/decode a sub-frame level data
communications. Without low latency, user can only encode/decode a
complete/full frame only.
More information about H264 low latency can be found in codec release
package:
* H.264 Encoder 2.0 on HDVICP2 and Media Controller Based Platform
User's Guide (SPRUHG3), Appendix G - Low Latency / Sub Frame Level
Synchronization
* H.264 Decoder 2.0 on HDVICP2 and Media Controller Based Platform
User's Guide (SPRUHF9), Appendix I - Low Latency / Sub Frame Level
Synchronization
This commit is only implemented low latency with IVIDEO_NUMROWS.
H.264 encoder handles inputDataMode = IVIDEO_NUMROWS with getDataFxn
as callback to get the numRows being filled into the inputBuffer pointer
passed at process call.
From H.264 encoder user guide Appendix G, more details can be found in
sec. G2 H.264 Encoder Input with sub frame level synchronization
H.264 decoder handles outputDataMode = IVIDEO_NUMROWS with putDataFxn as
callback to notify client on the numRows/numBlocks being filled by codec
into the outputBuffer pointer passed at process call.
From H.264 decoder user guide Appendix I, more details can be found in
sec. I.2 Details of using Sub Frame Level data sync at output side.
The update is only valid on video codec on IVA-HD.
This changes depend on the changes done on IPUMM DCE server.
No low latency update is performed on video codec on DSP.
This commit has dependencies on:
IPC 3.42.00.02 or latest
IPUMM commit ids:
commit e37750cc921a9442c48e7212824b28850ac3aaa7
- H.264 low latency - IVIDEO_NUMROWS
commit 266749c0b6a2584d563625f881f998c3d78ca873
- Handling when MPU crashes, eg. CTRL-C on MPU side.
commit 030572aaa1964bb50a903852fab0ecc0149b6b7e
- H.264 Low Latency - sync put_DataFxn to MPU side
Change-Id: I308bc74a879099f38705df6e6dda4a86b6645986
Signed-off-by: Buddy Liong <buddy.liong@ti.com>
-rw-r--r-- | dce_priv.h | 6 | ||||
-rw-r--r-- | dce_rpc.h | 6 | ||||
-rw-r--r-- | libdce.c | 672 | ||||
-rw-r--r-- | test_qnx/dce_enc_test/dce_enc_test.c | 766 | ||||
-rw-r--r-- | test_qnx/dce_enc_test/dce_enc_test.use | 44 | ||||
-rw-r--r-- | test_qnx/dce_test/dce_test.c | 460 | ||||
-rw-r--r-- | test_qnx/dce_test/dce_test.use | 25 |
7 files changed, 1546 insertions, 433 deletions
@@ -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 | ||
@@ -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 | ||
67 | typedef 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 | ||
67 | typedef enum dce_codec_type { | 73 | typedef enum dce_codec_type { |
68 | OMAP_DCE_VIDENC2 = 1, | 74 | OMAP_DCE_VIDENC2 = 1, |
@@ -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 */ |
51 | MmRpc_Handle MmRpcHandle[MAX_REMOTEDEVICES] = { NULL}; | 51 | MmRpc_Handle MmRpcHandle[MAX_REMOTEDEVICES] = { NULL}; |
52 | Engine_Handle gEngineHandle[MAX_INSTANCES][MAX_REMOTEDEVICES] = { {NULL, NULL}}; | 52 | Engine_Handle gEngineHandle[MAX_INSTANCES][MAX_REMOTEDEVICES] = { {NULL, NULL}}; |
53 | MmRpc_Handle MmRpcCallbackHandle = NULL; | ||
54 | static int MmRpcCallback_count = 0; | ||
53 | 55 | ||
54 | #ifdef BUILDOS_LINUX | 56 | #ifdef BUILDOS_LINUX |
55 | pthread_mutex_t ipc_mutex; | 57 | pthread_mutex_t ipc_mutex; |
58 | pthread_mutex_t dce_callback_mutex; | ||
56 | #else | 59 | #else |
57 | pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER; | 60 | pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER; |
61 | static pthread_mutex_t dce_callback_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
58 | #endif | 62 | #endif |
59 | 63 | ||
60 | static int __ClientCount[MAX_REMOTEDEVICES] = {0}; | 64 | static int __ClientCount[MAX_REMOTEDEVICES] = {0}; |
61 | int dce_debug = DCE_DEBUG_LEVEL; | 65 | int dce_debug = DCE_DEBUG_LEVEL; |
62 | const String DCE_DEVICE_NAME[MAX_REMOTEDEVICES]= {"rpmsg-dce","rpmsg-dce-dsp"}; | 66 | const String DCE_DEVICE_NAME[MAX_REMOTEDEVICES]= {"rpmsg-dce","rpmsg-dce-dsp"}; |
67 | const String DCE_CALLBACK_NAME = "dce-callback"; | ||
68 | |||
69 | typedef 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 | |||
88 | static CallbackFlag callbackmsg[MAX_INSTANCES]; | ||
63 | 89 | ||
64 | /***************** INLINE FUNCTIONS ******************/ | 90 | /***************** INLINE FUNCTIONS ******************/ |
91 | static 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 | |||
102 | static 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 | |||
65 | static inline void Fill_MmRpc_fxnCtx(MmRpc_FxnCtx *fxnCtx, int fxn_id, int num_params, int num_xlts, MmRpc_Xlt *xltAry) | 115 | static 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 | ||
107 | static int __inline getCoreIndexFromName(String name) | 157 | static 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 | ||
120 | static int __inline getCoreIndexFromCodec(int codec_id) | 170 | static 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. */ | ||
221 | int 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 | |||
299 | EXIT: | ||
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. */ | ||
308 | int 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 | |||
382 | EXIT: | ||
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 | */ |
209 | void dce_ipc_deinit(int core, int tableIdx) | 427 | void 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 | ||
233 | static 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 | ||
354 | EXIT: | 558 | EXIT: |
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 | ||
417 | EXIT: | 617 | EXIT: |
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 | ||
471 | EXIT: | 665 | EXIT: |
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 | ||
542 | EXIT: | 730 | EXIT: |
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 | ||
766 | EXIT: | 948 | EXIT: |
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 | ||
803 | EXIT: | 979 | EXIT: |
804 | /*Relinquish IPC*/ | ||
805 | pthread_mutex_unlock(&ipc_mutex); | ||
806 | return; | 980 | return; |
807 | } | 981 | } |
808 | 982 | ||
@@ -810,27 +984,110 @@ EXIT: | |||
810 | VIDDEC3_Handle VIDDEC3_create(Engine_Handle engine, String name, | 984 | VIDDEC3_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 | |||
1045 | EXIT: | ||
1046 | /*Relinquish IPC*/ | ||
1047 | pthread_mutex_unlock(&ipc_mutex); | ||
818 | return (codec); | 1048 | return (codec); |
819 | } | 1049 | } |
820 | 1050 | ||
821 | XDAS_Int32 VIDDEC3_control(VIDDEC3_Handle codec, VIDDEC3_Cmd id, | 1051 | XDAS_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 | ||
850 | Void VIDDEC3_delete(VIDDEC3_Handle codec) | 1160 | Void 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) | |||
858 | VIDENC2_Handle VIDENC2_create(Engine_Handle engine, String name, | 1206 | VIDENC2_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 | |||
1264 | EXIT: | ||
1265 | /*Relinquish IPC*/ | ||
1266 | pthread_mutex_unlock(&ipc_mutex); | ||
866 | return (codec); | 1267 | return (codec); |
867 | } | 1268 | } |
868 | 1269 | ||
869 | XDAS_Int32 VIDENC2_control(VIDENC2_Handle codec, VIDENC2_Cmd id, | 1270 | XDAS_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 | ||
898 | Void VIDENC2_delete(VIDENC2_Handle codec) | 1362 | Void 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 | |||
96 | typedef struct InputBuffer InputBuffer; | ||
97 | |||
98 | struct 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 | |||
107 | static InputBuffer *head = NULL; | ||
108 | |||
77 | enum { | 109 | enum { |
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; | |||
114 | IMPEG4ENC_Status *mpeg4enc_status = NULL; | 146 | IMPEG4ENC_Status *mpeg4enc_status = NULL; |
115 | 147 | ||
116 | unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ | 148 | unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ |
149 | int endOfFile = 0; | ||
150 | char *in_pattern, *out_pattern; | ||
151 | int in_cnt = 0, out_cnt = 0; | ||
152 | InputBuffer *buf = NULL; | ||
117 | static int input_offset = 0; | 153 | static int input_offset = 0; |
118 | 154 | ||
155 | #ifdef ROWMODE_INPUTDUMP | ||
156 | FILE *inputDump; | ||
157 | char Buff1[100]; | ||
158 | static int GlobalCount1 = 0; | ||
159 | static int read_input_count = 0; | ||
160 | #endif | ||
161 | |||
162 | #ifdef DUMPOUTPUTDATA | ||
163 | FILE *outputDump; | ||
164 | #endif | ||
165 | |||
166 | // This global only used in low latency IVIDEO_NUMROWS | ||
167 | static int numBlock = 10; | ||
168 | static int input_y_offset = 0; | ||
169 | static int input_uv_offset = 0; | ||
170 | static int dest_y_offset = 0; | ||
171 | static int dest_uv_offset = 0; | ||
172 | |||
119 | static void *tiler_alloc(int width, int height) | 173 | static 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 | /* ************************************************************************* */ | 253 | void input_free(void) |
200 | /* utilities to allocate/manage 2d input buffers */ | 254 | { |
255 | InputBuffer *buf = head; | ||
201 | 256 | ||
202 | typedef 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 | ||
204 | struct InputBuffer { | 269 | int 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 | |||
316 | int 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 | |||
365 | InputBuffer *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 | |||
377 | void 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 | 407 | int 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); |
239 | FILE *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. |
243 | FILE *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 */ |
248 | int read_input(const char *pattern, int cnt, char *input) | 520 | int 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 */ | ||
621 | XDAS_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 */ |
352 | int main(int argc, char * *argv) | 654 | int 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 | ||
1512 | shutdown: | 1786 | shutdown: |
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 | ||
1517 | out: | 1793 | out: |
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 | ||
40 | Examples: | 40 | Examples: |
41 | 1. Encoding h.264 | 41 | 1. 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 | |||
68 | 2. encoding Mpeg4 | 78 | 2. 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 | |||
83 | 3. Encoding H.263 | 100 | 3. 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 | ||
98 | Currently 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 | |||
122 | Currently 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 | |||
85 | enum { | 96 | enum { |
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 | ||
109 | static int numBlock = 2; | ||
110 | static int output_y_offset = 0; | ||
111 | static int output_uv_offset = 0; | ||
112 | static int numRow_y_offset = 0; | ||
113 | static int numRow_uv_offset = 0; | ||
114 | char *out_pattern; | ||
115 | char *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 | 121 | int orig_width, orig_height, width, height, frames_to_write, padded_width, padded_height, num_buffers, tiler; | |
102 | int width, height, frames_to_write, padded_width, padded_height, num_buffers, tiler; | ||
103 | Engine_Handle engine = NULL; | 122 | Engine_Handle engine = NULL; |
104 | VIDDEC3_Handle codec = NULL; | 123 | VIDDEC3_Handle codec = NULL; |
105 | VIDDEC3_Params *params = NULL; | 124 | VIDDEC3_Params *params = NULL; |
@@ -129,6 +148,7 @@ IJPEGVDEC_Status *mjpeg_status = NULL; | |||
129 | IMPEG2VDEC_Params *mpeg2_params = NULL; | 148 | IMPEG2VDEC_Params *mpeg2_params = NULL; |
130 | IMPEG2VDEC_DynamicParams *mpeg2_dynParams = NULL; | 149 | IMPEG2VDEC_DynamicParams *mpeg2_dynParams = NULL; |
131 | IMPEG2VDEC_Status *mpeg2_status = NULL; | 150 | IMPEG2VDEC_Status *mpeg2_status = NULL; |
151 | int out_cnt = 0; | ||
132 | 152 | ||
133 | unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ | 153 | unsigned int frameSize[64000]; /* Buffer for keeping frame sizes */ |
134 | static int input_offset = 0; | 154 | static 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! */ |
219 | static OutputBuffer *head = NULL; | 239 | static 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 | ||
522 | static int GlobalFileCount = 0; | ||
523 | #endif | ||
524 | static int total_numRows = 0; | ||
525 | //Create 2 temp buffers for Y and UV | ||
526 | char *y_buffer = NULL; | ||
527 | int y_buffer_offset = 0; | ||
528 | char *orig_y_buffer = NULL; | ||
529 | char *uv_buffer = NULL; | ||
530 | int uv_buffer_offset = 0; | ||
531 | char *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 */ | ||
534 | int 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 */ |
499 | int write_output(const char *pattern, int cnt, char *y, char *uv, int stride) | 648 | int 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. */ | ||
747 | XDAS_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 */ |
592 | int main(int argc, char * *argv) | 802 | int 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 | ||
1464 | shutdown: | 1766 | shutdown: |
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 | ||
1469 | out: | 1773 | out: |
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 | ||
13 | Examples: | 13 | Examples: |
14 | 1. decoding h.264 | 14 | 1. 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 | ||
18 | 2. decoding mpeg4 | 19 | 2. 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 | ||
22 | 3. decoding vc1ap | 23 | 3. 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 | ||
26 | 4. decoding vc1smp | 27 | 4. 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 | ||
30 | 5. decoding mjpeg | 31 | 5. 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 | ||
34 | 6. decoding mpeg2 | 35 | 6. 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 | ||
38 | Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2 | 39 | Currently supported codecs: h264, mpeg4, vc1ap, vc1smp, mjpeg, mpeg2 |