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