1 
2 /*
3  * Copyright (C) Texas Instruments - http://www.ti.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 /* =============================================================================
22 *             Texas Instruments OMAP(TM) Platform Software
23 *  (c) Copyright Texas Instruments, Incorporated.  All Rights Reserved.
24 *
25 *  Use of this software is controlled by the terms and conditions found
26 *  in the license agreement under which this software has been supplied.
27 * =========================================================================== */
28 /**
29 * @file OMX_VideoEnc_Utils.h
30 *
31 * This file implements OMX Component for MPEG-4 encoder that
32 * is fully compliant with the OMX specification 1.5.
33 *
34 * @path  $(CSLPATH)\inc
35 *
36 * @rev  0.1
37 */
38 /* -------------------------------------------------------------------------- */
39 /* =============================================================================
40 *!
41 *! Revision History
42 *! ================================================================
43 *!
44 *! 02-Feb-2006 mf: Revisions appear in reverse chronological order;
45 *! that is, newest first.  The date format is dd-Mon-yyyy.
46 * =========================================================================== */
47 
48 #ifndef OMX_VIDEOENC_UTILS__H
49 #define OMX_VIDEOENC_UTILS__H
50 
51 #include "LCML_DspCodec.h"
52 #include "LCML_Types.h"
53 #include "LCML_CodecInterface.h"
54 #ifdef RESOURCE_MANAGER_ENABLED
55 #include <ResourceManagerProxyAPI.h>
56 #endif
57 #include "OMX_VideoEnc_DSP.h"
58 #ifdef __PERF_INSTRUMENTATION__
59     #include "perf.h"
60     #endif
61 #include <OMX_TI_Debug.h>
62 #include <OMX_Component.h>
63 #ifdef LOG_TAG
64     #undef LOG_TAG
65 #endif
66 #define LOG_TAG "TI_OMX_VideoEnc"
67 
68 #ifdef UNDER_CE
69     #include <oaf_debug.h>
70     #include <pthread.h>
71 #endif
72 #include "OMX_TI_Common.h"
73 #include <utils/Log.h>
74 
75 /* this is the max of VIDENC_MAX_NUM_OF_IN_BUFFERS and VIDENC_MAX_NUM_OF_OUT_BUFFERS */
76 #define VIDENC_MAX_NUM_OF_BUFFERS     10
77 #define VIDENC_MAX_NUM_OF_IN_BUFFERS  10
78 #define VIDENC_MAX_NUM_OF_OUT_BUFFERS 10
79 #define VIDENC_NUM_OF_IN_BUFFERS  5
80 #define VIDENC_NUM_OF_OUT_BUFFERS 10
81 
82 #define VIDENC_NUM_OF_PORTS 2
83 
84 #define VIDENC_MAXBITRATES 7
85 
86 #if 1
87     #define GPP_PRIVATE_NODE_HEAP
88 #endif
89 
90 #if 1
91     #define __KHRONOS_CONF__
92 #endif
93 
94 #if 1
95     #define __KHRONOS_CONF_1_1__
96 #endif
97 
98 #define KHRONOS_1_2
99 
100 #define VIDENC_MAX_COMPONENT_TIMEOUT 0xFFFFFFFF
101 #define OMX_NOPORT 0xFFFFFFFE
102 #define MAXNUMSLCGPS 8  /*< max. number of slice groups*/
103 /* Remove after OMX 1.1 migration */
104 #ifndef __KHRONOS_CONF_1_1__
105     #define OMX_BUFFERFLAG_SYNCFRAME 0x00000040
106 #endif
107 #define OMX_LFRAMETYPE_H264 1
108 #define OMX_LFRAMETYPE_IDR_H264 4
109 #define OMX_CFRAMETYPE_MPEG4 1
110 /*Select Timeout */
111 #define  VIDENC_TIMEOUT_SEC 120;
112 #define  VIDENC_TIMEOUT_USEC 0;
113 #define WVGA_MAX_WIDTH 854
114 #define WVGA_MAX_HEIGHT WVGA_MAX_WIDTH
115 
116 /*
117 * Definition of capabilities index and structure
118 * Needed to inform OpenCore about component capabilities.
119 */
120 #define PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
121 
122 typedef struct PV_OMXComponentCapabilityFlagsType
123 {
124     /* OMX COMPONENT CAPABILITY RELATED MEMBERS*/
125     OMX_BOOL iIsOMXComponentMultiThreaded;
126     OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
127     OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
128     OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
129     OMX_BOOL iOMXComponentSupportsPartialFrames;
130     OMX_BOOL iOMXComponentUsesNALStartCode;
131     OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
132     OMX_BOOL iOMXComponentUsesFullAVCFrames;
133 } PV_OMXComponentCapabilityFlagsType;
134 
135 /*
136  * Redirects control flow in an error situation.
137  * The OMX_CONF_CMD_BAIL label is defined inside the calling function.
138  */
139 #define OMX_CONF_BAIL_IF_ERROR(_eError)                     \
140 do {                                                        \
141     if(_eError != OMX_ErrorNone) {                          \
142         goto OMX_CONF_CMD_BAIL;                             \
143         }                                                   \
144 } while(0)
145 
146 #define OMX_VIDENC_BAIL_IF_ERROR(_eError, _hComp)           \
147 do {                                                        \
148     if(_eError != OMX_ErrorNone) {  \
149         _eError = OMX_VIDENC_HandleError(_hComp, _eError);  \
150         if(_eError != OMX_ErrorNone) {                      \
151             OMX_ERROR5(_hComp->dbg, "*Fatal Error : %x\n", _eError); \
152             goto OMX_CONF_CMD_BAIL;                         \
153         }                                                   \
154     }                                                       \
155 } while(0)
156 
157 /*
158  * Sets error type and redirects control flow to error handling and cleanup section
159  */
160 #define OMX_CONF_SET_ERROR_BAIL(_eError, _eCode)\
161 do {                                                        \
162     _eError = _eCode;                                       \
163     goto OMX_CONF_CMD_BAIL;                                 \
164 } while(0)
165 
166 #define OMX_VIDENC_SET_ERROR_BAIL(_eError, _eCode, _hComp)\
167 do {                                                        \
168     _eError = _eCode;                                       \
169     OMX_ERROR5(_hComp->dbg, "*Fatal Error : %x\n", eError); \
170     OMX_VIDENC_HandleError(_hComp, _eError);                \
171     goto OMX_CONF_CMD_BAIL;                                 \
172 } while(0)
173 
174 /*
175  * Checking paramaters for non-NULL values.
176  * The macro takes three parameters because inside the code the highest
177  *   number of parameters passed for checking in a single instance is three.
178  * In case one or two parameters are passed, the ramaining parameters
179  *   are set to 1 (or a nonzero value).
180  */
181 #define OMX_CONF_CHECK_CMD(_ptr1, _ptr2, _ptr3)             \
182 do {                                                        \
183     if(!_ptr1 || !_ptr2 || !_ptr3){                         \
184         eError = OMX_ErrorBadParameter;                     \
185         goto OMX_CONF_CMD_BAIL;                             \
186     }                                                       \
187 } while(0)
188 
189 /*
190 * Initialize the Circular Buffer data. The Tail and Head pointers are NULL.
191 *The number of nodes inside the circular buffer is equal to zero.
192 *Also the number of nodes that contains BufferData is iqual zero.
193 *It should be in the ComponentInit call of the Component.
194 */
195 #define OMX_CONF_CIRCULAR_BUFFER_INIT(_pPrivateData_)       \
196 do {                                                        \
197     (_pPrivateData_)->sCircularBuffer.pHead = NULL;         \
198     (_pPrivateData_)->sCircularBuffer.pTail = NULL;         \
199     (_pPrivateData_)->sCircularBuffer.nElements = 0;        \
200         (_pPrivateData_)->sCircularBuffer.nFillElements = 0;\
201 } while(0)
202 
203 /*
204 *Restart the Circular Buffer. The tail points to the same node as the head. The
205 *number of fill elements is set to zero. It should be put in the Idle->Execution
206 *transition.
207 */
208 #define OMX_CONF_CIRCULAR_BUFFER_RESTART(_sCircular_)       \
209 do {                                                        \
210     (_sCircular_).pTail = (_sCircular_).pHead;              \
211     (_sCircular_).nFillElements = 0;                        \
212 } while(0)
213 
214 /*
215 *Add node to the Circular Buffer.  Should be use when UseBuffer or AllocateBuffer
216 *is call. The new node is insert in the head of the list. The it will go the last node
217 *and rewrite pNext with the new address of the Head.
218 */
219 #define OMX_CONF_CIRCULAR_BUFFER_ADD_NODE(_pPrivateData_, _sCircular_)\
220 do {                                                        \
221     if((_sCircular_).nElements < VIDENC_MAX_NUM_OF_BUFFERS) \
222     {                                                       \
223         OMX_U8 _i_ = 0;                                      \
224         OMX_CONF_CIRCULAR_BUFFER_NODE* pTmp = (_sCircular_).pHead;\
225         VIDENC_MALLOC( (_sCircular_).pHead,                 \
226                         sizeof(OMX_CONF_CIRCULAR_BUFFER_NODE),\
227                         OMX_CONF_CIRCULAR_BUFFER_NODE,      \
228                         (_pPrivateData_)->pMemoryListHead,  \
229                         (_pPrivateData_)->dbg);             \
230         (_sCircular_).nElements++;                          \
231         if(!pTmp){                                           \
232             (_sCircular_).pHead->pNext = (_sCircular_).pHead;\
233             (_sCircular_).pTail = (_sCircular_).pHead;      \
234         }                                                   \
235         else{                                               \
236             (_sCircular_).pHead->pNext = pTmp;              \
237             for(_i_=2 ; _i_ < (_sCircular_).nElements; _i_++) \
238                     pTmp = pTmp->pNext;                     \
239             pTmp->pNext = (_sCircular_).pHead;              \
240         }                                                   \
241     }                                                       \
242 } while(0)
243 
244 /*
245 * Will move the Tail of the Cirular Buffer to the next element. In the tail resides the last buffer to enter
246 *the component from the Application layer. It will get all the Data to be propageted from
247 * the pBufferHeader and write it in the node. Then it will move the Tail to the next element.
248 *It should be put in the function that handles the filled buffer from the application.
249 */
250 #define OMX_CONF_CIRCULAR_BUFFER_MOVE_TAIL(_pBufHead_, _sCircular_, _pPrivateData_)\
251 do {                                                        \
252     if((_pPrivateData_)->pMarkBuf){                        \
253         (_sCircular_).pTail->pMarkData = (_pPrivateData_)->pMarkBuf->pMarkData;\
254         (_sCircular_).pTail->hMarkTargetComponent = (_pPrivateData_)->pMarkBuf->hMarkTargetComponent;\
255         (_pPrivateData_)->pMarkBuf = NULL;                  \
256     }                                                       \
257     else{                                                   \
258         (_sCircular_).pTail->pMarkData = (_pBufHead_)->pMarkData; \
259         (_sCircular_).pTail->hMarkTargetComponent = (_pBufHead_)->hMarkTargetComponent;\
260     }                                                       \
261     (_sCircular_).pTail->nTickCount = (_pBufHead_)->nTickCount;\
262     (_sCircular_).pTail->nTimeStamp = (_pBufHead_)->nTimeStamp;\
263     (_sCircular_).pTail->nFlags = (_pBufHead_)->nFlags;      \
264     (_sCircular_).pTail = (_sCircular_).pTail->pNext;       \
265     (_sCircular_).nFillElements++;                          \
266     if(((_sCircular_).pTail == (_sCircular_).pHead) &&      \
267        ((_sCircular_).nFillElements != 0)){                 \
268         OMX_TRACE2((_pPrivateData_)->dbg, "**Warning:Circular Buffer Full.\n"); \
269     }                                                       \
270 } while(0)
271 
272 /*
273 *Will move the Head of the Circular Buffer to the next element. In the head is the Data of the first Buffer
274 *to enter to the Application layer. It will propagate the Data and put it in the pBufferHeader
275 *that goes to the Application layer. Then it will move the Head to the Next element.
276 *It should be put in the function that handles the filled buffers that comes from the DSP.
277 */
278 #define OMX_CONF_CIRCULAR_BUFFER_MOVE_HEAD(_pBufHead_, _sCircular_, _pPrivateData_) \
279 do {                                                         \
280     (_pBufHead_)->pMarkData = (_sCircular_).pHead->pMarkData;\
281     (_pBufHead_)->hMarkTargetComponent = (_sCircular_).pHead->hMarkTargetComponent;\
282     (_pBufHead_)->nTickCount = (_sCircular_).pHead->nTickCount;\
283     (_pBufHead_)->nTimeStamp = (_sCircular_).pHead->nTimeStamp;\
284     (_pBufHead_)->nFlags = (_sCircular_).pHead->nFlags;      \
285     (_sCircular_).pHead = (_sCircular_).pHead->pNext;       \
286     (_sCircular_).nFillElements--;                          \
287     if(((_sCircular_).pTail == (_sCircular_).pHead) &&      \
288        ((_sCircular_).nFillElements == 0)){                 \
289         OMX_TRACE1((_pPrivateData_)->dbg, "**Note:Circular Buffer Empty.\n"); \
290     }                                                       \
291 } while(0)
292 
293 /*
294 *This Macro will delete a node from the Circular Buffer. It will rearrenge the conections
295 *between the nodes, and restart the CircularBuffer. The Tail and Head will point to the same
296 *location and the nFillElement will be set to 0. It should be in the FreeBuffer call.
297 */
298 #define OMX_CONF_CIRCULAR_BUFFER_DELETE_NODE(_pPrivateData_, _sCircular_)\
299 do {                                                        \
300     OMX_CONF_CIRCULAR_BUFFER_NODE* pTmp1 = (_sCircular_).pHead;\
301     OMX_CONF_CIRCULAR_BUFFER_NODE* pTmp2 = NULL;            \
302     if(((_sCircular_).pHead != NULL) &&                     \
303        ((_sCircular_).pTail != NULL)){                      \
304         while(pTmp1->pNext != (_sCircular_).pHead){         \
305             pTmp2 = pTmp1;                                  \
306             pTmp1 = pTmp1->pNext;                           \
307         }                                                   \
308         VIDENC_FREE(pTmp1,(_pPrivateData_)->pMemoryListHead, (_pPrivateData_)->dbg); \
309         (_sCircular_).nElements--;                          \
310         (_sCircular_).nFillElements = 0;                    \
311         if(pTmp2 != NULL){                                  \
312             pTmp2->pNext = (_sCircular_).pHead;             \
313             (_sCircular_).pTail = (_sCircular_).pHead;      \
314         }                                                   \
315         else {                                              \
316             (_sCircular_).pHead = NULL;                     \
317             (_sCircular_).pTail = NULL;                     \
318         }                                                   \
319     }                                                       \
320 } while(0)
321 
322 /*
323  * Checking for version compliance.
324  * If the nSize of the OMX structure is not set, raises bad parameter error.
325  * In case of version mismatch, raises a version mismatch error.
326  */
327 
328 
329 #define OMX_CONF_CHK_VERSION(_s_, _name_, _e_)              \
330 do {                                                        \
331     if((_s_)->nSize != sizeof(_name_)) _e_ = OMX_ErrorBadParameter; \
332     if(((_s_)->nVersion.s.nVersionMajor != 0x1)||           \
333        ((_s_)->nVersion.s.nVersionMinor != 0x0)||           \
334        ((_s_)->nVersion.s.nRevision != 0x0)||               \
335        ((_s_)->nVersion.s.nStep != 0x0)) _e_ = OMX_ErrorVersionMismatch;\
336     if(_e_ != OMX_ErrorNone) goto OMX_CONF_CMD_BAIL;        \
337 } while(0)
338 
339 /*
340  * Initializes a data structure using a pointer to the structure.
341  * The initialization of OMX structures always sets up the nSize and nVersion fields
342  *   of the structure.
343  */
344 #define OMX_CONF_INIT_STRUCT(_s_, _name_)       \
345 do {                                            \
346     (_s_)->nSize = sizeof(_name_);              \
347     (_s_)->nVersion.s.nVersionMajor = 0x1;      \
348     (_s_)->nVersion.s.nVersionMinor = 0x0;      \
349     (_s_)->nVersion.s.nRevision     = 0x0;      \
350     (_s_)->nVersion.s.nStep         = 0x0;      \
351 } while(0)
352 
353 
354 /* Event Handler Macro*/
355 #define OMX_VIDENC_EVENT_HANDLER(_hComponent_, _eEvent_, _nData1_, _nData2_, _pEventData_) \
356 do {                                                        \
357     if((_hComponent_)->bHideEvents != OMX_TRUE )            \
358         (_hComponent_)->sCbData.EventHandler((_hComponent_)->pHandle, \
359                                             (_hComponent_)->pHandle->pApplicationPrivate, \
360                                             _eEvent_,       \
361                                             _nData1_,       \
362                                             _nData2_,       \
363                                             _pEventData_);  \
364                                                             \
365         OMX_PRINT1((_hComponent_)->dbg, "EventHandler : %lx : %lx : %lx \n", (OMX_U32) (_eEvent_), (OMX_U32) (_nData1_), (OMX_U32) (_nData2_)); \
366                                                             \
367 } while(0)
368 
369 #define VIDENC_MALLOC(_p_, _s_, _c_, _h_, dbg)              \
370 do {                                                        \
371     _p_ = (_c_*)malloc(_s_);                                \
372     if (_p_ == NULL) {                                      \
373         OMX_TRACE4(dbg, "malloc() error.\n");               \
374         eError = OMX_ErrorInsufficientResources;            \
375         goto OMX_CONF_CMD_BAIL;                             \
376     }                                                       \
377     else {                                                  \
378         OMX_TRACE1(dbg, "malloc() -> %p\n", _p_);           \
379     }                                                       \
380     memset((_p_), 0x0, _s_);                                \
381     if ((_p_) == NULL) {                                    \
382         OMX_TRACE4(dbg, "memset() error.\n");               \
383         eError = OMX_ErrorUndefined;                        \
384         goto OMX_CONF_CMD_BAIL;                             \
385     }                                                       \
386     eError = OMX_VIDENC_ListAdd(&(dbg), _h_, _p_);          \
387     if (eError == OMX_ErrorInsufficientResources) {         \
388         OMX_TRACE4(dbg, "malloc() error.\n");               \
389         goto OMX_CONF_CMD_BAIL;                             \
390     }                                                       \
391 } while(0)
392 
393 #define VIDENC_FREE(_p_, _h_, dbg)                          \
394 do {                                                        \
395     OMX_VIDENC_ListRemove((&dbg), _h_, _p_);                \
396     _p_ = NULL;                                             \
397 } while(0)
398 
399 typedef struct VIDENC_NODE
400 {
401     OMX_PTR pData;
402     struct VIDENC_NODE* pNext;
403 }VIDENC_NODE;
404 
405 typedef enum VIDEOENC_PORT_INDEX
406 {
407     VIDENC_INPUT_PORT = 0x0,
408     VIDENC_OUTPUT_PORT
409 } VIDEOENC_PORT_INDEX;
410 
411 /* Custom set/get param */
412 typedef struct VIDENC_CUSTOM_DEFINITION
413 {
414     OMX_U8 cCustomName[128];
415     OMX_INDEXTYPE nCustomIndex;
416 } VIDENC_CUSTOM_DEFINITION;
417 
418 typedef struct OMX_CONF_CIRCULAR_BUFFER_NODE
419 {
420     OMX_HANDLETYPE hMarkTargetComponent;
421     OMX_PTR pMarkData;
422     OMX_U32 nTickCount;
423     OMX_TICKS nTimeStamp;
424     OMX_U32 nFlags;
425     struct OMX_CONF_CIRCULAR_BUFFER_NODE* pNext;
426 } OMX_CONF_CIRCULAR_BUFFER_NODE;
427 
428 typedef struct OMX_CONF_CIRCULAR_BUFFER
429 {
430     struct OMX_CONF_CIRCULAR_BUFFER_NODE* pHead;
431     struct OMX_CONF_CIRCULAR_BUFFER_NODE* pTail;
432     OMX_U8 nElements;
433     OMX_U8 nFillElements;
434 } OMX_CONF_CIRCULAR_BUFFER;
435 
436 typedef enum VIDENC_CUSTOM_INDEX
437 {
438     #ifdef KHRONOS_1_2
439         VideoEncodeCustomParamIndexVBVSize = OMX_IndexVendorStartUnused,
440     #else
441         VideoEncodeCustomParamIndexVBVSize = OMX_IndexIndexVendorStartUnused,
442     #endif
443     VideoEncodeCustomParamIndexDeblockFilter,
444     VideoEncodeCustomConfigIndexForceIFrame,
445     VideoEncodeCustomConfigIndexIntraFrameInterval,
446     VideoEncodeCustomConfigIndexTargetFrameRate,
447     VideoEncodeCustomConfigIndexQPI,
448     VideoEncodeCustomConfigIndexAIRRate,
449     VideoEncodeCustomConfigIndexUnrestrictedMV,
450     /*Segment mode Metadata*/
451     VideoEncodeCustomConfigIndexMVDataEnable,
452     VideoEncodeCustomConfigIndexResyncDataEnable,
453     /*ASO*/
454     VideoEncodeCustomConfigIndexNumSliceASO,
455     VideoEncodeCustomConfigIndexAsoSliceOrder,
456     /*FMO*/
457     VideoEncodeCustomConfigIndexNumSliceGroups,
458     VideoEncodeCustomConfigIndexSliceGroupMapType,
459     VideoEncodeCustomConfigIndexSliceGroupChangeDirectionFlag,
460     VideoEncodeCustomConfigIndexSliceGroupChangeRate,
461     VideoEncodeCustomConfigIndexSliceGroupChangeCycle,
462     VideoEncodeCustomConfigIndexSliceGroupParams,
463     /*others*/
464     VideoEncodeCustomConfigIndexMIRRate,
465     VideoEncodeCustomConfigIndexMaxMVperMB,
466     VideoEncodeCustomConfigIndexIntra4x4EnableIdc,
467     /*only for H264*/
468     VideoEncodeCustomParamIndexEncodingPreset,
469     VideoEncodeCustomParamIndexNALFormat,
470     /* debug config */
471     VideoEncodeCustomConfigIndexDebug
472 } VIDENC_CUSTOM_INDEX;
473 
474 typedef enum VIDENC_BUFFER_OWNER
475 {
476     VIDENC_BUFFER_WITH_CLIENT = 0x0,
477     VIDENC_BUFFER_WITH_COMPONENT,
478     VIDENC_BUFFER_WITH_DSP,
479     VIDENC_BUFFER_WITH_TUNNELEDCOMP
480 } VIDENC_BUFFER_OWNER;
481 
482 typedef enum VIDENC_AVC_NAL_FORMAT
483 {
484     VIDENC_AVC_NAL_UNIT = 0,    /*Default, one buffer per frame, no NAL mode*/
485     VIDENC_AVC_NAL_SLICE,       /*One NAL unit per buffer, one or more NAL units conforms a Frame*/
486     VIDENC_AVC_NAL_FRAME        /*One frame per buffer, one or more NAL units inside the buffer*/
487 }VIDENC_AVC_NAL_FORMAT;
488 
489 typedef struct VIDENC_BUFFER_PRIVATE
490 {
491     OMX_PTR pMetaData;/*pointer to metadata structure, this structure is used when MPEG4 segment mode is enabled  */
492     OMX_BUFFERHEADERTYPE* pBufferHdr;
493     OMX_PTR pUalgParam;
494     VIDENC_BUFFER_OWNER eBufferOwner;
495     OMX_BOOL bAllocByComponent;
496     OMX_BOOL bReadFromPipe;
497 } VIDENC_BUFFER_PRIVATE;
498 
499 typedef struct VIDENC_MPEG4_SEGMENTMODE_METADATA
500 {
501     unsigned int mvDataSize;/*unsigned int*/
502     unsigned int numPackets;/*unsigned int*/
503     OMX_PTR pMVData;/*pointer to unsigned char MVData[3264]*/
504     OMX_PTR pResyncData;/*pointer to unsigned char ResyncData[5408]*/
505 }VIDENC_MPEG4_SEGMENTMODE_METADATA;
506 
507 typedef struct VIDEOENC_PORT_TYPE
508 {
509     OMX_U32 nBufferCnt;
510     OMX_U32 nTunnelPort;
511     OMX_HANDLETYPE hTunnelComponent;
512     OMX_BUFFERSUPPLIERTYPE eSupplierSetting;
513     OMX_PARAM_PORTDEFINITIONTYPE* pPortDef;
514     OMX_VIDEO_PARAM_PORTFORMATTYPE* pPortFormat;
515 
516 #ifdef __KHRONOS_CONF_1_1__
517     OMX_VIDEO_PARAM_PROFILELEVELTYPE* pProfileType;
518     OMX_CONFIG_FRAMERATETYPE* pFrameRateConfig;
519     OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateTypeConfig;
520     OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pErrorCorrectionType;
521     OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pIntraRefreshType;
522 #endif
523 
524     OMX_VIDEO_PARAM_BITRATETYPE* pBitRateType;
525     VIDENC_BUFFER_PRIVATE* pBufferPrivate[VIDENC_MAX_NUM_OF_BUFFERS];
526 } VIDEOENC_PORT_TYPE;
527 
528 #ifndef KHRONOS_1_2
529 typedef enum OMX_EXTRADATATYPE
530 {
531         OMX_ExtraDataNone = 0,
532         OMX_ExtraDataQuantization
533 } OMX_EXTRADATATYPE;
534 #endif
535 
536 typedef struct OMX_OTHER_EXTRADATATYPE_1_1_2
537 {
538     OMX_U32 nSize;
539     OMX_VERSIONTYPE nVersion;
540     OMX_U32 nPortIndex;
541     OMX_EXTRADATATYPE eType;
542     OMX_U32 nDataSize;
543     OMX_U8 data[1];
544 } OMX_OTHER_EXTRADATATYPE_1_1_2;
545 
546 typedef struct VIDEO_PROFILE_LEVEL
547 {
548     OMX_S32  nProfile;
549     OMX_S32  nLevel;
550 } VIDEO_PROFILE_LEVEL_TYPE;
551 
552 /* ======================================================================= */
553 /**
554  * pthread variable to indicate OMX returned all buffers to app
555  */
556 /* ======================================================================= */
557 pthread_mutex_t bufferReturned_mutex;
558 pthread_cond_t bufferReturned_condition;
559 
560 /**
561  * The VIDENC_COMPONENT_PRIVATE data structure is used to store component's
562  *                              private data.
563  */
564 typedef struct VIDENC_COMPONENT_PRIVATE
565 {
566     OMX_PORT_PARAM_TYPE* pPortParamType;
567     VIDEOENC_PORT_TYPE* pCompPort[VIDENC_NUM_OF_PORTS];
568 #ifdef __KHRONOS_CONF_1_1__
569     OMX_PORT_PARAM_TYPE* pPortAudioType;
570     OMX_PORT_PARAM_TYPE* pPortImageType;
571     OMX_PORT_PARAM_TYPE* pPortOtherType;
572 #endif
573 
574     OMX_PRIORITYMGMTTYPE* pPriorityMgmt;
575     OMX_VIDEO_PARAM_AVCTYPE* pH264;
576     OMX_VIDEO_CONFIG_AVCINTRAPERIOD*  pH264IntraPeriod;  /* for intraFrameInterval */
577     OMX_VIDEO_PARAM_MOTIONVECTORTYPE* pMotionVector;     /* for searchRange, maxMVperMB, qpi */
578     OMX_VIDEO_PARAM_MPEG4TYPE* pMpeg4;
579     OMX_VIDEO_PARAM_H263TYPE* pH263;
580     OMX_VIDEO_PARAM_BITRATETYPE* pVidParamBitrate;
581     OMX_VIDEO_PARAM_QUANTIZATIONTYPE* pQuantization;
582 
583     OMX_CALLBACKTYPE sCbData;
584     OMX_COMPONENTTYPE* pHandle;
585     OMX_STATETYPE eState;
586     OMX_VERSIONTYPE ComponentVersion;
587     OMX_VERSIONTYPE SpecVersion;
588     OMX_STRING cComponentName;
589     int nFree_oPipe[2];
590     int nFilled_iPipe[2];
591     int nCmdPipe[2];
592     int nCmdDataPipe[2];
593     void* pModLcml;
594     void* pLcmlHandle;
595     LCML_DSP_INTERFACE* pLCML;
596     int nFrameCnt;
597 #ifdef __PERF_INSTRUMENTATION__
598     PERF_OBJHANDLE pPERF, pPERFcomp;
599     OMX_U32 nLcml_nCntIp;
600     OMX_U32 nLcml_nCntOpReceived;
601 #endif
602     unsigned int nVBVSize;
603     OMX_MARKTYPE* pMarkBuf;
604     OMX_PTR pMarkData;
605     OMX_HANDLETYPE hMarkTargetComponent;
606     OMX_U32 nFlags;
607     /* these are duplicates */
608     unsigned int nIntraFrameInterval;  /* should be OMX_VIDEO_CONFIG_AVCINTRAPERIOD */
609     unsigned int nTargetFrameRate;  /* should be OMX_CONFIG_FRAMERATETYPE */
610     unsigned int nPrevTargetFrameRate;
611     unsigned int nQPI;              /* same as OMX_VIDEO_PARAM_QUANTIZATIONTYPE */
612     unsigned int nAIRRate;          /* same as OMX_VIDEO_PARAM_INTRAREFRESHTYPE */
613     unsigned int nTargetBitRate;    /* should be OMX_VIDEO_CONFIG_BITRATETYPE */
614     OMX_U32 nMIRRate;
615     OMX_U8  ucUnrestrictedMV;
616     OMX_BOOL bSentFirstSpsPps;
617     unsigned char *sps;
618     OMX_U32  spsLen;
619 
620     OMX_U32 nInBufferSize;
621     OMX_U32 nOutBufferSize;
622 #ifndef UNDER_CE
623     pthread_mutex_t mVideoEncodeBufferMutex;
624 #endif
625     OMX_BOOL bDeblockFilter;
626     OMX_BOOL bCodecStarted;
627     OMX_BOOL bCodecLoaded;
628     OMX_BOOL bDSPStopAck;
629     OMX_BOOL bForceIFrame;
630     OMX_BOOL bFlushComplete;
631     OMX_BOOL bHideEvents;
632     OMX_BOOL bHandlingFatalError;
633     OMX_BOOL bUnresponsiveDsp;
634     VIDENC_NODE*  pMemoryListHead;
635     OMX_CONF_CIRCULAR_BUFFER sCircularBuffer;
636 
637 #ifdef __KHRONOS_CONF__
638 #ifdef __KHRONOS_CONF_1_1__
639     OMX_PARAM_COMPONENTROLETYPE componentRole;
640 #endif
641     OMX_BOOL bPassingIdleToLoaded;
642     OMX_BOOL bErrorLcmlHandle;
643     pthread_t ComponentThread;
644 #endif
645 
646 /*ASO*/
647     OMX_U32 numSliceASO;
648     OMX_U32 asoSliceOrder[MAXNUMSLCGPS];
649 /*FMO*/
650     OMX_U32 numSliceGroups;
651     OMX_U32 sliceGroupMapType;
652     OMX_U32 sliceGroupChangeDirectionFlag;
653     OMX_U32 sliceGroupChangeRate;
654     OMX_U32 sliceGroupChangeCycle;
655     OMX_U32 sliceGroupParams[MAXNUMSLCGPS];
656 #ifndef UNDER_CE
657     pthread_mutex_t videoe_mutex;   /* pthread_cond_t  control_cond; */
658     pthread_mutex_t videoe_mutex_app;
659     pthread_cond_t  populate_cond;
660     pthread_cond_t  unpopulate_cond;
661     pthread_cond_t  stop_cond;
662     pthread_cond_t  flush_cond;
663 #else
664     OMX_Event AlloBuf_event;
665     OMX_U8 AlloBuf_waitingsignal;
666 
667     OMX_Event InLoaded_event;
668     OMX_U8 InLoaded_readytoidle;
669 
670     OMX_Event InIdle_event;
671     OMX_U8 InIdle_goingtoloaded;
672 #endif
673     unsigned int nEncodingPreset;
674     VIDENC_AVC_NAL_FORMAT AVCNALFormat;
675     OMX_BOOL bMVDataEnable;
676     OMX_BOOL bResyncDataEnable;
677     IH264VENC_Intra4x4Params intra4x4EnableIdc;
678     OMX_U32 maxMVperMB;
679 #ifdef RESOURCE_MANAGER_ENABLED
680     RMPROXY_CALLBACKTYPE cRMCallBack;
681 #endif
682     OMX_BOOL bPreempted;
683     OMX_VIDEO_CODINGTYPE compressionFormats[3];
684     OMX_COLOR_FORMATTYPE colorFormats[3];
685     struct OMX_TI_Debug dbg;
686     PV_OMXComponentCapabilityFlagsType* pCapabilityFlags;
687     /*Variables neded to manage the VOL header request*/
688     MP4VE_GPP_SN_UALGInputParams* pTempUalgInpParams;
689     OMX_BOOL bRequestVOLHeader;
690     OMX_BOOL bWaitingForVOLHeaderBuffer;
691     OMX_BOOL bWaitingVOLHeaderCallback;
692 
693     /* Reference count for pending state change requests */
694     OMX_U32 nPendingStateChangeRequests;
695     pthread_mutex_t mutexStateChangeRequest;
696     pthread_cond_t StateChangeCondition;
697 
698     /* Variable related to variabe frame rate settings */
699     OMX_TICKS nLastUpdateTime;          /* Timstamp of last framerate update */
700     OMX_U32   nFrameRateUpdateInterval; /* Unit is number of frames */
701     OMX_U32   nFrameCount;              /* Number of input frames received since last framerate update */
702     OMX_TICKS nVideoTime;               /* Video duration since last framerate update */
703 
704     OMX_U32 EmptybufferdoneCount;
705     OMX_U32 EmptythisbufferCount;
706     OMX_U32 FillbufferdoneCount;
707     OMX_U32 FillthisbufferCount;
708 
709 } VIDENC_COMPONENT_PRIVATE;
710 
711 typedef OMX_ERRORTYPE (*fpo)(OMX_HANDLETYPE);
712 
713 /*--------function prototypes ---------------------------------*/
714 
715 #ifndef UNDER_CE
716     OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComp);
717 #endif
718 OMX_ERRORTYPE OMX_VIDENC_HandleLcmlEvent(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, TUsnCodecEvent eEvent, void* argsCb []);
719 
720 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSet(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
721 
722 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSet (VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
723 
724 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
725 
726 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
727 
728 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetExecuting(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
729 
730 OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetPause (VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
731 
732 OMX_ERRORTYPE OMX_VIDENC_HandleCommandFlush(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1, OMX_BOOL bInternalFlush);
733 
734 OMX_ERRORTYPE OMX_VIDENC_HandleCommandDisablePort(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
735 
736 OMX_ERRORTYPE OMX_VIDENC_HandleCommandEnablePort(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
737 
738 OMX_ERRORTYPE OMX_VIDENC_Process_FilledInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
739 
740 OMX_ERRORTYPE OMX_VIDENC_Process_FilledOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead);
741 
742 OMX_ERRORTYPE OMX_VIDENC_Process_FreeInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead);
743 
744 OMX_ERRORTYPE OMX_VIDENC_Process_FreeOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
745 
746 OMX_ERRORTYPE OMX_VIDENC_InitLCML(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
747 
748 OMX_ERRORTYPE OMX_VIDENC_InitDSP_H264Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
749 
750 OMX_ERRORTYPE OMX_VIDENC_InitDSP_Mpeg4Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
751 
752 OMX_ERRORTYPE OMX_VIDENC_LCML_Callback(TUsnCodecEvent event, void* argsCb [10]);
753 
754 OMX_ERRORTYPE OMX_VIDENC_Allocate_DSPResources (OMX_IN VIDENC_COMPONENT_PRIVATE* pComponentPrivate,
755                                                    OMX_IN OMX_U32 nPortIndex);
756 void OMX_VIDENC_EmptyDataPipes (VIDENC_COMPONENT_PRIVATE *pComponentPrivate);
757 
758 OMX_ERRORTYPE OMX_VIDENC_ListCreate(struct OMX_TI_Debug *dbg, struct VIDENC_NODE** pListHead);
759 
760 OMX_ERRORTYPE OMX_VIDENC_ListAdd(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, OMX_PTR pData);
761 
762 OMX_ERRORTYPE OMX_VIDENC_ListRemove(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, OMX_PTR pData);
763 
764 OMX_ERRORTYPE OMX_VIDENC_ListDestroy(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead);
765 
766 OMX_ERRORTYPE OMX_VIDENC_HandleError(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_ERRORTYPE eError);
767 #ifdef RESOURCE_MANAGER_ENABLED
768 void OMX_VIDENC_ResourceManagerCallBack(RMPROXY_COMMANDDATATYPE cbData);
769 #endif
770 
771 OMX_U32 GetMaxAVCBufferSize(OMX_U32 width, OMX_U32 height);
772 
773 OMX_U32 OMX_VIDENC_GetDefaultBitRate(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
774 
775 void printMpeg4Params(MP4VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs,
776                       struct OMX_TI_Debug *dbg);
777 
778 void printH264CreateParams(H264VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs, struct OMX_TI_Debug *dbg);
779 
780 void printMpeg4UAlgInParam(MP4VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg);
781 
782 void printH264UAlgInParam(H264VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg);
783 
784 OMX_ERRORTYPE AddStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
785 OMX_ERRORTYPE RemoveStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal);
786 
787 void OMX_VIDENC_IncrementBufferCountByOne(OMX_U32 *count);
788 void OMX_VIDEC_SignalIfAllBuffersAreReturned(VIDENC_COMPONENT_PRIVATE *pComponentPrivate);
789 #endif
790