• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 
19 #include "omx_mpeg4enc_component.h"
20 
21 #if PROXY_INTERFACE
22 #include "omx_proxy_interface.h"
23 #endif
24 
25 
26 
27 // This function is called by OMX_GetHandle and it creates an instance of the mpeg4 component AO
Mpeg4EncOmxComponentFactory(OMX_OUT OMX_HANDLETYPE * pHandle,OMX_IN OMX_PTR pAppData,OMX_PTR pProxy,OMX_STRING aOmxLibName,OMX_PTR & aOmxLib,OMX_PTR aOsclUuid,OMX_U32 & aRefCount)28 OMX_ERRORTYPE Mpeg4EncOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* pHandle, OMX_IN OMX_PTR pAppData, OMX_PTR pProxy, OMX_STRING aOmxLibName, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
29 {
30     OSCL_UNUSED_ARG(aOmxLibName);
31     OSCL_UNUSED_ARG(aOmxLib);
32     OSCL_UNUSED_ARG(aOsclUuid);
33     OSCL_UNUSED_ARG(aRefCount);
34 
35 
36     OmxComponentMpeg4EncAO* pOpenmaxAOType;
37     OMX_ERRORTYPE Status;
38 
39     // move InitMpeg4OmxComponentFields content to actual constructor
40 
41     pOpenmaxAOType = (OmxComponentMpeg4EncAO*) OSCL_NEW(OmxComponentMpeg4EncAO, ());
42 
43     if (NULL == pOpenmaxAOType)
44     {
45         return OMX_ErrorInsufficientResources;
46     }
47 
48     // set encoding mode to H263
49     pOpenmaxAOType->SetEncoderMode(MODE_MPEG4);
50 
51     //Call the construct component to initialize OMX types
52     Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
53 
54     *pHandle = pOpenmaxAOType->GetOmxHandle();
55 
56     return Status;
57 }
58 
59 
60 // This function is called by OMX_FreeHandle when component AO needs to be destroyed
Mpeg4EncOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle,OMX_PTR & aOmxLib,OMX_PTR aOsclUuid,OMX_U32 & aRefCount)61 OMX_ERRORTYPE Mpeg4EncOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
62 {
63     OSCL_UNUSED_ARG(aOmxLib);
64     OSCL_UNUSED_ARG(aOsclUuid);
65     OSCL_UNUSED_ARG(aRefCount);
66 
67     // get pointer to component AO
68     OmxComponentMpeg4EncAO* pOpenmaxAOType = (OmxComponentMpeg4EncAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
69 
70     // clean up decoder, OMX component stuff
71     pOpenmaxAOType->DestroyComponent();
72 
73     // destroy the AO class
74     OSCL_DELETE(pOpenmaxAOType);
75 
76     return OMX_ErrorNone;
77 }
78 
79 
80 // This function is called by OMX_GetHandle and it creates an instance of the h263 component AO
H263EncOmxComponentFactory(OMX_OUT OMX_HANDLETYPE * pHandle,OMX_IN OMX_PTR pAppData,OMX_PTR pProxy,OMX_STRING aOmxLibName,OMX_PTR & aOmxLib,OMX_PTR aOsclUuid,OMX_U32 & aRefCount)81 OMX_ERRORTYPE H263EncOmxComponentFactory(OMX_OUT OMX_HANDLETYPE* pHandle, OMX_IN  OMX_PTR pAppData, OMX_PTR pProxy, OMX_STRING aOmxLibName, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
82 {
83     OSCL_UNUSED_ARG(aOmxLibName);
84     OSCL_UNUSED_ARG(aOmxLib);
85     OSCL_UNUSED_ARG(aOsclUuid);
86     OSCL_UNUSED_ARG(aRefCount);
87 
88 
89     OmxComponentMpeg4EncAO* pOpenmaxAOType;
90     OMX_ERRORTYPE Status;
91 
92     // move InitMpeg4OmxComponentFields content to actual constructor
93 
94     pOpenmaxAOType = (OmxComponentMpeg4EncAO*) OSCL_NEW(OmxComponentMpeg4EncAO, ());
95 
96     if (NULL == pOpenmaxAOType)
97     {
98         return OMX_ErrorInsufficientResources;
99     }
100 
101     // set encoding mode to H263
102     pOpenmaxAOType->SetEncoderMode(MODE_H263);
103 
104     //Call the construct component to initialize OMX types
105     Status = pOpenmaxAOType->ConstructComponent(pAppData, pProxy);
106 
107     *pHandle = pOpenmaxAOType->GetOmxHandle();
108 
109     return Status;
110     ///////////////////////////////////////////////////////////////////////////////////////
111 }
112 
113 
114 // This function is called by OMX_FreeHandle when component AO needs to be destroyed
H263EncOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle,OMX_PTR & aOmxLib,OMX_PTR aOsclUuid,OMX_U32 & aRefCount)115 OMX_ERRORTYPE H263EncOmxComponentDestructor(OMX_IN OMX_HANDLETYPE pHandle, OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount)
116 {
117     OSCL_UNUSED_ARG(aOmxLib);
118     OSCL_UNUSED_ARG(aOsclUuid);
119     OSCL_UNUSED_ARG(aRefCount);
120 
121     // get pointer to component AO
122     OmxComponentMpeg4EncAO* pOpenmaxAOType = (OmxComponentMpeg4EncAO*)((OMX_COMPONENTTYPE*)pHandle)->pComponentPrivate;
123 
124     // clean up decoder, OMX component stuff
125     pOpenmaxAOType->DestroyComponent();
126 
127     // destroy the AO class
128     OSCL_DELETE(pOpenmaxAOType);
129 
130     return OMX_ErrorNone;
131 }
132 
133 #if (DYNAMIC_LOAD_OMX_M4VENC_COMPONENT || DYNAMIC_LOAD_OMX_H263ENC_COMPONENT)
134 class Mpeg4H263EncOmxSharedLibraryInterface:  public OsclSharedLibraryInterface,
135         public OmxSharedLibraryInterface
136 
137 {
138     public:
QueryOmxComponentInterface(const OsclUuid & aOmxTypeId,const OsclUuid & aInterfaceId)139         OsclAny *QueryOmxComponentInterface(const OsclUuid& aOmxTypeId, const OsclUuid& aInterfaceId)
140         {
141             if (PV_OMX_M4VENC_UUID == aOmxTypeId)
142             {
143                 if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
144                 {
145                     return ((OsclAny*)(&Mpeg4EncOmxComponentFactory));
146                 }
147                 else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
148                 {
149                     return ((OsclAny*)(&Mpeg4EncOmxComponentDestructor));
150                 }
151             }
152             else if (PV_OMX_H263ENC_UUID == aOmxTypeId)
153             {
154                 if (PV_OMX_CREATE_INTERFACE == aInterfaceId)
155                 {
156                     return ((OsclAny*)(&H263EncOmxComponentFactory));
157                 }
158                 else if (PV_OMX_DESTROY_INTERFACE == aInterfaceId)
159                 {
160                     return ((OsclAny*)(&H263EncOmxComponentDestructor));
161                 }
162             }
163             return NULL;
164         };
165 
SharedLibraryLookup(const OsclUuid & aInterfaceId)166         OsclAny *SharedLibraryLookup(const OsclUuid& aInterfaceId)
167         {
168             if (aInterfaceId == PV_OMX_SHARED_INTERFACE)
169             {
170                 return OSCL_STATIC_CAST(OmxSharedLibraryInterface*, this);
171             }
172             return NULL;
173         };
174 
Mpeg4H263EncOmxSharedLibraryInterface()175         Mpeg4H263EncOmxSharedLibraryInterface() {};
176 };
177 
178 // function to obtain the interface object from the shared library
179 extern "C"
180 {
PVGetInterface()181     OSCL_EXPORT_REF OsclAny* PVGetInterface()
182     {
183         return (OsclAny*) OSCL_NEW(Mpeg4H263EncOmxSharedLibraryInterface, ());
184     }
185 
PVReleaseInterface(OsclSharedLibraryInterface * aInstance)186     OSCL_EXPORT_REF void PVReleaseInterface(OsclSharedLibraryInterface* aInstance)
187     {
188         Mpeg4H263EncOmxSharedLibraryInterface* module = (Mpeg4H263EncOmxSharedLibraryInterface*)aInstance;
189         OSCL_DELETE(module);
190     }
191 }
192 
193 #endif
194 
SetEncoderMode(OMX_S32 aMode)195 void OmxComponentMpeg4EncAO::SetEncoderMode(OMX_S32 aMode)
196 {
197     iEncMode = aMode;
198 }
199 
200 
201 
ConstructComponent(OMX_PTR pAppData,OMX_PTR pProxy)202 OMX_ERRORTYPE OmxComponentMpeg4EncAO::ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy)
203 {
204     ComponentPortType *pInPort, *pOutPort;
205     OMX_ERRORTYPE Status;
206 
207     iNumPorts = 2;
208     iCompressedFormatPortNum = OMX_PORT_OUTPUTPORT_INDEX;
209     iOmxComponent.nSize = sizeof(OMX_COMPONENTTYPE);
210     iOmxComponent.pComponentPrivate = (OMX_PTR) this;  // pComponentPrivate points to THIS component AO class
211     ipComponentProxy = pProxy;
212     iOmxComponent.pApplicationPrivate = pAppData; // init the App data
213 
214 
215 #if PROXY_INTERFACE
216     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_TRUE;
217 
218     iOmxComponent.SendCommand = OmxComponentMpeg4EncAO::BaseComponentProxySendCommand;
219     iOmxComponent.GetParameter = OmxComponentMpeg4EncAO::BaseComponentProxyGetParameter;
220     iOmxComponent.SetParameter = OmxComponentMpeg4EncAO::BaseComponentProxySetParameter;
221     iOmxComponent.GetConfig = OmxComponentMpeg4EncAO::BaseComponentProxyGetConfig;
222     iOmxComponent.SetConfig = OmxComponentMpeg4EncAO::BaseComponentProxySetConfig;
223     iOmxComponent.GetExtensionIndex = OmxComponentMpeg4EncAO::BaseComponentProxyGetExtensionIndex;
224     iOmxComponent.GetState = OmxComponentMpeg4EncAO::BaseComponentProxyGetState;
225     iOmxComponent.UseBuffer = OmxComponentMpeg4EncAO::BaseComponentProxyUseBuffer;
226     iOmxComponent.AllocateBuffer = OmxComponentMpeg4EncAO::BaseComponentProxyAllocateBuffer;
227     iOmxComponent.FreeBuffer = OmxComponentMpeg4EncAO::BaseComponentProxyFreeBuffer;
228     iOmxComponent.EmptyThisBuffer = OmxComponentMpeg4EncAO::BaseComponentProxyEmptyThisBuffer;
229     iOmxComponent.FillThisBuffer = OmxComponentMpeg4EncAO::BaseComponentProxyFillThisBuffer;
230 
231 #else
232     iPVCapabilityFlags.iIsOMXComponentMultiThreaded = OMX_FALSE;
233 
234     iOmxComponent.SendCommand = OmxComponentMpeg4EncAO::BaseComponentSendCommand;
235     iOmxComponent.GetParameter = OmxComponentMpeg4EncAO::BaseComponentGetParameter;
236     iOmxComponent.SetParameter = OmxComponentMpeg4EncAO::BaseComponentSetParameter;
237     iOmxComponent.GetConfig = OmxComponentMpeg4EncAO::BaseComponentGetConfig;
238     iOmxComponent.SetConfig = OmxComponentMpeg4EncAO::BaseComponentSetConfig;
239     iOmxComponent.GetExtensionIndex = OmxComponentMpeg4EncAO::BaseComponentGetExtensionIndex;
240     iOmxComponent.GetState = OmxComponentMpeg4EncAO::BaseComponentGetState;
241     iOmxComponent.UseBuffer = OmxComponentMpeg4EncAO::BaseComponentUseBuffer;
242     iOmxComponent.AllocateBuffer = OmxComponentMpeg4EncAO::BaseComponentAllocateBuffer;
243     iOmxComponent.FreeBuffer = OmxComponentMpeg4EncAO::BaseComponentFreeBuffer;
244     iOmxComponent.EmptyThisBuffer = OmxComponentMpeg4EncAO::BaseComponentEmptyThisBuffer;
245     iOmxComponent.FillThisBuffer = OmxComponentMpeg4EncAO::BaseComponentFillThisBuffer;
246 #endif
247 
248     iOmxComponent.SetCallbacks = OmxComponentMpeg4EncAO::BaseComponentSetCallbacks;
249     iOmxComponent.nVersion.s.nVersionMajor = SPECVERSIONMAJOR;
250     iOmxComponent.nVersion.s.nVersionMinor = SPECVERSIONMINOR;
251     iOmxComponent.nVersion.s.nRevision = SPECREVISION;
252     iOmxComponent.nVersion.s.nStep = SPECSTEP;
253 
254     // PV capability
255     iPVCapabilityFlags.iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
256     iPVCapabilityFlags.iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE;
257     iPVCapabilityFlags.iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
258     iPVCapabilityFlags.iOMXComponentSupportsPartialFrames = OMX_TRUE;
259     iPVCapabilityFlags.iOMXComponentUsesNALStartCodes = OMX_FALSE;
260     iPVCapabilityFlags.iOMXComponentCanHandleIncompleteFrames = OMX_TRUE;
261     iPVCapabilityFlags.iOMXComponentUsesFullAVCFrames = OMX_FALSE;
262 
263     if (ipAppPriv)
264     {
265         oscl_free(ipAppPriv);
266         ipAppPriv = NULL;
267     }
268 
269     ipAppPriv = (ComponentPrivateType*) oscl_malloc(sizeof(ComponentPrivateType));
270     if (NULL == ipAppPriv)
271     {
272         return OMX_ErrorInsufficientResources;
273     }
274 
275     //Construct base class now
276     Status = ConstructBaseComponent(pAppData);
277 
278     if (OMX_ErrorNone != Status)
279     {
280         return Status;
281     }
282 
283     /** Domain specific section for input raw port */ //OMX_PARAM_PORTDEFINITIONTYPE
284     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
285     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
286     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"raw";
287     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
288     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
289     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
290 
291     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
292     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176;
293     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144;
294     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
295     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
296     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.eDir = OMX_DirInput;
297     //Set to a default value, will change later during setparameter call
298     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_INPUT_BUFFER_MP4ENC;
299     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
300     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.nBufferSize = INPUT_BUFFER_SIZE_MP4ENC;
301     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
302     ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
303 
304 
305     /** Domain specific section for output mpeg4/h263 port */
306     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
307     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDomain = OMX_PortDomainVideo;
308     if (MODE_MPEG4 == iEncMode)
309     {
310         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/mpeg4";
311         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
312 
313     }
314     else if (MODE_H263 == iEncMode)
315     {
316         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.cMIMEType = (OMX_STRING)"video/h263";
317         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
318     }
319 
320     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.pNativeRender = 0;
321     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.bFlagErrorConcealment = OMX_FALSE;
322     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.eColorFormat = OMX_COLOR_FormatUnused;
323     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameWidth = 176;
324     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nFrameHeight = 144;
325     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.nBitrate = 64000;
326     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video.xFramerate = (15 << 16);
327     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.eDir = OMX_DirOutput;
328     //Set to a default value, will change later during setparameter call
329     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountActual = NUMBER_OUTPUT_BUFFER_MP4ENC;
330     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferCountMin = 1;
331     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.nBufferSize = OUTPUT_BUFFER_SIZE_MP4ENC;
332     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bEnabled = OMX_TRUE;
333     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.bPopulated = OMX_FALSE;
334 
335 
336     //OMX_VIDEO_PARAM_MPEG4TYPE
337     //Default values for mpeg4 video output param port
338     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
339     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileCore;
340     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.eLevel = OMX_VIDEO_MPEG4Level2;
341     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.nPFrames = 10;
342     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.nBFrames = 0;        //No support for B frames
343     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.nMaxPacketSize = 256;    //Default value
344     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
345     ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4.bGov = OMX_FALSE;
346 
347     //This will be an additional structure maintained on output port if the encoder is H.263
348     if (MODE_H263 == iEncMode)
349     {
350         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
351         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.eProfile = OMX_VIDEO_H263ProfileBaseline;
352         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.eLevel = OMX_VIDEO_H263Level45;
353         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.bPLUSPTYPEAllowed = OMX_FALSE;
354         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
355         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.bForceRoundingTypeToZero = OMX_TRUE;
356         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.nPictureHeaderRepetition = 0;
357         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263.nGOBHeaderInterval = 0;
358     }
359 
360 
361     if (MODE_MPEG4 == iEncMode)
362     {
363         //OMX_VIDEO_PARAM_PROFILELEVELTYPE structure
364         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
365         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0;
366         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_MPEG4ProfileCore;
367         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_MPEG4Level2;
368     }
369     else if (MODE_H263 == iEncMode)
370     {
371         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
372         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.nProfileIndex = 0;
373         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eProfile = OMX_VIDEO_H263ProfileBaseline;
374         ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel.eLevel = OMX_VIDEO_H263Level45;
375     }
376 
377 
378     iPortTypesParam.nPorts = 2;
379     iPortTypesParam.nStartPortNumber = 0;
380 
381     pInPort = (ComponentPortType*) ipPorts[OMX_PORT_INPUTPORT_INDEX];
382     pOutPort = (ComponentPortType*) ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
383 
384     pInPort->ActualNumPortFormatsSupported = 4;
385 
386     //OMX_VIDEO_PARAM_PORTFORMATTYPE INPUT PORT SETTINGS
387     //On input port for index 0
388     SetHeader(&pInPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
389     pInPort->VideoParam[0].nPortIndex = OMX_PORT_INPUTPORT_INDEX;
390     pInPort->VideoParam[0].nIndex = 0;
391     pInPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingUnused;
392     pInPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatYUV420Planar;
393     pInPort->VideoParam[0].xFramerate = (15 << 16);
394 
395     //On input port for index 1
396     SetHeader(&pInPort->VideoParam[1], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
397     pInPort->VideoParam[1].nPortIndex = OMX_PORT_INPUTPORT_INDEX;
398     pInPort->VideoParam[1].nIndex = 1;
399     pInPort->VideoParam[1].eCompressionFormat = OMX_VIDEO_CodingUnused;
400     pInPort->VideoParam[1].eColorFormat = OMX_COLOR_Format24bitRGB888;
401     pInPort->VideoParam[1].xFramerate = (15 << 16);
402 
403     //On input port for index 2
404     SetHeader(&pInPort->VideoParam[2], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
405     pInPort->VideoParam[2].nPortIndex = OMX_PORT_INPUTPORT_INDEX;
406     pInPort->VideoParam[2].nIndex = 2;
407     pInPort->VideoParam[2].eCompressionFormat = OMX_VIDEO_CodingUnused;
408     pInPort->VideoParam[2].eColorFormat = OMX_COLOR_Format12bitRGB444;
409     pInPort->VideoParam[2].xFramerate = (15 << 16);
410 
411     //On input port for index 3
412     SetHeader(&pInPort->VideoParam[3], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
413     pInPort->VideoParam[3].nPortIndex = OMX_PORT_INPUTPORT_INDEX;
414     pInPort->VideoParam[3].nIndex = 3;
415     pInPort->VideoParam[3].eCompressionFormat = OMX_VIDEO_CodingUnused;
416     pInPort->VideoParam[3].eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
417     pInPort->VideoParam[3].xFramerate = (15 << 16);
418 
419 
420     pOutPort->ActualNumPortFormatsSupported = 1;
421 
422     //OMX_VIDEO_PARAM_PORTFORMATTYPE OUTPUT PORT SETTINGS
423     //On output port for index 0
424     SetHeader(&pOutPort->VideoParam[0], sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
425     pOutPort->VideoParam[0].nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
426     pOutPort->VideoParam[0].nIndex = 0;
427     pOutPort->VideoParam[0].eColorFormat = OMX_COLOR_FormatUnused;
428     pOutPort->VideoParam[0].xFramerate = (15 << 16);
429     if (iEncMode == MODE_MPEG4)
430     {
431         pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingMPEG4;
432 
433     }
434     else if (iEncMode == MODE_H263)
435     {
436         pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingH263;
437     }
438 
439 
440     //OMX_CONFIG_ROTATIONTYPE SETTINGS ON INPUT PORT
441     SetHeader(&pInPort->VideoOrientationType, sizeof(OMX_CONFIG_ROTATIONTYPE));
442     pInPort->VideoOrientationType.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
443     pInPort->VideoOrientationType.nRotation = -1;  //For all the YUV formats that are other than RGB
444 
445 
446     //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE settings of output port
447     oscl_memset(&pOutPort->VideoErrorCorrection, 0, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
448     SetHeader(&pOutPort->VideoErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
449     pOutPort->VideoErrorCorrection.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
450     pOutPort->VideoErrorCorrection.bEnableDataPartitioning = OMX_FALSE; //As in node default is h263
451 
452 
453     //OMX_VIDEO_PARAM_BITRATETYPE settings of output port
454     SetHeader(&pOutPort->VideoRateType, sizeof(OMX_VIDEO_PARAM_BITRATETYPE));
455     pOutPort->VideoRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
456     pOutPort->VideoRateType.eControlRate = OMX_Video_ControlRateConstant;
457     pOutPort->VideoRateType.nTargetBitrate = 64000;
458 
459 
460     //OMX_CONFIG_FRAMERATETYPE default seetings (specified in khronos conformance test)
461     SetHeader(&pOutPort->VideoConfigFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE));
462     pOutPort->VideoConfigFrameRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
463     pOutPort->VideoConfigFrameRateType.xEncodeFramerate = (15 << 16);
464 
465     //OMX_VIDEO_CONFIG_BITRATETYPE default settings (specified in khronos conformance test)
466     SetHeader(&pOutPort->VideoConfigBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
467     pOutPort->VideoConfigBitRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
468     pOutPort->VideoConfigBitRateType.nEncodeBitrate = 64000;
469 
470 
471     //OMX_VIDEO_PARAM_QUANTIZATIONTYPE settings of output port
472     SetHeader(&pOutPort->VideoQuantType, sizeof(OMX_VIDEO_PARAM_QUANTIZATIONTYPE));
473     pOutPort->VideoQuantType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
474     pOutPort->VideoQuantType.nQpI = 15;
475     pOutPort->VideoQuantType.nQpP = 12;
476     pOutPort->VideoQuantType.nQpB = 12;
477 
478 
479     //OMX_VIDEO_PARAM_VBSMCTYPE settings of output port
480     oscl_memset(&pOutPort->VideoBlockMotionSize, 0, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE));
481     SetHeader(&pOutPort->VideoBlockMotionSize, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE));
482     pOutPort->VideoBlockMotionSize.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
483     pOutPort->VideoBlockMotionSize.b16x16 = OMX_TRUE;
484 
485 
486     //OMX_VIDEO_PARAM_MOTIONVECTORTYPE settings of output port
487     oscl_memset(&pOutPort->VideoMotionVector, 0, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE));
488     SetHeader(&pOutPort->VideoMotionVector, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE));
489     pOutPort->VideoMotionVector.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
490     pOutPort->VideoMotionVector.eAccuracy = OMX_Video_MotionVectorHalfPel;
491     pOutPort->VideoMotionVector.bUnrestrictedMVs = OMX_TRUE;
492     pOutPort->VideoMotionVector.sXSearchRange = 16;
493     pOutPort->VideoMotionVector.sYSearchRange = 16;
494 
495 
496     //OMX_VIDEO_PARAM_INTRAREFRESHTYPE settings of output port
497     oscl_memset(&pOutPort->VideoIntraRefresh, 0, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
498     SetHeader(&pOutPort->VideoIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
499     pOutPort->VideoIntraRefresh.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
500     pOutPort->VideoIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
501     pOutPort->VideoIntraRefresh.nCirMBs = 0;
502 
503 
504     //OMX_CONFIG_INTRAREFRESHVOPTYPE settings of output port
505     oscl_memset(&pOutPort->VideoIFrame, 0, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
506     SetHeader(&pOutPort->VideoIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
507     pOutPort->VideoIFrame.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
508     pOutPort->VideoIFrame.IntraRefreshVOP = OMX_FALSE;
509 
510 
511     //Construct the encoder object
512     if (ipMpegEncoderObject)
513     {
514         OSCL_DELETE(ipMpegEncoderObject);
515         ipMpegEncoderObject = NULL;
516     }
517 
518     ipMpegEncoderObject = OSCL_NEW(Mpeg4Encoder_OMX, ());
519 
520 #if PROXY_INTERFACE
521 
522     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSendCommand = BaseComponentSendCommand;
523     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetParameter = BaseComponentGetParameter;
524     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetParameter = BaseComponentSetParameter;
525     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetConfig = BaseComponentGetConfig;
526     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetConfig = BaseComponentSetConfig;
527     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex;
528     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetState = BaseComponentGetState;
529     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentUseBuffer = BaseComponentUseBuffer;
530     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentAllocateBuffer = BaseComponentAllocateBuffer;
531     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFreeBuffer = BaseComponentFreeBuffer;
532     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer;
533     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFillThisBuffer = BaseComponentFillThisBuffer;
534 
535 #endif
536 
537     return OMX_ErrorNone;
538 }
539 
540 
541 /** This function is called by the omx core when the component
542     * is disposed by the IL client with a call to FreeHandle().
543     */
544 
DestroyComponent()545 OMX_ERRORTYPE OmxComponentMpeg4EncAO::DestroyComponent()
546 {
547     if (OMX_FALSE != iIsInit)
548     {
549         ComponentDeInit();
550     }
551 
552     //Destroy the base class now
553     DestroyBaseComponent();
554 
555     if (ipMpegEncoderObject)
556     {
557         OSCL_DELETE(ipMpegEncoderObject);
558         ipMpegEncoderObject = NULL;
559     }
560 
561     if (ipAppPriv)
562     {
563         ipAppPriv->CompHandle = NULL;
564 
565         oscl_free(ipAppPriv);
566         ipAppPriv = NULL;
567     }
568 
569     return OMX_ErrorNone;
570 }
571 
572 
ProcessData()573 void OmxComponentMpeg4EncAO::ProcessData()
574 {
575     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData IN"));
576 
577     QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
578     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
579 
580     ComponentPortType*  pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX];
581     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
582 
583     OMX_U8*                 pOutBuffer;
584     OMX_U32                 OutputLength;
585     OMX_BOOL                EncodeReturn = OMX_FALSE;
586     OMX_COMPONENTTYPE*      pHandle = &iOmxComponent;
587 
588     if ((!iIsInputBufferEnded) || (iEndofStream))
589     {
590         //Check whether prev output bufer has been released or not
591         if (OMX_TRUE == iNewOutBufRequired)
592         {
593             //Check whether a new output buffer is available or not
594 
595             if (0 == (GetQueueNumElem(pOutputQueue)))
596             {
597                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
598                 return;
599             }
600 
601             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
602 
603             OSCL_ASSERT(NULL != ipOutputBuffer);
604             if (ipOutputBuffer == NULL)
605             {
606                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : ProcessData OUT ERR output buffer cannot be dequeued"));
607                 return;
608             }
609 
610             ipOutputBuffer->nFilledLen = 0;
611             iNewOutBufRequired = OMX_FALSE;
612 
613 
614             /* If some output data was left to be send from the last processing due to
615              * unavailability of required number of output buffers,
616              * copy it now and send back before processing new input frame */
617             if (iInternalOutBufFilledLen > 0)
618             {
619                 if (OMX_FALSE == CopyDataToOutputBuffer())
620                 {
621                     //We fell short of output buffers, exit now and wait for some more buffers to get queued
622                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
623                     return;
624                 }
625                 else
626                 {
627                     //Attach the end of frame flag while sending out the last piece of output buffer
628                     ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
629                     if (OMX_TRUE == iSyncFlag)
630                     {
631                         ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
632                         iSyncFlag = OMX_FALSE;
633                     }
634                     ReturnOutputBuffer(ipOutputBuffer, pOutPort);
635 
636                     //Dequeue new output buffer to continue encoding the next frame
637                     if (0 == (GetQueueNumElem(pOutputQueue)))
638                     {
639                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
640                         return;
641                     }
642 
643                     ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
644 
645                     OSCL_ASSERT(NULL != ipOutputBuffer);
646                     if (ipOutputBuffer == NULL)
647                     {
648                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : ProcessData OUT ERR output buffer cannot be dequeued"));
649                         return;
650                     }
651 
652                     ipOutputBuffer->nFilledLen = 0;
653                     iNewOutBufRequired = OMX_FALSE;
654                 }
655             }
656         }
657 
658         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
659          * command and hMarkTargetComponent as given by the specifications
660          */
661         if (ipMark != NULL)
662         {
663             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
664             ipOutputBuffer->pMarkData = ipMark->pMarkData;
665             ipMark = NULL;
666         }
667 
668         if (ipTargetComponent != NULL)
669         {
670             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
671             ipOutputBuffer->pMarkData = iTargetMarkData;
672             ipTargetComponent = NULL;
673 
674         }
675         //Mark buffer code ends here
676 
677         //Call the encoder only if there is some data to encode
678         if (iInputCurrLength > 0)
679         {
680             pOutBuffer = ipOutputBuffer->pBuffer;
681             OutputLength = ipOutputBuffer->nAllocLen;
682 
683             //Output buffer is passed as a short pointer
684             EncodeReturn = ipMpegEncoderObject->Mp4EncodeVideo(pOutBuffer,
685                            &OutputLength,
686                            &iBufferOverRun,
687                            &ipInternalOutBuffer,
688                            ipFrameDecodeBuffer,
689                            iInputCurrLength,
690                            iFrameTimestamp,
691                            &iOutputTimeStamp,
692                            &iSyncFlag);
693 
694 
695             //Chk whether output data has been generated or not
696             if (OutputLength > 0)
697             {
698                 //offset not required in our case, set it to zero
699                 ipOutputBuffer->nOffset = 0;
700                 ipOutputBuffer->nTimeStamp = iOutputTimeStamp;
701 
702                 if (OMX_FALSE == iBufferOverRun)
703                 {
704                     //No internal buffer is maintained
705                     ipOutputBuffer->nFilledLen = OutputLength;
706                 }
707                 else
708                 {
709                     iInternalOutBufFilledLen = OutputLength;
710                     iBufferOverRun = OMX_FALSE;
711                     CopyDataToOutputBuffer();
712 
713                 }   //else loop of if (OMX_FALSE == iMantainOutInternalBuffer)
714             }   //if (OutputLength > 0)  loop
715 
716 
717             //If encoder returned error in case of frame skip/corrupt frame, report it to the client via a callback
718             if ((OMX_FALSE == EncodeReturn) && (OMX_FALSE == iEndofStream))
719             {
720                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : Frame skipped, ProcessData ErrorStreamCorrupt callback send"));
721 
722                 (*(ipCallbacks->EventHandler))
723                 (pHandle,
724                  iCallbackData,
725                  OMX_EventError,
726                  OMX_ErrorStreamCorrupt,
727                  0,
728                  NULL);
729             }
730 
731 
732             //For the first time, encoder returns the volheader in output buffer and input remains unconsumed
733             //so do not return the input buffer yet
734             if (0 != iFrameCount)
735             {
736                 //Input bytes consumed now, return the buffer
737                 ipInputBuffer->nFilledLen = 0;
738                 ReturnInputBuffer(ipInputBuffer, pInPort);
739                 ipInputBuffer = NULL;
740 
741                 iIsInputBufferEnded = OMX_TRUE;
742                 iInputCurrLength = 0;
743             }
744 
745             iFrameCount++;
746         }
747 
748 
749         /* If EOS flag has come from the client & there are no more
750          * input buffers to decode, send the callback to the client
751          */
752         if (OMX_TRUE == iEndofStream)
753         {
754             if (((0 == iInputCurrLength) || (OMX_FALSE == EncodeReturn)) &&
755                     (0 == iInternalOutBufFilledLen))
756             {
757 
758                 (*(ipCallbacks->EventHandler))
759                 (pHandle,
760                  iCallbackData,
761                  OMX_EventBufferFlag,
762                  1,
763                  OMX_BUFFERFLAG_EOS,
764                  NULL);
765                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData EOS callback sent"));
766 
767 
768                 //Mark this flag false once the callback has been send back
769                 iEndofStream = OMX_FALSE;
770 
771                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
772                 if (OMX_TRUE == iSyncFlag)
773                 {
774                     ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
775                     iSyncFlag = OMX_FALSE;
776                 }
777                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
778 
779                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT"));
780                 return;
781             }
782 
783         }
784 
785         //Send the output buffer back after decode
786         if ((ipOutputBuffer->nFilledLen > 0) && (OMX_FALSE == iNewOutBufRequired))
787         {
788             //Attach the end of frame flag while sending out the last piece of output buffer
789             ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
790             if (OMX_TRUE == iSyncFlag)
791             {
792                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
793                 iSyncFlag = OMX_FALSE;
794             }
795             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
796         }
797 
798 
799         /* If there is some more processing left with current buffers, re-schedule the AO
800          * Do not go for more than one round of processing at a time.
801          * This may block the AO longer than required.
802          */
803         if ((iInputCurrLength != 0 || GetQueueNumElem(pInputQueue) > 0)
804                 && (GetQueueNumElem(pOutputQueue) > 0))
805         {
806             RunIfNotReady();
807         }
808     }
809 
810     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT"));
811 }
812 
813 
CopyDataToOutputBuffer()814 OMX_BOOL OmxComponentMpeg4EncAO::CopyDataToOutputBuffer()
815 {
816     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
817     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
818 
819     while (iInternalOutBufFilledLen > 0)
820     {
821         if (ipOutputBuffer->nAllocLen >= iInternalOutBufFilledLen)
822         {
823             //Pack the whole  data into the output buffer Alloc length data in one buffer and return it
824             oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, iInternalOutBufFilledLen);
825             ipOutputBuffer->nFilledLen = iInternalOutBufFilledLen;
826 
827         }
828         else
829         {
830             oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, ipOutputBuffer->nAllocLen);
831             ipOutputBuffer->nFilledLen = ipOutputBuffer->nAllocLen;
832         }
833 
834         iInternalOutBufFilledLen -= ipOutputBuffer->nFilledLen;
835         ipInternalOutBuffer += ipOutputBuffer->nFilledLen;
836 
837 
838         if (0 != iInternalOutBufFilledLen)
839         {
840             //Mark sync flag in each piece of partial output buffer
841             if (OMX_TRUE == iSyncFlag)
842             {
843                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
844             }
845             //Return the partial output buffer and try to fetch a new output buffer for filling the remaining data
846             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
847 
848             //Check whether a new output buffer is available or not
849             if (0 == (GetQueueNumElem(pOutputQueue)))
850             {
851                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : CopyDataToOutputBuffer OUT output buffer unavailable"));
852                 return OMX_FALSE;
853             }
854 
855             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
856 
857             OSCL_ASSERT(NULL != ipOutputBuffer);
858             if (ipOutputBuffer == NULL)
859             {
860                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : CopyDataToOutputBuffer  OUT ERR output buffer cannot be dequeued"));
861                 return OMX_FALSE;
862             }
863 
864             ipOutputBuffer->nFilledLen = 0;
865             ipOutputBuffer->nTimeStamp = iOutputTimeStamp;
866             ipOutputBuffer->nOffset = 0;
867             iNewOutBufRequired = OMX_FALSE;
868         }
869     }   //while (iInternalOutBufFilledLen > 0)
870 
871     return OMX_TRUE;
872 
873 }
874 
875 
876 //Not implemented & supported in case of base profile components
877 
ComponentGetRolesOfComponent(OMX_STRING * aRoleString)878 void OmxComponentMpeg4EncAO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString)
879 {
880     *aRoleString = (OMX_STRING)"video_encoder.mpeg4";
881 }
882 
883 
884 //Component constructor
OmxComponentMpeg4EncAO()885 OmxComponentMpeg4EncAO::OmxComponentMpeg4EncAO()
886 {
887     ipMpegEncoderObject = NULL;
888     iEncMode = MODE_H263;
889     //iMantainOutInternalBuffer = OMX_FALSE;
890     ipInternalOutBuffer = NULL;
891     iInternalOutBufFilledLen = 0;
892     iSyncFlag = OMX_FALSE;
893     iBufferOverRun = OMX_FALSE;
894 
895     if (!IsAdded())
896     {
897         AddToScheduler();
898     }
899 
900     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : constructed"));
901 }
902 
903 
904 //Active object destructor
~OmxComponentMpeg4EncAO()905 OmxComponentMpeg4EncAO::~OmxComponentMpeg4EncAO()
906 {
907     if (IsAdded())
908     {
909         RemoveFromScheduler();
910     }
911 
912     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : destructed"));
913 }
914 
915 
SetConfig(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentConfigStructure)916 OMX_ERRORTYPE OmxComponentMpeg4EncAO::SetConfig(
917     OMX_IN  OMX_HANDLETYPE hComponent,
918     OMX_IN  OMX_INDEXTYPE nIndex,
919     OMX_IN  OMX_PTR pComponentConfigStructure)
920 {
921     OSCL_UNUSED_ARG(hComponent);
922     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig IN"));
923 
924     OMX_U32 PortIndex;
925 
926     OMX_ERRORTYPE ErrorType = OMX_ErrorNone;
927     OMX_CONFIG_INTRAREFRESHVOPTYPE* pVideoIFrame;
928     OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateType;
929     OMX_CONFIG_FRAMERATETYPE* pFrameRateType;
930 
931 
932 
933     if (NULL == pComponentConfigStructure)
934     {
935         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error bad parameter"));
936         return OMX_ErrorBadParameter;
937     }
938 
939     switch (nIndex)
940     {
941         case OMX_IndexConfigVideoIntraVOPRefresh:
942         {
943             pVideoIFrame = (OMX_CONFIG_INTRAREFRESHVOPTYPE*) pComponentConfigStructure;
944             PortIndex = pVideoIFrame->nPortIndex;
945 
946             if (PortIndex != iCompressedFormatPortNum)
947             {
948                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
949                 return OMX_ErrorBadPortIndex;
950             }
951 
952             /*Check Structure Header*/
953             ErrorType = CheckHeader(pVideoIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
954             if (ErrorType != OMX_ErrorNone)
955             {
956                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
957                 return ErrorType;
958             }
959 
960             //Call the RequestI frame routine of the encoder in case of setconfig call
961             if (OMX_TRUE == pVideoIFrame->IntraRefreshVOP)
962             {
963                 ipMpegEncoderObject->Mp4RequestIFrame();
964 
965             }
966         }
967         break;
968 
969         case OMX_IndexConfigVideoBitrate:
970         {
971             pBitRateType = (OMX_VIDEO_CONFIG_BITRATETYPE*) pComponentConfigStructure;
972             PortIndex = pBitRateType->nPortIndex;
973 
974             if (PortIndex != iCompressedFormatPortNum)
975             {
976                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
977                 return OMX_ErrorBadPortIndex;
978             }
979 
980             /*Check Structure Header*/
981             ErrorType = CheckHeader(pBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
982             if (ErrorType != OMX_ErrorNone)
983             {
984                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
985                 return ErrorType;
986             }
987 
988             //Call the corresponding routine of the encoder in case of setconfig call
989             if (OMX_FALSE == (ipMpegEncoderObject->Mp4UpdateBitRate(pBitRateType->nEncodeBitrate)))
990             {
991                 return OMX_ErrorUnsupportedSetting;
992             }
993             ipPorts[PortIndex]->VideoConfigBitRateType.nEncodeBitrate = pBitRateType->nEncodeBitrate;
994         }
995         break;
996 
997         case OMX_IndexConfigVideoFramerate:
998         {
999             pFrameRateType = (OMX_CONFIG_FRAMERATETYPE*) pComponentConfigStructure;
1000             PortIndex = pFrameRateType->nPortIndex;
1001 
1002             if (PortIndex != iCompressedFormatPortNum)
1003             {
1004                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
1005                 return OMX_ErrorBadPortIndex;
1006             }
1007 
1008             /*Check Structure Header*/
1009             ErrorType = CheckHeader(pFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE));
1010             if (ErrorType != OMX_ErrorNone)
1011             {
1012                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
1013                 return ErrorType;
1014             }
1015 
1016             //Call the corresponding routine of the encoder in case of setconfig call
1017             if (OMX_FALSE == (ipMpegEncoderObject->Mp4UpdateFrameRate(pFrameRateType->xEncodeFramerate)))
1018             {
1019                 return OMX_ErrorUnsupportedSetting;
1020             }
1021 
1022             ipPorts[PortIndex]->VideoConfigFrameRateType.xEncodeFramerate = pFrameRateType->xEncodeFramerate;
1023         }
1024         break;
1025 
1026         default:
1027         {
1028             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error Unsupported Index"));
1029             return OMX_ErrorUnsupportedIndex;
1030         }
1031         break;
1032 
1033     }
1034 
1035 
1036     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig OUT"));
1037 
1038     return OMX_ErrorNone;
1039 
1040 }
1041 
1042 
1043 
1044 /** The Initialization function
1045  */
ComponentInit()1046 OMX_ERRORTYPE OmxComponentMpeg4EncAO::ComponentInit()
1047 {
1048     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit IN"));
1049 
1050     OMX_ERRORTYPE Status = OMX_ErrorNone;
1051 
1052     if (OMX_TRUE == iIsInit)
1053     {
1054         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit error incorrect operation"));
1055         return OMX_ErrorIncorrectStateOperation;
1056     }
1057     iIsInit = OMX_TRUE;
1058 
1059 
1060     if (!iCodecReady)
1061     {
1062         iCodecReady = OMX_TRUE;
1063     }
1064 
1065     //Check the H.263 parameters before initializing the encoder if there was any change in the SetParameter call
1066     if (MODE_H263 == iEncMode)
1067     {
1068         OMX_VIDEO_PARAM_H263TYPE* H263Param = (OMX_VIDEO_PARAM_H263TYPE*) & ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263;
1069 
1070         if ((OMX_VIDEO_H263ProfileBaseline != H263Param->eProfile) ||
1071                 (H263Param->eLevel > OMX_VIDEO_H263Level45) ||
1072                 (OMX_TRUE == H263Param->bPLUSPTYPEAllowed) ||
1073                 (0 == (H263Param->nAllowedPictureTypes & (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP))) ||
1074                 (0 != H263Param->nPictureHeaderRepetition))
1075         {
1076 
1077             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit Error, unsupported H.263 settings, OUT"));
1078             return OMX_ErrorUnsupportedSetting;
1079         }
1080     }
1081 
1082 
1083     //Library init routine
1084     Status = ipMpegEncoderObject->Mp4EncInit(iEncMode,
1085              ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video,
1086              ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoOrientationType,
1087              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video,
1088              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4,
1089              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoErrorCorrection,
1090              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoRateType,
1091              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoQuantType,
1092              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMotionVector,
1093              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoIntraRefresh,
1094              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263,
1095              &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel));
1096 
1097     iInputCurrLength = 0;
1098 
1099     //Used in dynamic port reconfiguration
1100     iFrameCount = 0;
1101     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit OUT"));
1102 
1103     return Status;
1104 
1105 }
1106 
1107 /** This function is called upon a transition to the idle or invalid state.
1108  *  Also it is called by the ComponentDestructor() function
1109  */
ComponentDeInit()1110 OMX_ERRORTYPE OmxComponentMpeg4EncAO::ComponentDeInit()
1111 {
1112     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentDeInit IN"));
1113 
1114     OMX_ERRORTYPE Status = OMX_ErrorNone;
1115 
1116     iIsInit = OMX_FALSE;
1117 
1118     if (iCodecReady)
1119     {
1120         Status = ipMpegEncoderObject->Mp4EncDeinit();
1121         iCodecReady = OMX_FALSE;
1122     }
1123 
1124     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentDeInit OUT"));
1125 
1126     return Status;
1127 
1128 }
1129 
1130 /* A component specific routine called from BufferMgmtWithoutMarker */
ProcessInBufferFlag()1131 void OmxComponentMpeg4EncAO::ProcessInBufferFlag()
1132 {
1133     iIsInputBufferEnded = OMX_FALSE;
1134 }
1135