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
122typedef 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)                     \
140do {                                                        \
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)           \
147do {                                                        \
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)\
161do {                                                        \
162    _eError = _eCode;                                       \
163    goto OMX_CONF_CMD_BAIL;                                 \
164} while(0)
165
166#define OMX_VIDENC_SET_ERROR_BAIL(_eError, _eCode, _hComp)\
167do {                                                        \
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)             \
182do {                                                        \
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_)       \
196do {                                                        \
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_)       \
209do {                                                        \
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_)\
220do {                                                        \
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_)\
251do {                                                        \
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_) \
279do {                                                         \
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_)\
299do {                                                        \
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_)              \
330do {                                                        \
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_)       \
345do {                                            \
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_) \
356do {                                                        \
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)              \
370do {                                                        \
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)                          \
394do {                                                        \
395    OMX_VIDENC_ListRemove((&dbg), _h_, _p_);                \
396    _p_ = NULL;                                             \
397} while(0)
398
399typedef struct VIDENC_NODE
400{
401    OMX_PTR pData;
402    struct VIDENC_NODE* pNext;
403}VIDENC_NODE;
404
405typedef enum VIDEOENC_PORT_INDEX
406{
407    VIDENC_INPUT_PORT = 0x0,
408    VIDENC_OUTPUT_PORT
409} VIDEOENC_PORT_INDEX;
410
411/* Custom set/get param */
412typedef struct VIDENC_CUSTOM_DEFINITION
413{
414    OMX_U8 cCustomName[128];
415    OMX_INDEXTYPE nCustomIndex;
416} VIDENC_CUSTOM_DEFINITION;
417
418typedef 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
428typedef 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
436typedef 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
474typedef 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
482typedef 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
489typedef 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
499typedef 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
507typedef 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
529typedef enum OMX_EXTRADATATYPE
530{
531        OMX_ExtraDataNone = 0,
532        OMX_ExtraDataQuantization
533} OMX_EXTRADATATYPE;
534#endif
535
536typedef 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
546typedef 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/* ======================================================================= */
557pthread_mutex_t bufferReturned_mutex;
558pthread_cond_t bufferReturned_condition;
559
560/**
561 * The VIDENC_COMPONENT_PRIVATE data structure is used to store component's
562 *                              private data.
563 */
564typedef 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
711typedef OMX_ERRORTYPE (*fpo)(OMX_HANDLETYPE);
712
713/*--------function prototypes ---------------------------------*/
714
715#ifndef UNDER_CE
716    OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE hComp);
717#endif
718OMX_ERRORTYPE OMX_VIDENC_HandleLcmlEvent(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, TUsnCodecEvent eEvent, void* argsCb []);
719
720OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSet(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
721
722OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSet (VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
723
724OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetIdle(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
725
726OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetLoaded (VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
727
728OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetExecuting(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
729
730OMX_ERRORTYPE OMX_VIDENC_HandleCommandStateSetPause (VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
731
732OMX_ERRORTYPE OMX_VIDENC_HandleCommandFlush(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1, OMX_BOOL bInternalFlush);
733
734OMX_ERRORTYPE OMX_VIDENC_HandleCommandDisablePort(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
735
736OMX_ERRORTYPE OMX_VIDENC_HandleCommandEnablePort(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_U32 nParam1);
737
738OMX_ERRORTYPE OMX_VIDENC_Process_FilledInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
739
740OMX_ERRORTYPE OMX_VIDENC_Process_FilledOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead);
741
742OMX_ERRORTYPE OMX_VIDENC_Process_FreeInBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BUFFERHEADERTYPE* pBufHead);
743
744OMX_ERRORTYPE OMX_VIDENC_Process_FreeOutBuf(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
745
746OMX_ERRORTYPE OMX_VIDENC_InitLCML(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
747
748OMX_ERRORTYPE OMX_VIDENC_InitDSP_H264Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
749
750OMX_ERRORTYPE OMX_VIDENC_InitDSP_Mpeg4Enc(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
751
752OMX_ERRORTYPE OMX_VIDENC_LCML_Callback(TUsnCodecEvent event, void* argsCb [10]);
753
754OMX_ERRORTYPE OMX_VIDENC_Allocate_DSPResources (OMX_IN VIDENC_COMPONENT_PRIVATE* pComponentPrivate,
755                                                   OMX_IN OMX_U32 nPortIndex);
756void OMX_VIDENC_EmptyDataPipes (VIDENC_COMPONENT_PRIVATE *pComponentPrivate);
757
758OMX_ERRORTYPE OMX_VIDENC_ListCreate(struct OMX_TI_Debug *dbg, struct VIDENC_NODE** pListHead);
759
760OMX_ERRORTYPE OMX_VIDENC_ListAdd(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, OMX_PTR pData);
761
762OMX_ERRORTYPE OMX_VIDENC_ListRemove(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead, OMX_PTR pData);
763
764OMX_ERRORTYPE OMX_VIDENC_ListDestroy(struct OMX_TI_Debug *dbg, struct VIDENC_NODE* pListHead);
765
766OMX_ERRORTYPE OMX_VIDENC_HandleError(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_ERRORTYPE eError);
767#ifdef RESOURCE_MANAGER_ENABLED
768void OMX_VIDENC_ResourceManagerCallBack(RMPROXY_COMMANDDATATYPE cbData);
769#endif
770
771OMX_U32 GetMaxAVCBufferSize(OMX_U32 width, OMX_U32 height);
772
773OMX_U32 OMX_VIDENC_GetDefaultBitRate(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
774
775void printMpeg4Params(MP4VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs,
776                      struct OMX_TI_Debug *dbg);
777
778void printH264CreateParams(H264VE_GPP_SN_Obj_CreatePhase* pCreatePhaseArgs, struct OMX_TI_Debug *dbg);
779
780void printMpeg4UAlgInParam(MP4VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg);
781
782void printH264UAlgInParam(H264VE_GPP_SN_UALGInputParams* pUalgInpParams, int printAlways, struct OMX_TI_Debug *dbg);
783
784OMX_ERRORTYPE AddStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate);
785OMX_ERRORTYPE RemoveStateTransition(VIDENC_COMPONENT_PRIVATE* pComponentPrivate, OMX_BOOL bEnableSignal);
786
787void OMX_VIDENC_IncrementBufferCountByOne(OMX_U32 *count);
788void OMX_VIDEC_SignalIfAllBuffersAreReturned(VIDENC_COMPONENT_PRIVATE *pComponentPrivate);
789#endif
790