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