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