aboutsummaryrefslogtreecommitdiff
path: root/nodes/pvomxbasedecnode/include/pvmf_omx_basedec_node.h
blob: c5db838762f39e18614fbe78296bd15e6db151e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
#ifndef PVMF_OMX_BASEDEC_NODE_H_INCLUDED
#define PVMF_OMX_BASEDEC_NODE_H_INCLUDED

#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif

#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif

#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif

#ifndef PVMF_NODE_INTERFACE_H_INCLUDED
#include "pvmf_node_interface.h"
#endif

#ifndef OSCL_PRIQUEUE_H_INCLUDED
#include "oscl_priqueue.h"
#endif

#ifndef PVMF_MEDIA_DATA_H_INCLUDED
#include "pvmf_media_data.h"
#endif

#ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
#include "oscl_mem_mempool.h"
#endif
#ifndef PVMF_MEMPOOL_H_INCLUDED
#include "pvmf_mempool.h"
#endif

#ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
#include "pvmf_simple_media_buffer.h"
#endif

#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif

#ifndef PVMF_POOL_BUFFER_ALLOCATOR_H_INCLUDED
#include "pvmf_pool_buffer_allocator.h"
#endif

#ifndef PVMF_NODE_UTILS_H_INCLUDED
#include "pvmf_node_utils.h"
#endif

#ifndef PVMF_OMX_BASEDEC_PORT_H_INCLUDED
#include "pvmf_omx_basedec_port.h"
#endif

#ifndef PVMF_OMX_BASEDEC_NODE_EXTENSION_INTERFACE_H_INCLUDED
#include "pvmf_omx_basedec_node_extension_interface.h"
#endif

#ifndef PVMF_META_DATA_EXTENSION_H_INCLUDED
#include "pvmf_meta_data_extension.h"
#endif

#ifndef PV_MIME_STRING_UTILS_H_INCLUDED
#include "pv_mime_string_utils.h"
#endif

#ifndef OMX_Core_h
#include "OMX_Core.h"
#endif

#ifndef OMX_Component_h
#include "OMX_Component.h"
#endif

#ifndef PVMF_OMX_BASEDEC_CALLBACKS_H_INCLUDED
#include "pvmf_omx_basedec_callbacks.h"
#endif

#ifndef OSCLCONFIG_IO_H_INCLUDED
#include "osclconfig_io.h"
#endif
#ifndef OSCL_MEM_H_INCLUDED
#include "oscl_mem.h"
#endif

#if (PVLOGGER_INST_LEVEL >= PVLOGMSG_INST_REL)
#ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
#include "pvmf_media_clock.h"
#endif
#endif

#ifndef PVMF_FIXEDSIZE_BUFFER_ALLOC_H_INCLUDED
#include "pvmf_fixedsize_buffer_alloc.h"
#endif

#ifndef __MEDIA_CLOCK_CONVERTER_H
#include "media_clock_converter.h"
#endif

#define MAX_NAL_PER_FRAME 100

typedef struct OutputBufCtrlStruct
{
    OMX_BUFFERHEADERTYPE *pBufHdr;
} OutputBufCtrlStruct;

#if 0
typedef struct InputBufCtrlStruct
{
    OMX_BUFFERHEADERTYPE *pBufHdr;
    PVMFSharedMediaDataPtr pMediaData;
} InputBufCtrlStruct;
#else
class InputBufCtrlStruct
{
    public:
        InputBufCtrlStruct(): pBufHdr(NULL) {}

    public:
        OMX_BUFFERHEADERTYPE *pBufHdr;
        PVMFSharedMediaDataPtr pMediaData;
};
#endif


// fwd class declaration
class PVLogger;
//memory allocator type for this node.
typedef OsclMemAllocator PVMFOMXBaseDecNodeAllocator;


// CALLBACK PROTOTYPES
OMX_ERRORTYPE CallbackEventHandler(OMX_OUT OMX_HANDLETYPE aComponent,
                                   OMX_OUT OMX_PTR aAppData,
                                   OMX_OUT OMX_EVENTTYPE aEvent,
                                   OMX_OUT OMX_U32 aData1,
                                   OMX_OUT OMX_U32 aData2,
                                   OMX_OUT OMX_PTR aEventData);

OMX_ERRORTYPE CallbackEmptyBufferDone(OMX_OUT OMX_HANDLETYPE aComponent,
                                      OMX_OUT OMX_PTR aAppData,
                                      OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);

OMX_ERRORTYPE CallbackFillBufferDone(OMX_OUT OMX_HANDLETYPE aComponent,
                                     OMX_OUT OMX_PTR aAppData,
                                     OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);



//Default values for number of Input/Output buffers. If the component needs more than this, it will be
// negotiated. If the component does not need more than this number, the default is used
#define NUMBER_INPUT_BUFFER 5
#define NUMBER_OUTPUT_BUFFER 9

// nal start code is 0001
#define NAL_START_CODE_SIZE 4
const unsigned char NAL_START_CODE[4] = {0, 0, 0, 1};

////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////
/////////////////////////
/////////////////////////
// CUSTOM DEALLOCATOR FOR MEDIA DATA SHARED PTR WRAPPER:
//                      1) Deallocates the underlying output buffer
//                      2) Deallocates the pvci buffer wrapper and the rest of accompanying structures
//                    Deallocator is created as part of the wrapper, and travels with the buffer wrapper

class PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA : public OsclDestructDealloc
{
    public:
        PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA(Oscl_DefAlloc* allocator, void *pMempoolData) :
                buf_alloc(allocator), ptr_to_data_to_dealloc(pMempoolData) {};
        virtual ~PVOMXDecBufferSharedPtrWrapperCombinedCleanupDA() {};

        virtual void destruct_and_dealloc(OsclAny* ptr)
        {
            // call buffer deallocator
            if (buf_alloc != NULL)
            {
                buf_alloc->deallocate(ptr_to_data_to_dealloc);
            }

            // finally, free the shared ptr wrapper memory
            oscl_free(ptr);
        }

    private:
        Oscl_DefAlloc* buf_alloc;
        void *ptr_to_data_to_dealloc;
};


#define PVMFOMXBaseDecNodeCommandBase PVMFGenericNodeCommand<PVMFOMXBaseDecNodeAllocator>

class PVMFOMXBaseDecNodeCommand: public PVMFOMXBaseDecNodeCommandBase
{
    public:
        //constructor for Custom2 command
        void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, const OsclAny*aContext)
        {
            PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
            iParam1 = (OsclAny*)arg1;
            iParam2 = (OsclAny*)arg2;
            iParam3 = (OsclAny*) & arg3;
        }
        void Parse(int32&arg1, int32&arg2, int32*&arg3)
        {
            arg1 = (int32)iParam1;
            arg2 = (int32)iParam2;
            arg3 = (int32*)iParam3;
        }

        void Construct(PVMFSessionId s, int32 cmd, PVMFMetadataList* aKeyList, uint32 aStartIndex, int32 aMaxEntries, char* aQueryKey, const OsclAny* aContext)
        {
            PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
            iStartIndex = aStartIndex;
            iMaxEntries = aMaxEntries;

            if (aQueryKey == NULL)
            {
                query_key[0] = 0;
            }
            else
            {
                if (aQueryKey != NULL)
                    oscl_strncpy(query_key, aQueryKey, oscl_strlen(aQueryKey) + 1);
            }

            iParam1 = (OsclAny*)aKeyList;
            iParam2 = NULL;
            iParam3 = NULL;
            iParam4 = NULL;
            iParam5 = NULL;
        }

        void Parse(PVMFMetadataList*& MetaDataListPtr, uint32 &aStartingIndex, int32 &aMaxEntries, char*&aQueryKey)
        {
            MetaDataListPtr = (PVMFMetadataList*)iParam1;
            aStartingIndex = iStartIndex;
            aMaxEntries = iMaxEntries;
            if (query_key[0] == 0)
            {
                aQueryKey = NULL;
            }
            else
            {
                aQueryKey = query_key;
            }
        }

        // Constructor and parser for GetNodeMetadataValue
        void Construct(PVMFSessionId s, int32 cmd, PVMFMetadataList* aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>* aValueList, uint32 aStartIndex, int32 aMaxEntries, const OsclAny* aContext)
        {
            PVMFOMXBaseDecNodeCommandBase::Construct(s, cmd, aContext);
            iParam1 = (OsclAny*)aKeyList;
            iParam2 = (OsclAny*)aValueList;

            iStartIndex = aStartIndex;
            iMaxEntries = aMaxEntries;

            iParam3 = NULL;
            iParam4 = NULL;
            iParam5 = NULL;
        }
        void Parse(PVMFMetadataList* &aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>* &aValueList, uint32 &aStartingIndex, int32 &aMaxEntries)
        {
            aKeyList = (PVMFMetadataList*)iParam1;
            aValueList = (Oscl_Vector<PvmiKvp, OsclMemAllocator>*)iParam2;
            aStartingIndex = iStartIndex;
            aMaxEntries = iMaxEntries;
        }

        virtual bool hipri()
        {
            //this routine identifies commands that need to
            //go at the front of the queue.  derived command
            //classes can override it if needed.
            return (iCmd == PVOMXBASEDEC_NODE_CMD_CANCELALL
                    || iCmd == PVOMXBASEDEC_NODE_CMD_CANCELCMD);
        }

        enum PVOMXBaseDecNodeCmdType
        {
            PVOMXBASEDEC_NODE_CMD_QUERYUUID,
            PVOMXBASEDEC_NODE_CMD_QUERYINTERFACE,
            PVOMXBASEDEC_NODE_CMD_INIT,
            PVOMXBASEDEC_NODE_CMD_PREPARE,
            PVOMXBASEDEC_NODE_CMD_REQUESTPORT,
            PVOMXBASEDEC_NODE_CMD_START,
            PVOMXBASEDEC_NODE_CMD_PAUSE,
            PVOMXBASEDEC_NODE_CMD_STOP,
            PVOMXBASEDEC_NODE_CMD_FLUSH,
            PVOMXBASEDEC_NODE_CMD_RELEASEPORT,
            PVOMXBASEDEC_NODE_CMD_RESET,
            PVOMXBASEDEC_NODE_CMD_CANCELCMD,
            PVOMXBASEDEC_NODE_CMD_CANCELALL,
            PVOMXBASEDEC_NODE_CMD_INVALID,
            PVOMXBASEDEC_NODE_CMD_GETNODEMETADATAKEY,
            PVOMXBASEDEC_NODE_CMD_GETNODEMETADATAVALUE
        };

    private:
        uint32 iStartIndex;
        uint32 iMaxEntries;
        char query_key[256];

};

//Default vector reserve size
#define PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE 10

//Starting value for command IDs
#define PVMF_OMXBASEDEC_NODE_COMMAND_ID_START 6000

///////////////////////////////////////////////////////////////////////////////////////////////////////
//CAPABILITY AND CONFIG

// Structure to hold the key string info for
// capability-and-config
struct PVOMXBaseDecNodeKeyStringData
{
    char iString[64];
    PvmiKvpType iType;
    PvmiKvpValueType iValueType;
};

// The number of characters to allocate for the key string
#define PVOMXBASEDECNODECONFIG_KEYSTRING_SIZE 128

//Mimetypes for the custom interface
#define PVMF_OMX_BASE_DEC_NODE_MIMETYPE "pvxxx/OMXBaseDecNode"
#define PVMF_BASEMIMETYPE "pvxxx"

//Command queue type
typedef PVMFNodeCommandQueue<PVMFOMXBaseDecNodeCommand, PVMFOMXBaseDecNodeAllocator> PVMFOMXBaseDecNodeCmdQ;


class PVMFOMXBaseDecNode
        : public OsclActiveObject
        , public PVMFNodeInterface
        , public OsclMemPoolFixedChunkAllocatorObserver
        , public PVMFOMXBaseDecNodeExtensionInterface
        , public PVMFMetadataExtensionInterface
        , public PvmiCapabilityAndConfig

{
    public:
        OSCL_IMPORT_REF PVMFOMXBaseDecNode(int32 aPriority, const char aAOName[], bool aHwAccelerated = true);
        OSCL_IMPORT_REF virtual ~PVMFOMXBaseDecNode();

        // From PVMFNodeInterface
        OSCL_IMPORT_REF virtual PVMFStatus ThreadLogon() = 0;
        OSCL_IMPORT_REF PVMFStatus ThreadLogoff();
        OSCL_IMPORT_REF PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability);
        OSCL_IMPORT_REF PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL);
        OSCL_IMPORT_REF PVMFCommandId QueryUUID(PVMFSessionId, const PvmfMimeString& aMimeType,
                                                Oscl_Vector<PVUuid, PVMFOMXBaseDecNodeAllocator>& aUuids,
                                                bool aExactUuidsOnly = false,
                                                const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId QueryInterface(PVMFSessionId, const PVUuid& aUuid,
                PVInterface*& aInterfacePtr,
                const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId RequestPort(PVMFSessionId
                , int32 aPortTag, const PvmfMimeString* aPortConfig = NULL, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId ReleasePort(PVMFSessionId, PVMFPortInterface& aPort, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Init(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Prepare(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Start(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Stop(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Flush(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Pause(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId Reset(PVMFSessionId, const OsclAny* aContext = NULL);
        OSCL_IMPORT_REF PVMFCommandId CancelAllCommands(PVMFSessionId, const OsclAny* aContextData = NULL);
        OSCL_IMPORT_REF PVMFCommandId CancelCommand(PVMFSessionId, PVMFCommandId aCmdId, const OsclAny* aContextData = NULL);

        // From PVMFPortActivityHandler
        OSCL_IMPORT_REF void HandlePortActivity(const PVMFPortActivity& aActivity);

        // From PVInterface
        OSCL_IMPORT_REF virtual void addRef();
        OSCL_IMPORT_REF virtual void removeRef();
        OSCL_IMPORT_REF virtual bool queryInterface(const PVUuid& uuid, PVInterface*& iface);
        OSCL_IMPORT_REF virtual PVMFStatus SetDecoderNodeConfiguration(PVMFOMXBaseDecNodeConfig& aConfig);

        //**********begin PVMFMetadataExtensionInterface
        OSCL_IMPORT_REF virtual uint32 GetNumMetadataKeys(char* query_key = NULL) = 0;
        OSCL_IMPORT_REF virtual uint32 GetNumMetadataValues(PVMFMetadataList& aKeyList) = 0;
        OSCL_IMPORT_REF PVMFCommandId GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, uint32 starting_index, int32 max_entries,
                char* query_key = NULL, const OsclAny* aContextData = NULL);
        OSCL_IMPORT_REF PVMFCommandId GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList,
                Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, int32 max_entries, const OsclAny* aContextData = NULL);
        OSCL_IMPORT_REF PVMFStatus ReleaseNodeMetadataKeys(PVMFMetadataList& aKeyList, uint32 starting_index, uint32 end_index);
        OSCL_IMPORT_REF PVMFStatus ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 starting_index, uint32 end_index);
        //**********End PVMFMetadataExtensionInterface
        OSCL_IMPORT_REF virtual bool VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements) = 0;

        //********** CB Functions to serve OpenMAX Decoder

        //Process callback functions. They will be executed in testapp thread context
        //  These callbacks are used only in the Multithreaded component case
        OSCL_IMPORT_REF OsclReturnCode ProcessCallbackEventHandler_MultiThreaded(OsclAny* P);
        OSCL_IMPORT_REF OsclReturnCode ProcessCallbackEmptyBufferDone_MultiThreaded(OsclAny* P);
        OSCL_IMPORT_REF OsclReturnCode ProcessCallbackFillBufferDone_MultiThreaded(OsclAny* P);

        //Callback objects - again, these are used only in the case of Multithreaded component
        EventHandlerThreadSafeCallbackAO*    iThreadSafeHandlerEventHandler;
        EmptyBufferDoneThreadSafeCallbackAO* iThreadSafeHandlerEmptyBufferDone;
        FillBufferDoneThreadSafeCallbackAO*  iThreadSafeHandlerFillBufferDone;

        OMX_CALLBACKTYPE       iCallbacks; // structure that contains callback ptrs.
        // OMX CALLBACKS
        // 1) AO OMX component running in the same thread as the OMX node
        //  In this case, the callbacks can be called directly from the component
        //  The callback: OMX Component->CallbackEventHandler->EventHandlerProcessing
        //  The callback can perform do RunIfNotReady

        // 2) Multithreaded component
        //  In this case, the callback is made using the threadsafe callback (TSCB) AO
        //  Component thread : OMX Component->CallbackEventHandler->TSCB(ReceiveEvent)
        //  Node thread      : TSCB(ProcessEvent)->ProcessCallbackEventHandler_MultiThreaded->EventHandlerProcessing


        //==============================================================================

        OSCL_IMPORT_REF virtual OMX_ERRORTYPE EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
                OMX_OUT OMX_PTR aAppData,
                OMX_OUT OMX_EVENTTYPE aEvent,
                OMX_OUT OMX_U32 aData1,
                OMX_OUT OMX_U32 aData2,
                OMX_OUT OMX_PTR aEventData) = 0;

        OSCL_IMPORT_REF OMX_ERRORTYPE EmptyBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
                OMX_OUT OMX_PTR aAppData,
                OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);

        OSCL_IMPORT_REF OMX_ERRORTYPE FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
                OMX_OUT OMX_PTR aAppData,
                OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer);

        bool IsComponentMultiThreaded()
        {
            return iIsOMXComponentMultiThreaded;
        };

        // From PvmiCapabilityAndConfig
        OSCL_IMPORT_REF void setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver);
        OSCL_IMPORT_REF PVMFStatus getParametersSync(PvmiMIOSession aSession, PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext);
        OSCL_IMPORT_REF PVMFStatus releaseParameters(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements);
        OSCL_IMPORT_REF void createContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
        OSCL_IMPORT_REF void setContextParameters(PvmiMIOSession aSession, PvmiCapabilityContext& aContext, PvmiKvp* aParameters, int aNumParamElements);
        OSCL_IMPORT_REF void DeleteContext(PvmiMIOSession aSession, PvmiCapabilityContext& aContext);
        OSCL_IMPORT_REF void setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP);
        OSCL_IMPORT_REF PVMFCommandId setParametersAsync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements, PvmiKvp*& aRetKVP, OsclAny* aContext = NULL);
        OSCL_IMPORT_REF uint32 getCapabilityMetric(PvmiMIOSession aSession);
        OSCL_IMPORT_REF PVMFStatus verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int aNumElements);
        OSCL_IMPORT_REF virtual bool ProcessIncomingMsg(PVMFPortInterface* aPort);
        OSCL_IMPORT_REF void Run();
    protected:
        OSCL_IMPORT_REF void CommandComplete(PVMFOMXBaseDecNodeCmdQ& aCmdQ, PVMFOMXBaseDecNodeCommand& aCmd, PVMFStatus aStatus, OsclAny* aEventData = NULL);

        virtual void DoQueryUuid(PVMFOMXBaseDecNodeCommand&) = 0;
        void DoQueryInterface(PVMFOMXBaseDecNodeCommand&);
        virtual void DoRequestPort(PVMFOMXBaseDecNodeCommand&) = 0;
        virtual void DoReleasePort(PVMFOMXBaseDecNodeCommand&) = 0;
        void DoInit(PVMFOMXBaseDecNodeCommand&);
        void DoPrepare(PVMFOMXBaseDecNodeCommand&);
        void DoStart(PVMFOMXBaseDecNodeCommand&);
        void DoStop(PVMFOMXBaseDecNodeCommand&);
        void DoPause(PVMFOMXBaseDecNodeCommand&);
        void DoReset(PVMFOMXBaseDecNodeCommand&);
        void DoFlush(PVMFOMXBaseDecNodeCommand&);
        virtual PVMFStatus DoGetNodeMetadataKey(PVMFOMXBaseDecNodeCommand&) = 0;
        virtual PVMFStatus DoGetNodeMetadataValue(PVMFOMXBaseDecNodeCommand&) = 0;
        void DoCancelAllCommands(PVMFOMXBaseDecNodeCommand&);
        void DoCancelCommand(PVMFOMXBaseDecNodeCommand&);

        bool ProcessCommand(PVMFOMXBaseDecNodeCommand& aCmd);
        bool ProcessOutgoingMsg(PVMFPortInterface* aPort);
        PVMFStatus HandleProcessingState();
        virtual PVMFStatus HandlePortReEnable() = 0;

        virtual bool InitDecoder(PVMFSharedMediaDataPtr&) = 0;

        OSCL_IMPORT_REF OsclAny* AllocateKVPKeyArray(int32& aLeaveCode, PvmiKvpValueType aValueType, int32 aNumElements);
        int32 PushKVPKey(OSCL_HeapString<OsclMemAllocator>& aString, PVMFMetadataList* aKeyList)
        {
            int32 leavecode = OsclErrNone;
            OSCL_TRY(leavecode, aKeyList->push_back(aString));
            return leavecode;
        }

        int32 PushKVPKey(const char* aString, PVMFMetadataList& aKeyList)
        {
            int32 leavecode = OsclErrNone;
            OSCL_TRY(leavecode, aKeyList.push_back(aString));
            return leavecode;
        }

        int32 PushKVP(PvmiKvp aKVP, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList)
        {
            int32 leavecode = OsclErrNone;
            OSCL_TRY(leavecode, aValueList.push_back(aKVP));
            return leavecode;
        }

        int32 AllocateChunkFromMemPool(OsclAny*& aCtrlStructPtr, OsclMemPoolFixedChunkAllocator *aMemPool, int32 aAllocSize)
        {
            int32 leavecode = OsclErrNone;
            OSCL_TRY(leavecode, aCtrlStructPtr = (OsclAny *) aMemPool->allocate(aAllocSize));
            return leavecode;
        }

        // DV:
        virtual bool NegotiateComponentParameters(OMX_PTR aOutputParameters) = 0;

        bool SetDefaultCapabilityFlags();
        OSCL_IMPORT_REF bool CreateOutMemPool(uint32 num);
        OSCL_IMPORT_REF bool CreateInputMemPool(uint32 num);
        OSCL_IMPORT_REF bool ProvideBuffersToComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
                uint32 aAllocSize,   // size to allocate from pool (hdr only or hdr+ buffer)
                uint32 aNumBuffers,    // number of buffers
                uint32 aActualBufferSize, // aactual buffer size
                uint32 aPortIndex,      // port idx
                bool aUseBufferOK,  // can component use OMX_UseBuffer?
                bool    aIsThisInputBuffer // is this input or output
                                                      );

        bool FreeBuffersFromComponent(OsclMemPoolFixedChunkAllocator *aMemPool, // allocator
                                      uint32 aAllocSize,     // size to allocate from pool (hdr only or hdr+ buffer)
                                      uint32 aNumBuffers,    // number of buffers
                                      uint32 aPortIndex,      // port idx
                                      bool  aIsThisInputBuffer      // is this input or output
                                     );

        OsclSharedPtr<class PVMFMediaDataImpl> WrapOutputBuffer(uint8 *pData, uint32 aDataLen, OsclAny *pContext);
        virtual bool QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen) = 0;

        bool SendOutputBufferToOMXComponent();
        OSCL_IMPORT_REF bool SendInputBufferToOMXComponent();

        OSCL_IMPORT_REF bool SendConfigBufferToOMXComponent(uint8 *initbuffer, uint32 initbufsize);
        bool SendEOSBufferToOMXComponent();

        bool HandleRepositioning(void);
        bool SendBeginOfMediaStreamCommand(void);
        bool SendEndOfTrackCommand(void);

        bool AppendExtraDataToBuffer(InputBufCtrlStruct* aInputBuffer, OMX_EXTRADATATYPE aType, uint8* aExtraData, uint8 aDataLength);

        virtual bool ReleaseAllPorts() = 0;
        bool DeleteOMXBaseDecoder();

        OSCL_IMPORT_REF void ChangeNodeState(TPVMFNodeInterfaceState aNewState);

        OSCL_IMPORT_REF void HandleComponentStateChange(OMX_U32 decoder_state);

        // Capability And Config Helper Methods
        OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext);
        OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements);
        OSCL_IMPORT_REF virtual void DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP);
        OSCL_IMPORT_REF virtual PVMFStatus DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements);

        // From OsclMemPoolFixedChunkAllocatorObserver
        OSCL_IMPORT_REF void freechunkavailable(OsclAny*);

        OSCL_IMPORT_REF PVMFCommandId QueueCommandL(PVMFOMXBaseDecNodeCommand& aCmd);

        friend class PVMFOMXBaseDecPort;

        // Ports pointers
        PVMFPortInterface* iInPort;
        PVMFPortInterface* iOutPort;

        // Commands
        PVMFOMXBaseDecNodeCmdQ iInputCommands;
        PVMFOMXBaseDecNodeCmdQ iCurrentCommand;

        // Shared pointer for Media Msg.Input buffer
        PVMFSharedMediaDataPtr iDataIn;

        // OUTPUT BUFFER RELATED MEMBERS
        // Output buffer memory pool
        OsclMemPoolFixedChunkAllocator *iOutBufMemoryPool;

        // Memory pool for simple media data
        OsclMemPoolFixedChunkAllocator *iMediaDataMemPool;

        // Fragment pool for format specific info
        PVMFBufferPoolAllocator iFsiFragmentAlloc;
        // Fragment pool for private data format specific info
        PVMFBufferPoolAllocator iPrivateDataFsiFragmentAlloc;

        // Size of output buffer (negotiated with component)
        uint32 iOMXComponentOutputBufferSize;

        // size of output to allocate (OMX_ALLOCATE_BUFFER =  size of buf header )
        // (OMX_USE_BUFFER = size of buf header + iOMXCoponentOutputBufferSize)
        uint32 iOutputAllocSize;

        // Number of output buffers (negotiated with component)
        uint32 iNumOutputBuffers;

        // Number of output buffers in possession of the component or downstream,
        // namely, number of unavailable buffers
        uint32 iNumOutstandingOutputBuffers;

        // flag to prevent sending output buffers downstream during flushing etc.
        bool iDoNotSendOutputBuffersDownstreamFlag;

        // flag to prevent freeing the buffers twice
        bool iOutputBuffersFreed;


        OsclAny *ipPrivateData;

        // INPUT BUFFER RELATED MEMBERS
        OsclMemPoolFixedChunkAllocator *iInBufMemoryPool;
        uint32 iOMXComponentInputBufferSize; // size of input buffer that the component sees (negotiated with the component)
        uint32 iInputAllocSize;     // size of input buffer to allocate (OMX_ALLOCATE_BUFFER =  size of buf header )
        // (OMX_USE_BUFFER = size of buf header + iOMXCoponentInputBufferSize)
        uint32 iNumInputBuffers; // total num of input buffers (negotiated with component)

        uint32 iNumOutstandingInputBuffers; // number of input buffers in use (i.e. unavailable)

        bool iDoNotSaveInputBuffersFlag;

        // flag to prevent freeing buffers twice
        bool iInputBuffersFreed;

        // input buffer fragmentation etc.
        uint32 iCopyPosition;               // for copying memfrag data into a buffer
        uint32 iFragmentSizeRemainingToCopy;
        bool    iIsNewDataFragment;
        // partial frame assembly logic flags
        bool    iFirstPieceOfPartialFrame;
        bool    iObtainNewInputBuffer;
        bool    iKeepDroppingMsgsUntilMarkerBit;
        bool    iFirstDataMsgAfterBOS;
        InputBufCtrlStruct *iInputBufferUnderConstruction;
        bool    iIncompleteFrame;

        OSCL_IMPORT_REF void DropCurrentBufferUnderConstruction();
        OSCL_IMPORT_REF void SendIncompleteBufferUnderConstruction();

        // input data info
        uint32 iCurrFragNum;
        uint32 iCodecSeqNum;    // sequence number tracking
        uint32 iInPacketSeqNum;

        uint32 iInTimestamp;
        uint32 iInDuration;
        uint32 iInNumFrags;
        uint32 iCurrentMsgMarkerBit;

        // DYNAMIC PORT RE-CONFIGURATION
        uint32 iInputPortIndex;
        uint32 iOutputPortIndex;
        OMX_PARAM_PORTDEFINITIONTYPE iParamPort;
        uint32 iPortIndexForDynamicReconfig;
        bool iSecondPortReportedChange;
        bool iDynamicReconfigInProgress;
        uint32 iSecondPortToReconfig;
        bool iPauseCommandWasSentToComponent;
        bool iStopCommandWasSentToComponent;

        OMX_BUFFERHEADERTYPE *iInputBufferToResendToComponent; // ptr to input buffer that is not empty, but that the OMX component returned
        // we need to resend this same buffer back to the component

        ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
        bool iOMXComponentSupportsExternalOutputBufferAlloc;
        bool iOMXComponentSupportsExternalInputBufferAlloc;
        bool iOMXComponentSupportsMovableInputBuffers;
        bool iSetMarkerBitForEveryFrag; // is every fragment complete frame (e.g. AVC file playback = each fragment is a NAL)
        bool iIsOMXComponentMultiThreaded;
        bool iOMXComponentSupportsPartialFrames;
        bool iOMXComponentUsesNALStartCodes;
        bool iOMXComponentUsesFullAVCFrames;
        bool iOMXComponentCanHandleIncompleteFrames;

        // State definitions for HandleProcessingState() state machine
        typedef enum
        {
            EPVMFOMXBaseDecNodeProcessingState_Idle,                  //default state after constraction/reset
            EPVMFOMXBaseDecNodeProcessingState_InitDecoder,           //initialization of H264 decoder after handle was obtained
            EPVMFOMXBaseDecNodeProcessingState_WaitForInitCompletion, // waiting for init completion
            EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode,         //nornal operation state of the decoder
            EPVMFOMXBaseDecNodeProcessingState_WaitForOutputBuffer,   //wait state for avalible media output buffer
            EPVMFOMXBaseDecNodeProcessingState_WaitForOutputPort,     //wait state, output port is busy
            EPVMFOMXBaseDecNodeProcessingState_WaitForOutgoingQueue,   //wait state, outgoing queue
            EPVMFOMXBaseDecNodeProcessingState_PortReconfig,            // Dynamic Port Reconfiguration - step 1
            EPVMFOMXBaseDecNodeProcessingState_WaitForBufferReturn,     //  step 2
            EPVMFOMXBaseDecNodeProcessingState_WaitForPortDisable,      // Dynamic Port Reconfiguration - step 3
            EPVMFOMXBaseDecNodeProcessingState_PortReEnable,            // Dynamic Port Reconfiguration - step 4
            EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable,       // step 5
            EPVMFOMXBaseDecNodeProcessingState_Stopping,                // when STOP command is issued, the node has to wait for component to transition into
            // idle state. The buffers keep coming back , the node is rescheduled
            // to run. Prevent the node from sending buffers back
            EPVMFOMXBaseDecNodeProcessingState_Pausing                  // when PAUSE command is issued, the node has to wait for component to transition into
            // paused state.
            // Video: This prevents the node from sending buffers back
            // Audio: The buffers may still keep coming back , the node is rescheduled
            // to run. Prevent the node from sending buffers back to component

        } PVMFOMXBaseDecNode_ProcessingState;

        // State of HandleProcessingState() state machine
        PVMFOMXBaseDecNode_ProcessingState iProcessingState;

        // Handle of OMX Component
        OMX_HANDLETYPE iOMXDecoder;

        // Current State of the component
        OMX_STATETYPE iCurrentDecoderState;

        // BOS
        bool iSendBOS;
        uint32 iStreamID;
        uint32 iBOSTimestamp;

        // repositioning related flags
        bool iIsRepositioningRequestSentToComponent;
        bool iIsRepositionDoneReceivedFromComponent;
        bool iIsOutputPortFlushed;
        bool iIsInputPortFlushed;

        //EOS control flags
        bool iIsEOSSentToComponent;
        bool iIsEOSReceivedFromComponent;

        // Send Fsi configuration flag
        bool    sendFsi;

        // Pointer to input data fragment
        uint8* iBitstreamBuffer;
        // Size of input data fragment
        int32 iBitstreamSize;

        // Output frame sequence counter
        uint32 iSeqNum;

        // Input frame sequence counter
        uint32 iSeqNum_In;

        // Added to Scheduler Flag
        bool iIsAdded;

        // Log related
        PVLogger* iLogger;
        PVLogger* iDataPathLogger;
        PVLogger* iClockLogger;
        PVLogger *iRunlLogger;

        // Counter of fragment read from current Media Msg.Input buffer
        uint fragnum;
        // Number of fragments in the Media Msg.Input buffer
        uint numfrags;

        // Time stamp to be used on output buffer
        uint32 iOutTimeStamp;

        // Node configuration update
        PVMFOMXBaseDecNodeConfig iNodeConfig;

        // Capability exchange
        PVMFNodeCapability iCapability;

        // Reference counter for extension
        uint32 iExtensionRefCount;

        // Vector for KVP
        Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> iAvailableMetadataKeys;

        // EOS flag
        bool iEndOfDataReached;
        // Time stame upon EOS
        PVMFTimestamp iEndOfDataTimestamp;

        /* Diagnostic log related */
        PVLogger* iDiagnosticsLogger;
        bool iDiagnosticsLogged;
        void LogDiagnostics();

        uint32 iFrameCounter;

        uint32 iAvgBitrateValue;
        bool iResetInProgress;
        bool iResetMsgSent;
        bool iStopInResetMsgSent;

        // AVC NAL counter and size array
        uint32 iNALCount;
        uint32 iNALSizeArray[MAX_NAL_PER_FRAME]; // NAL count shouldn't exceed 100

        OsclAny **out_ctrl_struct_ptr ;
        OsclAny **out_buff_hdr_ptr ;
        OsclAny **in_ctrl_struct_ptr ;
        OsclAny **in_buff_hdr_ptr ;

        PVInterface* ipExternalOutputBufferAllocatorInterface;
        PVMFFixedSizeBufferAlloc* ipFixedSizeBufferAlloc;
        bool iCompactFSISettingSucceeded;

        // Timestamp, timescale, OMX Ticks related conversions
        uint32 iInTimeScale;
        uint32 iOutTimeScale;
        uint32 iTimeScale;
        MediaClockConverter iInputTimestampClock;
        OMX_TICKS iOMXTicksTimestamp;
        OSCL_IMPORT_REF OMX_TICKS ConvertTimestampIntoOMXTicks(const MediaClockConverter &src);
        uint32 ConvertOMXTicksIntoTimestamp(const OMX_TICKS &src);
        OMX_BOOL bHWAccelerated;
};


#endif // PVMF_OMXBASEDEC_NODE_H_INCLUDED