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