componentbase.cpp revision 35ff01df238a01bfef109b68eb68a82de8722c5f
1/*
2 * componentbase.cpp, component base class
3 *
4 * Copyright (c) 2009-2010 Wind River Systems, Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <stdlib.h>
20#include <string.h>
21
22#include <pthread.h>
23
24#include <OMX_Core.h>
25#include <OMX_Component.h>
26
27#include <componentbase.h>
28
29#include <queue.h>
30#include <workqueue.h>
31#include <OMX_IndexExt.h>
32
33//#define LOG_NDEBUG 0
34
35#define LOG_TAG "componentbase"
36#include <log.h>
37
38/*
39 * CmdProcessWork
40 */
41CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci)
42{
43    this->ci = ci;
44
45    workq = new WorkQueue;
46
47    __queue_init(&q);
48    pthread_mutex_init(&lock, NULL);
49
50    workq->StartWork(true);
51
52    LOGV("command process workqueue started\n");
53}
54
55CmdProcessWork::~CmdProcessWork()
56{
57    struct cmd_s *temp;
58
59    workq->StopWork();
60    delete workq;
61
62    while ((temp = PopCmdQueue()))
63        free(temp);
64
65    pthread_mutex_destroy(&lock);
66
67    LOGV("command process workqueue stopped\n");
68}
69
70OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd)
71{
72    int ret;
73
74    pthread_mutex_lock(&lock);
75    ret = queue_push_tail(&q, cmd);
76    if (ret) {
77        pthread_mutex_unlock(&lock);
78        return OMX_ErrorInsufficientResources;
79    }
80
81    workq->ScheduleWork(this);
82    pthread_mutex_unlock(&lock);
83
84    return OMX_ErrorNone;
85}
86
87struct cmd_s *CmdProcessWork::PopCmdQueue(void)
88{
89    struct cmd_s *cmd;
90
91    pthread_mutex_lock(&lock);
92    cmd = (struct cmd_s *)queue_pop_head(&q);
93    pthread_mutex_unlock(&lock);
94
95    return cmd;
96}
97
98void CmdProcessWork::Work(void)
99{
100    struct cmd_s *cmd;
101
102    cmd = PopCmdQueue();
103    if (cmd) {
104        ci->CmdHandler(cmd);
105        free(cmd);
106    }
107}
108
109/* end of CmdProcessWork */
110
111/*
112 * ComponentBase
113 */
114/*
115 * constructor & destructor
116 */
117void ComponentBase::__ComponentBase(void)
118{
119    memset(name, 0, OMX_MAX_STRINGNAME_SIZE);
120    cmodule = NULL;
121    handle = NULL;
122
123    roles = NULL;
124    nr_roles = 0;
125
126    working_role = NULL;
127
128    ports = NULL;
129    nr_ports = 0;
130    memset(&portparam, 0, sizeof(portparam));
131
132    state = OMX_StateUnloaded;
133
134    cmdwork = NULL;
135
136    bufferwork = NULL;
137
138    pthread_mutex_init(&ports_block, NULL);
139    pthread_mutex_init(&state_block, NULL);
140}
141
142ComponentBase::ComponentBase()
143{
144    __ComponentBase();
145}
146
147ComponentBase::ComponentBase(const OMX_STRING name)
148{
149    __ComponentBase();
150    SetName(name);
151}
152
153ComponentBase::~ComponentBase()
154{
155    pthread_mutex_destroy(&ports_block);
156    pthread_mutex_destroy(&state_block);
157
158    if (roles) {
159        if (roles[0])
160            free(roles[0]);
161        free(roles);
162    }
163}
164
165/* end of constructor & destructor */
166
167/*
168 * accessor
169 */
170/* name */
171void ComponentBase::SetName(const OMX_STRING name)
172{
173    strncpy(this->name, name, (strlen(name) < OMX_MAX_STRINGNAME_SIZE) ? strlen(name) : (OMX_MAX_STRINGNAME_SIZE-1));
174   // strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
175    this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
176}
177
178const OMX_STRING ComponentBase::GetName(void)
179{
180    return name;
181}
182
183/* component module */
184void ComponentBase::SetCModule(CModule *cmodule)
185{
186    this->cmodule = cmodule;
187}
188
189CModule *ComponentBase::GetCModule(void)
190{
191    return cmodule;
192}
193
194/* end of accessor */
195
196/*
197 * core methods & helpers
198 */
199/* roles */
200OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles,
201                                                 const OMX_U8 **roles)
202{
203    OMX_U32 i;
204
205    if (!roles || !nr_roles)
206        return OMX_ErrorBadParameter;
207
208    if (this->roles) {
209        free(this->roles[0]);
210        free(this->roles);
211        this->roles = NULL;
212    }
213
214    this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
215    if (!this->roles)
216        return OMX_ErrorInsufficientResources;
217
218    this->roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE * nr_roles);
219    if (!this->roles[0]) {
220        free(this->roles);
221        this->roles = NULL;
222        return OMX_ErrorInsufficientResources;
223    }
224
225    for (i = 0; i < nr_roles; i++) {
226        if (i < nr_roles-1)
227            this->roles[i+1] = this->roles[i] + OMX_MAX_STRINGNAME_SIZE;
228
229        strncpy((OMX_STRING)&this->roles[i][0],
230                (const OMX_STRING)&roles[i][0], OMX_MAX_STRINGNAME_SIZE);
231    }
232
233    this->nr_roles = nr_roles;
234    return OMX_ErrorNone;
235}
236
237/* GetHandle & FreeHandle */
238OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle,
239                                       OMX_PTR pAppData,
240                                       OMX_CALLBACKTYPE *pCallBacks)
241{
242    OMX_U32 i;
243    OMX_ERRORTYPE ret;
244
245    if (!pHandle)
246        return OMX_ErrorBadParameter;
247
248    if (handle)
249        return OMX_ErrorUndefined;
250
251    cmdwork = new CmdProcessWork(this);
252    if (!cmdwork)
253        return OMX_ErrorInsufficientResources;
254
255    bufferwork = new WorkQueue();
256    if (!bufferwork) {
257        ret = OMX_ErrorInsufficientResources;
258        goto free_cmdwork;
259    }
260
261    handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle));
262    if (!handle) {
263        ret = OMX_ErrorInsufficientResources;
264        goto free_bufferwork;
265    }
266
267    /* handle initialization */
268    SetTypeHeader(handle, sizeof(*handle));
269    handle->pComponentPrivate = static_cast<OMX_PTR>(this);
270    handle->pApplicationPrivate = pAppData;
271
272    /* connect handle's functions */
273    handle->GetComponentVersion = NULL;
274    handle->SendCommand = SendCommand;
275    handle->GetParameter = GetParameter;
276    handle->SetParameter = SetParameter;
277    handle->GetConfig = GetConfig;
278    handle->SetConfig = SetConfig;
279    handle->GetExtensionIndex = GetExtensionIndex;
280    handle->GetState = GetState;
281    handle->ComponentTunnelRequest = NULL;
282    handle->UseBuffer = UseBuffer;
283    handle->AllocateBuffer = AllocateBuffer;
284    handle->FreeBuffer = FreeBuffer;
285    handle->EmptyThisBuffer = EmptyThisBuffer;
286    handle->FillThisBuffer = FillThisBuffer;
287    handle->SetCallbacks = SetCallbacks;
288    handle->ComponentDeInit = NULL;
289    handle->UseEGLImage = NULL;
290    handle->ComponentRoleEnum = ComponentRoleEnum;
291
292    appdata = pAppData;
293    callbacks = pCallBacks;
294
295    if (nr_roles == 1) {
296        SetWorkingRole((OMX_STRING)&roles[0][0]);
297        ret = ApplyWorkingRole();
298        if (ret != OMX_ErrorNone) {
299            SetWorkingRole(NULL);
300            goto free_handle;
301        }
302    }
303
304    *pHandle = (OMX_HANDLETYPE *)handle;
305    state = OMX_StateLoaded;
306    return OMX_ErrorNone;
307
308free_handle:
309    free(handle);
310
311    appdata = NULL;
312    callbacks = NULL;
313    *pHandle = NULL;
314
315free_bufferwork:
316    delete bufferwork;
317
318free_cmdwork:
319    delete cmdwork;
320
321    return ret;
322}
323
324OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent)
325{
326    OMX_ERRORTYPE ret;
327
328    if (hComponent != handle)
329        return OMX_ErrorBadParameter;
330
331    if (state != OMX_StateLoaded)
332        return OMX_ErrorIncorrectStateOperation;
333
334    FreePorts();
335
336    free(handle);
337
338    appdata = NULL;
339    callbacks = NULL;
340
341    delete cmdwork;
342    delete bufferwork;
343
344    state = OMX_StateUnloaded;
345    return OMX_ErrorNone;
346}
347
348/* end of core methods & helpers */
349
350/*
351 * component methods & helpers
352 */
353OMX_ERRORTYPE ComponentBase::SendCommand(
354    OMX_IN  OMX_HANDLETYPE hComponent,
355    OMX_IN  OMX_COMMANDTYPE Cmd,
356    OMX_IN  OMX_U32 nParam1,
357    OMX_IN  OMX_PTR pCmdData)
358{
359    ComponentBase *cbase;
360
361    if (!hComponent)
362        return OMX_ErrorBadParameter;
363
364    cbase = static_cast<ComponentBase *>
365        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
366    if (!cbase)
367        return OMX_ErrorBadParameter;
368
369    return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData);
370}
371
372OMX_ERRORTYPE ComponentBase::CBaseSendCommand(
373    OMX_IN  OMX_HANDLETYPE hComponent,
374    OMX_IN  OMX_COMMANDTYPE Cmd,
375    OMX_IN  OMX_U32 nParam1,
376    OMX_IN  OMX_PTR pCmdData)
377{
378    struct cmd_s *cmd;
379
380    if (hComponent != handle)
381        return OMX_ErrorInvalidComponent;
382
383    /* basic error check */
384    switch (Cmd) {
385    case OMX_CommandStateSet:
386        /*
387         * Todo
388         */
389        break;
390    case OMX_CommandFlush: {
391        OMX_U32 port_index = nParam1;
392
393        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
394            return OMX_ErrorBadPortIndex;
395        break;
396    }
397    case OMX_CommandPortDisable:
398    case OMX_CommandPortEnable: {
399        OMX_U32 port_index = nParam1;
400
401        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
402            return OMX_ErrorBadPortIndex;
403        break;
404    }
405    case OMX_CommandMarkBuffer: {
406        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData;
407        OMX_MARKTYPE *copiedmark;
408        OMX_U32 port_index = nParam1;
409
410        if (port_index > nr_ports-1)
411            return OMX_ErrorBadPortIndex;
412
413        if (!mark || !mark->hMarkTargetComponent)
414            return OMX_ErrorBadParameter;
415
416        copiedmark = (OMX_MARKTYPE *)malloc(sizeof(*copiedmark));
417        if (!copiedmark)
418            return OMX_ErrorInsufficientResources;
419
420        copiedmark->hMarkTargetComponent = mark->hMarkTargetComponent;
421        copiedmark->pMarkData = mark->pMarkData;
422        pCmdData = (OMX_PTR)copiedmark;
423        break;
424    }
425    default:
426        LOGE("command %d not supported\n", Cmd);
427        return OMX_ErrorUnsupportedIndex;
428    }
429
430    cmd = (struct cmd_s *)malloc(sizeof(*cmd));
431    if (!cmd)
432        return OMX_ErrorInsufficientResources;
433
434    cmd->cmd = Cmd;
435    cmd->param1 = nParam1;
436    cmd->cmddata = pCmdData;
437
438    return cmdwork->PushCmdQueue(cmd);
439}
440
441OMX_ERRORTYPE ComponentBase::GetParameter(
442    OMX_IN  OMX_HANDLETYPE hComponent,
443    OMX_IN  OMX_INDEXTYPE nParamIndex,
444    OMX_INOUT OMX_PTR pComponentParameterStructure)
445{
446    ComponentBase *cbase;
447
448    if (!hComponent)
449        return OMX_ErrorBadParameter;
450
451    cbase = static_cast<ComponentBase *>
452        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
453    if (!cbase)
454        return OMX_ErrorBadParameter;
455
456    return cbase->CBaseGetParameter(hComponent, nParamIndex,
457                                    pComponentParameterStructure);
458}
459
460OMX_ERRORTYPE ComponentBase::CBaseGetParameter(
461    OMX_IN  OMX_HANDLETYPE hComponent,
462    OMX_IN  OMX_INDEXTYPE nParamIndex,
463    OMX_INOUT OMX_PTR pComponentParameterStructure)
464{
465    OMX_ERRORTYPE ret = OMX_ErrorNone;
466
467    if (hComponent != handle)
468        return OMX_ErrorBadParameter;
469
470    switch (nParamIndex) {
471    case OMX_IndexParamAudioInit:
472    case OMX_IndexParamVideoInit:
473    case OMX_IndexParamImageInit:
474    case OMX_IndexParamOtherInit: {
475        OMX_PORT_PARAM_TYPE *p =
476            (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
477
478        ret = CheckTypeHeader(p, sizeof(*p));
479        if (ret != OMX_ErrorNone)
480            return ret;
481
482        memcpy(p, &portparam, sizeof(*p));
483        break;
484    }
485    case OMX_IndexParamPortDefinition: {
486        OMX_PARAM_PORTDEFINITIONTYPE *p =
487            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
488        OMX_U32 index = p->nPortIndex;
489        PortBase *port = NULL;
490
491        ret = CheckTypeHeader(p, sizeof(*p));
492        if (ret != OMX_ErrorNone)
493            return ret;
494
495        if (index < nr_ports)
496            port = ports[index];
497
498        if (!port)
499            return OMX_ErrorBadPortIndex;
500
501        memcpy(p, port->GetPortDefinition(), sizeof(*p));
502        break;
503    }
504    case OMX_IndexParamCompBufferSupplier:
505        /*
506         * Todo
507         */
508
509        ret = OMX_ErrorUnsupportedIndex;
510        break;
511
512    default:
513        ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure);
514    } /* switch */
515
516    return ret;
517}
518
519OMX_ERRORTYPE ComponentBase::SetParameter(
520    OMX_IN  OMX_HANDLETYPE hComponent,
521    OMX_IN  OMX_INDEXTYPE nIndex,
522    OMX_IN  OMX_PTR pComponentParameterStructure)
523{
524    ComponentBase *cbase;
525
526    if (!hComponent)
527        return OMX_ErrorBadParameter;
528
529    cbase = static_cast<ComponentBase *>
530        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
531    if (!cbase)
532        return OMX_ErrorBadParameter;
533
534    return cbase->CBaseSetParameter(hComponent, nIndex,
535                                    pComponentParameterStructure);
536}
537
538OMX_ERRORTYPE ComponentBase::CBaseSetParameter(
539    OMX_IN  OMX_HANDLETYPE hComponent,
540    OMX_IN  OMX_INDEXTYPE nIndex,
541    OMX_IN  OMX_PTR pComponentParameterStructure)
542{
543    OMX_ERRORTYPE ret = OMX_ErrorNone;
544
545    if (hComponent != handle)
546        return OMX_ErrorBadParameter;
547
548    switch (nIndex) {
549    case OMX_IndexParamAudioInit:
550    case OMX_IndexParamVideoInit:
551    case OMX_IndexParamImageInit:
552    case OMX_IndexParamOtherInit:
553        /* preventing clients from setting OMX_PORT_PARAM_TYPE */
554        ret = OMX_ErrorUnsupportedIndex;
555        break;
556    case OMX_IndexParamPortDefinition: {
557        OMX_PARAM_PORTDEFINITIONTYPE *p =
558            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
559        OMX_U32 index = p->nPortIndex;
560        PortBase *port = NULL;
561
562        ret = CheckTypeHeader(p, sizeof(*p));
563        if (ret != OMX_ErrorNone)
564            return ret;
565
566        if (index < nr_ports)
567            port = ports[index];
568
569        if (!port)
570            return OMX_ErrorBadPortIndex;
571
572        if (port->IsEnabled()) {
573            if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
574                return OMX_ErrorIncorrectStateOperation;
575        }
576
577        ret = port->SetPortDefinition(p, false);
578        if (ret != OMX_ErrorNone) {
579            return ret;
580        }
581        break;
582    }
583    case OMX_IndexParamCompBufferSupplier:
584        /*
585         * Todo
586         */
587
588        ret = OMX_ErrorUnsupportedIndex;
589        break;
590    case OMX_IndexParamStandardComponentRole: {
591        OMX_PARAM_COMPONENTROLETYPE *p =
592            (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
593
594        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
595            return OMX_ErrorIncorrectStateOperation;
596
597        ret = CheckTypeHeader(p, sizeof(*p));
598        if (ret != OMX_ErrorNone)
599            return ret;
600
601        ret = SetWorkingRole((OMX_STRING)p->cRole);
602        if (ret != OMX_ErrorNone)
603            return ret;
604
605        if (ports)
606            FreePorts();
607
608        ret = ApplyWorkingRole();
609        if (ret != OMX_ErrorNone) {
610            SetWorkingRole(NULL);
611            return ret;
612        }
613        break;
614    }
615
616    default:
617        ret = ComponentSetParameter(nIndex, pComponentParameterStructure);
618    } /* switch */
619
620    return ret;
621}
622
623OMX_ERRORTYPE ComponentBase::GetConfig(
624    OMX_IN  OMX_HANDLETYPE hComponent,
625    OMX_IN  OMX_INDEXTYPE nIndex,
626    OMX_INOUT OMX_PTR pComponentConfigStructure)
627{
628    ComponentBase *cbase;
629
630    if (!hComponent)
631        return OMX_ErrorBadParameter;
632
633    cbase = static_cast<ComponentBase *>
634        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
635    if (!cbase)
636        return OMX_ErrorBadParameter;
637
638    return cbase->CBaseGetConfig(hComponent, nIndex,
639                                 pComponentConfigStructure);
640}
641
642OMX_ERRORTYPE ComponentBase::CBaseGetConfig(
643    OMX_IN  OMX_HANDLETYPE hComponent,
644    OMX_IN  OMX_INDEXTYPE nIndex,
645    OMX_INOUT OMX_PTR pComponentConfigStructure)
646{
647    OMX_ERRORTYPE ret;
648
649    if (hComponent != handle)
650        return OMX_ErrorBadParameter;
651
652    switch (nIndex) {
653    default:
654        ret = ComponentGetConfig(nIndex, pComponentConfigStructure);
655    }
656
657    return ret;
658}
659
660OMX_ERRORTYPE ComponentBase::SetConfig(
661    OMX_IN  OMX_HANDLETYPE hComponent,
662    OMX_IN  OMX_INDEXTYPE nIndex,
663    OMX_IN  OMX_PTR pComponentConfigStructure)
664{
665    ComponentBase *cbase;
666
667    if (!hComponent)
668        return OMX_ErrorBadParameter;
669
670    cbase = static_cast<ComponentBase *>
671        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
672    if (!cbase)
673        return OMX_ErrorBadParameter;
674
675    return cbase->CBaseSetConfig(hComponent, nIndex,
676                                 pComponentConfigStructure);
677}
678
679OMX_ERRORTYPE ComponentBase::CBaseSetConfig(
680    OMX_IN  OMX_HANDLETYPE hComponent,
681    OMX_IN  OMX_INDEXTYPE nIndex,
682    OMX_IN  OMX_PTR pComponentConfigStructure)
683{
684    OMX_ERRORTYPE ret;
685
686    if (hComponent != handle)
687        return OMX_ErrorBadParameter;
688
689    switch (nIndex) {
690    default:
691        ret = ComponentSetConfig(nIndex, pComponentConfigStructure);
692    }
693
694    return ret;
695}
696
697OMX_ERRORTYPE ComponentBase::GetExtensionIndex(
698    OMX_IN  OMX_HANDLETYPE hComponent,
699    OMX_IN  OMX_STRING cParameterName,
700    OMX_OUT OMX_INDEXTYPE* pIndexType)
701{
702    ComponentBase *cbase;
703
704    if (!hComponent)
705        return OMX_ErrorBadParameter;
706
707    cbase = static_cast<ComponentBase *>
708        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
709    if (!cbase)
710        return OMX_ErrorBadParameter;
711
712    return cbase->CBaseGetExtensionIndex(hComponent, cParameterName,
713                                         pIndexType);
714}
715
716OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex(
717    OMX_IN  OMX_HANDLETYPE hComponent,
718    OMX_IN  OMX_STRING cParameterName,
719    OMX_OUT OMX_INDEXTYPE* pIndexType)
720{
721    /*
722     * Todo
723     */
724    if (hComponent != handle) {
725
726        return OMX_ErrorBadParameter;
727    }
728
729    if (!strcmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers")) {
730        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexStoreMetaDataInBuffers);
731        return OMX_ErrorNone;
732    }
733
734    if (!strcmp(cParameterName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
735        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer);
736        return OMX_ErrorNone;
737    }
738
739    if (!strcmp(cParameterName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
740        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtGetNativeBufferUsage);
741        return OMX_ErrorNone;
742    }
743
744    if (!strcmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer")) {
745        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer);
746        return OMX_ErrorNone;
747    }
748
749    if (!strcmp(cParameterName, "OMX.Intel.index.rotation")) {
750        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees);
751        return OMX_ErrorNone;
752    }
753
754    if (!strcmp(cParameterName, "OMX.Intel.index.enableSyncEncoding")) {
755        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSyncEncoding);
756        return OMX_ErrorNone;
757    }
758
759    if (!strcmp(cParameterName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
760        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtPrependSPSPPS);
761        return OMX_ErrorNone;
762    }
763
764#ifdef TARGET_HAS_VPP
765    if (!strcmp(cParameterName, "OMX.Intel.index.vppBufferNum")) {
766        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum);
767        return OMX_ErrorNone;
768    }
769#endif
770
771	if (!strcmp(cParameterName, "OMX.Intel.index.enableErrorReport")) {
772        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableErrorReport);
773        return OMX_ErrorNone;
774    }
775
776    return OMX_ErrorUnsupportedIndex;
777}
778
779OMX_ERRORTYPE ComponentBase::GetState(
780    OMX_IN  OMX_HANDLETYPE hComponent,
781    OMX_OUT OMX_STATETYPE* pState)
782{
783    ComponentBase *cbase;
784
785    if (!hComponent)
786        return OMX_ErrorBadParameter;
787
788    cbase = static_cast<ComponentBase *>
789        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
790    if (!cbase)
791        return OMX_ErrorBadParameter;
792
793    return cbase->CBaseGetState(hComponent, pState);
794}
795
796OMX_ERRORTYPE ComponentBase::CBaseGetState(
797    OMX_IN  OMX_HANDLETYPE hComponent,
798    OMX_OUT OMX_STATETYPE* pState)
799{
800    if (hComponent != handle)
801        return OMX_ErrorBadParameter;
802
803    pthread_mutex_lock(&state_block);
804    *pState = state;
805    pthread_mutex_unlock(&state_block);
806    return OMX_ErrorNone;
807}
808OMX_ERRORTYPE ComponentBase::UseBuffer(
809    OMX_IN OMX_HANDLETYPE hComponent,
810    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
811    OMX_IN OMX_U32 nPortIndex,
812    OMX_IN OMX_PTR pAppPrivate,
813    OMX_IN OMX_U32 nSizeBytes,
814    OMX_IN OMX_U8 *pBuffer)
815{
816    ComponentBase *cbase;
817
818    if (!hComponent)
819        return OMX_ErrorBadParameter;
820
821    cbase = static_cast<ComponentBase *>
822        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
823    if (!cbase)
824        return OMX_ErrorBadParameter;
825
826    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
827                                 pAppPrivate, nSizeBytes, pBuffer);
828}
829
830OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
831    OMX_IN OMX_HANDLETYPE hComponent,
832    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
833    OMX_IN OMX_U32 nPortIndex,
834    OMX_IN OMX_PTR pAppPrivate,
835    OMX_IN OMX_U32 nSizeBytes,
836    OMX_IN OMX_U8 *pBuffer)
837{
838    PortBase *port = NULL;
839    OMX_ERRORTYPE ret;
840
841    if (hComponent != handle)
842        return OMX_ErrorBadParameter;
843
844    if (!ppBufferHdr)
845        return OMX_ErrorBadParameter;
846    *ppBufferHdr = NULL;
847
848    if (!pBuffer)
849        return OMX_ErrorBadParameter;
850
851    if (ports)
852        if (nPortIndex < nr_ports)
853            port = ports[nPortIndex];
854
855    if (!port)
856        return OMX_ErrorBadParameter;
857
858    if (port->IsEnabled()) {
859        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
860            return OMX_ErrorIncorrectStateOperation;
861    }
862
863    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
864                           pBuffer);
865}
866
867OMX_ERRORTYPE ComponentBase::AllocateBuffer(
868    OMX_IN OMX_HANDLETYPE hComponent,
869    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
870    OMX_IN OMX_U32 nPortIndex,
871    OMX_IN OMX_PTR pAppPrivate,
872    OMX_IN OMX_U32 nSizeBytes)
873{
874    ComponentBase *cbase;
875
876    if (!hComponent)
877        return OMX_ErrorBadParameter;
878
879    cbase = static_cast<ComponentBase *>
880        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
881    if (!cbase)
882        return OMX_ErrorBadParameter;
883
884    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
885                                      pAppPrivate, nSizeBytes);
886}
887
888OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
889    OMX_IN OMX_HANDLETYPE hComponent,
890    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
891    OMX_IN OMX_U32 nPortIndex,
892    OMX_IN OMX_PTR pAppPrivate,
893    OMX_IN OMX_U32 nSizeBytes)
894{
895    PortBase *port = NULL;
896    OMX_ERRORTYPE ret;
897
898    if (hComponent != handle)
899        return OMX_ErrorBadParameter;
900
901    if (!ppBuffer)
902        return OMX_ErrorBadParameter;
903    *ppBuffer = NULL;
904
905    if (ports)
906        if (nPortIndex < nr_ports)
907            port = ports[nPortIndex];
908
909    if (!port)
910        return OMX_ErrorBadParameter;
911
912    if (port->IsEnabled()) {
913        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
914            return OMX_ErrorIncorrectStateOperation;
915    }
916
917    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
918}
919
920OMX_ERRORTYPE ComponentBase::FreeBuffer(
921    OMX_IN  OMX_HANDLETYPE hComponent,
922    OMX_IN  OMX_U32 nPortIndex,
923    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
924{
925    ComponentBase *cbase;
926
927    if (!hComponent)
928        return OMX_ErrorBadParameter;
929
930    cbase = static_cast<ComponentBase *>
931        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
932    if (!cbase)
933        return OMX_ErrorBadParameter;
934
935    return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
936}
937
938OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
939    OMX_IN  OMX_HANDLETYPE hComponent,
940    OMX_IN  OMX_U32 nPortIndex,
941    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
942{
943    PortBase *port = NULL;
944    OMX_ERRORTYPE ret;
945
946    if (hComponent != handle)
947        return OMX_ErrorBadParameter;
948
949    if (!pBuffer)
950        return OMX_ErrorBadParameter;
951
952    if (ports)
953        if (nPortIndex < nr_ports)
954            port = ports[nPortIndex];
955
956    if (!port)
957        return OMX_ErrorBadParameter;
958
959    ProcessorPreFreeBuffer(nPortIndex, pBuffer);
960
961    return port->FreeBuffer(nPortIndex, pBuffer);
962}
963
964OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
965    OMX_IN  OMX_HANDLETYPE hComponent,
966    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
967{
968    ComponentBase *cbase;
969
970    if (!hComponent)
971        return OMX_ErrorBadParameter;
972
973    cbase = static_cast<ComponentBase *>
974        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
975    if (!cbase)
976        return OMX_ErrorBadParameter;
977
978    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
979}
980
981OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
982    OMX_IN  OMX_HANDLETYPE hComponent,
983    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
984{
985    PortBase *port = NULL;
986    OMX_U32 port_index;
987    OMX_ERRORTYPE ret;
988
989    if ((hComponent != handle) || !pBuffer)
990        return OMX_ErrorBadParameter;
991
992    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
993    if (ret != OMX_ErrorNone)
994        return ret;
995
996    port_index = pBuffer->nInputPortIndex;
997    if (port_index == (OMX_U32)-1)
998        return OMX_ErrorBadParameter;
999
1000    if (ports)
1001        if (port_index < nr_ports)
1002            port = ports[port_index];
1003
1004    if (!port)
1005        return OMX_ErrorBadParameter;
1006
1007    if (pBuffer->pInputPortPrivate != port)
1008        return OMX_ErrorBadParameter;
1009
1010    if (port->IsEnabled()) {
1011        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1012            state != OMX_StatePause)
1013            return OMX_ErrorIncorrectStateOperation;
1014    }
1015
1016    if (!pBuffer->hMarkTargetComponent) {
1017        OMX_MARKTYPE *mark;
1018
1019        mark = port->PopMark();
1020        if (mark) {
1021            pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent;
1022            pBuffer->pMarkData = mark->pMarkData;
1023            free(mark);
1024        }
1025    }
1026
1027    ProcessorPreEmptyBuffer(pBuffer);
1028
1029    ret = port->PushThisBuffer(pBuffer);
1030    if (ret == OMX_ErrorNone)
1031        bufferwork->ScheduleWork(this);
1032
1033    return ret;
1034}
1035
1036OMX_ERRORTYPE ComponentBase::FillThisBuffer(
1037    OMX_IN  OMX_HANDLETYPE hComponent,
1038    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1039{
1040    ComponentBase *cbase;
1041
1042    if (!hComponent)
1043        return OMX_ErrorBadParameter;
1044
1045    cbase = static_cast<ComponentBase *>
1046        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1047    if (!cbase)
1048        return OMX_ErrorBadParameter;
1049
1050    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
1051}
1052
1053OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
1054    OMX_IN  OMX_HANDLETYPE hComponent,
1055    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1056{
1057    PortBase *port = NULL;
1058    OMX_U32 port_index;
1059    OMX_ERRORTYPE ret;
1060
1061    if ((hComponent != handle) || !pBuffer)
1062        return OMX_ErrorBadParameter;
1063
1064    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
1065    if (ret != OMX_ErrorNone)
1066        return ret;
1067
1068    port_index = pBuffer->nOutputPortIndex;
1069    if (port_index == (OMX_U32)-1)
1070        return OMX_ErrorBadParameter;
1071
1072    if (ports)
1073        if (port_index < nr_ports)
1074            port = ports[port_index];
1075
1076    if (!port)
1077        return OMX_ErrorBadParameter;
1078
1079    if (pBuffer->pOutputPortPrivate != port)
1080        return OMX_ErrorBadParameter;
1081
1082    if (port->IsEnabled()) {
1083        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1084            state != OMX_StatePause)
1085            return OMX_ErrorIncorrectStateOperation;
1086    }
1087
1088    ProcessorPreFillBuffer(pBuffer);
1089
1090    ret = port->PushThisBuffer(pBuffer);
1091    if (ret == OMX_ErrorNone)
1092        bufferwork->ScheduleWork(this);
1093
1094    return ret;
1095}
1096
1097OMX_ERRORTYPE ComponentBase::SetCallbacks(
1098    OMX_IN  OMX_HANDLETYPE hComponent,
1099    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
1100    OMX_IN  OMX_PTR pAppData)
1101{
1102    ComponentBase *cbase;
1103
1104    if (!hComponent)
1105        return OMX_ErrorBadParameter;
1106
1107    cbase = static_cast<ComponentBase *>
1108        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1109    if (!cbase)
1110        return OMX_ErrorBadParameter;
1111
1112    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
1113}
1114
1115OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
1116    OMX_IN  OMX_HANDLETYPE hComponent,
1117    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
1118    OMX_IN  OMX_PTR pAppData)
1119{
1120    if (hComponent != handle)
1121        return OMX_ErrorBadParameter;
1122
1123    appdata = pAppData;
1124    callbacks = pCallbacks;
1125
1126    return OMX_ErrorNone;
1127}
1128
1129OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1130    OMX_IN OMX_HANDLETYPE hComponent,
1131    OMX_OUT OMX_U8 *cRole,
1132    OMX_IN OMX_U32 nIndex)
1133{
1134    ComponentBase *cbase;
1135
1136    if (!hComponent)
1137        return OMX_ErrorBadParameter;
1138
1139    cbase = static_cast<ComponentBase *>
1140        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1141    if (!cbase)
1142        return OMX_ErrorBadParameter;
1143
1144    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1145}
1146
1147OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1148    OMX_IN OMX_HANDLETYPE hComponent,
1149    OMX_OUT OMX_U8 *cRole,
1150    OMX_IN OMX_U32 nIndex)
1151{
1152    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1153        return OMX_ErrorBadParameter;
1154
1155    if (nIndex >= nr_roles)
1156        return OMX_ErrorBadParameter;
1157
1158    strncpy((char *)cRole, (const char *)roles[nIndex],
1159            OMX_MAX_STRINGNAME_SIZE);
1160    return OMX_ErrorNone;
1161}
1162
1163/* implement CmdHandlerInterface */
1164static const char *cmd_name[OMX_CommandMarkBuffer+2] = {
1165    "OMX_CommandStateSet",
1166    "OMX_CommandFlush",
1167    "OMX_CommandPortDisable",
1168    "OMX_CommandPortEnable",
1169    "OMX_CommandMarkBuffer",
1170    "Unknown Command",
1171};
1172
1173static inline const char *GetCmdName(OMX_COMMANDTYPE cmd)
1174{
1175    if (cmd > OMX_CommandMarkBuffer)
1176        cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1);
1177
1178    return cmd_name[cmd];
1179}
1180
1181void ComponentBase::CmdHandler(struct cmd_s *cmd)
1182{
1183    LOGV("%s:%s: handling %s command\n",
1184         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1185
1186    switch (cmd->cmd) {
1187    case OMX_CommandStateSet: {
1188        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1189
1190        pthread_mutex_lock(&state_block);
1191        TransState(transition);
1192        pthread_mutex_unlock(&state_block);
1193        break;
1194    }
1195    case OMX_CommandFlush: {
1196        OMX_U32 port_index = cmd->param1;
1197        pthread_mutex_lock(&ports_block);
1198        ProcessorFlush(port_index);
1199        FlushPort(port_index, 1);
1200        pthread_mutex_unlock(&ports_block);
1201        break;
1202    }
1203    case OMX_CommandPortDisable: {
1204        OMX_U32 port_index = cmd->param1;
1205
1206        TransStatePort(port_index, PortBase::OMX_PortDisabled);
1207        break;
1208    }
1209    case OMX_CommandPortEnable: {
1210        OMX_U32 port_index = cmd->param1;
1211
1212        TransStatePort(port_index, PortBase::OMX_PortEnabled);
1213        break;
1214    }
1215    case OMX_CommandMarkBuffer: {
1216        OMX_U32 port_index = (OMX_U32)cmd->param1;
1217        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata;
1218
1219        PushThisMark(port_index, mark);
1220        break;
1221    }
1222    default:
1223        LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n",
1224             GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd);
1225        break;
1226    } /* switch */
1227
1228    LOGV("%s:%s: command %s handling done\n",
1229         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1230}
1231
1232/*
1233 * SendCommand:OMX_CommandStateSet
1234 * called in CmdHandler or called in other parts of component for reporting
1235 * internal error (OMX_StateInvalid).
1236 */
1237/*
1238 * Todo
1239 *   Resource Management (OMX_StateWaitForResources)
1240 *   for now, we never notify OMX_ErrorInsufficientResources,
1241 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1242 */
1243static const char *state_name[OMX_StateWaitForResources+2] = {
1244    "OMX_StateInvalid",
1245    "OMX_StateLoaded",
1246    "OMX_StateIdle",
1247    "OMX_StateExecuting",
1248    "OMX_StatePause",
1249    "OMX_StateWaitForResources",
1250    "Unknown State",
1251};
1252
1253static inline const char *GetStateName(OMX_STATETYPE state)
1254{
1255    if (state > OMX_StateWaitForResources)
1256        state = (OMX_STATETYPE)(OMX_StateWaitForResources+1);
1257
1258    return state_name[state];
1259}
1260
1261void ComponentBase::TransState(OMX_STATETYPE transition)
1262{
1263    OMX_STATETYPE current = this->state;
1264    OMX_EVENTTYPE event;
1265    OMX_U32 data1, data2;
1266    OMX_ERRORTYPE ret;
1267
1268    LOGV("%s:%s: try to transit state from %s to %s\n",
1269         GetName(), GetWorkingRole(), GetStateName(current),
1270         GetStateName(transition));
1271
1272    /* same state */
1273    if (current == transition) {
1274        ret = OMX_ErrorSameState;
1275        LOGE("%s:%s: exit failure, same state (%s)\n",
1276             GetName(), GetWorkingRole(), GetStateName(current));
1277        goto notify_event;
1278    }
1279
1280    /* invalid state */
1281    if (current == OMX_StateInvalid) {
1282        ret = OMX_ErrorInvalidState;
1283        LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n",
1284             GetName(), GetWorkingRole());
1285        goto notify_event;
1286    }
1287
1288    if (transition == OMX_StateLoaded)
1289        ret = TransStateToLoaded(current);
1290    else if (transition == OMX_StateIdle)
1291        ret = TransStateToIdle(current);
1292    else if (transition == OMX_StateExecuting)
1293        ret = TransStateToExecuting(current);
1294    else if (transition == OMX_StatePause)
1295        ret = TransStateToPause(current);
1296    else if (transition == OMX_StateInvalid)
1297        ret = TransStateToInvalid(current);
1298    else if (transition == OMX_StateWaitForResources)
1299        ret = TransStateToWaitForResources(current);
1300    else
1301        ret = OMX_ErrorIncorrectStateTransition;
1302
1303notify_event:
1304    if (ret == OMX_ErrorNone) {
1305        event = OMX_EventCmdComplete;
1306        data1 = OMX_CommandStateSet;
1307        data2 = transition;
1308
1309        state = transition;
1310        LOGD("%s:%s: transition from %s to %s completed",
1311             GetName(), GetWorkingRole(),
1312             GetStateName(current), GetStateName(transition));
1313    }
1314    else {
1315        event = OMX_EventError;
1316        data1 = ret;
1317        data2 = 0;
1318
1319        if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) {
1320            state = OMX_StateInvalid;
1321            LOGE("%s:%s: exit failure, transition from %s to %s, "
1322                 "current state is %s\n",
1323                 GetName(), GetWorkingRole(), GetStateName(current),
1324                 GetStateName(transition), GetStateName(state));
1325        }
1326    }
1327
1328    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1329
1330    /* WaitForResources workaround */
1331    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1332        callbacks->EventHandler(handle, appdata,
1333                                OMX_EventResourcesAcquired, 0, 0, NULL);
1334}
1335
1336inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1337{
1338    OMX_ERRORTYPE ret;
1339
1340    if (current == OMX_StateIdle) {
1341        OMX_U32 i;
1342
1343        for (i = 0; i < nr_ports; i++)
1344	{
1345            if (ports[i]->GetPortBufferCount() > 0) {
1346                ports[i]->WaitPortBufferCompletion();
1347	    };
1348	};
1349
1350        ret = ProcessorDeinit();
1351        if (ret != OMX_ErrorNone) {
1352            LOGE("%s:%s: ProcessorDeinit() failed "
1353                 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(),
1354                 ret);
1355            goto out;
1356        }
1357    }
1358    else if (current == OMX_StateWaitForResources) {
1359        LOGV("%s:%s: "
1360             "state transition's requested from WaitForResources to Loaded\n",
1361             GetName(), GetWorkingRole());
1362
1363        /*
1364         * from WaitForResources to Loaded considered from Loaded to Loaded.
1365         * do nothing
1366         */
1367
1368        ret = OMX_ErrorNone;
1369    }
1370    else
1371        ret = OMX_ErrorIncorrectStateTransition;
1372
1373out:
1374    return ret;
1375}
1376
1377inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1378{
1379    OMX_ERRORTYPE ret;
1380
1381    if (current == OMX_StateLoaded) {
1382        OMX_U32 i;
1383        for (i = 0; i < nr_ports; i++) {
1384             if (ports[i]->IsEnabled())
1385                 ports[i]->WaitPortBufferCompletion();
1386        }
1387
1388        ret = ProcessorInit();
1389        if (ret != OMX_ErrorNone) {
1390            LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n",
1391                 GetName(), GetWorkingRole(), ret);
1392            goto out;
1393        }
1394    }
1395    else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) {
1396        pthread_mutex_lock(&ports_block);
1397        FlushPort(OMX_ALL, 0);
1398        pthread_mutex_unlock(&ports_block);
1399        LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole());
1400
1401        bufferwork->CancelScheduledWork(this);
1402        LOGV("%s:%s: discarded all scheduled buffer process work\n",
1403             GetName(), GetWorkingRole());
1404
1405        if (current == OMX_StatePause) {
1406            bufferwork->ResumeWork();
1407            LOGV("%s:%s: buffer process work resumed\n",
1408                 GetName(), GetWorkingRole());
1409        }
1410
1411        bufferwork->StopWork();
1412        LOGV("%s:%s: buffer process work stopped\n",
1413             GetName(), GetWorkingRole());
1414
1415        ret = ProcessorStop();
1416        if (ret != OMX_ErrorNone) {
1417            LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n",
1418                 GetName(), GetWorkingRole(), ret);
1419            goto out;
1420        }
1421    }
1422    else if (current == OMX_StateWaitForResources) {
1423        LOGV("%s:%s: "
1424             "state transition's requested from WaitForResources to Idle\n",
1425             GetName(), GetWorkingRole());
1426
1427        /* same as Loaded to Idle BUT DO NOTHING for now */
1428
1429        ret = OMX_ErrorNone;
1430    }
1431    else
1432        ret = OMX_ErrorIncorrectStateTransition;
1433
1434out:
1435    return ret;
1436}
1437
1438inline OMX_ERRORTYPE
1439ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1440{
1441    OMX_ERRORTYPE ret;
1442
1443    if (current == OMX_StateIdle) {
1444        bufferwork->StartWork(true);
1445        LOGV("%s:%s: buffer process work started with executing state\n",
1446             GetName(), GetWorkingRole());
1447
1448        ret = ProcessorStart();
1449        if (ret != OMX_ErrorNone) {
1450            LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n",
1451                 GetName(), GetWorkingRole(), ret);
1452            goto out;
1453        }
1454    }
1455    else if (current == OMX_StatePause) {
1456        bufferwork->ResumeWork();
1457        LOGV("%s:%s: buffer process work resumed\n",
1458             GetName(), GetWorkingRole());
1459
1460        ret = ProcessorResume();
1461        if (ret != OMX_ErrorNone) {
1462            LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n",
1463                 GetName(), GetWorkingRole(), ret);
1464            goto out;
1465        }
1466    }
1467    else
1468        ret = OMX_ErrorIncorrectStateTransition;
1469
1470out:
1471    return ret;
1472}
1473
1474inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1475{
1476    OMX_ERRORTYPE ret;
1477
1478    if (current == OMX_StateIdle) {
1479        bufferwork->StartWork(false);
1480        LOGV("%s:%s: buffer process work started with paused state\n",
1481             GetName(), GetWorkingRole());
1482
1483        ret = ProcessorStart();
1484        if (ret != OMX_ErrorNone) {
1485            LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n",
1486                 GetName(), GetWorkingRole(), ret);
1487            goto out;
1488        }
1489    }
1490    else if (current == OMX_StateExecuting) {
1491        bufferwork->PauseWork();
1492        LOGV("%s:%s: buffer process work paused\n",
1493             GetName(), GetWorkingRole());
1494
1495        ret = ProcessorPause();
1496        if (ret != OMX_ErrorNone) {
1497            LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n",
1498                 GetName(), GetWorkingRole(), ret);
1499            goto out;
1500        }
1501    }
1502    else
1503        ret = OMX_ErrorIncorrectStateTransition;
1504
1505out:
1506    return ret;
1507}
1508
1509inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1510{
1511    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1512
1513    /*
1514     * Todo
1515     *   graceful escape
1516     */
1517
1518    return ret;
1519}
1520
1521inline OMX_ERRORTYPE
1522ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1523{
1524    OMX_ERRORTYPE ret;
1525
1526    if (current == OMX_StateLoaded) {
1527        LOGV("%s:%s: "
1528             "state transition's requested from Loaded to WaitForResources\n",
1529             GetName(), GetWorkingRole());
1530        ret = OMX_ErrorNone;
1531    }
1532    else
1533        ret = OMX_ErrorIncorrectStateTransition;
1534
1535    return ret;
1536}
1537
1538/* mark buffer */
1539void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark)
1540{
1541    PortBase *port = NULL;
1542    OMX_EVENTTYPE event;
1543    OMX_U32 data1, data2;
1544    OMX_ERRORTYPE ret;
1545
1546    if (ports)
1547        if (port_index < nr_ports)
1548            port = ports[port_index];
1549
1550    if (!port) {
1551        ret = OMX_ErrorBadPortIndex;
1552        goto notify_event;
1553    }
1554
1555    ret = port->PushMark(mark);
1556    if (ret != OMX_ErrorNone) {
1557        /* don't report OMX_ErrorInsufficientResources */
1558        ret = OMX_ErrorUndefined;
1559        goto notify_event;
1560    }
1561
1562notify_event:
1563    if (ret == OMX_ErrorNone) {
1564        event = OMX_EventCmdComplete;
1565        data1 = OMX_CommandMarkBuffer;
1566        data2 = port_index;
1567    }
1568    else {
1569        event = OMX_EventError;
1570        data1 = ret;
1571        data2 = 0;
1572    }
1573
1574    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1575}
1576
1577void ComponentBase::FlushPort(OMX_U32 port_index, bool notify)
1578{
1579    OMX_U32 i, from_index, to_index;
1580
1581    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1582        return;
1583
1584    if (port_index == OMX_ALL) {
1585        from_index = 0;
1586        to_index = nr_ports - 1;
1587    }
1588    else {
1589        from_index = port_index;
1590        to_index = port_index;
1591    }
1592
1593    LOGV("%s:%s: flush ports (from index %lu to %lu)\n",
1594         GetName(), GetWorkingRole(), from_index, to_index);
1595
1596    for (i = from_index; i <= to_index; i++) {
1597        ports[i]->FlushPort();
1598        if (notify)
1599            callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1600                                    OMX_CommandFlush, i, NULL);
1601    }
1602
1603    LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole());
1604}
1605
1606extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp
1607
1608void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state)
1609{
1610    OMX_EVENTTYPE event;
1611    OMX_U32 data1, data2;
1612    OMX_U32 i, from_index, to_index;
1613    OMX_ERRORTYPE ret;
1614
1615    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1616        return;
1617
1618    if (port_index == OMX_ALL) {
1619        from_index = 0;
1620        to_index = nr_ports - 1;
1621    }
1622    else {
1623        from_index = port_index;
1624        to_index = port_index;
1625    }
1626
1627    LOGV("%s:%s: transit ports state to %s (from index %lu to %lu)\n",
1628         GetName(), GetWorkingRole(), GetPortStateName(state),
1629         from_index, to_index);
1630
1631    pthread_mutex_lock(&ports_block);
1632    for (i = from_index; i <= to_index; i++) {
1633        ret = ports[i]->TransState(state);
1634        if (ret == OMX_ErrorNone) {
1635            event = OMX_EventCmdComplete;
1636            if (state == PortBase::OMX_PortEnabled) {
1637                data1 = OMX_CommandPortEnable;
1638                ProcessorReset();
1639            } else {
1640                data1 = OMX_CommandPortDisable;
1641            }
1642            data2 = i;
1643        }
1644        else {
1645            event = OMX_EventError;
1646            data1 = ret;
1647            data2 = 0;
1648        }
1649        callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1650                                data1, data2, NULL);
1651    }
1652    pthread_mutex_unlock(&ports_block);
1653
1654    LOGV("%s:%s: transit ports state to %s completed\n",
1655         GetName(), GetWorkingRole(), GetPortStateName(state));
1656}
1657
1658/* set working role */
1659OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role)
1660{
1661    OMX_U32 i;
1662
1663    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1664        return OMX_ErrorIncorrectStateOperation;
1665
1666    if (!role) {
1667        working_role = NULL;
1668        return OMX_ErrorNone;
1669    }
1670
1671    for (i = 0; i < nr_roles; i++) {
1672        if (!strcmp((char *)&roles[i][0], role)) {
1673            working_role = (OMX_STRING)&roles[i][0];
1674            return OMX_ErrorNone;
1675        }
1676    }
1677
1678    LOGE("%s: cannot find %s role\n", GetName(), role);
1679    return OMX_ErrorBadParameter;
1680}
1681
1682/* apply a working role for a component having multiple roles */
1683OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void)
1684{
1685    OMX_U32 i;
1686    OMX_ERRORTYPE ret;
1687
1688    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1689        return OMX_ErrorIncorrectStateOperation;
1690
1691    if (!working_role)
1692        return OMX_ErrorBadParameter;
1693
1694    if (!callbacks || !appdata)
1695        return OMX_ErrorBadParameter;
1696
1697    ret = AllocatePorts();
1698    if (ret != OMX_ErrorNone) {
1699        LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret);
1700        return ret;
1701    }
1702
1703    /* now we can access ports */
1704    for (i = 0; i < nr_ports; i++) {
1705        ports[i]->SetOwner(handle);
1706        ports[i]->SetCallbacks(handle, callbacks, appdata);
1707    }
1708
1709    LOGI("%s: set working role %s:", GetName(), GetWorkingRole());
1710    return OMX_ErrorNone;
1711}
1712
1713OMX_ERRORTYPE ComponentBase::AllocatePorts(void)
1714{
1715    OMX_DIRTYPE dir;
1716    bool has_input, has_output;
1717    OMX_U32 i;
1718    OMX_ERRORTYPE ret;
1719
1720    if (ports)
1721        return OMX_ErrorBadParameter;
1722
1723    ret = ComponentAllocatePorts();
1724    if (ret != OMX_ErrorNone) {
1725        LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n",
1726             name, ret);
1727        return ret;
1728    }
1729
1730    has_input = false;
1731    has_output = false;
1732    ret = OMX_ErrorNone;
1733    for (i = 0; i < nr_ports; i++) {
1734        dir = ports[i]->GetPortDirection();
1735        if (dir == OMX_DirInput)
1736            has_input = true;
1737        else if (dir == OMX_DirOutput)
1738            has_output = true;
1739        else {
1740            ret = OMX_ErrorUndefined;
1741            break;
1742        }
1743    }
1744    if (ret != OMX_ErrorNone)
1745        goto free_ports;
1746
1747    if ((has_input == false) && (has_output == true))
1748        cvariant = CVARIANT_SOURCE;
1749    else if ((has_input == true) && (has_output == true))
1750        cvariant = CVARIANT_FILTER;
1751    else if ((has_input == true) && (has_output == false))
1752        cvariant = CVARIANT_SINK;
1753    else
1754        goto free_ports;
1755
1756    return OMX_ErrorNone;
1757
1758free_ports:
1759    LOGE("%s(): exit, unknown component variant\n", __func__);
1760    FreePorts();
1761    return OMX_ErrorUndefined;
1762}
1763
1764/* called int FreeHandle() */
1765OMX_ERRORTYPE ComponentBase::FreePorts(void)
1766{
1767    if (ports) {
1768        OMX_U32 i, this_nr_ports = this->nr_ports;
1769
1770        for (i = 0; i < this_nr_ports; i++) {
1771            if (ports[i]) {
1772                OMX_MARKTYPE *mark;
1773                /* it should be empty before this */
1774                while ((mark = ports[i]->PopMark()))
1775                    free(mark);
1776
1777                delete ports[i];
1778                ports[i] = NULL;
1779            }
1780        }
1781        delete []ports;
1782        ports = NULL;
1783    }
1784
1785    return OMX_ErrorNone;
1786}
1787
1788/* buffer processing */
1789/* implement WorkableInterface */
1790void ComponentBase::Work(void)
1791{
1792    OMX_BUFFERHEADERTYPE **buffers[nr_ports];
1793    OMX_BUFFERHEADERTYPE *buffers_hdr[nr_ports];
1794    OMX_BUFFERHEADERTYPE *buffers_org[nr_ports];
1795    buffer_retain_t retain[nr_ports];
1796    OMX_U32 i;
1797    OMX_ERRORTYPE ret;
1798
1799    if (nr_ports == 0) {
1800        return;
1801    }
1802
1803    pthread_mutex_lock(&ports_block);
1804
1805    while(IsAllBufferAvailable())
1806    {
1807        for (i = 0; i < nr_ports; i++) {
1808            buffers_hdr[i] = ports[i]->PopBuffer();
1809            buffers[i] = &buffers_hdr[i];
1810            buffers_org[i] = buffers_hdr[i];
1811            retain[i] = BUFFER_RETAIN_NOT_RETAIN;
1812        }
1813
1814        if (working_role != NULL && !strncmp((char*)working_role, "video_decoder", 13)){
1815            ret = ProcessorProcess(buffers, &retain[0], nr_ports);
1816        }else{
1817            ret = ProcessorProcess(buffers_hdr, &retain[0], nr_ports);
1818        }
1819
1820        if (ret == OMX_ErrorNone) {
1821            PostProcessBuffers(buffers, &retain[0]);
1822
1823            for (i = 0; i < nr_ports; i++) {
1824                if(retain[i] == BUFFER_RETAIN_GETAGAIN) {
1825                    ports[i]->RetainThisBuffer(*buffers[i], false);
1826                }
1827                else if (retain[i] == BUFFER_RETAIN_ACCUMULATE) {
1828                    ports[i]->RetainThisBuffer(*buffers[i], true);
1829                }
1830                else if (retain[i] == BUFFER_RETAIN_OVERRIDDEN) {
1831                    ports[i]->RetainAndReturnBuffer(buffers_org[i], *buffers[i]);
1832                }
1833                else if (retain[i] == BUFFER_RETAIN_CACHE) {
1834                    //nothing to do
1835                } else {
1836                    ports[i]->ReturnThisBuffer(*buffers[i]);
1837                }
1838            }
1839        }
1840        else {
1841
1842            for (i = 0; i < nr_ports; i++) {
1843                /* return buffers by hands, these buffers're not in queue */
1844                ports[i]->ReturnThisBuffer(*buffers[i]);
1845                /* flush ports */
1846                ports[i]->FlushPort();
1847            }
1848
1849            callbacks->EventHandler(handle, appdata, OMX_EventError, ret,
1850                                    0, NULL);
1851        }
1852    }
1853
1854    pthread_mutex_unlock(&ports_block);
1855}
1856
1857bool ComponentBase::IsAllBufferAvailable(void)
1858{
1859    OMX_U32 i;
1860    OMX_U32 nr_avail = 0;
1861
1862    for (i = 0; i < nr_ports; i++) {
1863        OMX_U32 length = 0;
1864
1865        if (ports[i]->IsEnabled())
1866            length = ports[i]->BufferQueueLength();
1867
1868        if (length)
1869            nr_avail++;
1870    }
1871
1872    if (nr_avail == nr_ports)
1873        return true;
1874    else
1875        return false;
1876}
1877
1878inline void ComponentBase::SourcePostProcessBuffers(
1879    OMX_BUFFERHEADERTYPE ***buffers,
1880    const buffer_retain_t *retain)
1881{
1882    OMX_U32 i;
1883
1884    for (i = 0; i < nr_ports; i++) {
1885        /*
1886         * in case of source component, buffers're marked when they come
1887         * from the ouput ports
1888         */
1889        if (!(*buffers[i])->hMarkTargetComponent) {
1890            OMX_MARKTYPE *mark;
1891
1892            mark = ports[i]->PopMark();
1893            if (mark) {
1894                (*buffers[i])->hMarkTargetComponent = mark->hMarkTargetComponent;
1895                (*buffers[i])->pMarkData = mark->pMarkData;
1896                free(mark);
1897            }
1898        }
1899    }
1900}
1901
1902inline void ComponentBase::FilterPostProcessBuffers(
1903    OMX_BUFFERHEADERTYPE ***buffers,
1904    const buffer_retain_t *retain)
1905{
1906    OMX_MARKTYPE *mark;
1907    OMX_U32 i, j;
1908
1909    for (i = 0; i < nr_ports; i++) {
1910        if (ports[i]->GetPortDirection() == OMX_DirInput) {
1911            for (j = 0; j < nr_ports; j++) {
1912                if (ports[j]->GetPortDirection() != OMX_DirOutput)
1913                    continue;
1914
1915                /* propagates EOS flag */
1916                /* clear input EOS at the end of this loop */
1917                if (retain[i] != BUFFER_RETAIN_GETAGAIN) {
1918                    if ((*buffers[i])->nFlags & OMX_BUFFERFLAG_EOS)
1919                        (*buffers[j])->nFlags |= OMX_BUFFERFLAG_EOS;
1920                }
1921
1922                /* propagates marks */
1923                /*
1924                 * if hMarkTargetComponent == handle then the mark's not
1925                 * propagated
1926                 */
1927                if ((*buffers[i])->hMarkTargetComponent &&
1928                    ((*buffers[i])->hMarkTargetComponent != handle)) {
1929                    if ((*buffers[j])->hMarkTargetComponent) {
1930                        mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1931                        if (mark) {
1932                            mark->hMarkTargetComponent =
1933                                (*buffers[i])->hMarkTargetComponent;
1934                            mark->pMarkData = (*buffers[i])->pMarkData;
1935                            ports[j]->PushMark(mark);
1936                            mark = NULL;
1937                            (*buffers[i])->hMarkTargetComponent = NULL;
1938                            (*buffers[i])->pMarkData = NULL;
1939                        }
1940                    }
1941                    else {
1942                        mark = ports[j]->PopMark();
1943                        if (mark) {
1944                            (*buffers[j])->hMarkTargetComponent =
1945                                mark->hMarkTargetComponent;
1946                            (*buffers[j])->pMarkData = mark->pMarkData;
1947                            free(mark);
1948
1949                            mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1950                            if (mark) {
1951                                mark->hMarkTargetComponent =
1952                                    (*buffers[i])->hMarkTargetComponent;
1953                                mark->pMarkData = (*buffers[i])->pMarkData;
1954                                ports[j]->PushMark(mark);
1955                                mark = NULL;
1956                                (*buffers[i])->hMarkTargetComponent = NULL;
1957                                (*buffers[i])->pMarkData = NULL;
1958                            }
1959                        }
1960                        else {
1961                            (*buffers[j])->hMarkTargetComponent =
1962                                (*buffers[i])->hMarkTargetComponent;
1963                            (*buffers[j])->pMarkData = (*buffers[i])->pMarkData;
1964                            (*buffers[i])->hMarkTargetComponent = NULL;
1965                            (*buffers[i])->pMarkData = NULL;
1966                        }
1967                    }
1968                }
1969            }
1970            /* clear input buffer's EOS */
1971            if (retain[i] != BUFFER_RETAIN_GETAGAIN)
1972                (*buffers[i])->nFlags &= ~OMX_BUFFERFLAG_EOS;
1973        }
1974    }
1975}
1976
1977inline void ComponentBase::SinkPostProcessBuffers(
1978    OMX_BUFFERHEADERTYPE ***buffers,
1979    const buffer_retain_t *retain)
1980{
1981    return;
1982}
1983
1984void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
1985                                       const buffer_retain_t *retain)
1986{
1987
1988    if (cvariant == CVARIANT_SOURCE)
1989        SourcePostProcessBuffers(buffers, retain);
1990    else if (cvariant == CVARIANT_FILTER)
1991        FilterPostProcessBuffers(buffers, retain);
1992    else if (cvariant == CVARIANT_SINK) {
1993        SinkPostProcessBuffers(buffers, retain);
1994    }
1995    else {
1996        LOGE("%s(): fatal error unknown component variant (%d)\n",
1997             __func__, cvariant);
1998    }
1999}
2000
2001/* processor default callbacks */
2002OMX_ERRORTYPE ComponentBase::ProcessorInit(void)
2003{
2004    return OMX_ErrorNone;
2005}
2006OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void)
2007{
2008    return OMX_ErrorNone;
2009}
2010
2011OMX_ERRORTYPE ComponentBase::ProcessorStart(void)
2012{
2013    return OMX_ErrorNone;
2014}
2015
2016OMX_ERRORTYPE ComponentBase::ProcessorReset(void)
2017{
2018    return OMX_ErrorNone;
2019}
2020
2021
2022OMX_ERRORTYPE ComponentBase::ProcessorStop(void)
2023{
2024    return OMX_ErrorNone;
2025}
2026
2027OMX_ERRORTYPE ComponentBase::ProcessorPause(void)
2028{
2029    return OMX_ErrorNone;
2030}
2031
2032OMX_ERRORTYPE ComponentBase::ProcessorResume(void)
2033{
2034    return OMX_ErrorNone;
2035}
2036
2037OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32 port_index)
2038{
2039    return OMX_ErrorNone;
2040}
2041
2042OMX_ERRORTYPE ComponentBase::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer)
2043{
2044    return OMX_ErrorNone;
2045}
2046
2047OMX_ERRORTYPE ComponentBase::ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE* buffer)
2048{
2049    return OMX_ErrorNone;
2050}
2051
2052OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE **pBuffers,
2053                                           buffer_retain_t *retain,
2054                                           OMX_U32 nr_buffers)
2055{
2056    LOGE("ProcessorProcess not be implemented");
2057    return OMX_ErrorNotImplemented;
2058}
2059OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE ***pBuffers,
2060                                           buffer_retain_t *retain,
2061                                           OMX_U32 nr_buffers)
2062{
2063    LOGE("ProcessorProcess not be implemented");
2064    return OMX_ErrorNotImplemented;
2065}
2066
2067OMX_ERRORTYPE ComponentBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer)
2068{
2069    return OMX_ErrorNone;
2070
2071}
2072/* end of processor callbacks */
2073
2074/* helper for derived class */
2075const OMX_STRING ComponentBase::GetWorkingRole(void)
2076{
2077    return &working_role[0];
2078}
2079
2080const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void)
2081{
2082    return handle;
2083}
2084#if 0
2085void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader,
2086                               bool dumpdata)
2087{
2088    OMX_U8 *pbuffer = bufferheader->pBuffer, *p;
2089    OMX_U32 offset = bufferheader->nOffset;
2090    OMX_U32 alloc_len = bufferheader->nAllocLen;
2091    OMX_U32 filled_len =  bufferheader->nFilledLen;
2092    OMX_U32 left = filled_len, oneline;
2093    OMX_U32 index = 0, i;
2094    /* 0x%04lx:  %02x %02x .. (n = 16)\n\0 */
2095    char prbuffer[8 + 3 * 0x10 + 2], *pp;
2096    OMX_U32 prbuffer_len;
2097
2098    LOGD("Component %s DumpBuffer\n", name);
2099    LOGD("%s port index = %lu",
2100         (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output",
2101         (bufferheader->nInputPortIndex != 0x7fffffff) ?
2102         bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex);
2103    LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n",
2104         alloc_len, offset, filled_len);
2105    LOGD("nTimeStamp = %lld, nTickCount = %lu",
2106         bufferheader->nTimeStamp,
2107         bufferheader->nTickCount);
2108    LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags);
2109    LOGD("hMarkTargetComponent = %p, pMarkData = %p\n",
2110         bufferheader->hMarkTargetComponent, bufferheader->pMarkData);
2111
2112    if (!pbuffer || !alloc_len || !filled_len)
2113        return;
2114
2115    if (offset + filled_len > alloc_len)
2116        return;
2117
2118    if (!dumpdata)
2119        return;
2120
2121    p = pbuffer + offset;
2122    while (left) {
2123        oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */
2124        pp += sprintf(pp, "0x%04lx: ", index);
2125        for (i = 0; i < oneline; i++)
2126            pp += sprintf(pp, " %02x", *(p + i));
2127        pp += sprintf(pp, "\n");
2128        *pp = '\0';
2129
2130        index += 0x10;
2131        p += oneline;
2132        left -= oneline;
2133
2134        pp = &prbuffer[0];
2135        LOGD("%s", pp);
2136    }
2137}
2138#endif
2139/* end of component methods & helpers */
2140
2141/*
2142 * omx header manipuation
2143 */
2144void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
2145{
2146    OMX_U32 *nsize;
2147    OMX_VERSIONTYPE *nversion;
2148
2149    if (!type)
2150        return;
2151
2152    nsize = (OMX_U32 *)type;
2153    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2154
2155    *nsize = size;
2156    nversion->nVersion = OMX_SPEC_VERSION;
2157}
2158
2159OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size)
2160{
2161    OMX_U32 *nsize;
2162    OMX_VERSIONTYPE *nversion;
2163
2164    if (!type)
2165        return OMX_ErrorBadParameter;
2166
2167    nsize = (OMX_U32 *)type;
2168    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2169
2170    if (*nsize != size)
2171        return OMX_ErrorBadParameter;
2172
2173    if (nversion->nVersion != OMX_SPEC_VERSION)
2174        return OMX_ErrorVersionMismatch;
2175
2176    return OMX_ErrorNone;
2177}
2178
2179/* end of ComponentBase */
2180