• 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         oscl_strncpy((OMX_STRING)iComponentRole, (OMX_STRING)"video_encoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
433     }
434     else if (iEncMode == MODE_H263)
435     {
436         pOutPort->VideoParam[0].eCompressionFormat = OMX_VIDEO_CodingH263;
437         oscl_strncpy((OMX_STRING)iComponentRole, (OMX_STRING)"video_encoder.h263", OMX_MAX_STRINGNAME_SIZE);
438     }
439 
440 
441     //OMX_CONFIG_ROTATIONTYPE SETTINGS ON INPUT PORT
442     SetHeader(&pInPort->VideoOrientationType, sizeof(OMX_CONFIG_ROTATIONTYPE));
443     pInPort->VideoOrientationType.nPortIndex = OMX_PORT_INPUTPORT_INDEX;
444     pInPort->VideoOrientationType.nRotation = -1;  //For all the YUV formats that are other than RGB
445 
446 
447     //OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE settings of output port
448     oscl_memset(&pOutPort->VideoErrorCorrection, 0, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
449     SetHeader(&pOutPort->VideoErrorCorrection, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
450     pOutPort->VideoErrorCorrection.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
451     pOutPort->VideoErrorCorrection.bEnableDataPartitioning = OMX_FALSE; //As in node default is h263
452 
453 
454     //OMX_VIDEO_PARAM_BITRATETYPE settings of output port
455     SetHeader(&pOutPort->VideoRateType, sizeof(OMX_VIDEO_PARAM_BITRATETYPE));
456     pOutPort->VideoRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
457     pOutPort->VideoRateType.eControlRate = OMX_Video_ControlRateConstant;
458     pOutPort->VideoRateType.nTargetBitrate = 64000;
459 
460 
461     //OMX_CONFIG_FRAMERATETYPE default seetings (specified in khronos conformance test)
462     SetHeader(&pOutPort->VideoConfigFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE));
463     pOutPort->VideoConfigFrameRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
464     pOutPort->VideoConfigFrameRateType.xEncodeFramerate = (15 << 16);
465 
466     //OMX_VIDEO_CONFIG_BITRATETYPE default settings (specified in khronos conformance test)
467     SetHeader(&pOutPort->VideoConfigBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
468     pOutPort->VideoConfigBitRateType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
469     pOutPort->VideoConfigBitRateType.nEncodeBitrate = 64000;
470 
471 
472     //OMX_VIDEO_PARAM_QUANTIZATIONTYPE settings of output port
473     SetHeader(&pOutPort->VideoQuantType, sizeof(OMX_VIDEO_PARAM_QUANTIZATIONTYPE));
474     pOutPort->VideoQuantType.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
475     pOutPort->VideoQuantType.nQpI = 15;
476     pOutPort->VideoQuantType.nQpP = 12;
477     pOutPort->VideoQuantType.nQpB = 12;
478 
479 
480     //OMX_VIDEO_PARAM_VBSMCTYPE settings of output port
481     oscl_memset(&pOutPort->VideoBlockMotionSize, 0, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE));
482     SetHeader(&pOutPort->VideoBlockMotionSize, sizeof(OMX_VIDEO_PARAM_VBSMCTYPE));
483     pOutPort->VideoBlockMotionSize.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
484     pOutPort->VideoBlockMotionSize.b16x16 = OMX_TRUE;
485 
486 
487     //OMX_VIDEO_PARAM_MOTIONVECTORTYPE settings of output port
488     oscl_memset(&pOutPort->VideoMotionVector, 0, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE));
489     SetHeader(&pOutPort->VideoMotionVector, sizeof(OMX_VIDEO_PARAM_MOTIONVECTORTYPE));
490     pOutPort->VideoMotionVector.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
491     pOutPort->VideoMotionVector.eAccuracy = OMX_Video_MotionVectorHalfPel;
492     pOutPort->VideoMotionVector.bUnrestrictedMVs = OMX_TRUE;
493     pOutPort->VideoMotionVector.sXSearchRange = 16;
494     pOutPort->VideoMotionVector.sYSearchRange = 16;
495 
496 
497     //OMX_VIDEO_PARAM_INTRAREFRESHTYPE settings of output port
498     oscl_memset(&pOutPort->VideoIntraRefresh, 0, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
499     SetHeader(&pOutPort->VideoIntraRefresh, sizeof(OMX_VIDEO_PARAM_INTRAREFRESHTYPE));
500     pOutPort->VideoIntraRefresh.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
501     pOutPort->VideoIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
502     pOutPort->VideoIntraRefresh.nCirMBs = 0;
503 
504 
505     //OMX_CONFIG_INTRAREFRESHVOPTYPE settings of output port
506     oscl_memset(&pOutPort->VideoIFrame, 0, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
507     SetHeader(&pOutPort->VideoIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
508     pOutPort->VideoIFrame.nPortIndex = OMX_PORT_OUTPUTPORT_INDEX;
509     pOutPort->VideoIFrame.IntraRefreshVOP = OMX_FALSE;
510 
511 
512     //Construct the encoder object
513     if (ipMpegEncoderObject)
514     {
515         OSCL_DELETE(ipMpegEncoderObject);
516         ipMpegEncoderObject = NULL;
517     }
518 
519     ipMpegEncoderObject = OSCL_NEW(Mpeg4Encoder_OMX, ());
520 
521 #if PROXY_INTERFACE
522 
523     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSendCommand = BaseComponentSendCommand;
524     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetParameter = BaseComponentGetParameter;
525     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetParameter = BaseComponentSetParameter;
526     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetConfig = BaseComponentGetConfig;
527     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentSetConfig = BaseComponentSetConfig;
528     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetExtensionIndex = BaseComponentGetExtensionIndex;
529     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentGetState = BaseComponentGetState;
530     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentUseBuffer = BaseComponentUseBuffer;
531     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentAllocateBuffer = BaseComponentAllocateBuffer;
532     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFreeBuffer = BaseComponentFreeBuffer;
533     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentEmptyThisBuffer = BaseComponentEmptyThisBuffer;
534     ((ProxyApplication_OMX*)ipComponentProxy)->ComponentFillThisBuffer = BaseComponentFillThisBuffer;
535 
536 #endif
537 
538     return OMX_ErrorNone;
539 }
540 
541 
542 /** This function is called by the omx core when the component
543     * is disposed by the IL client with a call to FreeHandle().
544     */
545 
DestroyComponent()546 OMX_ERRORTYPE OmxComponentMpeg4EncAO::DestroyComponent()
547 {
548     if (OMX_FALSE != iIsInit)
549     {
550         ComponentDeInit();
551     }
552 
553     //Destroy the base class now
554     DestroyBaseComponent();
555 
556     if (ipMpegEncoderObject)
557     {
558         OSCL_DELETE(ipMpegEncoderObject);
559         ipMpegEncoderObject = NULL;
560     }
561 
562     if (ipAppPriv)
563     {
564         ipAppPriv->CompHandle = NULL;
565 
566         oscl_free(ipAppPriv);
567         ipAppPriv = NULL;
568     }
569 
570     return OMX_ErrorNone;
571 }
572 
573 
ProcessData()574 void OmxComponentMpeg4EncAO::ProcessData()
575 {
576     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData IN"));
577 
578     QueueType* pInputQueue = ipPorts[OMX_PORT_INPUTPORT_INDEX]->pBufferQueue;
579     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
580 
581     ComponentPortType*  pInPort = ipPorts[OMX_PORT_INPUTPORT_INDEX];
582     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
583 
584     OMX_U8*                 pOutBuffer;
585     OMX_U32                 OutputLength;
586     OMX_BOOL                EncodeReturn = OMX_FALSE;
587     OMX_COMPONENTTYPE*      pHandle = &iOmxComponent;
588 
589     if ((!iIsInputBufferEnded) || (iEndofStream))
590     {
591         //Check whether prev output bufer has been released or not
592         if (OMX_TRUE == iNewOutBufRequired)
593         {
594             //Check whether a new output buffer is available or not
595 
596             if (0 == (GetQueueNumElem(pOutputQueue)))
597             {
598                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
599                 return;
600             }
601 
602             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
603 
604             OSCL_ASSERT(NULL != ipOutputBuffer);
605             if (ipOutputBuffer == NULL)
606             {
607                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : ProcessData OUT ERR output buffer cannot be dequeued"));
608                 return;
609             }
610 
611             ipOutputBuffer->nFilledLen = 0;
612             iNewOutBufRequired = OMX_FALSE;
613 
614 
615             /* If some output data was left to be send from the last processing due to
616              * unavailability of required number of output buffers,
617              * copy it now and send back before processing new input frame */
618             if (iInternalOutBufFilledLen > 0)
619             {
620                 if (OMX_FALSE == CopyDataToOutputBuffer())
621                 {
622                     //We fell short of output buffers, exit now and wait for some more buffers to get queued
623                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
624                     return;
625                 }
626                 else
627                 {
628                     //Attach the end of frame flag while sending out the last piece of output buffer
629                     ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
630                     if (OMX_TRUE == iSyncFlag)
631                     {
632                         ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
633                         iSyncFlag = OMX_FALSE;
634                     }
635                     ReturnOutputBuffer(ipOutputBuffer, pOutPort);
636 
637                     //Dequeue new output buffer to continue encoding the next frame
638                     if (0 == (GetQueueNumElem(pOutputQueue)))
639                     {
640                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT output buffer unavailable"));
641                         return;
642                     }
643 
644                     ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
645 
646                     OSCL_ASSERT(NULL != ipOutputBuffer);
647                     if (ipOutputBuffer == NULL)
648                     {
649                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : ProcessData OUT ERR output buffer cannot be dequeued"));
650                         return;
651                     }
652 
653                     ipOutputBuffer->nFilledLen = 0;
654                     iNewOutBufRequired = OMX_FALSE;
655                 }
656             }
657         }
658 
659         /* Code for the marking buffer. Takes care of the OMX_CommandMarkBuffer
660          * command and hMarkTargetComponent as given by the specifications
661          */
662         if (ipMark != NULL)
663         {
664             ipOutputBuffer->hMarkTargetComponent = ipMark->hMarkTargetComponent;
665             ipOutputBuffer->pMarkData = ipMark->pMarkData;
666             ipMark = NULL;
667         }
668 
669         if (ipTargetComponent != NULL)
670         {
671             ipOutputBuffer->hMarkTargetComponent = ipTargetComponent;
672             ipOutputBuffer->pMarkData = iTargetMarkData;
673             ipTargetComponent = NULL;
674 
675         }
676         //Mark buffer code ends here
677 
678         //Call the encoder only if there is some data to encode
679         if (iInputCurrLength > 0)
680         {
681             pOutBuffer = ipOutputBuffer->pBuffer;
682             OutputLength = ipOutputBuffer->nAllocLen;
683 
684             //Output buffer is passed as a short pointer
685             EncodeReturn = ipMpegEncoderObject->Mp4EncodeVideo(pOutBuffer,
686                            &OutputLength,
687                            &iBufferOverRun,
688                            &ipInternalOutBuffer,
689                            ipFrameDecodeBuffer,
690                            iInputCurrLength,
691                            iFrameTimestamp,
692                            &iOutputTimeStamp,
693                            &iSyncFlag);
694 
695 
696             //Chk whether output data has been generated or not
697             if (OutputLength > 0)
698             {
699                 //offset not required in our case, set it to zero
700                 ipOutputBuffer->nOffset = 0;
701                 ipOutputBuffer->nTimeStamp = iOutputTimeStamp;
702 
703                 if (OMX_FALSE == iBufferOverRun)
704                 {
705                     //No internal buffer is maintained
706                     ipOutputBuffer->nFilledLen = OutputLength;
707                 }
708                 else
709                 {
710                     iInternalOutBufFilledLen = OutputLength;
711                     iBufferOverRun = OMX_FALSE;
712                     CopyDataToOutputBuffer();
713 
714                 }   //else loop of if (OMX_FALSE == iMantainOutInternalBuffer)
715             }   //if (OutputLength > 0)  loop
716 
717 
718             //If encoder returned error in case of frame skip/corrupt frame, report it to the client via a callback
719             if ((OMX_FALSE == EncodeReturn) && (OMX_FALSE == iEndofStream))
720             {
721                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : Frame skipped, ProcessData ErrorStreamCorrupt callback send"));
722 
723                 (*(ipCallbacks->EventHandler))
724                 (pHandle,
725                  iCallbackData,
726                  OMX_EventError,
727                  OMX_ErrorStreamCorrupt,
728                  0,
729                  NULL);
730             }
731 
732 
733             //For the first time, encoder returns the volheader in output buffer and input remains unconsumed
734             //so do not return the input buffer yet
735             if (0 != iFrameCount)
736             {
737                 //Input bytes consumed now, return the buffer
738                 ipInputBuffer->nFilledLen = 0;
739                 ReturnInputBuffer(ipInputBuffer, pInPort);
740                 ipInputBuffer = NULL;
741 
742                 iIsInputBufferEnded = OMX_TRUE;
743                 iInputCurrLength = 0;
744             }
745 
746             iFrameCount++;
747         }
748 
749 
750         /* If EOS flag has come from the client & there are no more
751          * input buffers to decode, send the callback to the client
752          */
753         if (OMX_TRUE == iEndofStream)
754         {
755             if (((0 == iInputCurrLength) || (OMX_FALSE == EncodeReturn)) &&
756                     (0 == iInternalOutBufFilledLen))
757             {
758 
759                 (*(ipCallbacks->EventHandler))
760                 (pHandle,
761                  iCallbackData,
762                  OMX_EventBufferFlag,
763                  1,
764                  OMX_BUFFERFLAG_EOS,
765                  NULL);
766                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData EOS callback sent"));
767 
768 
769                 //Mark this flag false once the callback has been send back
770                 iEndofStream = OMX_FALSE;
771 
772                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
773                 if (OMX_TRUE == iSyncFlag)
774                 {
775                     ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
776                     iSyncFlag = OMX_FALSE;
777                 }
778                 ReturnOutputBuffer(ipOutputBuffer, pOutPort);
779 
780                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT"));
781                 return;
782             }
783 
784         }
785 
786         //Send the output buffer back after decode
787         if ((ipOutputBuffer->nFilledLen > 0) && (OMX_FALSE == iNewOutBufRequired))
788         {
789             //Attach the end of frame flag while sending out the last piece of output buffer
790             ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
791             if (OMX_TRUE == iSyncFlag)
792             {
793                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
794                 iSyncFlag = OMX_FALSE;
795             }
796             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
797         }
798 
799 
800         /* If there is some more processing left with current buffers, re-schedule the AO
801          * Do not go for more than one round of processing at a time.
802          * This may block the AO longer than required.
803          */
804         if ((iInputCurrLength != 0 || GetQueueNumElem(pInputQueue) > 0)
805                 && (GetQueueNumElem(pOutputQueue) > 0))
806         {
807             RunIfNotReady();
808         }
809     }
810 
811     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ProcessData OUT"));
812 }
813 
814 
CopyDataToOutputBuffer()815 OMX_BOOL OmxComponentMpeg4EncAO::CopyDataToOutputBuffer()
816 {
817     ComponentPortType*  pOutPort = ipPorts[OMX_PORT_OUTPUTPORT_INDEX];
818     QueueType* pOutputQueue = ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->pBufferQueue;
819 
820     while (iInternalOutBufFilledLen > 0)
821     {
822         if (ipOutputBuffer->nAllocLen >= iInternalOutBufFilledLen)
823         {
824             //Pack the whole  data into the output buffer Alloc length data in one buffer and return it
825             oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, iInternalOutBufFilledLen);
826             ipOutputBuffer->nFilledLen = iInternalOutBufFilledLen;
827 
828         }
829         else
830         {
831             oscl_memcpy(ipOutputBuffer->pBuffer, ipInternalOutBuffer, ipOutputBuffer->nAllocLen);
832             ipOutputBuffer->nFilledLen = ipOutputBuffer->nAllocLen;
833         }
834 
835         iInternalOutBufFilledLen -= ipOutputBuffer->nFilledLen;
836         ipInternalOutBuffer += ipOutputBuffer->nFilledLen;
837 
838 
839         if (0 != iInternalOutBufFilledLen)
840         {
841             //Mark sync flag in each piece of partial output buffer
842             if (OMX_TRUE == iSyncFlag)
843             {
844                 ipOutputBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
845             }
846             //Return the partial output buffer and try to fetch a new output buffer for filling the remaining data
847             ReturnOutputBuffer(ipOutputBuffer, pOutPort);
848 
849             //Check whether a new output buffer is available or not
850             if (0 == (GetQueueNumElem(pOutputQueue)))
851             {
852                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : CopyDataToOutputBuffer OUT output buffer unavailable"));
853                 return OMX_FALSE;
854             }
855 
856             ipOutputBuffer = (OMX_BUFFERHEADERTYPE*) DeQueue(pOutputQueue);
857 
858             OSCL_ASSERT(NULL != ipOutputBuffer);
859             if (ipOutputBuffer == NULL)
860             {
861                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "OmxComponentMpeg4EncAO : CopyDataToOutputBuffer  OUT ERR output buffer cannot be dequeued"));
862                 return OMX_FALSE;
863             }
864 
865             ipOutputBuffer->nFilledLen = 0;
866             ipOutputBuffer->nTimeStamp = iOutputTimeStamp;
867             ipOutputBuffer->nOffset = 0;
868             iNewOutBufRequired = OMX_FALSE;
869         }
870     }   //while (iInternalOutBufFilledLen > 0)
871 
872     return OMX_TRUE;
873 
874 }
875 
876 
877 //Not implemented & supported in case of base profile components
878 
ComponentGetRolesOfComponent(OMX_STRING * aRoleString)879 void OmxComponentMpeg4EncAO::ComponentGetRolesOfComponent(OMX_STRING* aRoleString)
880 {
881     *aRoleString = (OMX_STRING)"video_encoder.mpeg4";
882 }
883 
884 
885 //Component constructor
OmxComponentMpeg4EncAO()886 OmxComponentMpeg4EncAO::OmxComponentMpeg4EncAO()
887 {
888     ipMpegEncoderObject = NULL;
889     iEncMode = MODE_H263;
890     //iMantainOutInternalBuffer = OMX_FALSE;
891     ipInternalOutBuffer = NULL;
892     iInternalOutBufFilledLen = 0;
893     iSyncFlag = OMX_FALSE;
894     iBufferOverRun = OMX_FALSE;
895 
896     if (!IsAdded())
897     {
898         AddToScheduler();
899     }
900 
901     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : constructed"));
902 }
903 
904 
905 //Active object destructor
~OmxComponentMpeg4EncAO()906 OmxComponentMpeg4EncAO::~OmxComponentMpeg4EncAO()
907 {
908     if (IsAdded())
909     {
910         RemoveFromScheduler();
911     }
912 
913     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : destructed"));
914 }
915 
916 
SetConfig(OMX_IN OMX_HANDLETYPE hComponent,OMX_IN OMX_INDEXTYPE nIndex,OMX_IN OMX_PTR pComponentConfigStructure)917 OMX_ERRORTYPE OmxComponentMpeg4EncAO::SetConfig(
918     OMX_IN  OMX_HANDLETYPE hComponent,
919     OMX_IN  OMX_INDEXTYPE nIndex,
920     OMX_IN  OMX_PTR pComponentConfigStructure)
921 {
922     OSCL_UNUSED_ARG(hComponent);
923     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig IN"));
924 
925     OMX_U32 PortIndex;
926 
927     OMX_ERRORTYPE ErrorType = OMX_ErrorNone;
928     OMX_CONFIG_INTRAREFRESHVOPTYPE* pVideoIFrame;
929     OMX_VIDEO_CONFIG_BITRATETYPE* pBitRateType;
930     OMX_CONFIG_FRAMERATETYPE* pFrameRateType;
931 
932 
933 
934     if (NULL == pComponentConfigStructure)
935     {
936         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error bad parameter"));
937         return OMX_ErrorBadParameter;
938     }
939 
940     switch (nIndex)
941     {
942         case OMX_IndexConfigVideoIntraVOPRefresh:
943         {
944             pVideoIFrame = (OMX_CONFIG_INTRAREFRESHVOPTYPE*) pComponentConfigStructure;
945             PortIndex = pVideoIFrame->nPortIndex;
946 
947             if (PortIndex != iCompressedFormatPortNum)
948             {
949                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
950                 return OMX_ErrorBadPortIndex;
951             }
952 
953             /*Check Structure Header*/
954             ErrorType = CheckHeader(pVideoIFrame, sizeof(OMX_CONFIG_INTRAREFRESHVOPTYPE));
955             if (ErrorType != OMX_ErrorNone)
956             {
957                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
958                 return ErrorType;
959             }
960 
961             //Call the RequestI frame routine of the encoder in case of setconfig call
962             if (OMX_TRUE == pVideoIFrame->IntraRefreshVOP)
963             {
964                 ipMpegEncoderObject->Mp4RequestIFrame();
965 
966             }
967         }
968         break;
969 
970         case OMX_IndexConfigVideoBitrate:
971         {
972             pBitRateType = (OMX_VIDEO_CONFIG_BITRATETYPE*) pComponentConfigStructure;
973             PortIndex = pBitRateType->nPortIndex;
974 
975             if (PortIndex != iCompressedFormatPortNum)
976             {
977                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
978                 return OMX_ErrorBadPortIndex;
979             }
980 
981             /*Check Structure Header*/
982             ErrorType = CheckHeader(pBitRateType, sizeof(OMX_VIDEO_CONFIG_BITRATETYPE));
983             if (ErrorType != OMX_ErrorNone)
984             {
985                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
986                 return ErrorType;
987             }
988 
989             //Call the corresponding routine of the encoder in case of setconfig call
990             if (OMX_FALSE == (ipMpegEncoderObject->Mp4UpdateBitRate(pBitRateType->nEncodeBitrate)))
991             {
992                 return OMX_ErrorUnsupportedSetting;
993             }
994             ipPorts[PortIndex]->VideoConfigBitRateType.nEncodeBitrate = pBitRateType->nEncodeBitrate;
995         }
996         break;
997 
998         case OMX_IndexConfigVideoFramerate:
999         {
1000             pFrameRateType = (OMX_CONFIG_FRAMERATETYPE*) pComponentConfigStructure;
1001             PortIndex = pFrameRateType->nPortIndex;
1002 
1003             if (PortIndex != iCompressedFormatPortNum)
1004             {
1005                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error invalid port index"));
1006                 return OMX_ErrorBadPortIndex;
1007             }
1008 
1009             /*Check Structure Header*/
1010             ErrorType = CheckHeader(pFrameRateType, sizeof(OMX_CONFIG_FRAMERATETYPE));
1011             if (ErrorType != OMX_ErrorNone)
1012             {
1013                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error param check failed"));
1014                 return ErrorType;
1015             }
1016 
1017             //Call the corresponding routine of the encoder in case of setconfig call
1018             if (OMX_FALSE == (ipMpegEncoderObject->Mp4UpdateFrameRate(pFrameRateType->xEncodeFramerate)))
1019             {
1020                 return OMX_ErrorUnsupportedSetting;
1021             }
1022 
1023             ipPorts[PortIndex]->VideoConfigFrameRateType.xEncodeFramerate = pFrameRateType->xEncodeFramerate;
1024         }
1025         break;
1026 
1027         default:
1028         {
1029             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig error Unsupported Index"));
1030             return OMX_ErrorUnsupportedIndex;
1031         }
1032         break;
1033 
1034     }
1035 
1036 
1037     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : SetConfig OUT"));
1038 
1039     return OMX_ErrorNone;
1040 
1041 }
1042 
1043 
1044 
1045 /** The Initialization function
1046  */
ComponentInit()1047 OMX_ERRORTYPE OmxComponentMpeg4EncAO::ComponentInit()
1048 {
1049     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit IN"));
1050 
1051     OMX_ERRORTYPE Status = OMX_ErrorNone;
1052 
1053     if (OMX_TRUE == iIsInit)
1054     {
1055         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit error incorrect operation"));
1056         return OMX_ErrorIncorrectStateOperation;
1057     }
1058     iIsInit = OMX_TRUE;
1059 
1060 
1061     if (!iCodecReady)
1062     {
1063         iCodecReady = OMX_TRUE;
1064     }
1065 
1066     //Check the H.263 parameters before initializing the encoder if there was any change in the SetParameter call
1067     if (MODE_H263 == iEncMode)
1068     {
1069         OMX_VIDEO_PARAM_H263TYPE* H263Param = (OMX_VIDEO_PARAM_H263TYPE*) & ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263;
1070 
1071         if ((OMX_VIDEO_H263ProfileBaseline != H263Param->eProfile) ||
1072                 (H263Param->eLevel > OMX_VIDEO_H263Level45) ||
1073                 (OMX_TRUE == H263Param->bPLUSPTYPEAllowed) ||
1074                 (0 == (H263Param->nAllowedPictureTypes & (OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP))) ||
1075                 (0 != H263Param->nPictureHeaderRepetition))
1076         {
1077 
1078             PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit Error, unsupported H.263 settings, OUT"));
1079             return OMX_ErrorUnsupportedSetting;
1080         }
1081     }
1082 
1083 
1084     //Library init routine
1085     Status = ipMpegEncoderObject->Mp4EncInit(iEncMode,
1086              ipPorts[OMX_PORT_INPUTPORT_INDEX]->PortParam.format.video,
1087              ipPorts[OMX_PORT_INPUTPORT_INDEX]->VideoOrientationType,
1088              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->PortParam.format.video,
1089              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMpeg4,
1090              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoErrorCorrection,
1091              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoRateType,
1092              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoQuantType,
1093              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoMotionVector,
1094              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoIntraRefresh,
1095              ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->VideoH263,
1096              &(ipPorts[OMX_PORT_OUTPUTPORT_INDEX]->ProfileLevel));
1097 
1098     iInputCurrLength = 0;
1099 
1100     //Used in dynamic port reconfiguration
1101     iFrameCount = 0;
1102     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentInit OUT"));
1103 
1104     return Status;
1105 
1106 }
1107 
1108 /** This function is called upon a transition to the idle or invalid state.
1109  *  Also it is called by the ComponentDestructor() function
1110  */
ComponentDeInit()1111 OMX_ERRORTYPE OmxComponentMpeg4EncAO::ComponentDeInit()
1112 {
1113     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentDeInit IN"));
1114 
1115     OMX_ERRORTYPE Status = OMX_ErrorNone;
1116 
1117     iIsInit = OMX_FALSE;
1118 
1119     if (iCodecReady)
1120     {
1121         Status = ipMpegEncoderObject->Mp4EncDeinit();
1122         iCodecReady = OMX_FALSE;
1123     }
1124 
1125     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "OmxComponentMpeg4EncAO : ComponentDeInit OUT"));
1126 
1127     return Status;
1128 
1129 }
1130 
1131 /* A component specific routine called from BufferMgmtWithoutMarker */
ProcessInBufferFlag()1132 void OmxComponentMpeg4EncAO::ProcessInBufferFlag()
1133 {
1134     iIsInputBufferEnded = OMX_FALSE;
1135 }
1136