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