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