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#include "pvmf_omx_videodec_node.h"
19#include "pvlogger.h"
20#include "oscl_error_codes.h"
21#include "pvmf_omx_basedec_port.h"
22#include "pv_mime_string_utils.h"
23#include "oscl_snprintf.h"
24#include "pvmf_media_cmd.h"
25#include "pvmf_media_msg_format_ids.h"
26#include "pvmi_kvp_util.h"
27// needed for capability and config
28#include "pv_omx_config_parser.h"
29
30
31#include "OMX_Core.h"
32#include "pvmf_omx_basedec_callbacks.h"     //used for thin AO in Decoder's callbacks
33#include "pv_omxcore.h"
34#include "OMX_Video.h"
35
36#include "utils/Log.h"
37#undef LOG_TAG
38#define LOG_TAG "PVOMXVidDecNode"
39
40#define CONFIG_SIZE_AND_VERSION(param) \
41        param.nSize=sizeof(param); \
42        param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR; \
43        param.nVersion.s.nVersionMinor = SPECVERSIONMINOR; \
44        param.nVersion.s.nRevision = SPECREVISION; \
45        param.nVersion.s.nStep = SPECSTEP;
46
47
48#define PVOMXVIDEODEC_EXTRA_YUVBUFFER_POOLNUM 3
49#define PVOMXVIDEODEC_MEDIADATA_POOLNUM (PVOMXVIDEODECMAXNUMDPBFRAMESPLUS1 + PVOMXVIDEODEC_EXTRA_YUVBUFFER_POOLNUM)
50
51
52// Node default settings
53#define PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF false
54#define PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF 0  // 0 (nopostproc),1(deblock),3(deblock&&dering)
55#define PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF false
56// H263 default settings
57#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF 40000
58#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN 20000
59#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX 120000
60#define PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF 352
61#define PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF 288
62#define PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN 4
63#define PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX 352
64// M4v default settings
65#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF 40000
66#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN 20000
67#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX 120000
68#define PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF 352
69#define PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF 288
70#define PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN 4
71#define PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX 352
72
73// AVC default settings
74#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_DEF 20000
75#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_MIN 20000
76#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_MAX 120000
77#define PVOMXVIDEODECNODE_CONFIG_AVCMAXWIDTH_DEF 352
78#define PVOMXVIDEODECNODE_CONFIG_AVCMAXHEIGHT_DEF 288
79#define PVOMXVIDEODECNODE_CONFIG_AVCMAXDIMENSION_MIN 4
80#define PVOMXVIDEODECNODE_CONFIG_AVCMAXDIMENSION_MAX 352
81
82/* WMV default settings */
83#define PVOMXVIDEODECNODE_CONFIG_WMVMAXWIDTH_DEF 352
84#define PVOMXVIDEODECNODE_CONFIG_WMVMAXHEIGHT_DEF 288
85
86
87#define PVMF_OMXVIDEODEC_NUM_METADATA_VALUES 6
88
89// Constant character strings for metadata keys
90static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY[] = "codec-info/video/format";
91static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY[] = "codec-info/video/width";
92static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY[] = "codec-info/video/height";
93static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY[] = "codec-info/video/profile";
94static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY[] = "codec-info/video/level";
95static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY[] = "codec-info/video/avgbitrate";//(bits per sec)
96
97static const char PVOMXVIDEODECMETADATA_SEMICOLON[] = ";";
98
99/////////////////////////////////////////////////////////////////////////////
100// Class Destructor
101/////////////////////////////////////////////////////////////////////////////
102PVMFOMXVideoDecNode::~PVMFOMXVideoDecNode()
103{
104    ReleaseAllPorts();
105}
106
107/////////////////////////////////////////////////////////////////////////////
108// Add AO to the scheduler
109/////////////////////////////////////////////////////////////////////////////
110PVMFStatus PVMFOMXVideoDecNode::ThreadLogon()
111{
112    PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXVideoDecNode:ThreadLogon"));
113
114    switch (iInterfaceState)
115    {
116        case EPVMFNodeCreated:
117            if (!IsAdded())
118            {
119                AddToScheduler();
120                iIsAdded = true;
121            }
122            iLogger = PVLogger::GetLoggerObject("PVMFOMXVideoDecNode");
123            iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXVideoDecNode");
124            iDataPathLogger = PVLogger::GetLoggerObject("datapath");
125            iClockLogger = PVLogger::GetLoggerObject("clock");
126            iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.decnode.OMXVideoDecnode");
127
128            SetState(EPVMFNodeIdle);
129            return PVMFSuccess;
130        default:
131            return PVMFErrInvalidState;
132    }
133}
134
135/////////////////////
136// Private Section //
137/////////////////////
138
139/////////////////////////////////////////////////////////////////////////////
140// Class Constructor
141/////////////////////////////////////////////////////////////////////////////
142PVMFOMXVideoDecNode::PVMFOMXVideoDecNode(int32 aPriority, bool aHwAccelerated) :
143        PVMFOMXBaseDecNode(aPriority, "PVMFOMXVideoDecNode", aHwAccelerated),
144        iH263MaxBitstreamFrameSize(PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF),
145        iH263MaxWidth(PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF),
146        iH263MaxHeight(PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF),
147        iM4VMaxBitstreamFrameSize(PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF),
148        iM4VMaxWidth(PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF),
149        iM4VMaxHeight(PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF),
150        iNewWidth(0),
151        iNewHeight(0)
152{
153    iInterfaceState = EPVMFNodeCreated;
154
155    iNodeConfig.iPostProcessingEnable = PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF;
156    iNodeConfig.iPostProcessingMode = PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF;
157    iNodeConfig.iDropFrame = PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF;
158    iNodeConfig.iMimeType = PVMF_MIME_FORMAT_UNKNOWN;
159
160
161    int32 err;
162    OSCL_TRY(err,
163
164             //Create the input command queue.  Use a reserve to avoid lots of
165             //dynamic memory allocation.
166             iInputCommands.Construct(PVMF_OMXBASEDEC_NODE_COMMAND_ID_START, PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE);
167
168             //Create the "current command" queue.  It will only contain one
169             //command at a time, so use a reserve of 1.
170             iCurrentCommand.Construct(0, 1);
171
172             //Set the node capability data.
173             //This node can support an unlimited number of ports.
174             iCapability.iCanSupportMultipleInputPorts = false;
175             iCapability.iCanSupportMultipleOutputPorts = false;
176             iCapability.iHasMaxNumberOfPorts = true;
177             iCapability.iMaxNumberOfPorts = 2;
178             iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_MP4);
179             iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_RAW);
180             iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO);
181             iCapability.iInputFormatCapability.push_back(PVMF_MIME_M4V);
182             iCapability.iInputFormatCapability.push_back(PVMF_MIME_H2631998);
183             iCapability.iInputFormatCapability.push_back(PVMF_MIME_H2632000);
184             iCapability.iInputFormatCapability.push_back(PVMF_MIME_WMV);
185             iCapability.iOutputFormatCapability.push_back(PVMF_MIME_YUV420);
186
187             iAvailableMetadataKeys.reserve(PVMF_OMXVIDEODEC_NUM_METADATA_VALUES);
188             iAvailableMetadataKeys.clear();
189            );
190
191    // need to init this allocator since verifyParameterSync (using the buffers) may be called through
192    // port interface before anything else happens.
193    OSCL_TRY(err, iFsiFragmentAlloc.size(PVOMXVIDEODEC_MEDIADATA_POOLNUM, sizeof(PVMFYuvFormatSpecificInfo0)));
194
195    OSCL_TRY(err, iPrivateDataFsiFragmentAlloc.size(PVOMXVIDEODEC_MEDIADATA_POOLNUM, sizeof(OsclAny *)));
196
197    iLastYUVWidth = 0;
198    iLastYUVHeight = 0;
199    iStride = 0;
200    iSliceHeight = 0;
201}
202
203/////////////////////////////////////////////////////////////////////////////
204// This routine will handle the PortReEnable state
205/////////////////////////////////////////////////////////////////////////////
206PVMFStatus PVMFOMXVideoDecNode::HandlePortReEnable()
207{
208    // set the port index so that we get parameters for the proper port
209    iParamPort.nPortIndex = iPortIndexForDynamicReconfig;
210
211    CONFIG_SIZE_AND_VERSION(iParamPort);
212
213    // get new parameters of the port
214    OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
215
216    // send command for port re-enabling (for this to happen, we must first recreate the buffers)
217    OMX_SendCommand(iOMXDecoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL);
218
219    // is this output port?
220    if (iPortIndexForDynamicReconfig == iOutputPortIndex)
221    {
222        // set the new width / height
223        iYUVWidth =  iParamPort.format.video.nFrameWidth;
224        iYUVHeight = iParamPort.format.video.nFrameHeight;
225
226        iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
227
228        // do we need to increase the number of buffers?
229        if (iNumOutputBuffers < iParamPort.nBufferCountMin)
230            iNumOutputBuffers = iParamPort.nBufferCountMin;
231
232        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
233                        (0, "PVMFOMXVideoDecNode::HandlePortReEnable() new output buffers %d, size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
234
235        iStride = OSCL_ABS(iParamPort.format.video.nStride);
236        iSliceHeight = iParamPort.format.video.nSliceHeight;
237
238        // This should not happen. If it does, it is a bug in the OMX component.
239        OSCL_ASSERT( (iStride < iParamPort.format.video.nFrameWidth) || (iSliceHeight < iParamPort.format.video.nFrameHeight) );
240        if (iStride < iParamPort.format.video.nFrameWidth)
241        {
242            iStride = iParamPort.format.video.nFrameWidth;
243        }
244
245        if (iSliceHeight < iParamPort.format.video.nFrameHeight)
246        {
247            iSliceHeight = iParamPort.format.video.nFrameHeight;
248        }
249
250        // Before allocating new set of output buffers, re-send Video FSI to
251        // media output node in case of dynamic port reconfiguration
252
253        sendFsi = true;
254        iCompactFSISettingSucceeded = false;
255
256        iLastYUVWidth = iYUVWidth ;
257        iLastYUVHeight = iYUVHeight;
258
259        // Check if Fsi configuration need to be sent
260        if (sendFsi)
261        {
262            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
263                            (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Re-sending YUV FSI after Dynamic port reconfiguration"));
264
265            int fsiErrorCode = 0;
266            OsclRefCounterMemFrag yuvFsiMemfrag;
267
268            OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get(););
269
270            OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
271                                 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Failed to allocate memory for FSI")));
272
273            if (fsiErrorCode == 0)
274            {
275                PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0());
276                if (fsiInfo != NULL)
277                {
278                    fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID;
279                    fsiInfo->video_format = iYUVFormat;
280                    fsiInfo->display_width = iYUVWidth;
281                    fsiInfo->display_height = iYUVHeight;
282                    fsiInfo->num_buffers = iNumOutputBuffers;
283                    fsiInfo->buffer_size = iOMXComponentOutputBufferSize;
284                    fsiInfo->width = iStride;
285                    fsiInfo->height = iSliceHeight;
286
287                    OsclMemAllocator alloc;
288                    int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV) + 1;
289                    PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
290
291                    if (NULL == KvpKey)
292                    {
293                        return false;
294                    }
295
296                    oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV, KeyLength);
297                    int32 err;
298
299                    OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey););
300                    if (err != OsclErrNone)
301                    {
302                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
303                                        (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem to set FSI"));
304
305                    }
306                    else
307                    {
308                        sendFsi = false;
309                        iCompactFSISettingSucceeded = true;
310                    }
311
312
313
314                    alloc.deallocate((OsclAny*)(KvpKey));
315                    fsiInfo->video_format.~PVMFFormatType();
316                }
317                else
318                {
319                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
320                                    (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem allocating Output FSI"));
321                    SetState(EPVMFNodeError);
322                    ReportErrorEvent(PVMFErrNoMemory);
323                    return false; // this is going to make everything go out of scope
324                }
325            }
326            else
327            {
328                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
329                                (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem allocating Output FSI"));
330                return false; // this is going to make everything go out of scope
331            }
332
333
334        }
335
336        //Buffer allocation has to be done again in case we landed to port reconfiguration
337        PvmiKvp* kvp = NULL;
338        int numKvp = 0;
339        PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
340        int32 err, err1;
341        ipExternalOutputBufferAllocatorInterface = NULL;
342
343        OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
344
345        if ((err == OsclErrNone) && (NULL != kvp))
346        {
347            ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;
348
349            if (ipExternalOutputBufferAllocatorInterface)
350            {
351                PVInterface* pTempPVInterfacePtr = NULL;
352
353                OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
354
355                OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
356
357                if (err1 != OsclErrNone)
358                {
359                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
360                                    (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Unable to Release Parameters"));
361                }
362
363                if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
364                {
365                    ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
366
367                    uint32 iNumBuffers, iBufferSize;
368
369                    iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
370                    iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
371
372                    if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
373                    {
374                        ipExternalOutputBufferAllocatorInterface->removeRef();
375                        ipExternalOutputBufferAllocatorInterface = NULL;
376                    }
377                    else
378                    {
379                        iNumOutputBuffers = iNumBuffers;
380                        iOMXComponentOutputBufferSize = iBufferSize;
381                    }
382                }
383                else
384                {
385                    ipExternalOutputBufferAllocatorInterface->removeRef();
386                    ipExternalOutputBufferAllocatorInterface = NULL;
387                }
388            }
389        }
390
391
392        /* Allocate output buffers */
393        if (!CreateOutMemPool(iNumOutputBuffers))
394        {
395
396            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
397                            (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate output buffers "));
398
399            SetState(EPVMFNodeError);
400            ReportErrorEvent(PVMFErrNoMemory);
401            return PVMFErrNoMemory;
402        }
403
404        if (out_ctrl_struct_ptr == NULL)
405        {
406
407            out_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
408
409            if (out_ctrl_struct_ptr == NULL)
410            {
411                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
412                                (0, "PVMFOMXVideoDecNode::HandlePortReEnable() out_ctrl_struct_ptr == NULL"));
413
414                SetState(EPVMFNodeError);
415                ReportErrorEvent(PVMFErrNoMemory);
416                return PVMFErrNoMemory;
417            }
418        }
419
420        if (out_buff_hdr_ptr == NULL)
421        {
422
423            out_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *));
424
425            if (out_buff_hdr_ptr == NULL)
426            {
427                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
428                                (0, "PVMFOMXVideoDecNode::HandlePortReEnable()  out_buff_hdr_ptr == NULL"));
429
430                SetState(EPVMFNodeError);
431                ReportErrorEvent(PVMFErrNoMemory);
432                return PVMFErrNoMemory;
433            }
434        }
435
436
437        if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
438                                       iOutputAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
439                                       iNumOutputBuffers, // number of buffers
440                                       iOMXComponentOutputBufferSize, // actual buffer size
441                                       iOutputPortIndex, // port idx
442                                       iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
443                                       false // this is not input
444                                      ))
445        {
446
447
448            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
449                            (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide output buffers to component"));
450
451            SetState(EPVMFNodeError);
452            ReportErrorEvent(PVMFErrNoMemory);
453            return PVMFErrNoMemory;
454
455        }
456
457        // do not drop output any more, i.e. enable output to be sent downstream
458        iDoNotSendOutputBuffersDownstreamFlag = false;
459
460
461    }
462    else
463    {
464        // this is input port
465
466        iOMXComponentInputBufferSize = iParamPort.nBufferSize;
467        // do we need to increase the number of buffers?
468        if (iNumInputBuffers < iParamPort.nBufferCountMin)
469            iNumInputBuffers = iParamPort.nBufferCountMin;
470
471        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
472                        (0, "PVMFOMXVideoDecNode::HandlePortReEnable() new buffers %d, size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
473
474        /* Allocate input buffers */
475        if (!CreateInputMemPool(iNumInputBuffers))
476        {
477            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
478                            (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate new input buffers to component"));
479
480            SetState(EPVMFNodeError);
481            ReportErrorEvent(PVMFErrNoMemory);
482            return PVMFErrNoMemory;
483        }
484
485        if (in_ctrl_struct_ptr == NULL)
486        {
487
488            in_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
489
490            if (in_ctrl_struct_ptr == NULL)
491            {
492                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
493                                (0, "PVMFOMXVideoDecNode::HandlePortReEnable() in_ctrl_struct_ptr == NULL"));
494
495                SetState(EPVMFNodeError);
496                ReportErrorEvent(PVMFErrNoMemory);
497                return PVMFErrNoMemory;
498            }
499        }
500
501        if (in_buff_hdr_ptr == NULL)
502        {
503
504            in_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *));
505
506            if (in_buff_hdr_ptr == NULL)
507            {
508                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
509                                (0, "PVMFOMXVideoDecNode::HandlePortReEnable()  in_buff_hdr_ptr == NULL"));
510
511                SetState(EPVMFNodeError);
512                ReportErrorEvent(PVMFErrNoMemory);
513                return PVMFErrNoMemory;
514            }
515        }
516
517        if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
518                                       iInputAllocSize,  // size to allocate from pool (hdr only or hdr+ buffer)
519                                       iNumInputBuffers, // number of buffers
520                                       iOMXComponentInputBufferSize, // actual buffer size
521                                       iInputPortIndex, // port idx
522                                       iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
523                                       true // this is input
524                                      ))
525        {
526
527
528            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
529                            (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide new input buffers to component"));
530
531            SetState(EPVMFNodeError);
532            ReportErrorEvent(PVMFErrNoMemory);
533            return PVMFErrNoMemory;
534
535        }
536        // do not drop partially consumed input
537        iDoNotSaveInputBuffersFlag = false;
538
539
540    }
541
542    // if the callback that the port was re-enabled has not arrived yet, wait for it
543    // if it has arrived, it will set the state to either PortReconfig or to ReadyToDecode
544    if (iProcessingState != EPVMFOMXBaseDecNodeProcessingState_PortReconfig &&
545            iProcessingState != EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode)
546        iProcessingState = EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable;
547
548    return PVMFSuccess; // allow rescheduling of the node
549}
550////////////////////////////////////////////////////////////////////////////////
551bool PVMFOMXVideoDecNode::NegotiateComponentParameters(OMX_PTR aOutputParameters)
552{
553    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
554                    (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() In"));
555
556    OMX_ERRORTYPE Err;
557    // first get the number of ports and port indices
558    OMX_PORT_PARAM_TYPE VideoPortParameters;
559    uint32 NumPorts;
560    uint32 ii;
561
562    //set version and size;
563    CONFIG_SIZE_AND_VERSION(VideoPortParameters);
564    // get starting number
565    Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoInit, &VideoPortParameters);
566    NumPorts = VideoPortParameters.nPorts; // must be at least 2 of them (in&out)
567
568    if (Err != OMX_ErrorNone || NumPorts < 2)
569    {
570        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
571                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() There is insuffucient (%d) ports", NumPorts));
572        return false;
573    }
574
575
576    // loop through video ports starting from the starting index to find index of the first input port
577    for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
578    {
579        // get port parameters, and determine if it is input or output
580        // if there are more than 2 ports, the first one we encounter that has input direction is picked
581
582        CONFIG_SIZE_AND_VERSION(iParamPort);
583
584        //port
585        iParamPort.nPortIndex = ii; // iInputPortIndex; //OMF_MC_H264D_PORT_INDEX_OF_STREAM;
586        Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
587
588        if (Err != OMX_ErrorNone)
589        {
590            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
591                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
592
593            return false;
594        }
595
596        if (iParamPort.eDir == OMX_DirInput)
597        {
598            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
599                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Found Input port index %d ", ii));
600
601            iInputPortIndex = ii;
602            break;
603        }
604    }
605    if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
606    {
607        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
608                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Cannot find any input port "));
609        return false;
610    }
611
612
613    // loop through video ports starting from the starting index to find index of the first output port
614    for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++)
615    {
616        // get port parameters, and determine if it is input or output
617        // if there are more than 2 ports, the first one we encounter that has output direction is picked
618
619        CONFIG_SIZE_AND_VERSION(iParamPort);
620
621        //port
622        iParamPort.nPortIndex = ii;
623        Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
624
625        if (Err != OMX_ErrorNone)
626        {
627            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
628                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
629
630            return false;
631        }
632
633        if (iParamPort.eDir == OMX_DirOutput)
634        {
635            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
636                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Found Output port index %d ", ii));
637
638            iOutputPortIndex = ii;
639            break;
640        }
641    }
642    if (ii == VideoPortParameters.nStartPortNumber + NumPorts)
643    {
644        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
645                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Cannot find any output port "));
646        return false;
647    }
648
649
650
651    // now get input parameters
652    CONFIG_SIZE_AND_VERSION(iParamPort);
653
654    //Input port
655    iParamPort.nPortIndex = iInputPortIndex;
656    Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
657    if (Err != OMX_ErrorNone)
658    {
659        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
660                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with input port %d ", iInputPortIndex));
661        return false;
662    }
663
664    // preset the number of input buffers
665
666    //iNumInputBuffers = NUMBER_INPUT_BUFFER;
667    iNumInputBuffers = iParamPort.nBufferCountActual;  // use the value provided by component
668
669    // do we need to increase the number of buffers?
670    if (iNumInputBuffers < iParamPort.nBufferCountMin)
671        iNumInputBuffers = iParamPort.nBufferCountMin;
672    iOMXComponentInputBufferSize = iParamPort.nBufferSize;
673
674    iParamPort.nBufferCountActual = iNumInputBuffers;
675
676    // set the number of actual input buffers
677    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
678                    (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Inport buffers %d,size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
679
680
681    VideoOMXConfigParserOutputs *pOutputParameters;
682
683    pOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
684
685
686    // set the width/height on INPUT port parameters (this may change during port reconfig)
687    if ((pOutputParameters->width != 0) && (pOutputParameters->height != 0))
688    {
689        iParamPort.format.video.nFrameWidth = pOutputParameters->width;
690        iParamPort.format.video.nFrameHeight = pOutputParameters->height;
691    }
692
693    CONFIG_SIZE_AND_VERSION(iParamPort);
694    Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
695    if (Err != OMX_ErrorNone)
696    {
697        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
698                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in input port %d ", iInputPortIndex));
699        return false;
700    }
701
702    //Port 1 for output port
703    iParamPort.nPortIndex = iOutputPortIndex;
704    CONFIG_SIZE_AND_VERSION(iParamPort);
705    Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
706    if (Err != OMX_ErrorNone)
707    {
708        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
709                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
710        return false;
711    }
712
713    // check if params are OK. In case of H263, width/height cannot be obtained until
714    // 1st frame is decoded, so read them from the output port.
715    // otherwise, used Width/Height from the config parser utility
716    // set the width/height based on port parameters (this may change during port reconfig)
717    if ((pOutputParameters->width != 0) && (pOutputParameters->height != 0) && iInPort && (((PVMFOMXDecPort*)iInPort)->iFormat != PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat != PVMF_MIME_H2632000))
718    {
719		// set width and height obtained from config parser in the output port as well
720		iParamPort.format.video.nFrameWidth = pOutputParameters->width;
721        iParamPort.format.video.nFrameHeight = pOutputParameters->height;
722        iYUVWidth  = pOutputParameters->width;
723        iYUVHeight = pOutputParameters->height;
724    }
725    else
726    {
727        iYUVWidth =  iParamPort.format.video.nFrameWidth;
728        iYUVHeight = iParamPort.format.video.nFrameHeight;
729    }
730
731	// Send the parameters right away to allow the OMX component to re-calculate the buffer size
732	// based on the new width and height that was just provided
733	CONFIG_SIZE_AND_VERSION(iParamPort);
734
735    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
736                    (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
737
738    Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
739    if (Err != OMX_ErrorNone)
740    {
741        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
742                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex));
743        return false;
744    }
745
746	// Now - read the same parameters back again with potentially new buffer sizes
747	iParamPort.nPortIndex = iOutputPortIndex;
748    CONFIG_SIZE_AND_VERSION(iParamPort);
749    Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
750    if (Err != OMX_ErrorNone)
751    {
752        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
753                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
754        return false;
755    }
756
757
758    //iNumOutputBuffers = NUMBER_OUTPUT_BUFFER;
759    iNumOutputBuffers = iParamPort.nBufferCountActual;
760    if (iNumOutputBuffers > NUMBER_OUTPUT_BUFFER)
761        iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; // make sure number of output buffers is not larger than port queue size
762
763    iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
764    if (iNumOutputBuffers < iParamPort.nBufferCountMin)
765        iNumOutputBuffers = iParamPort.nBufferCountMin;
766
767    iStride = OSCL_ABS(iParamPort.format.video.nStride);
768    iSliceHeight = iParamPort.format.video.nSliceHeight;
769
770    // This should not happen. If it does, it is a bug in the OMX component.
771    OSCL_ASSERT( (iStride < iParamPort.format.video.nFrameWidth) || (iSliceHeight < iParamPort.format.video.nFrameHeight) );
772    if (iStride < iParamPort.format.video.nFrameWidth)
773    {
774        iStride = iParamPort.format.video.nFrameWidth;
775    }
776
777    if(iSliceHeight < iParamPort.format.video.nFrameHeight)
778    {
779        iSliceHeight = iParamPort.format.video.nFrameHeight;
780    }
781
782    //Send the FSI information to media output node here, before setting output
783    //port parameters to the omx component
784
785    if (iLastYUVWidth != iYUVWidth || iYUVHeight != iLastYUVHeight)
786    {
787        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
788                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Sending YUV FSI"));
789
790        // set a flag to send Fsi configuration
791        sendFsi = true;
792        iCompactFSISettingSucceeded = false;
793        //store new values for reference
794        iLastYUVWidth = iYUVWidth ;
795        iLastYUVHeight = iYUVHeight;
796    }
797
798{
799    // Get video color format
800    OMX_VIDEO_PARAM_PORTFORMATTYPE VideoPortFormat;
801    // init to unknown
802    iOMXVideoColorFormat = OMX_COLOR_FormatUnused;
803    CONFIG_SIZE_AND_VERSION(VideoPortFormat);
804    VideoPortFormat.nPortIndex = iOutputPortIndex;
805
806    VideoPortFormat.nIndex = 0; // read the preferred format - first
807
808// doing this in a while loop while incrementing nIndex will get all supported formats
809// until component says OMX_ErrorNoMore
810// For now, we just use the preferred one (with nIndex=0) assuming it is supported at MIO
811
812    Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat);
813    if (Err != OMX_ErrorNone)
814    {
815        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
816                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem getting video port format"));
817        return false;
818    }
819    // check if color format is valid and set DeBlocking
820    if (VideoPortFormat.eCompressionFormat == OMX_VIDEO_CodingUnused)
821    {
822        // color format is valid, so read it
823        iOMXVideoColorFormat = VideoPortFormat.eColorFormat;
824
825        // Now set the format to confirm parameters
826        CONFIG_SIZE_AND_VERSION(VideoPortFormat);
827
828        Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat);
829        if (Err != OMX_ErrorNone)
830        {
831            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
832                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video port format"));
833            return false;
834        }
835    }
836
837    // now that we have the color format, interpret it
838    if (iOMXVideoColorFormat == OMX_COLOR_Format8bitRGB332)
839    {
840        iYUVFormat = PVMF_MIME_RGB8;
841    }
842    else if (iOMXVideoColorFormat == OMX_COLOR_Format12bitRGB444)
843    {
844        iYUVFormat = PVMF_MIME_RGB12;
845    }
846    else if (iOMXVideoColorFormat >= OMX_COLOR_Format16bitARGB4444 && iOMXVideoColorFormat <= OMX_COLOR_Format16bitBGR565)
847    {
848        iYUVFormat = PVMF_MIME_RGB16;
849    }
850    else if (iOMXVideoColorFormat >= OMX_COLOR_Format24bitRGB888 && iOMXVideoColorFormat <= OMX_COLOR_Format24bitARGB1887)
851    {
852        iYUVFormat = PVMF_MIME_RGB24;
853    }
854    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420Planar)
855    {
856        iYUVFormat = PVMF_MIME_YUV420_PLANAR; // Y, U, V are separate - entire planes
857    }
858    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420PackedPlanar)
859    {
860        iYUVFormat = PVMF_MIME_YUV420_PACKEDPLANAR; // each slice contains Y,U,V separate
861    }
862    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
863    {
864        iYUVFormat = PVMF_MIME_YUV420_SEMIPLANAR; // Y and UV interleaved - entire planes
865    }
866    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar)
867    {
868        iYUVFormat = PVMF_MIME_YUV420_PACKEDSEMIPLANAR; // Y and UV interleaved - sliced
869    }
870    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422Planar)
871    {
872        iYUVFormat = PVMF_MIME_YUV422_PLANAR; // Y, U, V are separate - entire planes
873    }
874    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422PackedPlanar)
875    {
876        iYUVFormat = PVMF_MIME_YUV422_PACKEDPLANAR; // each slice contains Y,U,V separate
877    }
878    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422SemiPlanar)
879    {
880        iYUVFormat = PVMF_MIME_YUV422_SEMIPLANAR; // Y and UV interleaved - entire planes
881    }
882    else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422PackedSemiPlanar)
883    {
884        iYUVFormat = PVMF_MIME_YUV422_PACKEDSEMIPLANAR; // Y and UV interleaved - sliced
885    }
886    else if (iOMXVideoColorFormat == OMX_COLOR_FormatCbYCrY)
887    {
888        iYUVFormat = PVMF_MIME_YUV422_INTERLEAVED_UYVY; // Y, U, V interleaved
889    }
890    else if (iOMXVideoColorFormat == 0x7FA30C00) // SPECIAL VALUE
891    {
892        iYUVFormat = PVMF_MIME_YUV420_SEMIPLANAR_YVU; // semiplanar with Y and VU interleaved
893    }
894    else
895    {
896        iYUVFormat = PVMF_MIME_FORMAT_UNKNOWN;
897        return false;
898    }
899}
900
901    // Check if Fsi configuration need to be sent
902    if (sendFsi)
903    {
904        int fsiErrorCode = 0;
905        OsclRefCounterMemFrag yuvFsiMemfrag;
906
907        OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get(););
908
909        OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
910                             (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Failed to allocate memory for FSI")));
911
912        if (fsiErrorCode == 0)
913        {
914            PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0());
915            if (fsiInfo != NULL)
916            {
917                fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID;
918                fsiInfo->video_format = iYUVFormat;
919                fsiInfo->display_width = iYUVWidth;
920                fsiInfo->display_height = iYUVHeight;
921                fsiInfo->num_buffers = iNumOutputBuffers;
922                fsiInfo->buffer_size = iOMXComponentOutputBufferSize;
923                fsiInfo->width = iStride;
924                fsiInfo->height = iSliceHeight;
925
926                OsclMemAllocator alloc;
927                int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV) + 1;
928                PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
929
930                if (NULL == KvpKey)
931                {
932                    return false;
933                }
934
935                oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV, KeyLength);
936                int32 err;
937
938                OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey););
939
940                if (err != OsclErrNone)
941                {
942                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
943                                    (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem to set FSI"));
944                }
945                else
946                {
947                    iCompactFSISettingSucceeded = true;
948                    sendFsi = false;
949                }
950
951
952                alloc.deallocate((OsclAny*)(KvpKey));
953                fsiInfo->video_format.~PVMFFormatType();
954            }
955            else
956            {
957                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
958                                (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
959                SetState(EPVMFNodeError);
960                ReportErrorEvent(PVMFErrNoMemory);
961                return false; // this is going to make everything go out of scope
962            }
963        }
964        else
965        {
966            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
967                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
968            return false; // this is going to make everything go out of scope
969        }
970
971
972    }
973
974    //Try querying the buffer allocator KVP for output buffer allocation outside the node
975
976    PvmiKvp* kvp = NULL;
977    int numKvp = 0;
978    PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
979    int32 err, err1;
980    ipExternalOutputBufferAllocatorInterface = NULL;
981
982    OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
983
984    if ((err == OsclErrNone) && (NULL != kvp))
985    {
986        ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;
987
988        if (ipExternalOutputBufferAllocatorInterface)
989        {
990            PVInterface* pTempPVInterfacePtr = NULL;
991
992            OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
993
994            OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
995
996            if (err1 != OsclErrNone)
997            {
998                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
999                                (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Unable to Release Parameters"));
1000            }
1001
1002
1003            if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
1004            {
1005                ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
1006
1007                uint32 iNumBuffers, iBufferSize;
1008
1009                iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
1010                iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
1011
1012                if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
1013                {
1014                    ipExternalOutputBufferAllocatorInterface->removeRef();
1015                    ipExternalOutputBufferAllocatorInterface = NULL;
1016                }
1017                else
1018                {
1019                    iNumOutputBuffers = iNumBuffers;
1020                    iOMXComponentOutputBufferSize = iBufferSize;
1021                }
1022            }
1023            else
1024            {
1025                ipExternalOutputBufferAllocatorInterface->removeRef();
1026                ipExternalOutputBufferAllocatorInterface = NULL;
1027
1028            }
1029        }
1030    }
1031
1032
1033    iParamPort.nBufferCountActual = iNumOutputBuffers;
1034    CONFIG_SIZE_AND_VERSION(iParamPort);
1035
1036    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1037                    (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
1038
1039    Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1040    if (Err != OMX_ErrorNone)
1041    {
1042        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1043                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex));
1044        return false;
1045    }
1046
1047
1048    //Set input video format
1049    //This is need it since a single component could handle differents roles
1050
1051    // Init to desire format
1052    PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
1053    if (iInPort != NULL)
1054    {
1055        Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
1056    }
1057    if (Format == PVMF_MIME_H264_VIDEO ||
1058            Format == PVMF_MIME_H264_VIDEO_MP4 ||
1059            Format == PVMF_MIME_H264_VIDEO_RAW)
1060    {
1061        iOMXVideoCompressionFormat = OMX_VIDEO_CodingAVC;
1062    }
1063    else if (Format == PVMF_MIME_M4V)
1064    {
1065        iOMXVideoCompressionFormat = OMX_VIDEO_CodingMPEG4;
1066    }
1067    else if (Format == PVMF_MIME_H2631998 ||
1068             Format == PVMF_MIME_H2632000)
1069    {
1070        iOMXVideoCompressionFormat = OMX_VIDEO_CodingH263;
1071    }
1072    else if (Format == PVMF_MIME_WMV)
1073    {
1074        iOMXVideoCompressionFormat = OMX_VIDEO_CodingWMV;
1075    }
1076    else
1077    {
1078        // Illegal codec specified.
1079        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1080                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format"));
1081        return false;
1082    }
1083
1084    if ((iOMXVideoCompressionFormat == OMX_VIDEO_CodingMPEG4) ||
1085            (iOMXVideoCompressionFormat == OMX_VIDEO_CodingH263))
1086    {
1087        // Enable deblocking for these two video types
1088        OMX_PARAM_DEBLOCKINGTYPE DeBlock;
1089        CONFIG_SIZE_AND_VERSION(DeBlock);
1090
1091        DeBlock.nPortIndex = iOutputPortIndex;
1092        DeBlock.bDeblocking = OMX_TRUE;
1093
1094        Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamCommonDeblocking, &DeBlock);
1095        if (Err != OMX_ErrorNone)
1096        {
1097            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1098                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting deblocking flag"));
1099            // Dont return false in this case.  If enabling DeBlocking fails, just continue.
1100        }
1101    }
1102
1103    OMX_VIDEO_PARAM_PORTFORMATTYPE VideoPortFormat;
1104    CONFIG_SIZE_AND_VERSION(VideoPortFormat);
1105    VideoPortFormat.nPortIndex = iInputPortIndex;
1106
1107    // Search the proper format index and set it.
1108    // Since we already know that the component has the role we need, search until finding the proper nIndex
1109    // if component does not find the format will return OMX_ErrorNoMore
1110
1111    for (ii = 0;; ii++)
1112    {
1113        VideoPortFormat.nIndex = ii;
1114        Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat);
1115        if (Err != OMX_ErrorNone)
1116        {
1117            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1118                            (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format"));
1119            return false;
1120        }
1121        if (iOMXVideoCompressionFormat == VideoPortFormat.eCompressionFormat)
1122        {
1123            break;
1124        }
1125    }
1126    // Now set the format to confirm parameters
1127    Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat);
1128    if (Err != OMX_ErrorNone)
1129    {
1130        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1131                        (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format"));
1132        return false;
1133    }
1134
1135    return true;
1136}
1137
1138/////////////////////////////////////////////////////////////////////////////
1139bool PVMFOMXVideoDecNode::InitDecoder(PVMFSharedMediaDataPtr& DataIn)
1140{
1141    OSCL_UNUSED_ARG(DataIn);
1142
1143    uint16 length = 0, size = 0;
1144    uint8 *tmp_ptr;
1145    PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
1146
1147    OsclRefCounterMemFrag DataFrag;
1148    OsclRefCounterMemFrag refCtrMemFragOut;
1149
1150
1151
1152    // NOTE: the component may not start decoding without providing the Output buffer to it,
1153    //      here, we're sending input/config buffers.
1154    //      Then, we'll go to ReadyToDecode state and send output as well
1155
1156    if (iInPort != NULL)
1157    {
1158        Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
1159    }
1160    if (Format == PVMF_MIME_H264_VIDEO ||
1161            Format == PVMF_MIME_H264_VIDEO_MP4)
1162    {
1163        uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig();
1164        int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize();
1165
1166        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for H264 Decoder. Initialization data Size %d.", initbufsize));
1167
1168        if (initbufsize > 0)
1169        {
1170
1171            // there may be more than 1 NAL in config info in format specific data memfragment (SPS, PPS)
1172            tmp_ptr = initbuffer;
1173            do
1174            {
1175                length = (uint16)(tmp_ptr[1] << 8) | tmp_ptr[0];
1176                size += (length + 2);
1177                if (size > initbufsize)
1178                    break;
1179                tmp_ptr += 2;
1180
1181
1182                if (!SendConfigBufferToOMXComponent(tmp_ptr, length))
1183                {
1184                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1185                                    (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer"));
1186                    return false;
1187
1188                }
1189
1190                tmp_ptr += length;
1191
1192            }
1193            while (size < initbufsize);
1194        }
1195    }
1196    else if (Format == PVMF_MIME_M4V ||
1197             Format == PVMF_MIME_H2631998 ||
1198             Format == PVMF_MIME_H2632000)
1199    {
1200        uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig();
1201        int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize();
1202
1203        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for H263 Decoder. Initialization data Size %d.", initbufsize));
1204
1205        // for H263, the initbufsize is 0, and initbuf= NULL. Config is done after 1st frame of data
1206        if (initbufsize > 0)
1207        {
1208
1209            if (!SendConfigBufferToOMXComponent(initbuffer, initbufsize))
1210            {
1211                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1212                                (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer"));
1213                return false;
1214            }
1215        }
1216    }
1217    else if (Format == PVMF_MIME_WMV)
1218    {
1219        uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig();
1220        int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize();
1221
1222        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for WMV Decoder. Initialization data Size %d.", initbufsize));
1223
1224        if (initbufsize > 0)
1225        {
1226
1227            if (!SendConfigBufferToOMXComponent(initbuffer, initbufsize))
1228            {
1229                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1230                                (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer"));
1231                return false;
1232            }
1233        }
1234    }
1235    else
1236    {
1237        // Unknown codec type
1238        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1239                        (0, "PVMFOMXVideoDecNode::InitDecoder() Unknown codec type"));
1240        return false;
1241    }
1242
1243    //Varibles initialization
1244    //sendFsi = true;
1245
1246    return true;
1247}
1248
1249
1250
1251/////////////////////////////////////////////////////////////////////////////
1252////////////////////// CALLBACK PROCESSING FOR EVENT HANDLER
1253/////////////////////////////////////////////////////////////////////////////
1254OMX_ERRORTYPE PVMFOMXVideoDecNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
1255        OMX_OUT OMX_PTR aAppData,
1256        OMX_OUT OMX_EVENTTYPE aEvent,
1257        OMX_OUT OMX_U32 aData1,
1258        OMX_OUT OMX_U32 aData2,
1259        OMX_OUT OMX_PTR aEventData)
1260{
1261    OSCL_UNUSED_ARG(aComponent);
1262    OSCL_UNUSED_ARG(aAppData);
1263    OSCL_UNUSED_ARG(aEventData);
1264
1265    switch (aEvent)
1266    {
1267        case OMX_EventCmdComplete:
1268        {
1269
1270            switch (aData1)
1271            {
1272                case OMX_CommandStateSet:
1273                {
1274                    HandleComponentStateChange(aData2);
1275                    break;
1276                }
1277                case OMX_CommandFlush:
1278                {
1279
1280                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1281                                    (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandFlush - completed on port %d", aData2));
1282
1283                    if (iIsRepositioningRequestSentToComponent)
1284                    {
1285                        if (aData2 == iOutputPortIndex)
1286                        {
1287                            iIsOutputPortFlushed = true;
1288                        }
1289                        else if (aData2 == iInputPortIndex)
1290                        {
1291                            iIsInputPortFlushed = true;
1292                        }
1293
1294                        if (iIsOutputPortFlushed && iIsInputPortFlushed)
1295                        {
1296                            iIsRepositionDoneReceivedFromComponent = true;
1297                        }
1298                    }
1299
1300                    if (IsAdded())
1301                        RunIfNotReady();
1302
1303                }
1304                break;
1305
1306                case OMX_CommandPortDisable:
1307                {
1308                    // if port disable command is done, we can re-allocate the buffers and re-enable the port
1309
1310                    iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReEnable;
1311                    iPortIndexForDynamicReconfig =  aData2;
1312
1313                    RunIfNotReady();
1314                    break;
1315                }
1316                case OMX_CommandPortEnable:
1317                    // port enable command is done. Check if the other port also reported change.
1318                    // If not, we can start data flow. Otherwise, must start dynamic reconfig procedure for
1319                    // the other port as well.
1320                {
1321                    if (iSecondPortReportedChange)
1322                    {
1323                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1324                                        (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, dynamic reconfiguration needed on port %d", aData2, iSecondPortToReconfig));
1325
1326                        iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig;
1327                        iPortIndexForDynamicReconfig = iSecondPortToReconfig;
1328                        iSecondPortReportedChange = false;
1329                    }
1330                    else
1331                    {
1332                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1333                                        (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, resuming normal data flow", aData2));
1334                        iProcessingState = EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode;
1335                        iDynamicReconfigInProgress = false;
1336                        // in case pause or stop command was sent to component
1337                        // change processing state (because the node might otherwise
1338                        // start sending buffers to component before pause/stop is processed)
1339                        if (iPauseCommandWasSentToComponent)
1340                        {
1341                            iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Pausing;
1342                        }
1343                        if (iStopCommandWasSentToComponent)
1344                        {
1345                            iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Stopping;
1346                        }
1347                    }
1348                    RunIfNotReady();
1349                    break;
1350                }
1351
1352                case OMX_CommandMarkBuffer:
1353                    // nothing to do here yet;
1354                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1355                                    (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandMarkBuffer - completed - no action taken"));
1356
1357                    break;
1358
1359                default:
1360                {
1361                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1362                                    (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: Unsupported event"));
1363                    break;
1364                }
1365            }//end of switch (aData1)
1366
1367            break;
1368        }//end of case OMX_EventCmdComplete
1369
1370        case OMX_EventError:
1371        {
1372
1373            LOGE("Ln %d OMX_EventError nData1 %d nData2 %d", __LINE__, aData1, aData2);
1374            if (aData1 == (OMX_U32) OMX_ErrorStreamCorrupt)
1375            {
1376                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1377                                (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError - Bitstream corrupt error"));
1378                // Errors from corrupt bitstream are reported as info events
1379                ReportInfoEvent(PVMFInfoProcessingFailure, NULL);
1380
1381            }
1382            else if (aData1 == (OMX_U32) OMX_ErrorInvalidState)
1383            {
1384                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1385                                (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState"));
1386                HandleComponentStateChange(OMX_StateInvalid);
1387            }
1388            else
1389            {
1390
1391                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1392                                (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError"));
1393                // for now, any error from the component will be reported as error
1394                ReportErrorEvent(PVMFErrProcessing, NULL, NULL);
1395                SetState(EPVMFNodeError);
1396            }
1397            break;
1398
1399        }
1400
1401        case OMX_EventBufferFlag:
1402        {
1403            // the component is reporting it encountered end of stream flag
1404            // we'll send eos when we get the actual last buffer with marked eos
1405
1406            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1407                            (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventBufferFlag (EOS) flag returned from OMX component"));
1408
1409            RunIfNotReady();
1410            break;
1411        }//end of case OMX_EventBufferFlag
1412
1413        case OMX_EventMark:
1414        {
1415
1416            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1417                            (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventMark returned from OMX component - no action taken"));
1418
1419            RunIfNotReady();
1420            break;
1421        }//end of case OMX_EventMark
1422
1423        case OMX_EventPortSettingsChanged:
1424        {
1425
1426            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1427                            (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned from OMX component"));
1428
1429            // first check if dynamic reconfiguration is already in progress,
1430            // if so, wait until this is completed, and then initiate the 2nd reconfiguration
1431            if (iDynamicReconfigInProgress)
1432            {
1433                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1434                                (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d, dynamic reconfig already in progress", aData1));
1435
1436                iSecondPortToReconfig = aData1;
1437                iSecondPortReportedChange = true;
1438            }
1439            else
1440            {
1441                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1442                                (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d", aData1));
1443
1444                iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig;
1445                iPortIndexForDynamicReconfig = aData1;
1446                iDynamicReconfigInProgress = true;
1447            }
1448
1449            RunIfNotReady();
1450            break;
1451        }//end of case OMX_PortSettingsChanged
1452
1453        case OMX_EventResourcesAcquired:        //not supported
1454        {
1455            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1456                            (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventResourcesAcquired returned from OMX component - no action taken"));
1457
1458            RunIfNotReady();
1459
1460            break;
1461        }
1462
1463        default:
1464        {
1465            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1466                            (0, "PVMFOMXVideoDecNode::EventHandlerProcessing:  Unknown Event returned from OMX component - no action taken"));
1467
1468            break;
1469        }
1470
1471    }//end of switch (eEvent)
1472
1473
1474
1475    return OMX_ErrorNone;
1476}
1477
1478
1479
1480
1481////////////////////////////////////////////////////////////////////////////////////////////////
1482///////////////////////////// Put output buffer in outgoing queue //////////////////////////////
1483////////////////////////////////////////////////////////////////////////////////////////////////
1484bool PVMFOMXVideoDecNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen)
1485{
1486
1487    bool status = true;
1488    PVMFSharedMediaDataPtr mediaDataOut;
1489    int32 leavecode = OsclErrNone;
1490
1491    // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS
1492    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1493                    (0, "PVMFOMXVideoDecNode::QueueOutputFrame: In"));
1494
1495    // First check if we can put outgoing msg. into the queue
1496    if (iOutPort->IsOutgoingQueueBusy())
1497    {
1498        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1499                        (0, "PVMFOMXVideoDecNode::QueueOutputFrame() OutgoingQueue is busy"));
1500        return false;
1501    }
1502
1503    OSCL_TRY(leavecode,
1504             mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iMediaDataMemPool););
1505    if (OsclErrNone == leavecode)
1506    {
1507
1508        // Update the filled length of the fragment
1509        mediaDataOut->setMediaFragFilledLen(0, aDataLen);
1510
1511        // Set timestamp
1512        mediaDataOut->setTimestamp(iOutTimeStamp);
1513
1514        // Set Streamid
1515        mediaDataOut->setStreamID(iStreamID);
1516
1517        // Set sequence number
1518        mediaDataOut->setSeqNum(iSeqNum++);
1519
1520        PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXVideoDecNode::QueueOutputFrame(): - SeqNum=%d, TS=%d", iSeqNum, iOutTimeStamp));
1521
1522        int fsiErrorCode = 0;
1523
1524
1525        // Check if Fsi configuration need to be sent
1526        if (sendFsi && !iCompactFSISettingSucceeded)
1527        {
1528            OsclRefCounterMemFrag yuvFsiMemfrag;
1529
1530            OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get(););
1531
1532            OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1533                                 (0, "PVMFOMXVideoDecNode::RemoveOutputFrame() Failed to allocate memory for  FSI")));
1534
1535            if (fsiErrorCode == 0)
1536            {
1537                PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0());
1538                if (fsiInfo != NULL)
1539                {
1540                    fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID;
1541                    fsiInfo->video_format = iYUVFormat;
1542                    fsiInfo->display_width = iYUVWidth;
1543                    fsiInfo->display_height = iYUVHeight;
1544                    fsiInfo->width = iStride;
1545                    fsiInfo->height = iSliceHeight;
1546                    fsiInfo->buffer_size = iOMXComponentOutputBufferSize;
1547
1548                    OsclMemAllocator alloc;
1549                    int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1;
1550                    PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
1551
1552                    if (NULL == KvpKey)
1553                    {
1554                        SetState(EPVMFNodeError);
1555                        ReportErrorEvent(PVMFErrNoMemory);
1556                        return false;
1557                    }
1558
1559                    oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY, KeyLength);
1560                    int32 err;
1561
1562                    OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey););
1563                    if (err != OsclErrNone)
1564                    {
1565                        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1566                                        (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem to set FSI"));
1567                    }
1568
1569                    alloc.deallocate((OsclAny*)(KvpKey));
1570                    fsiInfo->video_format.~PVMFFormatType();
1571                }
1572                else
1573                {
1574                    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1575                                    (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI"));
1576                    SetState(EPVMFNodeError);
1577                    ReportErrorEvent(PVMFErrNoMemory);
1578                    return false; // this is going to make everything go out of scope
1579                }
1580            }
1581            else
1582            {
1583                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1584                                (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI"));
1585                return false; // this is going to make everything go out of scope
1586            }
1587
1588            // Reset the flag
1589            sendFsi = false;
1590        }
1591
1592
1593        // in case of special YVU format, attach fsi to every outgoing message containing ptr to private data
1594        if (iYUVFormat == PVMF_MIME_YUV420_SEMIPLANAR_YVU)
1595        {
1596            OsclRefCounterMemFrag privatedataFsiMemFrag;
1597
1598            OSCL_TRY(fsiErrorCode, privatedataFsiMemFrag = iPrivateDataFsiFragmentAlloc.get(););
1599
1600            OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1601                                 (0, "PVMFOMXVideoDecNode::RemoveOutputFrame() Failed to allocate memory for  FSI for private data")));
1602
1603            if (fsiErrorCode == 0)
1604            {
1605                uint8 *fsiptr = (uint8*) privatedataFsiMemFrag.getMemFragPtr();
1606                privatedataFsiMemFrag.getMemFrag().len = sizeof(OsclAny*);
1607                oscl_memcpy(fsiptr, &ipPrivateData, sizeof(OsclAny *)); // store ptr data into fsi
1608                mediaDataOut->setFormatSpecificInfo(privatedataFsiMemFrag);
1609            }
1610            else
1611            {
1612                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1613                                (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI for private data"));
1614                SetState(EPVMFNodeError);
1615                ReportErrorEvent(PVMFErrNoMemory);
1616                return false; // this is going to make everything go out of scope
1617            }
1618        }
1619
1620
1621        if (fsiErrorCode == 0)
1622        {
1623            // Send frame to downstream node
1624            PVMFSharedMediaMsgPtr mediaMsgOut;
1625            convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut);
1626
1627            if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess))
1628            {
1629                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO,
1630                                (0, "PVMFOMXVideoDecNode::QueueOutputFrame(): Queued frame OK "));
1631
1632            }
1633            else
1634            {
1635                // we should not get here because we always check for whether queue is busy or not
1636                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1637                                (0, "PVMFOMXVideoDecNode::QueueOutputFrame(): Send frame failed"));
1638                return false;
1639            }
1640
1641        }
1642
1643
1644    }//end of if (leavecode==0)
1645    else
1646    {
1647        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1648                        (0, "PVMFOMXVideoDecNode::QueueOutputFrame() call PVMFMediaData::createMediaData is failed"));
1649        return false;
1650    }
1651
1652    return status;
1653
1654}
1655
1656/////////////////////////////////////////////////////////////////////////////
1657void PVMFOMXVideoDecNode::DoRequestPort(PVMFOMXBaseDecNodeCommand& aCmd)
1658{
1659    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1660                    (0, "PVMFOMXVideoDecNode::DoRequestPort() In"));
1661    //This node supports port request from any state
1662
1663    //retrieve port tag.
1664    int32 tag;
1665    OSCL_String* portconfig;
1666
1667    aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(tag, portconfig);
1668
1669    PVMFPortInterface* port = NULL;
1670    int32 leavecode = OsclErrNone;
1671    //validate the tag...
1672    switch (tag)
1673    {
1674        case PVMF_OMX_DEC_NODE_PORT_TYPE_INPUT:
1675            if (iInPort)
1676            {
1677                CommandComplete(iInputCommands, aCmd, PVMFFailure);
1678                break;
1679            }
1680            OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, PVMF_OMX_VIDEO_DEC_INPUT_PORT_NAME)););
1681            if (leavecode || iInPort == NULL)
1682            {
1683                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1684                                (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Input port instantiation failed"));
1685                CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
1686                return;
1687            }
1688            port = iInPort;
1689            break;
1690
1691        case PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT:
1692            if (iOutPort)
1693            {
1694                CommandComplete(iInputCommands, aCmd, PVMFFailure);
1695                break;
1696            }
1697            OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, PVMF_OMX_VIDEO_DEC_OUTPUT_PORT_NAME)));
1698            if (leavecode || iOutPort == NULL)
1699            {
1700                PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1701                                (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Output port instantiation failed"));
1702                CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
1703                return;
1704            }
1705            port = iOutPort;
1706            break;
1707
1708        default:
1709            //bad port tag
1710            PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1711                            (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Invalid port tag"));
1712            CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
1713            return;
1714    }
1715
1716    //Return the port pointer to the caller.
1717    CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port);
1718}
1719
1720/////////////////////////////////////////////////////////////////////////////
1721void PVMFOMXVideoDecNode::DoReleasePort(PVMFOMXBaseDecNodeCommand& aCmd)
1722{
1723    PVMFPortInterface* p = NULL;
1724    aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(p);
1725    PVMFOMXDecPort* port = (PVMFOMXDecPort*)p;
1726
1727    if (port != NULL && (port == iInPort || port == iOutPort))
1728    {
1729        if (port == iInPort)
1730        {
1731            OSCL_DELETE(((PVMFOMXDecPort*)iInPort));
1732            iInPort = NULL;
1733        }
1734        else
1735        {
1736            OSCL_DELETE(((PVMFOMXDecPort*)iOutPort));
1737            iOutPort = NULL;
1738        }
1739        //delete the port.
1740        CommandComplete(iInputCommands, aCmd, PVMFSuccess);
1741    }
1742    else
1743    {
1744        //port not found.
1745        CommandComplete(iInputCommands, aCmd, PVMFFailure);
1746    }
1747}
1748
1749/////////////////////////////////////////////////////////////////////////////
1750PVMFStatus PVMFOMXVideoDecNode::DoGetNodeMetadataKey(PVMFOMXBaseDecNodeCommand& aCmd)
1751{
1752    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1753                    (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataKey() In"));
1754
1755    PVMFMetadataList* keylistptr = NULL;
1756    uint32 starting_index;
1757    int32 max_entries;
1758    char* query_key;
1759
1760    aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
1761
1762    // Check parameters
1763    if (keylistptr == NULL)
1764    {
1765        // The list pointer is invalid
1766        return PVMFErrArgument;
1767    }
1768
1769    // Update the available metadata keys
1770    iAvailableMetadataKeys.clear();
1771    int32 leavecode = OsclErrNone;
1772    leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY, iAvailableMetadataKeys);
1773    if (OsclErrNone != leavecode)
1774    {
1775        return PVMFErrNoMemory;
1776    }
1777
1778    if (iYUVWidth > 0 && iYUVHeight > 0)
1779    {
1780        leavecode = OsclErrNone;
1781        leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY, iAvailableMetadataKeys);
1782        if (OsclErrNone != leavecode)
1783        {
1784            return PVMFErrNoMemory;
1785        }
1786
1787        leavecode = OsclErrNone;
1788        leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, iAvailableMetadataKeys);
1789        if (OsclErrNone != leavecode)
1790        {
1791            return PVMFErrNoMemory;
1792        }
1793    }
1794    // add the profile, level and avgbitrate
1795    PVMF_MPEGVideoProfileType aProfile;
1796    PVMF_MPEGVideoLevelType aLevel;
1797    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
1798    {
1799        // For H263 this metadata will be available only after first frame decoding
1800        leavecode = OsclErrNone;
1801        leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY, iAvailableMetadataKeys);
1802        if (leavecode != OsclErrNone)
1803        {
1804            return PVMFErrNoMemory;
1805        }
1806
1807        leavecode = OsclErrNone;
1808        leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY, iAvailableMetadataKeys);
1809        if (OsclErrNone != leavecode)
1810        {
1811            return PVMFErrNoMemory;
1812        }
1813    }
1814    leavecode = OsclErrNone;
1815    leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, iAvailableMetadataKeys);
1816    if (OsclErrNone != leavecode)
1817    {
1818        return PVMFErrNoMemory;
1819    }
1820
1821    if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
1822    {
1823        // Invalid starting index and/or max entries
1824        return PVMFErrArgument;
1825    }
1826
1827    // Copy the requested keys
1828    uint32 num_entries = 0;
1829    int32 num_added = 0;
1830    for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
1831    {
1832        if (query_key == NULL)
1833        {
1834            // No query key so this key is counted
1835            ++num_entries;
1836            if (num_entries > starting_index)
1837            {
1838                // Past the starting index so copy the key
1839                leavecode = OsclErrNone;
1840                leavecode = PushKVPKey(iAvailableMetadataKeys[lcv] , keylistptr);
1841                if (OsclErrNone != leavecode)
1842                {
1843                    return PVMFErrNoMemory;
1844                }
1845                num_added++;
1846            }
1847        }
1848        else
1849        {
1850            // Check if the key matche the query key
1851            if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
1852            {
1853                // This key is counted
1854                ++num_entries;
1855                if (num_entries > starting_index)
1856                {
1857                    // Past the starting index so copy the key
1858                    leavecode = OsclErrNone;
1859                    leavecode = PushKVPKey(iAvailableMetadataKeys[lcv] , keylistptr);
1860                    if (OsclErrNone != leavecode)
1861                    {
1862                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key"));
1863                        return PVMFErrNoMemory;
1864                    }
1865                    num_added++;
1866                }
1867            }
1868        }
1869
1870        // Check if max number of entries have been copied
1871        if (max_entries > 0 && num_added >= max_entries)
1872        {
1873            break;
1874        }
1875    }
1876
1877    return PVMFSuccess;
1878}
1879
1880/////////////////////////////////////////////////////////////////////////////
1881PVMFStatus PVMFOMXVideoDecNode::DoGetNodeMetadataValue(PVMFOMXBaseDecNodeCommand& aCmd)
1882{
1883    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataValue() In"));
1884
1885    PVMFMetadataList* keylistptr = NULL;
1886    Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
1887    uint32 starting_index;
1888    int32 max_entries;
1889
1890    aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
1891
1892    // Check the parameters
1893    if (keylistptr == NULL || valuelistptr == NULL)
1894    {
1895        return PVMFErrArgument;
1896    }
1897
1898    uint32 numkeys = keylistptr->size();
1899
1900    if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
1901    {
1902        // Don't do anything
1903        return PVMFErrArgument;
1904    }
1905
1906    uint32 numvalentries = 0;
1907    int32 numentriesadded = 0;
1908    for (uint32 lcv = 0; lcv < numkeys; lcv++)
1909    {
1910        int32 leavecode = OsclErrNone;
1911        int32 leavecode1 = OsclErrNone;
1912        PvmiKvp KeyVal;
1913        KeyVal.key = NULL;
1914        uint32 KeyLen = 0;
1915
1916        if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
1917                iYUVWidth > 0)
1918        {
1919            // Video width
1920            // Increment the counter for the number of values found so far
1921            ++numvalentries;
1922
1923            // Create a value entry if past the starting index
1924            if (numvalentries > starting_index)
1925            {
1926                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1; // for "codec-info/video/width;"
1927                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1928                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1929
1930                // Allocate memory for the string
1931                leavecode = OsclErrNone;
1932                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1933                if (OsclErrNone == leavecode)
1934                {
1935                    // Copy the key string
1936                    oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1);
1937                    oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
1938                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1939                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1940                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1941                    // Copy the value
1942                    KeyVal.value.uint32_value = iYUVWidth;
1943                    // Set the length and capacity
1944                    KeyVal.length = 1;
1945                    KeyVal.capacity = 1;
1946                }
1947                else
1948                {
1949                    // Memory allocation failed
1950                    KeyVal.key = NULL;
1951                    break;
1952                }
1953            }
1954        }
1955        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
1956                 iYUVHeight > 0)
1957        {
1958            // Video height
1959            // Increment the counter for the number of values found so far
1960            ++numvalentries;
1961
1962            // Create a value entry if past the starting index
1963            if (numvalentries > starting_index)
1964            {
1965                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1; // for "codec-info/video/height;"
1966                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
1967                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
1968
1969                // Allocate memory for the string
1970                leavecode = OsclErrNone;
1971                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
1972                if (OsclErrNone == leavecode)
1973                {
1974                    // Copy the key string
1975                    oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1);
1976                    oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
1977                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
1978                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
1979                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
1980                    // Copy the value
1981                    KeyVal.value.uint32_value = iYUVHeight;
1982                    // Set the length and capacity
1983                    KeyVal.length = 1;
1984                    KeyVal.capacity = 1;
1985                }
1986                else
1987                {
1988                    // Memory allocation failed
1989                    KeyVal.key = NULL;
1990                    break;
1991                }
1992            }
1993        }
1994        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0))
1995        {
1996            // Video profile
1997            // Increment the counter for the number of values found so far
1998            ++numvalentries;
1999
2000            // Create a value entry if past the starting index
2001            if (numvalentries > starting_index)
2002            {
2003                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1; // for "codec-info/video/profile;"
2004                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2005                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
2006
2007                // Allocate memory for the string
2008                leavecode = OsclErrNone;
2009                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2010
2011                if (OsclErrNone == leavecode)
2012                {
2013                    PVMF_MPEGVideoProfileType aProfile;
2014                    PVMF_MPEGVideoLevelType aLevel;
2015                    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
2016                    {
2017                        // Copy the key string
2018                        oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1);
2019                        oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
2020                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2021                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
2022                        KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2023                        // Copy the value
2024                        KeyVal.value.uint32_value = (uint32)aProfile; // This is to be decided, who will interpret these value
2025                        // Set the length and capacity
2026                        KeyVal.length = 1;
2027                        KeyVal.capacity = 1;
2028                    }
2029                    else
2030                    {
2031                        // Memory allocation failed
2032                        KeyVal.key = NULL;
2033                        break;
2034                    }
2035                }
2036                else
2037                {
2038                    // Memory allocation failed
2039                    KeyVal.key = NULL;
2040                    break;
2041                }
2042            }
2043        }
2044        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0))
2045        {
2046            // Video level
2047            // Increment the counter for the number of values found so far
2048            ++numvalentries;
2049
2050            // Create a value entry if past the starting index
2051            if (numvalentries > starting_index)
2052            {
2053                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1; // for "codec-info/video/level;"
2054                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2055                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
2056
2057                // Allocate memory for the string
2058                leavecode = OsclErrNone;
2059                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2060
2061                if (OsclErrNone == leavecode)
2062                {
2063                    PVMF_MPEGVideoProfileType aProfile;
2064                    PVMF_MPEGVideoLevelType aLevel;
2065                    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
2066                    {
2067                        // Copy the key string
2068                        oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1);
2069                        oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
2070                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2071                        oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
2072                        KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2073                        // Copy the value
2074                        KeyVal.value.uint32_value = (uint32)aLevel; // This is to be decided, who will interpret these value
2075                        // Set the length and capacity
2076                        KeyVal.length = 1;
2077                        KeyVal.capacity = 1;
2078                    }
2079                    else
2080                    {
2081                        // Memory allocation failed
2082                        KeyVal.key = NULL;
2083                        break;
2084                    }
2085                }
2086                else
2087                {
2088                    // Memory allocation failed
2089                    KeyVal.key = NULL;
2090                    break;
2091                }
2092            }
2093        }
2094        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
2095                 (iAvgBitrateValue > 0))
2096        {
2097            // Video average bitrate
2098            // Increment the counter for the number of values found so far
2099            ++numvalentries;
2100
2101            // Create a value entry if past the starting index
2102            if (numvalentries > starting_index)
2103            {
2104                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1; // for "codec-info/video/avgbitrate;"
2105                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2106                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
2107
2108                // Allocate memory for the string
2109                leavecode = OsclErrNone;
2110                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2111
2112                if (OsclErrNone == leavecode)
2113                {
2114                    // Copy the key string
2115                    oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1);
2116                    oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
2117                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2118                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
2119                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2120                    // Copy the value
2121                    KeyVal.value.uint32_value = iAvgBitrateValue;
2122                    // Set the length and capacity
2123                    KeyVal.length = 1;
2124                    KeyVal.capacity = 1;
2125
2126                }
2127                else
2128                {
2129                    // Memory allocation failed
2130                    KeyVal.key = NULL;
2131                    break;
2132                }
2133            }
2134        }
2135        else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
2136                 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000 ||
2137                  ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V ||
2138                  ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 ||
2139                  ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW  || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV))
2140        {
2141            // Format
2142            // Increment the counter for the number of values found so far
2143            ++numvalentries;
2144
2145            // Create a value entry if past the starting index
2146            if (numvalentries > starting_index)
2147            {
2148                KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1; // for "codec-info/video/format;"
2149                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2150                KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
2151
2152                uint32 valuelen = 0;
2153
2154                if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
2155                {
2156                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO)) + 1; // Value string plus one for NULL terminator
2157                }
2158                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
2159                {
2160                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4)) + 1; // Value string plus one for NULL terminator
2161                }
2162                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
2163                {
2164                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW)) + 1; // Value string plus one for NULL terminator
2165                }
2166                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V)
2167                {
2168                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_M4V)) + 1; // Value string plus one for NULL terminator
2169                }
2170                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
2171                {
2172                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2631998)) + 1; // Value string plus one for NULL terminator
2173                }
2174                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
2175                {
2176                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2632000)) + 1; // Value string plus one for NULL terminator
2177                }
2178                else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV)
2179                {
2180                    valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMV)) + 1; // Value string plus one for NULL terminator
2181                }
2182                else
2183                {
2184                    // Should not enter here
2185                    OSCL_ASSERT(false);
2186                    valuelen = 1;
2187                }
2188
2189                // Allocate memory for the strings
2190                leavecode = OsclErrNone;
2191                KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2192                if (OsclErrNone == leavecode)
2193                {
2194                    KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen);
2195                }
2196
2197                if (OsclErrNone == leavecode && OsclErrNone == leavecode1)
2198                {
2199                    // Copy the key string
2200                    oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1);
2201                    oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON));
2202                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2203                    oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
2204                    KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2205                    // Copy the value
2206                    if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO)
2207                    {
2208                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO), valuelen);
2209                    }
2210                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4)
2211                    {
2212                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), valuelen);
2213                    }
2214                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)
2215                    {
2216                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW), valuelen);
2217                    }
2218                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V)
2219                    {
2220                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_M4V), valuelen);
2221                    }
2222                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998)
2223                    {
2224                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2631998), valuelen);
2225                    }
2226                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000)
2227                    {
2228                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen);
2229                    }
2230                    else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV)
2231                    {
2232                        oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMV), valuelen);
2233                    }
2234                    else
2235                    {
2236                        // Should not enter here
2237                        OSCL_ASSERT(false);
2238                    }
2239                    KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
2240                    // Set the length and capacity
2241                    KeyVal.length = valuelen;
2242                    KeyVal.capacity = valuelen;
2243                }
2244                else
2245                {
2246                    // Memory allocation failed so clean up
2247                    if (KeyVal.key)
2248                    {
2249                        OSCL_ARRAY_DELETE(KeyVal.key);
2250                        KeyVal.key = NULL;
2251                    }
2252                    if (KeyVal.value.pChar_value)
2253                    {
2254                        OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
2255                    }
2256                    break;
2257                }
2258            }
2259        }
2260
2261        if (KeyVal.key != NULL)
2262        {
2263            leavecode = OsclErrNone;
2264            leavecode = PushKVP(KeyVal, *valuelistptr);
2265            if (OsclErrNone != leavecode)
2266            {
2267                switch (GetValTypeFromKeyString(KeyVal.key))
2268                {
2269                    case PVMI_KVPVALTYPE_CHARPTR:
2270                        if (KeyVal.value.pChar_value != NULL)
2271                        {
2272                            OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
2273                            KeyVal.value.pChar_value = NULL;
2274                        }
2275                        break;
2276
2277                    default:
2278                        // Add more case statements if other value types are returned
2279                        break;
2280                }
2281
2282                OSCL_ARRAY_DELETE(KeyVal.key);
2283                KeyVal.key = NULL;
2284            }
2285            else
2286            {
2287                // Increment the counter for number of value entries added to the list
2288                ++numentriesadded;
2289            }
2290
2291            // Check if the max number of value entries were added
2292            if (max_entries > 0 && numentriesadded >= max_entries)
2293            {
2294                break;
2295            }
2296        }
2297    }
2298
2299    return PVMFSuccess;
2300}
2301
2302/////////////////////////////////////////////////////////////////////////////
2303bool PVMFOMXVideoDecNode::ReleaseAllPorts()
2304{
2305    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::ReleaseAllPorts() In"));
2306
2307    if (iInPort)
2308    {
2309        iInPort->ClearMsgQueues();
2310        iInPort->Disconnect();
2311        OSCL_DELETE(((PVMFOMXDecPort*)iInPort));
2312        iInPort = NULL;
2313    }
2314
2315    if (iOutPort)
2316    {
2317        iOutPort->ClearMsgQueues();
2318        iOutPort->Disconnect();
2319        OSCL_DELETE(((PVMFOMXDecPort*)iOutPort));
2320        iOutPort = NULL;
2321    }
2322
2323    return true;
2324}
2325
2326/////////////////////////////////////////////////////////////////////////////
2327void PVMFOMXVideoDecNode::DoQueryUuid(PVMFOMXBaseDecNodeCommand& aCmd)
2328{
2329    //This node supports Query UUID from any state
2330
2331    OSCL_String* mimetype;
2332    Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
2333    bool exactmatch;
2334    aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
2335
2336    //Try to match the input mimetype against any of
2337    //the custom interfaces for this node
2338
2339    //Match against custom interface1...
2340    if (*mimetype == PVMF_OMX_BASE_DEC_NODE_CUSTOM1_MIMETYPE
2341            //also match against base mimetypes for custom interface1,
2342            //unless exactmatch is set.
2343            || (!exactmatch && *mimetype == PVMF_OMX_VIDEO_DEC_NODE_MIMETYPE)
2344            || (!exactmatch && *mimetype == PVMF_BASEMIMETYPE))
2345    {
2346
2347        PVUuid uuid(PVMF_OMX_BASE_DEC_NODE_CUSTOM1_UUID);
2348        uuidvec->push_back(uuid);
2349    }
2350    CommandComplete(iInputCommands, aCmd, PVMFSuccess);
2351}
2352
2353/////////////////////////////////////////////////////////////////////////////
2354uint32 PVMFOMXVideoDecNode::GetNumMetadataKeys(char* aQueryKeyString)
2355{
2356    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetNumMetadataKeys() called"));
2357
2358    // Update the available metadata keys
2359    iAvailableMetadataKeys.clear();
2360    int32 errcode = OsclErrNone;
2361    OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY));
2362
2363    if (iYUVWidth > 0 && iYUVHeight > 0)
2364    {
2365        errcode = OsclErrNone;
2366        OSCL_TRY(errcode,
2367                 iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY);
2368                 iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY));
2369    }
2370    // add the profile, level and avgbitrate
2371    PVMF_MPEGVideoProfileType aProfile;
2372    PVMF_MPEGVideoLevelType aLevel;
2373    if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)
2374    {
2375        // For H263 this metadata will be available only after first frame decoding
2376        errcode = OsclErrNone;
2377        OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY));
2378        errcode = OsclErrNone;
2379        OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY));
2380    }
2381    errcode = OsclErrNone;
2382    OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY));
2383
2384
2385
2386    uint32 num_entries = 0;
2387
2388    if (aQueryKeyString == NULL)
2389    {
2390        num_entries = iAvailableMetadataKeys.size();
2391    }
2392    else
2393    {
2394        for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
2395        {
2396            if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
2397            {
2398                num_entries++;
2399            }
2400        }
2401    }
2402    return num_entries; // Number of elements
2403}
2404
2405/////////////////////////////////////////////////////////////////////////////
2406uint32 PVMFOMXVideoDecNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
2407{
2408    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetNumMetadataValues() called"));
2409
2410    uint32 numkeys = aKeyList.size();
2411
2412    if (numkeys <= 0)
2413    {
2414        // Don't do anything
2415        return 0;
2416    }
2417
2418    // Count the number of value entries for the provided key list
2419    uint32 numvalentries = 0;
2420    PVMF_MPEGVideoProfileType aProfile;
2421    PVMF_MPEGVideoLevelType aLevel;
2422    for (uint32 lcv = 0; lcv < numkeys; lcv++)
2423    {
2424        if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) &&
2425                iYUVWidth > 0)
2426        {
2427            // Video width
2428            ++numvalentries;
2429        }
2430        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) &&
2431                 iYUVHeight > 0)
2432        {
2433            // Video height
2434            ++numvalentries;
2435        }
2436        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0) &&
2437                 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))
2438
2439        {
2440            // Video profile
2441            ++numvalentries;
2442        }
2443        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0) &&
2444                 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess))
2445        {
2446            // Video level
2447            ++numvalentries;
2448        }
2449        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) &&
2450                 (iAvgBitrateValue > 0))
2451
2452        {
2453            // Video average bitrate
2454            if (iAvgBitrateValue > 0)
2455                ++numvalentries;
2456        }
2457        else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) &&
2458                 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW))
2459        {
2460            // Format
2461            ++numvalentries;
2462        }
2463    }
2464
2465    return numvalentries;
2466}
2467
2468////////////////////////////////////////////////////////////////////////////////////////////////
2469// CAPABILITY CONFIG PRIVATE
2470PVMFStatus PVMFOMXVideoDecNode::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
2471{
2472    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() In"));
2473    OSCL_UNUSED_ARG(aContext);
2474
2475    // Initialize the output parameters
2476    aNumParamElements = 0;
2477    aParameters = NULL;
2478
2479    // Count the number of components and parameters in the key
2480    int compcount = pv_mime_string_compcnt(aIdentifier);
2481    // Retrieve the first component from the key string
2482    char* compstr = NULL;
2483    pv_mime_string_extract_type(0, aIdentifier, compstr);
2484
2485    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 3)
2486    {
2487        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) < 0) || compcount != 3)
2488        {
2489            // First 3 component should be "x-pvmf/video/decoder" and there must
2490            // be at least three components
2491            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Unsupported key"));
2492            return PVMFErrArgument;
2493        }
2494    }
2495
2496    if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) >= 0)
2497    {
2498        aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS * sizeof(PvmiKvp));
2499        if (aParameters == NULL)
2500        {
2501            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
2502            return PVMFErrNoMemory;
2503        }
2504        oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS*sizeof(PvmiKvp));
2505        // Allocate memory for the key strings in each KVP
2506        PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
2507        if (memblock == NULL)
2508        {
2509            oscl_free(aParameters);
2510            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
2511            return PVMFErrNoMemory;
2512        }
2513        oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
2514        // Assign the key string buffer to each KVP
2515        int32 j;
2516        for (j = 0; j < PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS; ++j)
2517        {
2518            aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE);
2519        }
2520        // Copy the requested info
2521        for (j = 0; j < PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS; ++j)
2522        {
2523            oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/render/"), 20);
2524            oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigRenderKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigRenderKeys[j].iString));
2525            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype=uint32_value"), 21);
2526            aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
2527
2528            // Copy the requested info
2529            switch (j)
2530            {
2531                case 0: // "width"
2532                    // Return current value
2533                    aParameters[j].value.uint32_value = iNewWidth;
2534                    break;
2535                case 1: // "height"
2536                    aParameters[j].value.uint32_value = iNewHeight;
2537                    break;
2538                default:
2539                    break;
2540            }
2541        }
2542
2543        aNumParamElements = PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS;
2544    }
2545    else if (compcount == 3)
2546    {
2547        // Since key is "x-pvmf/video/decoder" return all
2548        // nodes available at this level. Ignore attribute
2549        // since capability is only allowed
2550
2551        // Allocate memory for the KVP list
2552        aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS * sizeof(PvmiKvp));
2553        if (aParameters == NULL)
2554        {
2555            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
2556            return PVMFErrNoMemory;
2557        }
2558        oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS*sizeof(PvmiKvp));
2559        // Allocate memory for the key strings in each KVP
2560        PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
2561        if (memblock == NULL)
2562        {
2563            oscl_free(aParameters);
2564            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
2565            return PVMFErrNoMemory;
2566        }
2567        oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
2568        // Assign the key string buffer to each KVP
2569        int32 j;
2570        for (j = 0; j < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++j)
2571        {
2572            aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE);
2573        }
2574        // Copy the requested info
2575        for (j = 0; j < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++j)
2576        {
2577            oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/"), 21);
2578            oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigBaseKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigBaseKeys[j].iString));
2579            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
2580            switch (PVOMXVideoDecNodeConfigBaseKeys[j].iType)
2581            {
2582                case PVMI_KVPTYPE_AGGREGATE:
2583                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
2584                    break;
2585
2586                case PVMI_KVPTYPE_POINTER:
2587                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
2588                    break;
2589
2590                case PVMI_KVPTYPE_VALUE:
2591                default:
2592                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
2593                    // Now append the valtype param
2594                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
2595                    switch (PVOMXVideoDecNodeConfigBaseKeys[j].iValueType)
2596                    {
2597                        case PVMI_KVPVALTYPE_BITARRAY32:
2598                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING));
2599                            break;
2600
2601                        case PVMI_KVPVALTYPE_UINT32:
2602                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
2603                            break;
2604
2605                        case PVMI_KVPVALTYPE_BOOL:
2606                        default:
2607                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
2608                            break;
2609                    }
2610                    break;
2611            }
2612
2613            aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
2614        }
2615
2616        aNumParamElements = PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS;
2617    }
2618    else
2619    {
2620        // Retrieve the fourth component from the key string
2621        pv_mime_string_extract_type(3, aIdentifier, compstr);
2622
2623        for (int32 vdeccomp4ind = 0; vdeccomp4ind < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++vdeccomp4ind)
2624        {
2625            // Go through each video dec component string at 4th level
2626            if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iString)) >= 0)
2627            {
2628                if (vdeccomp4ind == 3)
2629                {
2630                    // "x-pvmf/video/decoder/h263"
2631                    if (compcount == 4)
2632                    {
2633                        // Return list of H263 settings. Ignore the
2634                        // attribute since capability is only allowed
2635
2636                        // Allocate memory for the KVP list
2637                        aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_H263_NUMKEYS * sizeof(PvmiKvp));
2638                        if (aParameters == NULL)
2639                        {
2640                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
2641                            return PVMFErrNoMemory;
2642                        }
2643                        oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_H263_NUMKEYS*sizeof(PvmiKvp));
2644                        // Allocate memory for the key strings in each KVP
2645                        PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_H263_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
2646                        if (memblock == NULL)
2647                        {
2648                            oscl_free(aParameters);
2649                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
2650                            return PVMFErrNoMemory;
2651                        }
2652                        oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_H263_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
2653                        // Assign the key string buffer to each KVP
2654                        int32 j;
2655                        for (j = 0; j < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++j)
2656                        {
2657                            aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE);
2658                        }
2659                        // Copy the requested info
2660                        for (j = 0; j < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++j)
2661                        {
2662                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/h263/"), 26);
2663                            oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigH263Keys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigH263Keys[j].iString));
2664                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype="), 20);
2665                            switch (PVOMXVideoDecNodeConfigH263Keys[j].iValueType)
2666                            {
2667                                case PVMI_KVPVALTYPE_RANGE_UINT32:
2668                                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
2669                                    break;
2670
2671                                case PVMI_KVPVALTYPE_UINT32:
2672                                default:
2673                                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
2674                                    break;
2675                            }
2676
2677                            aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
2678                        }
2679
2680                        aNumParamElements = PVOMXVIDEODECNODECONFIG_H263_NUMKEYS;
2681                    }
2682                    else if (compcount > 4)
2683                    {
2684                        // Retrieve the fifth component from the key string
2685                        pv_mime_string_extract_type(4, aIdentifier, compstr);
2686
2687                        for (int32 vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++vdeccomp5ind)
2688                        {
2689                            if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iString)) >= 0)
2690                            {
2691                                // Determine what is requested
2692                                PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
2693                                if (reqattr == PVMI_KVPATTR_UNKNOWN)
2694                                {
2695                                    // Default is current setting
2696                                    reqattr = PVMI_KVPATTR_CUR;
2697                                }
2698
2699                                // Return the requested info
2700                                PVMFStatus retval = DoGetH263DecoderParameter(aParameters, aNumParamElements, vdeccomp5ind, reqattr);
2701                                if (retval != PVMFSuccess)
2702                                {
2703                                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving H.263 parameter failed"));
2704                                    return retval;
2705                                }
2706
2707                                // Break out of the for(vdeccomp5ind) loop
2708                                break;
2709                            }
2710                        }
2711                    }
2712                    else
2713                    {
2714                        // Right now video dec node doesn't support more than 5 components
2715                        // for the key sub-string so error out
2716                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key"));
2717                        return PVMFErrArgument;
2718                    }
2719                }
2720                else if (vdeccomp4ind == 4)
2721                {
2722                    // "x-pvmf/video/decoder/m4v"
2723                    if (compcount == 4)
2724                    {
2725                        // Return list of M4v settings. Ignore the
2726                        // attribute since capability is only allowed
2727
2728                        // Allocate memory for the KVP list
2729                        aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS * sizeof(PvmiKvp));
2730                        if (aParameters == NULL)
2731                        {
2732                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
2733                            return PVMFErrNoMemory;
2734                        }
2735                        oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS*sizeof(PvmiKvp));
2736                        // Allocate memory for the key strings in each KVP
2737                        PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
2738                        if (memblock == NULL)
2739                        {
2740                            oscl_free(aParameters);
2741                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
2742                            return PVMFErrNoMemory;
2743                        }
2744                        oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
2745                        // Assign the key string buffer to each KVP
2746                        int32 j;
2747                        for (j = 0; j < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++j)
2748                        {
2749                            aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE);
2750                        }
2751                        // Copy the requested info
2752                        for (j = 0; j < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++j)
2753                        {
2754                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/m4v/"), 25);
2755                            oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigM4VKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigM4VKeys[j].iString));
2756                            oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype="), 20);
2757                            switch (PVOMXVideoDecNodeConfigM4VKeys[j].iValueType)
2758                            {
2759                                case PVMI_KVPVALTYPE_RANGE_UINT32:
2760                                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
2761                                    break;
2762
2763                                case PVMI_KVPVALTYPE_UINT32:
2764                                default:
2765                                    oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
2766                                    break;
2767                            }
2768
2769                            aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
2770                        }
2771
2772                        aNumParamElements = PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS;
2773                    }
2774                    else if (compcount > 4)
2775                    {
2776                        // Retrieve the fifth component from the key string
2777                        pv_mime_string_extract_type(4, aIdentifier, compstr);
2778
2779                        for (int32 vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++vdeccomp5ind)
2780                        {
2781                            if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iString)) >= 0)
2782                            {
2783                                // Determine what is requested
2784                                PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
2785                                if (reqattr == PVMI_KVPATTR_UNKNOWN)
2786                                {
2787                                    // Default is current setting
2788                                    reqattr = PVMI_KVPATTR_CUR;
2789                                }
2790
2791                                // Return the requested info
2792                                PVMFStatus retval = DoGetM4VDecoderParameter(aParameters, aNumParamElements, vdeccomp5ind, reqattr);
2793                                if (retval != PVMFSuccess)
2794                                {
2795                                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving M4v parameter failed"));
2796                                    return retval;
2797                                }
2798
2799                                // Break out of the for(vdeccomp5ind) loop
2800                                break;
2801                            }
2802                        }
2803                    }
2804                    else
2805                    {
2806                        // Right now video dec node doesn't support more than 5 components
2807                        // for the key sub-string so error out
2808                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key"));
2809                        return PVMFErrArgument;
2810                    }
2811                }
2812                else if ((vdeccomp4ind == 0) || // "postproc_enable",
2813                         (vdeccomp4ind == 1) || // "postproc_type"
2814                         (vdeccomp4ind == 2) || // "dropframe_enable"
2815                         (vdeccomp4ind == 5)    // "format_type"
2816                        )
2817                {
2818                    if (compcount == 4)
2819                    {
2820                        // Determine what is requested
2821                        PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
2822                        if (reqattr == PVMI_KVPATTR_UNKNOWN)
2823                        {
2824                            reqattr = PVMI_KVPATTR_CUR;
2825                        }
2826
2827                        // Return the requested info
2828                        PVMFStatus retval = DoGetVideoDecNodeParameter(aParameters, aNumParamElements, vdeccomp4ind, reqattr);
2829                        if (retval != PVMFSuccess)
2830                        {
2831                            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving video dec node parameter failed"));
2832                            return retval;
2833                        }
2834                    }
2835                    else
2836                    {
2837                        // Right now videodec node doesn't support more than 4 components
2838                        // for this sub-key string so error out
2839                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key"));
2840                        return PVMFErrArgument;
2841                    }
2842                }
2843
2844                // Breakout of the for(vdeccomp4ind) loop
2845                break;
2846            }
2847        }
2848    }
2849
2850    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Out"));
2851    if (aNumParamElements == 0)
2852    {
2853        // If no one could get the parameter, return error
2854        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key"));
2855        return PVMFFailure;
2856    }
2857    else
2858    {
2859        return PVMFSuccess;
2860    }
2861}
2862
2863
2864PVMFStatus PVMFOMXVideoDecNode::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
2865{
2866    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() In"));
2867
2868    if (aParameters == NULL || aNumElements < 1)
2869    {
2870        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0"));
2871        return PVMFErrArgument;
2872    }
2873
2874    // Count the number of components and parameters in the key
2875    int compcount = pv_mime_string_compcnt(aParameters[0].key);
2876    // Retrieve the first component from the key string
2877    char* compstr = NULL;
2878    pv_mime_string_extract_type(0, aParameters[0].key, compstr);
2879
2880    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 3)
2881    {
2882        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) < 0) || compcount != 4)
2883        {
2884            // First 3 component should be "x-pvmf/video/decoder" and there must
2885            // be at least three components
2886            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Unsupported key"));
2887            return PVMFErrArgument;
2888        }
2889    }
2890
2891    if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) >= 0)
2892    {
2893        // Retrieve the third component from the key string
2894        pv_mime_string_extract_type(2, aParameters[0].key, compstr);
2895
2896        // Go through each KVP and release memory for value if allocated from heap
2897        for (int32 i = 0; i < aNumElements; ++i)
2898        {
2899            // Next check if it is a value type that allocated memory
2900            PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
2901            if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
2902            {
2903                PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
2904                if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
2905                {
2906                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Valtype not specified in key string"));
2907                    return PVMFErrArgument;
2908                }
2909
2910                if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
2911                {
2912                    oscl_free(aParameters[i].value.pChar_value);
2913                    aParameters[i].value.pChar_value = NULL;
2914                }
2915                else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
2916                {
2917                    oscl_free(aParameters[i].value.key_specific_value);
2918                    aParameters[i].value.key_specific_value = NULL;
2919                }
2920                else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
2921                {
2922                    range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
2923                    aParameters[i].value.key_specific_value = NULL;
2924                    oscl_free(rui32);
2925                }
2926
2927            }
2928        }
2929    }
2930    // Video dec node allocated its key strings in one chunk so just free the first key string ptr
2931    oscl_free(aParameters[0].key);
2932
2933    // Free memory for the parameter list
2934    oscl_free(aParameters);
2935    aParameters = NULL;
2936
2937    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Out"));
2938    return PVMFSuccess;
2939}
2940
2941
2942void PVMFOMXVideoDecNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
2943{
2944    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() In"));
2945
2946    if (aParameters == NULL || aNumElements < 1)
2947    {
2948        if (aParameters)
2949        {
2950            aRetKVP = aParameters;
2951        }
2952        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Passed in parameter invalid"));
2953        return;
2954    }
2955
2956    // Go through each parameter
2957    for (int32 paramind = 0; paramind < aNumElements; ++paramind)
2958    {
2959        // Count the number of components and parameters in the key
2960        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
2961        // Retrieve the first component from the key string
2962        char* compstr = NULL;
2963        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
2964
2965        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 4)
2966        {
2967            // First 3 components should be "x-pvmf/video/decoder" and there must
2968            // be at least four components
2969            aRetKVP = &aParameters[paramind];
2970            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key"));
2971            return;
2972        }
2973
2974        if (compcount == 4)
2975        {
2976            // Verify and set the passed-in video dec node setting
2977            PVMFStatus retval = DoVerifyAndSetVideoDecNodeParameter(aParameters[paramind], true);
2978            if (retval != PVMFSuccess)
2979            {
2980                aRetKVP = &aParameters[paramind];
2981                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
2982                return;
2983            }
2984        }
2985        else if (compcount == 5)
2986        {
2987            // Determine the 4th level component
2988            pv_mime_string_extract_type(3, aParameters[paramind].key, compstr);
2989            if (pv_mime_strcmp(compstr, _STRLIT_CHAR("h263")) >= 0)
2990            {
2991                // Verify and set the passed-in H.263 decoder setting
2992                PVMFStatus retval = DoVerifyAndSetH263DecoderParameter(aParameters[paramind], true);
2993                if (retval != PVMFSuccess)
2994                {
2995                    aRetKVP = &aParameters[paramind];
2996                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
2997                    return;
2998                }
2999            }
3000            else if (pv_mime_strcmp(compstr, _STRLIT_CHAR("m4v")) >= 0)
3001            {
3002                // Verify and set the passed-in M4v decoder setting
3003                PVMFStatus retval = DoVerifyAndSetM4VDecoderParameter(aParameters[paramind], true);
3004                if (retval != PVMFSuccess)
3005                {
3006                    aRetKVP = &aParameters[paramind];
3007                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind));
3008                    return;
3009                }
3010            }
3011            else
3012            {
3013                // Unknown key sub-string
3014                aRetKVP = &aParameters[paramind];
3015                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key"));
3016                return;
3017            }
3018        }
3019        else
3020        {
3021            // Do not support more than 5 components right now
3022            aRetKVP = &aParameters[paramind];
3023            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key"));
3024            return;
3025        }
3026    }
3027
3028    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Out"));
3029}
3030
3031/* This function finds a nal from the SC's, moves the bitstream pointer to the beginning of the NAL unit, returns the
3032    size of the NAL, and at the same time, updates the remaining size in the bitstream buffer that is passed in */
3033int32 PVMFOMXVideoDecNode::GetNAL_OMXNode(uint8** bitstream, int* size)
3034{
3035    int i = 0;
3036    int j;
3037    uint8* nal_unit = *bitstream;
3038    int count = 0;
3039
3040    /* find SC at the beginning of the NAL */
3041    while (nal_unit[i++] == 0 && i < *size)
3042    {
3043    }
3044
3045    if (nal_unit[i-1] == 1)
3046    {
3047        *bitstream = nal_unit + i;
3048    }
3049    else
3050    {
3051        j = *size;
3052        *size = 0;
3053        return j;  // no SC at the beginning, not supposed to happen
3054    }
3055
3056    j = i;
3057
3058    /* found the SC at the beginning of the NAL, now find the SC at the beginning of the next NAL */
3059    while (i < *size)
3060    {
3061        if (count == 2 && nal_unit[i] == 0x01)
3062        {
3063            i -= 2;
3064            break;
3065        }
3066
3067        if (nal_unit[i])
3068            count = 0;
3069        else
3070            count++;
3071        i++;
3072    }
3073
3074    *size -= i;
3075    return (i - j);
3076}
3077
3078
3079PVMFStatus PVMFOMXVideoDecNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
3080{
3081    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() In"));
3082
3083    if (aParameters == NULL || aNumElements < 1)
3084    {
3085        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Passed in parameter invalid"));
3086        return PVMFErrArgument;
3087    }
3088
3089    // Go through each parameter
3090    for (int32 paramind = 0; paramind < aNumElements; ++paramind)
3091    {
3092        // Count the number of components and parameters in the key
3093        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);
3094        // Retrieve the first component from the key string
3095        char* compstr = NULL;
3096        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);
3097
3098        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 4)
3099        {
3100            if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/media/format_specific_info")) < 0) || compcount < 3)
3101            {
3102                // First 3 components should be "x-pvmf/media/format_specific_info" and there must
3103                // be at least three components
3104                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key"));
3105                return PVMFErrArgument;
3106            }
3107            else
3108            {
3109                pvVideoConfigParserInputs aInputs;
3110                OMXConfigParserInputs aInputParameters;
3111                VideoOMXConfigParserOutputs aOutputParameters;
3112
3113                aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value);
3114                aInputs.inBytes = (int32)aParameters->capacity;
3115                aInputs.iMimeType = iNodeConfig.iMimeType;
3116                aInputParameters.inBytes = aInputs.inBytes;
3117                aInputParameters.inPtr = aInputs.inPtr;
3118
3119                if (aInputs.iMimeType ==  PVMF_MIME_H264_VIDEO ||
3120                        aInputs.iMimeType == PVMF_MIME_H264_VIDEO_MP4 ||
3121                        aInputs.iMimeType == PVMF_MIME_H264_VIDEO_RAW)
3122                {
3123                    aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.avc";
3124                }
3125                else if (aInputs.iMimeType ==  PVMF_MIME_M4V)
3126                {
3127                    aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.mpeg4";
3128                }
3129                else if (aInputs.iMimeType ==  PVMF_MIME_H2631998 ||
3130                         aInputs.iMimeType == PVMF_MIME_H2632000)
3131                {
3132                    aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.h263";
3133                }
3134                else if (aInputs.iMimeType ==  PVMF_MIME_WMV)
3135                {
3136                    aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.wmv";
3137                }
3138                else
3139                {
3140                    // Illegal codec specified.
3141                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Input port format other then codec type", iName.Str()));
3142
3143                }
3144
3145
3146                OMX_BOOL status = OMX_FALSE;
3147                OMX_U32 num_comps = 0;
3148                OMX_STRING *CompOfRole;
3149                OMX_U32 ii;
3150
3151                // call once to find out the number of components that can fit the role
3152
3153                OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
3154
3155                if (num_comps > 0)
3156                {
3157                    CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
3158                    for (ii = 0; ii < num_comps; ii++)
3159                        CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
3160
3161                    // call 2nd time to get the component names
3162                    OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
3163                    for (ii = 0; ii < num_comps; ii++)
3164                    {
3165                        aInputParameters.cComponentName = CompOfRole[ii];
3166                        status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
3167                        if (status == OMX_TRUE)
3168                        {
3169                            break;
3170                        }
3171                        else
3172                        {
3173                            status = OMX_FALSE;
3174                        }
3175                    }
3176
3177                    // whether successful or not, need to free CompOfRoles
3178                    for (ii = 0; ii < num_comps; ii++)
3179                    {
3180                        oscl_free(CompOfRole[ii]);
3181                        CompOfRole[ii] = NULL;
3182                    }
3183                    oscl_free(CompOfRole);
3184                }
3185                else
3186                {
3187                    // if no component supports the role, nothing else to do
3188                    return PVMFErrNotSupported;
3189                }
3190
3191                if (status == OMX_FALSE)
3192                {
3193                    return PVMFErrNotSupported;
3194                }
3195
3196                iNewWidth = aOutputParameters.width;
3197                iNewHeight = aOutputParameters.height;
3198
3199                return PVMFSuccess;
3200            }
3201        }
3202        else
3203        {
3204            if (compcount == 4)
3205            {
3206                // Verify and set the passed-in video dec node setting
3207                PVMFStatus retval = DoVerifyAndSetVideoDecNodeParameter(aParameters[paramind], false);
3208                if (retval != PVMFSuccess)
3209                {
3210                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind));
3211                    return retval;
3212                }
3213            }
3214            else if (compcount == 5)
3215            {
3216                // Determine the 4th level component
3217                pv_mime_string_extract_type(3, aParameters[paramind].key, compstr);
3218                if (pv_mime_strcmp(compstr, _STRLIT_CHAR("h263")) >= 0)
3219                {
3220                    // Verify and set the passed-in H.263 decoder setting
3221                    PVMFStatus retval = DoVerifyAndSetH263DecoderParameter(aParameters[paramind], false);
3222                    if (retval != PVMFSuccess)
3223                    {
3224                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind));
3225                        return retval;
3226                    }
3227                }
3228                else if (pv_mime_strcmp(compstr, _STRLIT_CHAR("m4v")) >= 0)
3229                {
3230                    // Verify and set the passed-in M4v decoder setting
3231                    PVMFStatus retval = DoVerifyAndSetM4VDecoderParameter(aParameters[paramind], false);
3232                    if (retval != PVMFSuccess)
3233                    {
3234                        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind));
3235                        return retval;
3236                    }
3237                }
3238                else
3239                {
3240                    // Unknown key sub-string
3241                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key"));
3242                    return PVMFErrArgument;
3243                }
3244            }
3245            else
3246            {
3247                // Do not support more than 5 components right now
3248                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key"));
3249                return PVMFErrArgument;
3250            }
3251        }
3252    }
3253
3254    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Out"));
3255    return PVMFSuccess;
3256}
3257
3258
3259
3260PVMFStatus PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
3261{
3262    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() In"));
3263
3264    aNumParamElements = 0;
3265
3266    // Allocate memory for the KVP
3267    aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
3268    if (aParameters == NULL)
3269    {
3270        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Memory allocation for KVP failed"));
3271        return PVMFErrNoMemory;
3272    }
3273    oscl_memset(aParameters, 0, sizeof(PvmiKvp));
3274    // Allocate memory for the key string in KVP
3275    PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
3276    if (memblock == NULL)
3277    {
3278        oscl_free(aParameters);
3279        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Memory allocation for key string failed"));
3280        return PVMFErrNoMemory;
3281    }
3282    oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
3283    // Assign the key string buffer to KVP
3284    aParameters[0].key = memblock;
3285
3286    // Copy the key string
3287    oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/"), 21);
3288    oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigBaseKeys[aIndex].iString));
3289    oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
3290    switch (PVOMXVideoDecNodeConfigBaseKeys[aIndex].iValueType)
3291    {
3292        case PVMI_KVPVALTYPE_BITARRAY32:
3293            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING));
3294            break;
3295
3296        case PVMI_KVPVALTYPE_KSV:
3297            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
3298            break;
3299
3300        case PVMI_KVPVALTYPE_BOOL:
3301            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
3302            break;
3303
3304        case PVMI_KVPVALTYPE_UINT32:
3305        default:
3306            if (reqattr == PVMI_KVPATTR_CAP)
3307            {
3308                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
3309            }
3310            else
3311            {
3312                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
3313            }
3314            break;
3315    }
3316    aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
3317
3318    // Copy the requested info
3319    switch (aIndex)
3320    {
3321        case 0: // "postproc_enable"
3322            if (reqattr == PVMI_KVPATTR_CUR)
3323            {
3324                // Return current value
3325                aParameters[0].value.bool_value = iNodeConfig.iPostProcessingEnable;
3326            }
3327            else if (reqattr == PVMI_KVPATTR_DEF)
3328            {
3329                // Return default
3330                aParameters[0].value.bool_value = PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF;
3331            }
3332
3333            break;
3334
3335        case 1: // "postproc_type"
3336            if (reqattr == PVMI_KVPATTR_CUR)
3337            {
3338                // Return current value
3339                aParameters[0].value.uint32_value = iNodeConfig.iPostProcessingMode;
3340            }
3341            else if (reqattr == PVMI_KVPATTR_DEF)
3342            {
3343                // Return default
3344                aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF;
3345            }
3346
3347            break;
3348
3349        case 2: // "dropframe_enable"
3350            if (reqattr == PVMI_KVPATTR_CUR)
3351            {
3352                // Return current value
3353                aParameters[0].value.bool_value = iNodeConfig.iDropFrame;
3354            }
3355            else if (reqattr == PVMI_KVPATTR_DEF)
3356            {
3357                // Return default
3358                aParameters[0].value.bool_value = PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF;
3359            }
3360
3361            break;
3362
3363        case 5: //"format-type"
3364            if (reqattr == PVMI_KVPATTR_CUR)
3365            {
3366                // Return current value
3367                aParameters[0].value.pChar_value = (char*)iNodeConfig.iMimeType.getMIMEStrPtr();
3368            }
3369            else if (reqattr == PVMI_KVPATTR_DEF)
3370            {
3371                // Return default
3372                aParameters[0].value.pChar_value = (char*)PVMF_MIME_FORMAT_UNKNOWN;
3373            }
3374
3375            break;
3376
3377        default:
3378            // Invalid index
3379            oscl_free(aParameters[0].key);
3380            oscl_free(aParameters);
3381            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Invalid index to video dec node parameter"));
3382            return PVMFErrArgument;
3383    }
3384
3385    aNumParamElements = 1;
3386
3387    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Out"));
3388    return PVMFSuccess;
3389}
3390
3391
3392PVMFStatus PVMFOMXVideoDecNode::DoGetH263DecoderParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
3393{
3394    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() In"));
3395
3396    aNumParamElements = 0;
3397
3398    // Allocate memory for the KVP
3399    aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
3400    if (aParameters == NULL)
3401    {
3402        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for KVP failed"));
3403        return PVMFErrNoMemory;
3404    }
3405    oscl_memset(aParameters, 0, sizeof(PvmiKvp));
3406    // Allocate memory for the key string in KVP
3407    PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
3408    if (memblock == NULL)
3409    {
3410        oscl_free(aParameters);
3411        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for key string failed"));
3412        return PVMFErrNoMemory;
3413    }
3414    oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
3415    // Assign the key string buffer to KVP
3416    aParameters[0].key = memblock;
3417
3418    // Copy the key string
3419    oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/h263/"), 26);
3420    oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigH263Keys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigH263Keys[aIndex].iString));
3421    oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
3422    switch (PVOMXVideoDecNodeConfigH263Keys[aIndex].iValueType)
3423    {
3424        case PVMI_KVPVALTYPE_RANGE_UINT32:
3425            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
3426            break;
3427
3428        case PVMI_KVPVALTYPE_UINT32:
3429        default:
3430            if (reqattr == PVMI_KVPATTR_CAP)
3431            {
3432                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
3433            }
3434            else
3435            {
3436                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
3437            }
3438            break;
3439    }
3440    aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
3441
3442    // Copy the requested info
3443    switch (aIndex)
3444    {
3445        case 0: // "maxbitstreamframesize"
3446            if (reqattr == PVMI_KVPATTR_CUR)
3447            {
3448                // Return current value
3449                aParameters[0].value.uint32_value = iH263MaxBitstreamFrameSize;
3450            }
3451            else if (reqattr == PVMI_KVPATTR_DEF)
3452            {
3453                // Return default
3454                aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF;
3455            }
3456            else
3457            {
3458                // Return capability
3459                range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
3460                if (rui32 == NULL)
3461                {
3462                    oscl_free(aParameters[0].key);
3463                    oscl_free(aParameters);
3464                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for range uint32 failed"));
3465                    return PVMFErrNoMemory;
3466                }
3467                rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN;
3468                rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX;
3469                aParameters[0].value.key_specific_value = (void*)rui32;
3470            }
3471            break;
3472
3473        case 1: // "maxdimension"
3474        {
3475            range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
3476            if (rui32 == NULL)
3477            {
3478                oscl_free(aParameters[0].key);
3479                oscl_free(aParameters);
3480                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for range uint32 failed"));
3481                return PVMFErrNoMemory;
3482            }
3483
3484            if (reqattr == PVMI_KVPATTR_CUR)
3485            {
3486                // Return current value
3487                rui32->min = iH263MaxWidth;
3488                rui32->max = iH263MaxHeight;
3489                aParameters[0].value.key_specific_value = (void*)rui32;
3490            }
3491            else if (reqattr == PVMI_KVPATTR_DEF)
3492            {
3493                // Return default
3494                rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF;
3495                rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF;
3496                aParameters[0].value.key_specific_value = (void*)rui32;
3497            }
3498            else
3499            {
3500                // Return capability
3501                rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN;
3502                rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX;
3503                aParameters[0].value.key_specific_value = (void*)rui32;
3504            }
3505        }
3506        break;
3507
3508        default:
3509            // Invalid index
3510            oscl_free(aParameters[0].key);
3511            oscl_free(aParameters);
3512            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Invalid index to H.263 decoder parameter"));
3513            return PVMFErrArgument;
3514    }
3515
3516    aNumParamElements = 1;
3517
3518    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Out"));
3519    return PVMFSuccess;
3520}
3521
3522
3523PVMFStatus PVMFOMXVideoDecNode::DoGetM4VDecoderParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr)
3524{
3525    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() In"));
3526
3527    aNumParamElements = 0;
3528
3529    // Allocate memory for the KVP
3530    aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
3531    if (aParameters == NULL)
3532    {
3533        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for KVP failed"));
3534        return PVMFErrNoMemory;
3535    }
3536    oscl_memset(aParameters, 0, sizeof(PvmiKvp));
3537    // Allocate memory for the key string in KVP
3538    PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char));
3539    if (memblock == NULL)
3540    {
3541        oscl_free(aParameters);
3542        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for key string failed"));
3543        return PVMFErrNoMemory;
3544    }
3545    oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char));
3546    // Assign the key string buffer to KVP
3547    aParameters[0].key = memblock;
3548
3549    // Copy the key string
3550    oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/m4v/"), 25);
3551    oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigM4VKeys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigM4VKeys[aIndex].iString));
3552    oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
3553    switch (PVOMXVideoDecNodeConfigM4VKeys[aIndex].iValueType)
3554    {
3555        case PVMI_KVPVALTYPE_RANGE_UINT32:
3556            oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
3557            break;
3558
3559        case PVMI_KVPVALTYPE_UINT32:
3560        default:
3561            if (reqattr == PVMI_KVPATTR_CAP)
3562            {
3563                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
3564            }
3565            else
3566            {
3567                oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
3568            }
3569            break;
3570    }
3571    aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0;
3572
3573    // Copy the requested info
3574    switch (aIndex)
3575    {
3576        case 0: // "maxbitstreamframesize"
3577            if (reqattr == PVMI_KVPATTR_CUR)
3578            {
3579                // Return current value
3580                aParameters[0].value.uint32_value = iM4VMaxBitstreamFrameSize;
3581            }
3582            else if (reqattr == PVMI_KVPATTR_DEF)
3583            {
3584                // Return default
3585                aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF;
3586            }
3587            else
3588            {
3589                // Return capability
3590                range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
3591                if (rui32 == NULL)
3592                {
3593                    oscl_free(aParameters[0].key);
3594                    oscl_free(aParameters);
3595                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for range uint32 failed"));
3596                    return PVMFErrNoMemory;
3597                }
3598                rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN;
3599                rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX;
3600                aParameters[0].value.key_specific_value = (void*)rui32;
3601            }
3602            break;
3603
3604        case 1: // "maxdimension"
3605        {
3606            range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
3607            if (rui32 == NULL)
3608            {
3609                oscl_free(aParameters[0].key);
3610                oscl_free(aParameters);
3611                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for range uint32 failed"));
3612                return PVMFErrNoMemory;
3613            }
3614
3615            if (reqattr == PVMI_KVPATTR_CUR)
3616            {
3617                // Return current value
3618                rui32->min = iM4VMaxWidth;
3619                rui32->max = iM4VMaxHeight;
3620                aParameters[0].value.key_specific_value = (void*)rui32;
3621            }
3622            else if (reqattr == PVMI_KVPATTR_DEF)
3623            {
3624                // Return default
3625                rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF;
3626                rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF;
3627                aParameters[0].value.key_specific_value = (void*)rui32;
3628            }
3629            else
3630            {
3631                // Return capability
3632                rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN;
3633                rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX;
3634                aParameters[0].value.key_specific_value = (void*)rui32;
3635            }
3636        }
3637        break;
3638
3639        default:
3640            // Invalid index
3641            oscl_free(aParameters[0].key);
3642            oscl_free(aParameters);
3643            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Invalid index to H.263 decoder parameter"));
3644            return PVMFErrArgument;
3645    }
3646
3647    aNumParamElements = 1;
3648
3649    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Out"));
3650    return PVMFSuccess;
3651}
3652
3653
3654PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter(PvmiKvp& aParameter, bool aSetParam)
3655{
3656    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() In"));
3657
3658    // Determine the valtype
3659    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
3660    if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
3661    {
3662        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Valtype in key string unknown"));
3663        return PVMFErrArgument;
3664    }
3665    // Retrieve the fourth component from the key string
3666    char* compstr = NULL;
3667    pv_mime_string_extract_type(3, aParameter.key, compstr);
3668
3669    int32 vdeccomp4ind = 0;
3670    for (vdeccomp4ind = 0; vdeccomp4ind < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++vdeccomp4ind)
3671    {
3672        // Go through each component string at 4th level
3673        if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iString)) >= 0)
3674        {
3675            // Break out of the for loop
3676            break;
3677        }
3678    }
3679
3680    if (vdeccomp4ind == PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS || vdeccomp4ind == 3 || vdeccomp4ind == 4)
3681    {
3682        // Match couldn't be found or non-leaf node specified
3683        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Unsupported key or non-leaf node"));
3684        return PVMFErrArgument;
3685    }
3686
3687    // Verify the valtype
3688    if (keyvaltype != PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iValueType)
3689    {
3690        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Valtype does not match for key"));
3691        return PVMFErrArgument;
3692    }
3693
3694    switch (vdeccomp4ind)
3695    {
3696        case 0: // "postproc_enable"
3697            // Nothing to validate since it is boolean
3698            // Change the config if to set
3699            if (aSetParam)
3700            {
3701                iNodeConfig.iPostProcessingEnable = aParameter.value.bool_value;
3702            }
3703            break;
3704
3705        case 1: // "postproc_type"
3706            // Nothing to validate since it is bitarray32
3707            // Change the config if to set
3708            if (aSetParam)
3709            {
3710                iNodeConfig.iPostProcessingMode = aParameter.value.uint32_value;
3711                if (iNodeConfig.iPostProcessingEnable && iOMXDecoder)
3712                {
3713                    // Don't do anything yet: Need to communicate post-processing to decoder
3714                    //iVideoDecoder->SetPostProcType(iNodeConfig.iPostProcessingMode);
3715                }
3716            }
3717            break;
3718
3719        case 2: // "dropframe_enable"
3720            // Nothing to validate since it is boolean
3721            // Change the config if to set
3722            if (aSetParam)
3723            {
3724                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3725                {
3726                    // This setting cannot be changed when decoder has been initialized
3727                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3728                    return PVMFErrInvalidState;
3729                }
3730
3731                iNodeConfig.iDropFrame = aParameter.value.bool_value;
3732            }
3733            break;
3734
3735        case 5: // "format-type"
3736            // Nothing to validate since it is boolean
3737            // Change the config if to set
3738            if (aSetParam)
3739            {
3740                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3741                {
3742                    // This setting cannot be changed when decoder has been initialized
3743                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3744                    return PVMFErrInvalidState;
3745                }
3746
3747                iNodeConfig.iMimeType = aParameter.value.pChar_value;
3748            }
3749            break;
3750
3751        default:
3752            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Invalid index for video dec node parameter"));
3753            return PVMFErrArgument;
3754    }
3755
3756    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Out"));
3757    return PVMFSuccess;
3758}
3759
3760
3761PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter(PvmiKvp& aParameter, bool aSetParam)
3762{
3763    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() In"));
3764
3765    // Determine the valtype
3766    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
3767    if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
3768    {
3769        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Valtype in key string unknown"));
3770        return PVMFErrArgument;
3771    }
3772    // Retrieve the fifth component from the key string
3773    char* compstr = NULL;
3774    pv_mime_string_extract_type(4, aParameter.key, compstr);
3775
3776    int32 vdeccomp5ind = 0;
3777    for (vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++vdeccomp5ind)
3778    {
3779        // Go through each component string at 5th level
3780        if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iString)) >= 0)
3781        {
3782            // Break out of the for loop
3783            break;
3784        }
3785    }
3786
3787    if (vdeccomp5ind == PVOMXVIDEODECNODECONFIG_H263_NUMKEYS)
3788    {
3789        // Match couldn't be found or non-leaf node specified
3790        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Unsupported key or non-leaf node"));
3791        return PVMFErrArgument;
3792    }
3793
3794    // Verify the valtype
3795    if (keyvaltype != PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iValueType)
3796    {
3797        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Valtype does not match for key"));
3798        return PVMFErrArgument;
3799    }
3800
3801    switch (vdeccomp5ind)
3802    {
3803        case 0: // "maxbitstreamframesize"
3804            // Check if within range
3805            if (aParameter.value.uint32_value < PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN ||
3806                    aParameter.value.uint32_value > PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX)
3807            {
3808                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid value for maxbitstreamframesize"));
3809                return PVMFErrArgument;
3810            }
3811            // Change the config if to set
3812            if (aSetParam)
3813            {
3814                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3815                {
3816                    // This setting cannot be changed when decoder has been initialized
3817                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3818                    return PVMFErrInvalidState;
3819                }
3820
3821                iH263MaxBitstreamFrameSize = aParameter.value.uint32_value;
3822            }
3823            break;
3824
3825        case 1: // "maxdimension"
3826        {
3827            range_uint32* rui32 = (range_uint32*)aParameter.value.key_specific_value;
3828            if (rui32 == NULL)
3829            {
3830                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() ksv for maxdimension is NULL"));
3831                return PVMFErrArgument;
3832            }
3833
3834            // Check if within range
3835            if (rui32->min < PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN ||
3836                    rui32->min > PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX ||
3837                    rui32->max < PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN ||
3838                    rui32->max > PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX)
3839            {
3840                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid range for maxdimension"));
3841                return PVMFErrArgument;
3842            }
3843
3844            // Change the config if to set
3845            if (aSetParam)
3846            {
3847                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3848                {
3849                    // This setting cannot be changed when decoder has been initialized
3850                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3851                    return PVMFErrInvalidState;
3852                }
3853
3854                iH263MaxWidth = rui32->min;
3855                iH263MaxHeight = rui32->max;
3856            }
3857        }
3858        break;
3859
3860        default:
3861            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid index for H.263 decoder parameter"));
3862            return PVMFErrArgument;
3863    }
3864
3865    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Out"));
3866    return PVMFSuccess;
3867}
3868
3869
3870PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter(PvmiKvp& aParameter, bool aSetParam)
3871{
3872    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() In"));
3873
3874    // Determine the valtype
3875    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
3876    if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
3877    {
3878        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Valtype in key string unknown"));
3879        return PVMFErrArgument;
3880    }
3881    // Retrieve the fifth component from the key string
3882    char* compstr = NULL;
3883    pv_mime_string_extract_type(4, aParameter.key, compstr);
3884
3885    int32 vdeccomp5ind = 0;
3886    for (vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++vdeccomp5ind)
3887    {
3888        // Go through each component string at 5th level
3889        if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iString)) >= 0)
3890        {
3891            // Break out of the for loop
3892            break;
3893        }
3894    }
3895
3896    if (vdeccomp5ind == PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS)
3897    {
3898        // Match couldn't be found or non-leaf node specified
3899        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Unsupported key or non-leaf node"));
3900        return PVMFErrArgument;
3901    }
3902
3903    // Verify the valtype
3904    if (keyvaltype != PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iValueType)
3905    {
3906        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Valtype does not match for key"));
3907        return PVMFErrArgument;
3908    }
3909
3910    switch (vdeccomp5ind)
3911    {
3912        case 0: // "maxbitstreamframesize"
3913            // Check if within range
3914            if (aParameter.value.uint32_value < PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN ||
3915                    aParameter.value.uint32_value > PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX)
3916            {
3917                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid value for maxbitstreamframesize"));
3918                return PVMFErrArgument;
3919            }
3920            // Change the config if to set
3921            if (aSetParam)
3922            {
3923                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3924                {
3925                    // This setting cannot be changed when decoder has been initialized
3926                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3927                    return PVMFErrInvalidState;
3928                }
3929
3930                iM4VMaxBitstreamFrameSize = aParameter.value.uint32_value;
3931            }
3932            break;
3933
3934        case 1: // "maxdimension"
3935        {
3936            range_uint32* rui32 = (range_uint32*)aParameter.value.key_specific_value;
3937            if (rui32 == NULL)
3938            {
3939                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() ksv for maxdimension is NULL"));
3940                return PVMFErrArgument;
3941            }
3942
3943            // Check if within range
3944            if (rui32->min < PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN ||
3945                    rui32->min > PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX ||
3946                    rui32->max < PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN ||
3947                    rui32->max > PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX)
3948            {
3949                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid range for maxdimension"));
3950                return PVMFErrArgument;
3951            }
3952
3953            // Change the config if to set
3954            if (aSetParam)
3955            {
3956                if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused)
3957                {
3958                    // This setting cannot be changed when decoder has been initialized
3959                    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused"));
3960                    return PVMFErrInvalidState;
3961                }
3962
3963                iM4VMaxWidth = rui32->min;
3964                iM4VMaxHeight = rui32->max;
3965            }
3966        }
3967        break;
3968
3969        default:
3970            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid index for M4v decoder parameter"));
3971            return PVMFErrArgument;
3972    }
3973
3974    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Out"));
3975    return PVMFSuccess;
3976}
3977
3978
3979
3980PVMFStatus PVMFOMXVideoDecNode::GetProfileAndLevel(PVMF_MPEGVideoProfileType& aProfile, PVMF_MPEGVideoLevelType& aLevel)
3981{
3982
3983    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() In"));
3984
3985    if (NULL == iOMXDecoder)
3986    {
3987        PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() iVideoDecoder is Null"));
3988        aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
3989        aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
3990        return PVMFFailure;
3991    }
3992
3993    PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() iVideoDecoder is Null"));
3994    aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE;
3995    aLevel  = PV_MPEG_VIDEO_LEVEL_UNKNOWN;
3996    // FOR NOW, JUST RETURN FAILURE, WE DON'T SUPPORT THIS FEATURE YET
3997    return PVMFFailure;
3998
3999
4000}
4001
4002
4003// DEFINITIONS for parsing the config information & sequence header for WMV
4004
4005#define GetUnalignedDword( pb, dw ) \
4006            (dw) = ((uint32) *(pb + 3) << 24) + \
4007                   ((uint32) *(pb + 2) << 16) + \
4008                   ((uint16) *(pb + 1) << 8) + *pb;
4009
4010#define GetUnalignedDwordEx( pb, dw )   GetUnalignedDword( pb, dw ); (pb) += sizeof(uint32);
4011#define LoadDWORD( dw, p )  GetUnalignedDwordEx( p, dw )
4012#ifndef MAKEFOURCC_WMC
4013#define MAKEFOURCC_WMC(ch0, ch1, ch2, ch3) \
4014        ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) |   \
4015        ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
4016
4017#define mmioFOURCC_WMC(ch0, ch1, ch2, ch3)  MAKEFOURCC_WMC(ch0, ch1, ch2, ch3)
4018#endif
4019
4020#define FOURCC_WMV3     mmioFOURCC_WMC('W','M','V','3')
4021#define FOURCC_WMV2     mmioFOURCC_WMC('W','M','V','2')
4022#define FOURCC_WMVA     mmioFOURCC_WMC('W','M','V','A')
4023
4024//For WMV3
4025enum { NOT_WMV3 = -1, WMV3_SIMPLE_PROFILE, WMV3_MAIN_PROFILE, WMV3_PC_PROFILE, WMV3_SCREEN };
4026
4027//For WMVA
4028#define ASFBINDING_SIZE                   1   // size of ASFBINDING is 1 byte
4029#define SC_SEQ          0x0F
4030#define SC_ENTRY        0x0E
4031
4032
4033bool PVMFOMXVideoDecNode::VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
4034{
4035    // unused parameters
4036    OSCL_UNUSED_ARG(aSession);
4037    OSCL_UNUSED_ARG(num_elements);
4038
4039    // call this in case of WMV format
4040    if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV)
4041    {
4042
4043        //verify bitrate
4044        if (pv_mime_strcmp(aParameters->key, PVMF_BITRATE_VALUE_KEY) == 0)
4045        {
4046            if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_BITRATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess)
4047            {
4048                return false;
4049            }
4050            return true;
4051        }
4052        else if (pv_mime_strcmp(aParameters->key, PVMF_FRAMERATE_VALUE_KEY) == 0)
4053        {
4054            if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_FRAMERATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess)
4055            {
4056                return false;
4057            }
4058            return true;
4059        }
4060        else if (pv_mime_strcmp(aParameters->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) < 0)
4061        {
4062            PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::VerifyParametersSync() - Unsupported Key"));
4063            return true;
4064        }
4065
4066        // pConfig points to format specific info and sequence header.
4067        uint8 *pConfig = (uint8*)(aParameters->value.key_specific_value);
4068        uint8 *pData;
4069        uint32 dwdat;
4070        uint32 NewCompression;
4071        uint32 NewSeqHeader;
4072        uint32 NewProfile, NewFrameRate, NewBitRate;
4073
4074        // We are interested in the following (and will extract it)
4075        //  1. Version (WMV9 or WMV8 etc.) (from format specific info)
4076        //  2. picture dimensions // from format specific info
4077        //  3. interlaced YUV411 /sprite content is not supported (from sequence header)
4078        //  4. framerate / bitrate information (from sequence header)
4079
4080        pData = pConfig + 15; // position ptr to Width & Height
4081
4082        LoadDWORD(dwdat, pData);
4083        iNewWidth = dwdat;
4084        LoadDWORD(dwdat, pData);
4085        iNewHeight = dwdat;
4086
4087        if (((iNewWidth != (uint32)iYUVWidth) || (iNewHeight != (uint32)iYUVHeight)) && iOutPort != NULL)
4088        {
4089            // see if downstream node can handle the re-sizing
4090            int32 errcode = OsclErrNone;
4091            OsclRefCounterMemFrag yuvFsiMemfrag;
4092            OSCL_TRY(errcode, yuvFsiMemfrag = iFsiFragmentAlloc.get());
4093
4094
4095            OSCL_FIRST_CATCH_ANY(errcode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::VerifyParametersSync() Failed to allocate memory for verifyParametersSync FSI")));
4096            if (OsclErrNone == errcode)
4097            {
4098                PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0());
4099                if (fsiInfo != NULL)
4100                {
4101                    fsiInfo->video_format = PVMF_MIME_YUV420;
4102                    fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID;
4103                    fsiInfo->display_width = iNewWidth;
4104                    fsiInfo->display_height = iNewHeight;
4105                    fsiInfo->width = (iNewWidth + 3) & -4;
4106                    fsiInfo->height = iNewHeight;
4107
4108                    if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_FORMAT_SPECIFIC_INFO_KEY, &yuvFsiMemfrag) != PVMFSuccess)
4109                    {
4110                        fsiInfo->video_format.~PVMFFormatType();
4111                        return false;
4112                    }
4113                    fsiInfo->video_format.~PVMFFormatType();
4114                }
4115                else
4116                {
4117                    return false;
4118                }
4119            }
4120            else
4121            {
4122                return false;
4123            }
4124        }
4125
4126        pData += 4; //position ptr to Compression type
4127
4128        LoadDWORD(dwdat, pData);
4129        NewCompression = dwdat;
4130
4131        if (NewCompression != FOURCC_WMV2 &&
4132                NewCompression != FOURCC_WMV3 &&
4133                NewCompression != FOURCC_WMVA)
4134            return false;
4135
4136
4137        // Check sequence header
4138        switch (NewCompression)
4139        {
4140            case FOURCC_WMV3:
4141            {
4142                pData = pConfig + 11 + 40; //sizeof(BITMAPINFOHEADER); // position to sequence header
4143
4144                LoadDWORD(dwdat, pData);
4145                NewSeqHeader = dwdat; // this is little endian read sequence header
4146
4147                uint32 YUV411flag, Spriteflag;
4148
4149                // For FOURCC_WMV3
4150                uint32 YUV411;
4151                uint32 SpriteMode;
4152                uint32 LoopFilter;
4153                uint32 Xintra8Switch;
4154                uint32 MultiresEnabled;
4155                uint32 X16bitXform;
4156                uint32 UVHpelBilinear;
4157                uint32 ExtendedMvMode;
4158                uint32 DQuantCodingOn;
4159                uint32 XformSwitch;
4160                uint32 DCTTable_MB_ENABLED;
4161                uint32 SequenceOverlap;
4162                uint32 StartCode;
4163                uint32 PreProcRange;
4164                uint32 NumBFrames;
4165                uint32 ExplicitSeqQuantizer;
4166                uint32 Use3QPDZQuantizer = 0;
4167                uint32 ExplicitFrameQuantizer = 0;
4168
4169
4170                bool bValidProfile = true;
4171
4172                NewProfile = (NewSeqHeader & 0xC0) >> 6; // 0 - simple , 1- main, 3 - complex, 2-forbidden
4173
4174                if (NewProfile == WMV3_PC_PROFILE)
4175                    return false;
4176
4177                YUV411flag = (NewSeqHeader & 0x20) >> 5;
4178                Spriteflag = (NewSeqHeader & 0x10) >> 4;
4179                if ((YUV411flag != 0) || (Spriteflag != 0))
4180                    return false;
4181
4182                YUV411              = (uint32)YUV411flag;
4183                SpriteMode          = (uint32)Spriteflag;
4184                LoopFilter          = (NewSeqHeader & 0x800) >> 11;
4185                Xintra8Switch       = (NewSeqHeader & 0x400) >> 10;
4186                MultiresEnabled     = (NewSeqHeader & 0x200) >> 9;
4187                X16bitXform         = (NewSeqHeader & 0x100) >> 8;
4188                UVHpelBilinear      = (NewSeqHeader & 0x800000) >> 23;
4189                ExtendedMvMode      = (NewSeqHeader & 0x400000) >> 22;
4190                DQuantCodingOn      = (NewSeqHeader & 0x300000) >> 20;
4191                XformSwitch         = (NewSeqHeader & 0x80000) >> 19;
4192                DCTTable_MB_ENABLED = (NewSeqHeader & 0x40000) >> 18;
4193                SequenceOverlap     = (NewSeqHeader & 0x20000) >> 17;
4194                StartCode           = (NewSeqHeader & 0x10000) >> 16;
4195                PreProcRange            = (NewSeqHeader & 0x80000000) >> 31;
4196                NumBFrames          = (NewSeqHeader & 0x70000000) >> 28;
4197                ExplicitSeqQuantizer    = (NewSeqHeader & 0x8000000) >> 27;
4198                if (ExplicitSeqQuantizer)
4199                    Use3QPDZQuantizer = (NewSeqHeader & 0x4000000) >> 26;
4200                else
4201                    ExplicitFrameQuantizer = (NewSeqHeader & 0x4000000) >> 26;
4202
4203                NewFrameRate = (NewSeqHeader & 0x0E) >> 1 ; // from 2 to 30 fps (in steps of 4)
4204                NewFrameRate = 4 * NewFrameRate + 2; // (in fps)
4205
4206                NewBitRate = (((NewSeqHeader & 0xF000) >> 24) | ((NewSeqHeader & 0x01) << 8));  // from 32 to 2016 kbps in steps of 64kbps
4207                NewBitRate = 64 * NewBitRate + 32; // (in kbps)
4208
4209                // Verify Profile
4210                if (!SpriteMode)
4211                {
4212                    if (NewProfile == WMV3_SIMPLE_PROFILE)
4213                    {
4214                        bValidProfile = (Xintra8Switch == 0) &&
4215                                        (X16bitXform == 1) &&
4216                                        (UVHpelBilinear == 1) &&
4217                                        (StartCode == 0) &&
4218                                        (LoopFilter == 0) &&
4219                                        (YUV411 == 0) &&
4220                                        (MultiresEnabled == 0) &&
4221                                        (DQuantCodingOn == 0) &&
4222                                        (NumBFrames == 0) &&
4223                                        (PreProcRange == 0);
4224
4225                    }
4226                    else if (NewProfile == WMV3_MAIN_PROFILE)
4227                    {
4228                        bValidProfile = (Xintra8Switch == 0) &&
4229                                        (X16bitXform == 1);
4230                    }
4231                    else if (NewProfile == WMV3_PC_PROFILE)
4232                    {
4233                        // no feature restrictions for complex profile.
4234                    }
4235
4236                    if (!bValidProfile)
4237                    {
4238                        return false;
4239                    }
4240                }
4241                else
4242                {
4243                    if (!Xintra8Switch   &&
4244                            !DCTTable_MB_ENABLED  &&
4245                            !YUV411 &&
4246                            !LoopFilter &&
4247                            !ExtendedMvMode &&
4248                            !MultiresEnabled &&
4249                            !UVHpelBilinear &&
4250                            !DQuantCodingOn &&
4251                            !XformSwitch &&
4252                            !StartCode &&
4253                            !PreProcRange &&
4254                            !ExplicitSeqQuantizer &&
4255                            !Use3QPDZQuantizer &&
4256                            !ExplicitFrameQuantizer)
4257                        return true;
4258                    else
4259                        return false;
4260                }
4261            }
4262            break;
4263            case FOURCC_WMVA:
4264            {
4265                pData = pConfig + 11 + 40 + ASFBINDING_SIZE; //sizeof(BITMAPINFOHEADER); // position to sequence header
4266
4267                LoadDWORD(dwdat, pData);
4268                NewSeqHeader = dwdat; // this is little endian read sequence header
4269
4270                int32 iPrefix;
4271                //ignore start code prefix
4272                iPrefix = NewSeqHeader & 0xFF;
4273                if (iPrefix != 0) return false;
4274                iPrefix = (NewSeqHeader & 0xFF00) >> 8;
4275                if (iPrefix != 0) return false;
4276                iPrefix = (NewSeqHeader & 0xFF0000) >> 16;
4277                if (iPrefix != 1) return false;
4278                iPrefix = (NewSeqHeader & 0xFF000000) >> 24;
4279                if (iPrefix != SC_SEQ) return false;
4280
4281                LoadDWORD(dwdat, pData);
4282                NewSeqHeader = dwdat;
4283
4284                NewProfile = (NewSeqHeader & 0xC0) >> 6;
4285                if (NewProfile != 3)
4286                    return false;
4287                pData += 3;
4288                LoadDWORD(dwdat, pData);
4289                NewSeqHeader = dwdat;
4290                //ignore start code prefix
4291                iPrefix = NewSeqHeader & 0xFF;
4292                if (iPrefix != 0) return false;
4293                iPrefix = (NewSeqHeader & 0xFF00) >> 8;
4294                if (iPrefix != 0) return false;
4295                iPrefix = (NewSeqHeader & 0xFF0000) >> 16;
4296                if (iPrefix != 1) return false;
4297                iPrefix = (NewSeqHeader & 0xFF000000) >> 24;
4298                if (iPrefix != SC_ENTRY) return false;
4299            }
4300            break;
4301
4302            case FOURCC_WMV2:
4303                break;
4304
4305            default:
4306                return false;
4307        }
4308
4309    } // end of if(format == PVMF_MIME_WMV)
4310    return true;
4311}
4312
4313