componentbase.cpp revision 57fbad335bcd1fc0b12cea2e58586015cec7b571
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    ProcessorPreFreeBuffer(nPortIndex, pBuffer);
1002
1003    return port->FreeBuffer(nPortIndex, pBuffer);
1004}
1005
1006OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
1007    OMX_IN  OMX_HANDLETYPE hComponent,
1008    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
1009{
1010    ComponentBase *cbase;
1011
1012    if (!hComponent)
1013        return OMX_ErrorBadParameter;
1014
1015    cbase = static_cast<ComponentBase *>
1016        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1017    if (!cbase)
1018        return OMX_ErrorBadParameter;
1019
1020    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
1021}
1022
1023OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
1024    OMX_IN  OMX_HANDLETYPE hComponent,
1025    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1026{
1027    PortBase *port = NULL;
1028    OMX_U32 port_index;
1029    OMX_ERRORTYPE ret;
1030
1031    if ((hComponent != handle) || !pBuffer)
1032        return OMX_ErrorBadParameter;
1033
1034    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
1035    if (ret != OMX_ErrorNone)
1036        return ret;
1037
1038    port_index = pBuffer->nInputPortIndex;
1039    if (port_index == (OMX_U32)-1)
1040        return OMX_ErrorBadParameter;
1041
1042    if (ports)
1043        if (port_index < nr_ports)
1044            port = ports[port_index];
1045
1046    if (!port)
1047        return OMX_ErrorBadParameter;
1048
1049    if (pBuffer->pInputPortPrivate != port)
1050        return OMX_ErrorBadParameter;
1051
1052    if (port->IsEnabled()) {
1053        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1054            state != OMX_StatePause)
1055            return OMX_ErrorIncorrectStateOperation;
1056    }
1057
1058    if (!pBuffer->hMarkTargetComponent) {
1059        OMX_MARKTYPE *mark;
1060
1061        mark = port->PopMark();
1062        if (mark) {
1063            pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent;
1064            pBuffer->pMarkData = mark->pMarkData;
1065            free(mark);
1066        }
1067    }
1068
1069    ret = port->PushThisBuffer(pBuffer);
1070    if (ret == OMX_ErrorNone)
1071        bufferwork->ScheduleWork(this);
1072
1073    return ret;
1074}
1075
1076OMX_ERRORTYPE ComponentBase::FillThisBuffer(
1077    OMX_IN  OMX_HANDLETYPE hComponent,
1078    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1079{
1080    ComponentBase *cbase;
1081
1082    if (!hComponent)
1083        return OMX_ErrorBadParameter;
1084
1085    cbase = static_cast<ComponentBase *>
1086        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1087    if (!cbase)
1088        return OMX_ErrorBadParameter;
1089
1090    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
1091}
1092
1093OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
1094    OMX_IN  OMX_HANDLETYPE hComponent,
1095    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1096{
1097    PortBase *port = NULL;
1098    OMX_U32 port_index;
1099    OMX_ERRORTYPE ret;
1100
1101    if ((hComponent != handle) || !pBuffer)
1102        return OMX_ErrorBadParameter;
1103
1104    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
1105    if (ret != OMX_ErrorNone)
1106        return ret;
1107
1108    port_index = pBuffer->nOutputPortIndex;
1109    if (port_index == (OMX_U32)-1)
1110        return OMX_ErrorBadParameter;
1111
1112    if (ports)
1113        if (port_index < nr_ports)
1114            port = ports[port_index];
1115
1116    if (!port)
1117        return OMX_ErrorBadParameter;
1118
1119    if (pBuffer->pOutputPortPrivate != port)
1120        return OMX_ErrorBadParameter;
1121
1122    if (port->IsEnabled()) {
1123        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1124            state != OMX_StatePause)
1125            return OMX_ErrorIncorrectStateOperation;
1126    }
1127
1128    ret = PreProcessBuffer(pBuffer);
1129    if (ret != OMX_ErrorNone)
1130       return ret;
1131
1132    pthread_mutex_lock(&output_queue_lock);
1133    ret = port->PushThisBuffer(pBuffer);
1134    pthread_mutex_unlock(&output_queue_lock);
1135    if (ret == OMX_ErrorNone)
1136        bufferwork->ScheduleWork(this);
1137
1138    return ret;
1139}
1140
1141OMX_ERRORTYPE ComponentBase::SetCallbacks(
1142    OMX_IN  OMX_HANDLETYPE hComponent,
1143    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
1144    OMX_IN  OMX_PTR pAppData)
1145{
1146    ComponentBase *cbase;
1147
1148    if (!hComponent)
1149        return OMX_ErrorBadParameter;
1150
1151    cbase = static_cast<ComponentBase *>
1152        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1153    if (!cbase)
1154        return OMX_ErrorBadParameter;
1155
1156    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
1157}
1158
1159OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
1160    OMX_IN  OMX_HANDLETYPE hComponent,
1161    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
1162    OMX_IN  OMX_PTR pAppData)
1163{
1164    if (hComponent != handle)
1165        return OMX_ErrorBadParameter;
1166
1167    appdata = pAppData;
1168    callbacks = pCallbacks;
1169
1170    return OMX_ErrorNone;
1171}
1172
1173OMX_ERRORTYPE ComponentBase::ComponentDeInit(
1174    OMX_IN  OMX_HANDLETYPE hComponent)
1175{
1176    ComponentBase *cbase;
1177
1178    if (!hComponent)
1179        return OMX_ErrorBadParameter;
1180
1181    cbase = static_cast<ComponentBase *>
1182        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1183    if (!cbase)
1184        return OMX_ErrorBadParameter;
1185
1186    return cbase->CBaseComponentDeInit(hComponent);
1187}
1188
1189OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit(
1190    OMX_IN  OMX_HANDLETYPE hComponent)
1191{
1192    /*
1193     * Todo
1194     */
1195
1196    return OMX_ErrorNotImplemented;
1197}
1198
1199OMX_ERRORTYPE ComponentBase::UseEGLImage(
1200    OMX_IN OMX_HANDLETYPE hComponent,
1201    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1202    OMX_IN OMX_U32 nPortIndex,
1203    OMX_IN OMX_PTR pAppPrivate,
1204    OMX_IN void* eglImage)
1205{
1206    ComponentBase *cbase;
1207
1208    if (!hComponent)
1209        return OMX_ErrorBadParameter;
1210
1211    cbase = static_cast<ComponentBase *>
1212        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1213    if (!cbase)
1214        return OMX_ErrorBadParameter;
1215
1216    return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex,
1217                                   pAppPrivate, eglImage);
1218}
1219
1220OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage(
1221    OMX_IN OMX_HANDLETYPE hComponent,
1222    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1223    OMX_IN OMX_U32 nPortIndex,
1224    OMX_IN OMX_PTR pAppPrivate,
1225    OMX_IN void* eglImage)
1226{
1227    /*
1228     * Todo
1229     */
1230
1231    return OMX_ErrorNotImplemented;
1232}
1233
1234OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1235    OMX_IN OMX_HANDLETYPE hComponent,
1236    OMX_OUT OMX_U8 *cRole,
1237    OMX_IN OMX_U32 nIndex)
1238{
1239    ComponentBase *cbase;
1240
1241    if (!hComponent)
1242        return OMX_ErrorBadParameter;
1243
1244    cbase = static_cast<ComponentBase *>
1245        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1246    if (!cbase)
1247        return OMX_ErrorBadParameter;
1248
1249    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1250}
1251
1252OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1253    OMX_IN OMX_HANDLETYPE hComponent,
1254    OMX_OUT OMX_U8 *cRole,
1255    OMX_IN OMX_U32 nIndex)
1256{
1257    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1258        return OMX_ErrorBadParameter;
1259
1260    if (nIndex > nr_roles)
1261        return OMX_ErrorBadParameter;
1262
1263    strncpy((char *)cRole, (const char *)roles[nIndex],
1264            OMX_MAX_STRINGNAME_SIZE);
1265    return OMX_ErrorNone;
1266}
1267
1268/* implement CmdHandlerInterface */
1269static const char *cmd_name[OMX_CommandMarkBuffer+2] = {
1270    "OMX_CommandStateSet",
1271    "OMX_CommandFlush",
1272    "OMX_CommandPortDisable",
1273    "OMX_CommandPortEnable",
1274    "OMX_CommandMarkBuffer",
1275    "Unknown Command",
1276};
1277
1278static inline const char *GetCmdName(OMX_COMMANDTYPE cmd)
1279{
1280    if (cmd > OMX_CommandMarkBuffer)
1281        cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1);
1282
1283    return cmd_name[cmd];
1284}
1285
1286void ComponentBase::CmdHandler(struct cmd_s *cmd)
1287{
1288    LOGV("%s:%s: handling %s command\n",
1289         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1290
1291    switch (cmd->cmd) {
1292    case OMX_CommandStateSet: {
1293        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1294
1295        TransState(transition);
1296        break;
1297    }
1298    case OMX_CommandFlush: {
1299        OMX_U32 port_index = cmd->param1;
1300
1301        FlushPort(port_index, 1);
1302        pthread_mutex_lock(&ports_block);
1303        ProcessorFlush(port_index);
1304        pthread_mutex_unlock(&ports_block);
1305        break;
1306    }
1307    case OMX_CommandPortDisable: {
1308        OMX_U32 port_index = cmd->param1;
1309
1310        TransStatePort(port_index, PortBase::OMX_PortDisabled);
1311        break;
1312    }
1313    case OMX_CommandPortEnable: {
1314        OMX_U32 port_index = cmd->param1;
1315
1316        TransStatePort(port_index, PortBase::OMX_PortEnabled);
1317        break;
1318    }
1319    case OMX_CommandMarkBuffer: {
1320        OMX_U32 port_index = (OMX_U32)cmd->param1;
1321        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata;
1322
1323        PushThisMark(port_index, mark);
1324        break;
1325    }
1326    default:
1327        LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n",
1328             GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd);
1329        break;
1330    } /* switch */
1331
1332    LOGV("%s:%s: command %s handling done\n",
1333         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1334}
1335
1336/*
1337 * SendCommand:OMX_CommandStateSet
1338 * called in CmdHandler or called in other parts of component for reporting
1339 * internal error (OMX_StateInvalid).
1340 */
1341/*
1342 * Todo
1343 *   Resource Management (OMX_StateWaitForResources)
1344 *   for now, we never notify OMX_ErrorInsufficientResources,
1345 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1346 */
1347static const char *state_name[OMX_StateWaitForResources+2] = {
1348    "OMX_StateInvalid",
1349    "OMX_StateLoaded",
1350    "OMX_StateIdle",
1351    "OMX_StateExecuting",
1352    "OMX_StatePause",
1353    "OMX_StateWaitForResources",
1354    "Unknown State",
1355};
1356
1357static inline const char *GetStateName(OMX_STATETYPE state)
1358{
1359    if (state > OMX_StateWaitForResources)
1360        state = (OMX_STATETYPE)(OMX_StateWaitForResources+1);
1361
1362    return state_name[state];
1363}
1364
1365void ComponentBase::TransState(OMX_STATETYPE transition)
1366{
1367    OMX_STATETYPE current = this->state;
1368    OMX_EVENTTYPE event;
1369    OMX_U32 data1, data2;
1370    OMX_ERRORTYPE ret;
1371
1372    LOGV("%s:%s: try to transit state from %s to %s\n",
1373         GetName(), GetWorkingRole(), GetStateName(current),
1374         GetStateName(transition));
1375
1376    /* same state */
1377    if (current == transition) {
1378        ret = OMX_ErrorSameState;
1379        LOGE("%s:%s: exit failure, same state (%s)\n",
1380             GetName(), GetWorkingRole(), GetStateName(current));
1381        goto notify_event;
1382    }
1383
1384    /* invalid state */
1385    if (current == OMX_StateInvalid) {
1386        ret = OMX_ErrorInvalidState;
1387        LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n",
1388             GetName(), GetWorkingRole());
1389        goto notify_event;
1390    }
1391
1392    if (transition == OMX_StateLoaded)
1393        ret = TransStateToLoaded(current);
1394    else if (transition == OMX_StateIdle)
1395        ret = TransStateToIdle(current);
1396    else if (transition == OMX_StateExecuting)
1397        ret = TransStateToExecuting(current);
1398    else if (transition == OMX_StatePause)
1399        ret = TransStateToPause(current);
1400    else if (transition == OMX_StateInvalid)
1401        ret = TransStateToInvalid(current);
1402    else if (transition == OMX_StateWaitForResources)
1403        ret = TransStateToWaitForResources(current);
1404    else
1405        ret = OMX_ErrorIncorrectStateTransition;
1406
1407notify_event:
1408    if (ret == OMX_ErrorNone) {
1409        event = OMX_EventCmdComplete;
1410        data1 = OMX_CommandStateSet;
1411        data2 = transition;
1412
1413        state = transition;
1414        LOGD("%s:%s: transition from %s to %s completed",
1415             GetName(), GetWorkingRole(),
1416             GetStateName(current), GetStateName(transition));
1417    }
1418    else {
1419        event = OMX_EventError;
1420        data1 = ret;
1421        data2 = 0;
1422
1423        if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) {
1424            state = OMX_StateInvalid;
1425            LOGE("%s:%s: exit failure, transition from %s to %s, "
1426                 "current state is %s\n",
1427                 GetName(), GetWorkingRole(), GetStateName(current),
1428                 GetStateName(transition), GetStateName(state));
1429        }
1430    }
1431
1432    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1433
1434    /* WaitForResources workaround */
1435    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1436        callbacks->EventHandler(handle, appdata,
1437                                OMX_EventResourcesAcquired, 0, 0, NULL);
1438}
1439
1440inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1441{
1442    OMX_ERRORTYPE ret;
1443
1444    if (current == OMX_StateIdle) {
1445        OMX_U32 i;
1446
1447        for (i = 0; i < nr_ports; i++)
1448	{
1449            if (ports[i]->GetPortBufferCount() > 0) {
1450                ports[i]->WaitPortBufferCompletion();
1451	    };
1452	};
1453
1454        ret = ProcessorDeinit();
1455        if (ret != OMX_ErrorNone) {
1456            LOGE("%s:%s: ProcessorDeinit() failed "
1457                 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(),
1458                 ret);
1459            goto out;
1460        }
1461    }
1462    else if (current == OMX_StateWaitForResources) {
1463        LOGV("%s:%s: "
1464             "state transition's requested from WaitForResources to Loaded\n",
1465             GetName(), GetWorkingRole());
1466
1467        /*
1468         * from WaitForResources to Loaded considered from Loaded to Loaded.
1469         * do nothing
1470         */
1471
1472        ret = OMX_ErrorNone;
1473    }
1474    else
1475        ret = OMX_ErrorIncorrectStateTransition;
1476
1477out:
1478    return ret;
1479}
1480
1481inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1482{
1483    OMX_ERRORTYPE ret;
1484
1485    if (current == OMX_StateLoaded) {
1486        OMX_U32 i;
1487
1488        ret = ProcessorInit();
1489        if (ret != OMX_ErrorNone) {
1490            LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n",
1491                 GetName(), GetWorkingRole(), ret);
1492            goto out;
1493        }
1494
1495        for (i = 0; i < nr_ports; i++) {
1496            if (ports[i]->IsEnabled())
1497                ports[i]->WaitPortBufferCompletion();
1498        }
1499    }
1500    else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) {
1501        FlushPort(OMX_ALL, 0);
1502        LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole());
1503
1504        bufferwork->CancelScheduledWork(this);
1505        LOGV("%s:%s: discarded all scheduled buffer process work\n",
1506             GetName(), GetWorkingRole());
1507
1508        if (current == OMX_StatePause) {
1509            bufferwork->ResumeWork();
1510            LOGV("%s:%s: buffer process work resumed\n",
1511                 GetName(), GetWorkingRole());
1512        }
1513
1514        bufferwork->StopWork();
1515        LOGV("%s:%s: buffer process work stopped\n",
1516             GetName(), GetWorkingRole());
1517
1518        ret = ProcessorStop();
1519        if (ret != OMX_ErrorNone) {
1520            LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n",
1521                 GetName(), GetWorkingRole(), ret);
1522            goto out;
1523        }
1524    }
1525    else if (current == OMX_StateWaitForResources) {
1526        LOGV("%s:%s: "
1527             "state transition's requested from WaitForResources to Idle\n",
1528             GetName(), GetWorkingRole());
1529
1530        /* same as Loaded to Idle BUT DO NOTHING for now */
1531
1532        ret = OMX_ErrorNone;
1533    }
1534    else
1535        ret = OMX_ErrorIncorrectStateTransition;
1536
1537out:
1538    return ret;
1539}
1540
1541inline OMX_ERRORTYPE
1542ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1543{
1544    OMX_ERRORTYPE ret;
1545
1546    if (current == OMX_StateIdle) {
1547        bufferwork->StartWork(true);
1548        LOGV("%s:%s: buffer process work started with executing state\n",
1549             GetName(), GetWorkingRole());
1550
1551        ret = ProcessorStart();
1552        if (ret != OMX_ErrorNone) {
1553            LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n",
1554                 GetName(), GetWorkingRole(), ret);
1555            goto out;
1556        }
1557    }
1558    else if (current == OMX_StatePause) {
1559        bufferwork->ResumeWork();
1560        LOGV("%s:%s: buffer process work resumed\n",
1561             GetName(), GetWorkingRole());
1562
1563        ret = ProcessorResume();
1564        if (ret != OMX_ErrorNone) {
1565            LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n",
1566                 GetName(), GetWorkingRole(), ret);
1567            goto out;
1568        }
1569    }
1570    else
1571        ret = OMX_ErrorIncorrectStateTransition;
1572
1573out:
1574    return ret;
1575}
1576
1577inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1578{
1579    OMX_ERRORTYPE ret;
1580
1581    if (current == OMX_StateIdle) {
1582        bufferwork->StartWork(false);
1583        LOGV("%s:%s: buffer process work started with paused state\n",
1584             GetName(), GetWorkingRole());
1585
1586        ret = ProcessorStart();
1587        if (ret != OMX_ErrorNone) {
1588            LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n",
1589                 GetName(), GetWorkingRole(), ret);
1590            goto out;
1591        }
1592    }
1593    else if (current == OMX_StateExecuting) {
1594        bufferwork->PauseWork();
1595        LOGV("%s:%s: buffer process work paused\n",
1596             GetName(), GetWorkingRole());
1597
1598        ret = ProcessorPause();
1599        if (ret != OMX_ErrorNone) {
1600            LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n",
1601                 GetName(), GetWorkingRole(), ret);
1602            goto out;
1603        }
1604    }
1605    else
1606        ret = OMX_ErrorIncorrectStateTransition;
1607
1608out:
1609    return ret;
1610}
1611
1612inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1613{
1614    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1615
1616    /*
1617     * Todo
1618     *   graceful escape
1619     */
1620
1621    return ret;
1622}
1623
1624inline OMX_ERRORTYPE
1625ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1626{
1627    OMX_ERRORTYPE ret;
1628
1629    if (current == OMX_StateLoaded) {
1630        LOGV("%s:%s: "
1631             "state transition's requested from Loaded to WaitForResources\n",
1632             GetName(), GetWorkingRole());
1633        ret = OMX_ErrorNone;
1634    }
1635    else
1636        ret = OMX_ErrorIncorrectStateTransition;
1637
1638    return ret;
1639}
1640
1641/* mark buffer */
1642void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark)
1643{
1644    PortBase *port = NULL;
1645    OMX_EVENTTYPE event;
1646    OMX_U32 data1, data2;
1647    OMX_ERRORTYPE ret;
1648
1649    if (ports)
1650        if (port_index < nr_ports)
1651            port = ports[port_index];
1652
1653    if (!port) {
1654        ret = OMX_ErrorBadPortIndex;
1655        goto notify_event;
1656    }
1657
1658    ret = port->PushMark(mark);
1659    if (ret != OMX_ErrorNone) {
1660        /* don't report OMX_ErrorInsufficientResources */
1661        ret = OMX_ErrorUndefined;
1662        goto notify_event;
1663    }
1664
1665notify_event:
1666    if (ret == OMX_ErrorNone) {
1667        event = OMX_EventCmdComplete;
1668        data1 = OMX_CommandMarkBuffer;
1669        data2 = port_index;
1670    }
1671    else {
1672        event = OMX_EventError;
1673        data1 = ret;
1674        data2 = 0;
1675    }
1676
1677    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1678}
1679
1680void ComponentBase::FlushPort(OMX_U32 port_index, bool notify)
1681{
1682    OMX_U32 i, from_index, to_index;
1683
1684    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1685        return;
1686
1687    if (port_index == OMX_ALL) {
1688        from_index = 0;
1689        to_index = nr_ports - 1;
1690    }
1691    else {
1692        from_index = port_index;
1693        to_index = port_index;
1694    }
1695
1696    LOGV("%s:%s: flush ports (from index %lu to %lu)\n",
1697         GetName(), GetWorkingRole(), from_index, to_index);
1698
1699    pthread_mutex_lock(&ports_block);
1700    for (i = from_index; i <= to_index; i++) {
1701        ports[i]->FlushPort();
1702        if (notify)
1703            callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1704                                    OMX_CommandFlush, i, NULL);
1705    }
1706    pthread_mutex_unlock(&ports_block);
1707
1708    LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole());
1709}
1710
1711extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp
1712
1713void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state)
1714{
1715    OMX_EVENTTYPE event;
1716    OMX_U32 data1, data2;
1717    OMX_U32 i, from_index, to_index;
1718    OMX_ERRORTYPE ret;
1719
1720    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1721        return;
1722
1723    if (port_index == OMX_ALL) {
1724        from_index = 0;
1725        to_index = nr_ports - 1;
1726    }
1727    else {
1728        from_index = port_index;
1729        to_index = port_index;
1730    }
1731
1732    LOGV("%s:%s: transit ports state to %s (from index %lu to %lu)\n",
1733         GetName(), GetWorkingRole(), GetPortStateName(state),
1734         from_index, to_index);
1735
1736    pthread_mutex_lock(&ports_block);
1737    for (i = from_index; i <= to_index; i++) {
1738        ret = ports[i]->TransState(state);
1739        if (ret == OMX_ErrorNone) {
1740            event = OMX_EventCmdComplete;
1741            if (state == PortBase::OMX_PortEnabled)
1742                data1 = OMX_CommandPortEnable;
1743            else
1744                data1 = OMX_CommandPortDisable;
1745            data2 = i;
1746        }
1747        else {
1748            event = OMX_EventError;
1749            data1 = ret;
1750            data2 = 0;
1751        }
1752        callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1753                                data1, data2, NULL);
1754    }
1755    pthread_mutex_unlock(&ports_block);
1756
1757    LOGV("%s:%s: transit ports state to %s completed\n",
1758         GetName(), GetWorkingRole(), GetPortStateName(state));
1759}
1760
1761/* set working role */
1762OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role)
1763{
1764    OMX_U32 i;
1765
1766    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1767        return OMX_ErrorIncorrectStateOperation;
1768
1769    if (!role) {
1770        working_role = NULL;
1771        return OMX_ErrorNone;
1772    }
1773
1774    for (i = 0; i < nr_roles; i++) {
1775        if (!strcmp((char *)&roles[i][0], role)) {
1776            working_role = (OMX_STRING)&roles[i][0];
1777            return OMX_ErrorNone;
1778        }
1779    }
1780
1781    LOGE("%s: cannot find %s role\n", GetName(), role);
1782    return OMX_ErrorBadParameter;
1783}
1784
1785/* apply a working role for a component having multiple roles */
1786OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void)
1787{
1788    OMX_U32 i;
1789    OMX_ERRORTYPE ret;
1790
1791    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1792        return OMX_ErrorIncorrectStateOperation;
1793
1794    if (!working_role)
1795        return OMX_ErrorBadParameter;
1796
1797    if (!callbacks || !appdata)
1798        return OMX_ErrorBadParameter;
1799
1800    ret = AllocatePorts();
1801    if (ret != OMX_ErrorNone) {
1802        LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret);
1803        return ret;
1804    }
1805
1806    /* now we can access ports */
1807    for (i = 0; i < nr_ports; i++) {
1808        ports[i]->SetOwner(handle);
1809        ports[i]->SetCallbacks(handle, callbacks, appdata);
1810    }
1811
1812    LOGI("%s: set working role %s:", GetName(), GetWorkingRole());
1813    return OMX_ErrorNone;
1814}
1815
1816OMX_ERRORTYPE ComponentBase::AllocatePorts(void)
1817{
1818    OMX_DIRTYPE dir;
1819    bool has_input, has_output;
1820    OMX_U32 i;
1821    OMX_ERRORTYPE ret;
1822
1823    if (ports)
1824        return OMX_ErrorBadParameter;
1825
1826    ret = ComponentAllocatePorts();
1827    if (ret != OMX_ErrorNone) {
1828        LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n",
1829             name, ret);
1830        return ret;
1831    }
1832
1833    has_input = false;
1834    has_output = false;
1835    ret = OMX_ErrorNone;
1836    for (i = 0; i < nr_ports; i++) {
1837        dir = ports[i]->GetPortDirection();
1838        if (dir == OMX_DirInput)
1839            has_input = true;
1840        else if (dir == OMX_DirOutput)
1841            has_output = true;
1842        else {
1843            ret = OMX_ErrorUndefined;
1844            break;
1845        }
1846    }
1847    if (ret != OMX_ErrorNone)
1848        goto free_ports;
1849
1850    if ((has_input == false) && (has_output == true))
1851        cvariant = CVARIANT_SOURCE;
1852    else if ((has_input == true) && (has_output == true))
1853        cvariant = CVARIANT_FILTER;
1854    else if ((has_input == true) && (has_output == false))
1855        cvariant = CVARIANT_SINK;
1856    else
1857        goto free_ports;
1858
1859    return OMX_ErrorNone;
1860
1861free_ports:
1862    LOGE("%s(): exit, unknown component variant\n", __func__);
1863    FreePorts();
1864    return ret;
1865}
1866
1867/* called int FreeHandle() */
1868OMX_ERRORTYPE ComponentBase::FreePorts(void)
1869{
1870    if (ports) {
1871        OMX_U32 i, this_nr_ports = this->nr_ports;
1872
1873        for (i = 0; i < this_nr_ports; i++) {
1874            if (ports[i]) {
1875                OMX_MARKTYPE *mark;
1876                /* it should be empty before this */
1877                while ((mark = ports[i]->PopMark()))
1878                    free(mark);
1879
1880                delete ports[i];
1881                ports[i] = NULL;
1882            }
1883        }
1884        delete []ports;
1885        ports = NULL;
1886    }
1887
1888    return OMX_ErrorNone;
1889}
1890
1891/* buffer processing */
1892/* implement WorkableInterface */
1893void ComponentBase::Work(void)
1894{
1895    OMX_BUFFERHEADERTYPE **buffers[nr_ports];
1896    OMX_BUFFERHEADERTYPE *buffers_hdr[nr_ports];
1897    buffer_retain_t retain[nr_ports];
1898    OMX_U32 i;
1899    OMX_ERRORTYPE ret;
1900
1901    pthread_mutex_lock(&ports_block);
1902
1903    while(IsAllBufferAvailable())
1904    {
1905        for (i = 0; i < nr_ports; i++) {
1906            buffers_hdr[i] = ports[i]->PopBuffer();
1907            buffers[i] = &buffers_hdr[i];
1908            retain[i] = BUFFER_RETAIN_NOT_RETAIN;
1909        }
1910
1911        if (!strncmp((char*)working_role, "video_decoder", 13)){
1912            ret = ProcessorProcess(buffers, &retain[0], nr_ports);
1913        }else{
1914            ret = ProcessorProcess(buffers_hdr, &retain[0], nr_ports);
1915        }
1916
1917        if (ret == OMX_ErrorNone) {
1918            PostProcessBuffers(buffers, &retain[0]);
1919
1920            for (i = 0; i < nr_ports; i++) {
1921
1922                if(retain[i] == BUFFER_RETAIN_GETAGAIN)
1923                    ports[i]->RetainThisBuffer(*buffers[i], false);
1924                else if (retain[i] == BUFFER_RETAIN_ACCUMULATE)
1925                    ports[i]->RetainThisBuffer(*buffers[i], true);
1926                else
1927                    ports[i]->ReturnThisBuffer(*buffers[i]);
1928            }
1929        }
1930        else {
1931            callbacks->EventHandler(handle, appdata, OMX_EventError, ret,
1932                                    0, NULL);
1933
1934            for (i = 0; i < nr_ports; i++) {
1935                /* return buffers by hands, these buffers're not in queue */
1936                ports[i]->ReturnThisBuffer(*buffers[i]);
1937                /* flush ports */
1938                ports[i]->FlushPort();
1939            }
1940        }
1941    }
1942
1943    pthread_mutex_unlock(&ports_block);
1944}
1945
1946bool ComponentBase::IsAllBufferAvailable(void)
1947{
1948
1949    pthread_mutex_lock(&output_queue_lock);
1950    PreProcessBufferQueue_Locked();
1951
1952    OMX_U32 i;
1953    OMX_U32 nr_avail = 0;
1954
1955    for (i = 0; i < nr_ports; i++) {
1956        OMX_U32 length = 0;
1957
1958        if (ports[i]->IsEnabled())
1959            length = ports[i]->BufferQueueLength();
1960
1961        if (length)
1962            nr_avail++;
1963    }
1964    pthread_mutex_unlock(&output_queue_lock);
1965
1966    if (nr_avail == nr_ports)
1967        return true;
1968    else
1969        return false;
1970}
1971
1972inline void ComponentBase::SourcePostProcessBuffers(
1973    OMX_BUFFERHEADERTYPE ***buffers,
1974    const buffer_retain_t *retain)
1975{
1976    OMX_U32 i;
1977
1978    for (i = 0; i < nr_ports; i++) {
1979        /*
1980         * in case of source component, buffers're marked when they come
1981         * from the ouput ports
1982         */
1983        if (!(*buffers[i])->hMarkTargetComponent) {
1984            OMX_MARKTYPE *mark;
1985
1986            mark = ports[i]->PopMark();
1987            if (mark) {
1988                (*buffers[i])->hMarkTargetComponent = mark->hMarkTargetComponent;
1989                (*buffers[i])->pMarkData = mark->pMarkData;
1990                free(mark);
1991            }
1992        }
1993    }
1994}
1995
1996inline void ComponentBase::FilterPostProcessBuffers(
1997    OMX_BUFFERHEADERTYPE ***buffers,
1998    const buffer_retain_t *retain)
1999{
2000    OMX_MARKTYPE *mark;
2001    OMX_U32 i, j;
2002
2003    for (i = 0; i < nr_ports; i++) {
2004        if (ports[i]->GetPortDirection() == OMX_DirInput) {
2005            for (j = 0; j < nr_ports; j++) {
2006                if (ports[j]->GetPortDirection() != OMX_DirOutput)
2007                    continue;
2008
2009                /* propagates EOS flag */
2010                /* clear input EOS at the end of this loop */
2011                if (retain[i] != BUFFER_RETAIN_GETAGAIN) {
2012                    if ((*buffers[i])->nFlags & OMX_BUFFERFLAG_EOS)
2013                        (*buffers[j])->nFlags |= OMX_BUFFERFLAG_EOS;
2014                }
2015
2016                /* propagates marks */
2017                /*
2018                 * if hMarkTargetComponent == handle then the mark's not
2019                 * propagated
2020                 */
2021                if ((*buffers[i])->hMarkTargetComponent &&
2022                    ((*buffers[i])->hMarkTargetComponent != handle)) {
2023                    if ((*buffers[j])->hMarkTargetComponent) {
2024                        mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
2025                        if (mark) {
2026                            mark->hMarkTargetComponent =
2027                                (*buffers[i])->hMarkTargetComponent;
2028                            mark->pMarkData = (*buffers[i])->pMarkData;
2029                            ports[j]->PushMark(mark);
2030                            mark = NULL;
2031                            (*buffers[i])->hMarkTargetComponent = NULL;
2032                            (*buffers[i])->pMarkData = NULL;
2033                        }
2034                    }
2035                    else {
2036                        mark = ports[j]->PopMark();
2037                        if (mark) {
2038                            (*buffers[j])->hMarkTargetComponent =
2039                                mark->hMarkTargetComponent;
2040                            (*buffers[j])->pMarkData = mark->pMarkData;
2041                            free(mark);
2042
2043                            mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
2044                            if (mark) {
2045                                mark->hMarkTargetComponent =
2046                                    (*buffers[i])->hMarkTargetComponent;
2047                                mark->pMarkData = (*buffers[i])->pMarkData;
2048                                ports[j]->PushMark(mark);
2049                                mark = NULL;
2050                                (*buffers[i])->hMarkTargetComponent = NULL;
2051                                (*buffers[i])->pMarkData = NULL;
2052                            }
2053                        }
2054                        else {
2055                            (*buffers[j])->hMarkTargetComponent =
2056                                (*buffers[i])->hMarkTargetComponent;
2057                            (*buffers[j])->pMarkData = (*buffers[i])->pMarkData;
2058                            (*buffers[i])->hMarkTargetComponent = NULL;
2059                            (*buffers[i])->pMarkData = NULL;
2060                        }
2061                    }
2062                }
2063            }
2064            /* clear input buffer's EOS */
2065            if (retain[i] != BUFFER_RETAIN_GETAGAIN)
2066                (*buffers[i])->nFlags &= ~OMX_BUFFERFLAG_EOS;
2067        }
2068    }
2069}
2070
2071inline void ComponentBase::SinkPostProcessBuffers(
2072    OMX_BUFFERHEADERTYPE ***buffers,
2073    const buffer_retain_t *retain)
2074{
2075    return;
2076}
2077
2078void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
2079                                       const buffer_retain_t *retain)
2080{
2081
2082    if (cvariant == CVARIANT_SOURCE)
2083        SourcePostProcessBuffers(buffers, retain);
2084    else if (cvariant == CVARIANT_FILTER)
2085        FilterPostProcessBuffers(buffers, retain);
2086    else if (cvariant == CVARIANT_SINK) {
2087        SinkPostProcessBuffers(buffers, retain);
2088    }
2089    else {
2090        LOGE("%s(): fatal error unknown component variant (%d)\n",
2091             __func__, cvariant);
2092    }
2093}
2094
2095/* processor default callbacks */
2096OMX_ERRORTYPE ComponentBase::ProcessorInit(void)
2097{
2098    return OMX_ErrorNone;
2099}
2100OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void)
2101{
2102    return OMX_ErrorNone;
2103}
2104
2105OMX_ERRORTYPE ComponentBase::ProcessorStart(void)
2106{
2107    return OMX_ErrorNone;
2108}
2109
2110OMX_ERRORTYPE ComponentBase::ProcessorStop(void)
2111{
2112    return OMX_ErrorNone;
2113}
2114
2115OMX_ERRORTYPE ComponentBase::ProcessorPause(void)
2116{
2117    return OMX_ErrorNone;
2118}
2119
2120OMX_ERRORTYPE ComponentBase::ProcessorResume(void)
2121{
2122    return OMX_ErrorNone;
2123}
2124
2125OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32 port_index)
2126{
2127    return OMX_ErrorNone;
2128}
2129
2130OMX_ERRORTYPE ComponentBase::PreProcessBuffer(OMX_BUFFERHEADERTYPE* buffer)
2131{
2132    return OMX_ErrorNone;
2133}
2134
2135OMX_ERRORTYPE ComponentBase::PreProcessBufferQueue_Locked()
2136{
2137    return OMX_ErrorNone;
2138}
2139OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE **pBuffers,
2140                                           buffer_retain_t *retain,
2141                                           OMX_U32 nr_buffers)
2142{
2143    LOGE("ProcessorProcess not be implemented");
2144    return OMX_ErrorNotImplemented;
2145}
2146OMX_ERRORTYPE ComponentBase::ProcessorProcess(OMX_BUFFERHEADERTYPE ***pBuffers,
2147                                           buffer_retain_t *retain,
2148                                           OMX_U32 nr_buffers)
2149{
2150    LOGE("ProcessorProcess not be implemented");
2151    return OMX_ErrorNotImplemented;
2152}
2153
2154OMX_ERRORTYPE ComponentBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer)
2155{
2156    return OMX_ErrorNone;
2157
2158}
2159
2160/* end of processor callbacks */
2161
2162/* helper for derived class */
2163const OMX_STRING ComponentBase::GetWorkingRole(void)
2164{
2165    return &working_role[0];
2166}
2167
2168const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void)
2169{
2170    return handle;
2171}
2172
2173void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader,
2174                               bool dumpdata)
2175{
2176    OMX_U8 *pbuffer = bufferheader->pBuffer, *p;
2177    OMX_U32 offset = bufferheader->nOffset;
2178    OMX_U32 alloc_len = bufferheader->nAllocLen;
2179    OMX_U32 filled_len =  bufferheader->nFilledLen;
2180    OMX_U32 left = filled_len, oneline;
2181    OMX_U32 index = 0, i;
2182    /* 0x%04lx:  %02x %02x .. (n = 16)\n\0 */
2183    char prbuffer[8 + 3 * 0x10 + 2], *pp;
2184    OMX_U32 prbuffer_len;
2185
2186    LOGD("Component %s DumpBuffer\n", name);
2187    LOGD("%s port index = %lu",
2188         (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output",
2189         (bufferheader->nInputPortIndex != 0x7fffffff) ?
2190         bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex);
2191    LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n",
2192         alloc_len, offset, filled_len);
2193    LOGD("nTimeStamp = %lld, nTickCount = %lu",
2194         bufferheader->nTimeStamp,
2195         bufferheader->nTickCount);
2196    LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags);
2197    LOGD("hMarkTargetComponent = %p, pMarkData = %p\n",
2198         bufferheader->hMarkTargetComponent, bufferheader->pMarkData);
2199
2200    if (!pbuffer || !alloc_len || !filled_len)
2201        return;
2202
2203    if (offset + filled_len > alloc_len)
2204        return;
2205
2206    if (!dumpdata)
2207        return;
2208
2209    p = pbuffer + offset;
2210    while (left) {
2211        oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */
2212        pp += sprintf(pp, "0x%04lx: ", index);
2213        for (i = 0; i < oneline; i++)
2214            pp += sprintf(pp, " %02x", *(p + i));
2215        pp += sprintf(pp, "\n");
2216        *pp = '\0';
2217
2218        index += 0x10;
2219        p += oneline;
2220        left -= oneline;
2221
2222        pp = &prbuffer[0];
2223        LOGD("%s", pp);
2224    }
2225}
2226
2227/* end of component methods & helpers */
2228
2229/*
2230 * omx header manipuation
2231 */
2232void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
2233{
2234    OMX_U32 *nsize;
2235    OMX_VERSIONTYPE *nversion;
2236
2237    if (!type)
2238        return;
2239
2240    nsize = (OMX_U32 *)type;
2241    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2242
2243    *nsize = size;
2244    nversion->nVersion = OMX_SPEC_VERSION;
2245}
2246
2247OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size)
2248{
2249    OMX_U32 *nsize;
2250    OMX_VERSIONTYPE *nversion;
2251
2252    if (!type)
2253        return OMX_ErrorBadParameter;
2254
2255    nsize = (OMX_U32 *)type;
2256    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2257
2258    if (*nsize != size)
2259        return OMX_ErrorBadParameter;
2260
2261    if (nversion->nVersion != OMX_SPEC_VERSION)
2262        return OMX_ErrorVersionMismatch;
2263
2264    return OMX_ErrorNone;
2265}
2266
2267/* end of ComponentBase */
2268