componentbase.cpp revision c127caa3755f46f028fe7ec6e7ab02cf33238f62
1/*
2 * Copyright (C) 2009 Wind River Systems.
3 */
4
5#include <stdlib.h>
6#include <string.h>
7
8#include <pthread.h>
9
10#include <OMX_Core.h>
11#include <OMX_Component.h>
12
13#include <componentbase.h>
14
15#include <queue.h>
16#include <workqueue.h>
17
18#define LOG_TAG "componentbase"
19#include <log.h>
20
21/*
22 * CmdProcessWork
23 */
24CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci)
25{
26    this->ci = ci;
27
28    workq = new WorkQueue;
29
30    __queue_init(&q);
31    pthread_mutex_init(&lock, NULL);
32
33    workq->StartWork();
34}
35
36CmdProcessWork::~CmdProcessWork()
37{
38    workq->StopWork();
39    delete workq;
40
41    pthread_mutex_lock(&lock);
42    queue_free_all(&q);
43    pthread_mutex_unlock(&lock);
44
45    pthread_mutex_destroy(&lock);
46}
47
48OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd)
49{
50    int ret;
51
52    pthread_mutex_lock(&lock);
53    ret = queue_push_tail(&q, cmd);
54    if (ret) {
55        pthread_mutex_unlock(&lock);
56        return OMX_ErrorInsufficientResources;
57    }
58
59    workq->ScheduleWork(this);
60    pthread_mutex_unlock(&lock);
61
62    return OMX_ErrorNone;
63}
64
65struct cmd_s *CmdProcessWork::PopCmdQueue(void)
66{
67    struct cmd_s *cmd;
68
69    pthread_mutex_lock(&lock);
70    cmd = (struct cmd_s *)queue_pop_head(&q);
71    pthread_mutex_unlock(&lock);
72
73    return cmd;
74}
75
76void CmdProcessWork::ScheduleIfAvailable(void)
77{
78    bool avail;
79
80    pthread_mutex_lock(&lock);
81    avail = queue_length(&q) ? true : false;
82    pthread_mutex_unlock(&lock);
83
84    if (avail)
85        workq->ScheduleWork(this);
86}
87
88void CmdProcessWork::Work(void)
89{
90    struct cmd_s *cmd;
91
92    cmd = PopCmdQueue();
93    if (cmd) {
94        ci->CmdHandler(cmd);
95        free(cmd);
96    }
97    ScheduleIfAvailable();
98}
99
100/* end of CmdProcessWork */
101
102/*
103 * ComponentBase
104 */
105/*
106 * constructor & destructor
107 */
108void ComponentBase::__ComponentBase(void)
109{
110    memset(name, 0, OMX_MAX_STRINGNAME_SIZE);
111    cmodule = NULL;
112    handle = NULL;
113
114    roles = NULL;
115    nr_roles = 0;
116
117    working_role = NULL;
118
119    ports = NULL;
120    nr_ports = 0;
121    memset(&portparam, 0, sizeof(portparam));
122
123    state = OMX_StateUnloaded;
124
125    cmdwork = new CmdProcessWork(this);
126
127    executing = false;
128    pthread_mutex_init(&executing_lock, NULL);
129    pthread_cond_init(&executing_wait, NULL);
130
131    bufferwork = new WorkQueue();
132
133    pthread_mutex_init(&ports_block, NULL);
134}
135
136ComponentBase::ComponentBase()
137{
138    __ComponentBase();
139}
140
141ComponentBase::ComponentBase(const OMX_STRING name)
142{
143    __ComponentBase();
144    SetName(name);
145}
146
147ComponentBase::~ComponentBase()
148{
149    delete cmdwork;
150
151    delete bufferwork;
152    pthread_mutex_destroy(&executing_lock);
153    pthread_cond_destroy(&executing_wait);
154
155    pthread_mutex_destroy(&ports_block);
156
157    if (roles) {
158        OMX_U32 i;
159
160        for (i = 0; i < nr_roles; i++)
161            free(roles[i]);
162
163        free(roles);
164    }
165}
166
167/* end of constructor & destructor */
168
169/*
170 * accessor
171 */
172/* name */
173void ComponentBase::SetName(const OMX_STRING name)
174{
175    strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
176    this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
177}
178
179const OMX_STRING ComponentBase::GetName(void)
180{
181    return name;
182}
183
184/* component module */
185void ComponentBase::SetCModule(CModule *cmodule)
186{
187    this->cmodule = cmodule;
188}
189
190CModule *ComponentBase::GetCModule(void)
191{
192    return cmodule;
193}
194
195/* end of accessor */
196
197/*
198 * core methods & helpers
199 */
200/* roles */
201OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles,
202                                                 const OMX_U8 **roles)
203{
204    OMX_U32 i;
205
206    if (!roles || !nr_roles)
207        return OMX_ErrorBadParameter;
208
209    if (this->roles) {
210        free(this->roles[0]);
211        free(this->roles);
212        this->roles = NULL;
213    }
214
215    this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
216    if (!this->roles)
217        return OMX_ErrorInsufficientResources;
218
219    this->roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE);
220    if (!this->roles) {
221        free(this->roles);
222        this->roles = NULL;
223        return OMX_ErrorInsufficientResources;
224    }
225
226    for (i = 0; i < nr_roles; i++) {
227        if (i < nr_roles-1)
228            roles[i+1] = roles[i] + OMX_MAX_STRINGNAME_SIZE;
229
230        strncpy((OMX_STRING)&this->roles[i][0],
231                (const OMX_STRING)&roles[i][0], OMX_MAX_STRINGNAME_SIZE);
232    }
233
234    this->nr_roles = nr_roles;
235    return OMX_ErrorNone;
236}
237
238/* GetHandle & FreeHandle */
239OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle,
240                                       OMX_PTR pAppData,
241                                       OMX_CALLBACKTYPE *pCallBacks)
242{
243    OMX_U32 i;
244    OMX_ERRORTYPE ret;
245
246    if (handle)
247        return OMX_ErrorUndefined;
248
249    if (nr_roles == 1)
250        SetWorkingRole((OMX_STRING)&roles[0]);
251
252    handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle));
253    if (!handle) {
254        SetWorkingRole(NULL);
255        return OMX_ErrorInsufficientResources;
256    }
257
258    /* handle initialization */
259    SetTypeHeader(handle, sizeof(*handle));
260    handle->pComponentPrivate = static_cast<OMX_PTR>(this);
261    handle->pApplicationPrivate = pAppData;
262
263    /* connect handle's functions */
264    handle->GetComponentVersion = GetComponentVersion;
265    handle->SendCommand = SendCommand;
266    handle->GetParameter = GetParameter;
267    handle->SetParameter = SetParameter;
268    handle->GetConfig = GetConfig;
269    handle->SetConfig = SetConfig;
270    handle->GetExtensionIndex = GetExtensionIndex;
271    handle->GetState = GetState;
272    handle->ComponentTunnelRequest = ComponentTunnelRequest;
273    handle->UseBuffer = UseBuffer;
274    handle->AllocateBuffer = AllocateBuffer;
275    handle->FreeBuffer = FreeBuffer;
276    handle->EmptyThisBuffer = EmptyThisBuffer;
277    handle->FillThisBuffer = FillThisBuffer;
278    handle->SetCallbacks = SetCallbacks;
279    handle->ComponentDeInit = ComponentDeInit;
280    handle->UseEGLImage = UseEGLImage;
281    handle->ComponentRoleEnum = ComponentRoleEnum;
282
283    appdata = pAppData;
284    callbacks = pCallBacks;
285    *pHandle = (OMX_HANDLETYPE *)handle;
286
287    state = OMX_StateLoaded;
288    return OMX_ErrorNone;
289}
290
291OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent)
292{
293    OMX_ERRORTYPE ret;
294
295    if (hComponent != handle)
296        return OMX_ErrorBadParameter;
297
298    if (state != OMX_StateLoaded)
299        return OMX_ErrorIncorrectStateOperation;
300
301    FreePorts();
302
303    free(handle);
304
305    appdata = NULL;
306    callbacks = NULL;
307
308    state = OMX_StateUnloaded;
309    return OMX_ErrorNone;
310}
311
312/* end of core methods & helpers */
313
314/*
315 * component methods & helpers
316 */
317OMX_ERRORTYPE ComponentBase::GetComponentVersion(
318    OMX_IN  OMX_HANDLETYPE hComponent,
319    OMX_OUT OMX_STRING pComponentName,
320    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
321    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
322    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
323{
324    ComponentBase *cbase;
325
326    if (!hComponent)
327        return OMX_ErrorBadParameter;
328
329    cbase = static_cast<ComponentBase *>
330        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
331    if (!cbase)
332        return OMX_ErrorBadParameter;
333
334    return cbase->CBaseGetComponentVersion(hComponent,
335                                           pComponentName,
336                                           pComponentVersion,
337                                           pSpecVersion,
338                                           pComponentUUID);
339}
340
341OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion(
342    OMX_IN  OMX_HANDLETYPE hComponent,
343    OMX_OUT OMX_STRING pComponentName,
344    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
345    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
346    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
347{
348    /*
349     * Todo
350     */
351
352    return OMX_ErrorNotImplemented;
353}
354
355OMX_ERRORTYPE ComponentBase::SendCommand(
356    OMX_IN  OMX_HANDLETYPE hComponent,
357    OMX_IN  OMX_COMMANDTYPE Cmd,
358    OMX_IN  OMX_U32 nParam1,
359    OMX_IN  OMX_PTR pCmdData)
360{
361    ComponentBase *cbase;
362
363    if (!hComponent)
364        return OMX_ErrorBadParameter;
365
366    cbase = static_cast<ComponentBase *>
367        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
368    if (!cbase)
369        return OMX_ErrorBadParameter;
370
371    return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData);
372}
373
374OMX_ERRORTYPE ComponentBase::CBaseSendCommand(
375    OMX_IN  OMX_HANDLETYPE hComponent,
376    OMX_IN  OMX_COMMANDTYPE Cmd,
377    OMX_IN  OMX_U32 nParam1,
378    OMX_IN  OMX_PTR pCmdData)
379{
380    struct cmd_s *cmd;
381
382    if (hComponent != handle)
383        return OMX_ErrorInvalidComponent;
384
385    /* basic error check */
386    switch (Cmd) {
387    case OMX_CommandStateSet:
388        /*
389         * Todo
390         */
391        break;
392    case OMX_CommandFlush:
393        /*
394         * Todo
395         */
396        //break;
397    case OMX_CommandPortDisable:
398        /*
399         * Todo
400         */
401        //break;
402    case OMX_CommandPortEnable:
403        /*
404         * Todo
405         */
406        //break;
407    case OMX_CommandMarkBuffer:
408        /*
409         * Todo
410         */
411        //break;
412    default:
413        LOGE("command %d not supported\n", Cmd);
414        return OMX_ErrorUnsupportedIndex;
415    }
416
417    cmd = (struct cmd_s *)malloc(sizeof(*cmd));
418    if (!cmd)
419        return OMX_ErrorInsufficientResources;
420
421    cmd->cmd = Cmd;
422    cmd->param1 = nParam1;
423    cmd->cmddata = pCmdData;
424
425    return cmdwork->PushCmdQueue(cmd);
426}
427
428OMX_ERRORTYPE ComponentBase::GetParameter(
429    OMX_IN  OMX_HANDLETYPE hComponent,
430    OMX_IN  OMX_INDEXTYPE nParamIndex,
431    OMX_INOUT OMX_PTR pComponentParameterStructure)
432{
433    ComponentBase *cbase;
434
435    if (!hComponent)
436        return OMX_ErrorBadParameter;
437
438    cbase = static_cast<ComponentBase *>
439        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
440    if (!cbase)
441        return OMX_ErrorBadParameter;
442
443    return cbase->CBaseGetParameter(hComponent, nParamIndex,
444                                    pComponentParameterStructure);
445}
446
447OMX_ERRORTYPE ComponentBase::CBaseGetParameter(
448    OMX_IN  OMX_HANDLETYPE hComponent,
449    OMX_IN  OMX_INDEXTYPE nParamIndex,
450    OMX_INOUT OMX_PTR pComponentParameterStructure)
451{
452    OMX_ERRORTYPE ret = OMX_ErrorNone;
453
454    if (hComponent != handle)
455        return OMX_ErrorBadParameter;
456
457    switch (nParamIndex) {
458    case OMX_IndexParamAudioInit:
459    case OMX_IndexParamVideoInit:
460    case OMX_IndexParamImageInit:
461    case OMX_IndexParamOtherInit: {
462        OMX_PORT_PARAM_TYPE *p =
463            (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
464
465        ret = CheckTypeHeader(p, sizeof(*p));
466        if (ret != OMX_ErrorNone)
467            return ret;
468
469        memcpy(p, &portparam, sizeof(*p));
470        break;
471    }
472    case OMX_IndexParamPortDefinition: {
473        OMX_PARAM_PORTDEFINITIONTYPE *p =
474            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
475        OMX_U32 index = p->nPortIndex;
476        PortBase *port = NULL;
477
478        ret = CheckTypeHeader(p, sizeof(*p));
479        if (ret != OMX_ErrorNone)
480            return ret;
481
482        if (index < nr_ports)
483            port = ports[index];
484
485        if (!port)
486            return OMX_ErrorBadParameter;
487
488        memcpy(p, port->GetPortParam(), sizeof(*p));
489        break;
490    }
491    case OMX_IndexParamAudioPortFormat: {
492        OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
493            (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
494        OMX_U32 index = p->nPortIndex;
495        PortBase *port = NULL;
496
497        ret = CheckTypeHeader(p, sizeof(*p));
498        if (ret != OMX_ErrorNone)
499            return ret;
500
501        if (index < nr_ports)
502            port = ports[index];
503
504        if (!port)
505            return OMX_ErrorBadParameter;
506
507        memcpy(p, port->GetAudioPortParam(), sizeof(*p));
508        break;
509    }
510    case OMX_IndexParamCompBufferSupplier:
511        /*
512         * Todo
513         */
514
515        ret = OMX_ErrorUnsupportedIndex;
516        break;
517    default:
518        ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure);
519    } /* switch */
520
521    return ret;
522}
523
524OMX_ERRORTYPE ComponentBase::SetParameter(
525    OMX_IN  OMX_HANDLETYPE hComponent,
526    OMX_IN  OMX_INDEXTYPE nIndex,
527    OMX_IN  OMX_PTR pComponentParameterStructure)
528{
529    ComponentBase *cbase;
530
531    if (!hComponent)
532        return OMX_ErrorBadParameter;
533
534    cbase = static_cast<ComponentBase *>
535        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
536    if (!cbase)
537        return OMX_ErrorBadParameter;
538
539    return cbase->CBaseSetParameter(hComponent, nIndex,
540                                    pComponentParameterStructure);
541}
542
543OMX_ERRORTYPE ComponentBase::CBaseSetParameter(
544    OMX_IN  OMX_HANDLETYPE hComponent,
545    OMX_IN  OMX_INDEXTYPE nIndex,
546    OMX_IN  OMX_PTR pComponentParameterStructure)
547{
548    OMX_ERRORTYPE ret = OMX_ErrorNone;
549
550    if (hComponent != handle)
551        return OMX_ErrorBadParameter;
552
553    switch (nIndex) {
554    case OMX_IndexParamAudioInit:
555    case OMX_IndexParamVideoInit:
556    case OMX_IndexParamImageInit:
557    case OMX_IndexParamOtherInit: {
558        OMX_PORT_PARAM_TYPE *p = (OMX_PORT_PARAM_TYPE *)
559            pComponentParameterStructure;
560
561        ret = CheckTypeHeader(p, sizeof(*p));
562        if (ret != OMX_ErrorNone)
563            return ret;
564
565        memcpy(&portparam, p, sizeof(*p));
566        break;
567    }
568    case OMX_IndexParamPortDefinition: {
569        OMX_PARAM_PORTDEFINITIONTYPE *p =
570            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
571        OMX_U32 index = p->nPortIndex;
572        PortBase *port = NULL;
573
574        ret = CheckTypeHeader(p, sizeof(*p));
575        if (ret != OMX_ErrorNone)
576            return ret;
577
578        if (index < nr_ports)
579            port = ports[index];
580
581        if (!port)
582            return OMX_ErrorBadParameter;
583
584        port->SetPortParam(p);
585        break;
586    }
587    case OMX_IndexParamAudioPortFormat: {
588        OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
589            (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
590        OMX_U32 index = p->nPortIndex;
591        PortBase *port = NULL;
592
593        ret = CheckTypeHeader(p, sizeof(*p));
594        if (ret != OMX_ErrorNone)
595            return ret;
596
597        if (index < nr_ports)
598            port = ports[index];
599
600        if (!port)
601            return OMX_ErrorBadParameter;
602
603        port->SetAudioPortParam(p);
604        break;
605    }
606    case OMX_IndexParamCompBufferSupplier:
607        /*
608         * Todo
609         */
610
611        ret = OMX_ErrorUnsupportedIndex;
612        break;
613    case OMX_IndexParamStandardComponentRole: {
614        OMX_PARAM_COMPONENTROLETYPE *p =
615            (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
616
617        ret = CheckTypeHeader(p, sizeof(*p));
618        if (ret != OMX_ErrorNone)
619            return ret;
620
621        ret = SetWorkingRole((OMX_STRING)p->cRole);
622        if (ret != OMX_ErrorNone)
623            return ret;
624        break;
625    }
626    default:
627        ret = ComponentSetParameter(nIndex, pComponentParameterStructure);
628    } /* switch */
629
630    return ret;
631}
632
633OMX_ERRORTYPE ComponentBase::GetConfig(
634    OMX_IN  OMX_HANDLETYPE hComponent,
635    OMX_IN  OMX_INDEXTYPE nIndex,
636    OMX_INOUT OMX_PTR pComponentConfigStructure)
637{
638    ComponentBase *cbase;
639
640    if (!hComponent)
641        return OMX_ErrorBadParameter;
642
643    cbase = static_cast<ComponentBase *>
644        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
645    if (!cbase)
646        return OMX_ErrorBadParameter;
647
648    return cbase->CBaseGetConfig(hComponent, nIndex,
649                                 pComponentConfigStructure);
650}
651
652OMX_ERRORTYPE ComponentBase::CBaseGetConfig(
653    OMX_IN  OMX_HANDLETYPE hComponent,
654    OMX_IN  OMX_INDEXTYPE nIndex,
655    OMX_INOUT OMX_PTR pComponentConfigStructure)
656{
657    OMX_ERRORTYPE ret;
658
659    if (hComponent != handle)
660        return OMX_ErrorBadParameter;
661
662    switch (nIndex) {
663    default:
664        ret = ComponentGetConfig(nIndex, pComponentConfigStructure);
665    }
666
667    return ret;
668}
669
670OMX_ERRORTYPE ComponentBase::SetConfig(
671    OMX_IN  OMX_HANDLETYPE hComponent,
672    OMX_IN  OMX_INDEXTYPE nIndex,
673    OMX_IN  OMX_PTR pComponentConfigStructure)
674{
675    ComponentBase *cbase;
676
677    if (!hComponent)
678        return OMX_ErrorBadParameter;
679
680    cbase = static_cast<ComponentBase *>
681        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
682    if (!cbase)
683        return OMX_ErrorBadParameter;
684
685    return cbase->CBaseSetConfig(hComponent, nIndex,
686                                 pComponentConfigStructure);
687}
688
689OMX_ERRORTYPE ComponentBase::CBaseSetConfig(
690    OMX_IN  OMX_HANDLETYPE hComponent,
691    OMX_IN  OMX_INDEXTYPE nIndex,
692    OMX_IN  OMX_PTR pComponentConfigStructure)
693{
694    OMX_ERRORTYPE ret;
695
696    if (hComponent != handle)
697        return OMX_ErrorBadParameter;
698
699    switch (nIndex) {
700    default:
701        ret = ComponentSetConfig(nIndex, pComponentConfigStructure);
702    }
703
704    return ret;
705}
706
707OMX_ERRORTYPE ComponentBase::GetExtensionIndex(
708    OMX_IN  OMX_HANDLETYPE hComponent,
709    OMX_IN  OMX_STRING cParameterName,
710    OMX_OUT OMX_INDEXTYPE* pIndexType)
711{
712    ComponentBase *cbase;
713
714    if (!hComponent)
715        return OMX_ErrorBadParameter;
716
717    cbase = static_cast<ComponentBase *>
718        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
719    if (!cbase)
720        return OMX_ErrorBadParameter;
721
722    return cbase->CBaseGetExtensionIndex(hComponent, cParameterName,
723                                         pIndexType);
724}
725
726OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex(
727    OMX_IN  OMX_HANDLETYPE hComponent,
728    OMX_IN  OMX_STRING cParameterName,
729    OMX_OUT OMX_INDEXTYPE* pIndexType)
730{
731    /*
732     * Todo
733     */
734
735    return OMX_ErrorNotImplemented;
736}
737
738OMX_ERRORTYPE ComponentBase::GetState(
739    OMX_IN  OMX_HANDLETYPE hComponent,
740    OMX_OUT OMX_STATETYPE* pState)
741{
742    ComponentBase *cbase;
743
744    if (!hComponent)
745        return OMX_ErrorBadParameter;
746
747    cbase = static_cast<ComponentBase *>
748        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
749    if (!cbase)
750        return OMX_ErrorBadParameter;
751
752    return cbase->CBaseGetState(hComponent, pState);
753}
754
755OMX_ERRORTYPE ComponentBase::CBaseGetState(
756    OMX_IN  OMX_HANDLETYPE hComponent,
757    OMX_OUT OMX_STATETYPE* pState)
758{
759    if (hComponent != handle)
760        return OMX_ErrorBadParameter;
761
762    *pState = state;
763    return OMX_ErrorNone;
764}
765
766OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest(
767    OMX_IN  OMX_HANDLETYPE hComponent,
768    OMX_IN  OMX_U32 nPort,
769    OMX_IN  OMX_HANDLETYPE hTunneledComponent,
770    OMX_IN  OMX_U32 nTunneledPort,
771    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
772{
773    ComponentBase *cbase;
774
775    if (!hComponent)
776        return OMX_ErrorBadParameter;
777
778    cbase = static_cast<ComponentBase *>
779        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
780    if (!cbase)
781        return OMX_ErrorBadParameter;
782
783    return cbase->CBaseComponentTunnelRequest(hComponent, nPort,
784                                              hTunneledComponent,
785                                              nTunneledPort, pTunnelSetup);
786}
787
788OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest(
789    OMX_IN  OMX_HANDLETYPE hComp,
790    OMX_IN  OMX_U32 nPort,
791    OMX_IN  OMX_HANDLETYPE hTunneledComp,
792    OMX_IN  OMX_U32 nTunneledPort,
793    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
794{
795    /*
796     * Todo
797     */
798
799    return OMX_ErrorNotImplemented;
800}
801
802OMX_ERRORTYPE ComponentBase::UseBuffer(
803    OMX_IN OMX_HANDLETYPE hComponent,
804    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
805    OMX_IN OMX_U32 nPortIndex,
806    OMX_IN OMX_PTR pAppPrivate,
807    OMX_IN OMX_U32 nSizeBytes,
808    OMX_IN OMX_U8 *pBuffer)
809{
810    ComponentBase *cbase;
811
812    if (!hComponent)
813        return OMX_ErrorBadParameter;
814
815    cbase = static_cast<ComponentBase *>
816        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
817    if (!cbase)
818        return OMX_ErrorBadParameter;
819
820    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
821                                 pAppPrivate, nSizeBytes, pBuffer);
822}
823
824OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
825    OMX_IN OMX_HANDLETYPE hComponent,
826    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
827    OMX_IN OMX_U32 nPortIndex,
828    OMX_IN OMX_PTR pAppPrivate,
829    OMX_IN OMX_U32 nSizeBytes,
830    OMX_IN OMX_U8 *pBuffer)
831{
832    PortBase *port = NULL;
833    OMX_ERRORTYPE ret;
834
835    if (hComponent != handle)
836        return OMX_ErrorBadParameter;
837
838    if (ports)
839        if (nPortIndex < nr_ports)
840            port = ports[nPortIndex];
841
842    if (!port)
843        return OMX_ErrorBadParameter;
844
845    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
846                           pBuffer);
847}
848
849OMX_ERRORTYPE ComponentBase::AllocateBuffer(
850    OMX_IN OMX_HANDLETYPE hComponent,
851    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
852    OMX_IN OMX_U32 nPortIndex,
853    OMX_IN OMX_PTR pAppPrivate,
854    OMX_IN OMX_U32 nSizeBytes)
855{
856    ComponentBase *cbase;
857
858    if (!hComponent)
859        return OMX_ErrorBadParameter;
860
861    cbase = static_cast<ComponentBase *>
862        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
863    if (!cbase)
864        return OMX_ErrorBadParameter;
865
866    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
867                                      pAppPrivate, nSizeBytes);
868}
869
870OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
871    OMX_IN OMX_HANDLETYPE hComponent,
872    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
873    OMX_IN OMX_U32 nPortIndex,
874    OMX_IN OMX_PTR pAppPrivate,
875    OMX_IN OMX_U32 nSizeBytes)
876{
877    PortBase *port = NULL;
878    OMX_ERRORTYPE ret;
879
880    if (hComponent != handle)
881        return OMX_ErrorBadParameter;
882
883    if (ports)
884        if (nPortIndex < nr_ports)
885            port = ports[nPortIndex];
886
887    if (!port)
888        return OMX_ErrorBadParameter;
889
890    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
891}
892
893OMX_ERRORTYPE ComponentBase::FreeBuffer(
894    OMX_IN  OMX_HANDLETYPE hComponent,
895    OMX_IN  OMX_U32 nPortIndex,
896    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
897{
898    ComponentBase *cbase;
899
900    if (!hComponent)
901        return OMX_ErrorBadParameter;
902
903    cbase = static_cast<ComponentBase *>
904        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
905    if (!cbase)
906        return OMX_ErrorBadParameter;
907
908    return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
909}
910
911OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
912    OMX_IN  OMX_HANDLETYPE hComponent,
913    OMX_IN  OMX_U32 nPortIndex,
914    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
915{
916    PortBase *port = NULL;
917    OMX_ERRORTYPE ret;
918
919    if (hComponent != handle)
920        return OMX_ErrorBadParameter;
921
922    if (ports)
923        if (nPortIndex < nr_ports)
924            port = ports[nPortIndex];
925
926    if (!port)
927        return OMX_ErrorBadParameter;
928
929    return port->FreeBuffer(nPortIndex, pBuffer);
930}
931
932OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
933    OMX_IN  OMX_HANDLETYPE hComponent,
934    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
935{
936    ComponentBase *cbase;
937
938    if (!hComponent)
939        return OMX_ErrorBadParameter;
940
941    cbase = static_cast<ComponentBase *>
942        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
943    if (!cbase)
944        return OMX_ErrorBadParameter;
945
946    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
947}
948
949OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
950    OMX_IN  OMX_HANDLETYPE hComponent,
951    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
952{
953    PortBase *port = NULL;
954    OMX_U32 port_index;
955    OMX_ERRORTYPE ret;
956
957    if ((hComponent != handle) || !pBuffer)
958        return OMX_ErrorBadParameter;
959
960    port_index = pBuffer->nInputPortIndex;
961    if (port_index == (OMX_U32)-1)
962        return OMX_ErrorBadParameter;
963
964    if (ports)
965        if (port_index < nr_ports)
966            port = ports[port_index];
967
968    if (!port)
969        return OMX_ErrorBadParameter;
970
971    ret = port->PushThisBuffer(pBuffer);
972    if (ret == OMX_ErrorNone)
973        bufferwork->ScheduleWork(this);
974
975    return ret;
976}
977
978OMX_ERRORTYPE ComponentBase::FillThisBuffer(
979    OMX_IN  OMX_HANDLETYPE hComponent,
980    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
981{
982    ComponentBase *cbase;
983
984    if (!hComponent)
985        return OMX_ErrorBadParameter;
986
987    cbase = static_cast<ComponentBase *>
988        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
989    if (!cbase)
990        return OMX_ErrorBadParameter;
991
992    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
993}
994
995OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
996    OMX_IN  OMX_HANDLETYPE hComponent,
997    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
998{
999    PortBase *port = NULL;
1000    OMX_U32 port_index;
1001    OMX_ERRORTYPE ret;
1002
1003    if ((hComponent != handle) || !pBuffer)
1004        return OMX_ErrorBadParameter;
1005
1006    port_index = pBuffer->nOutputPortIndex;
1007    if (port_index == (OMX_U32)-1)
1008        return OMX_ErrorBadParameter;
1009
1010    if (ports)
1011        if (port_index < nr_ports)
1012            port = ports[port_index];
1013
1014    if (!port)
1015        return OMX_ErrorBadParameter;
1016
1017    ret = port->PushThisBuffer(pBuffer);
1018    if (ret == OMX_ErrorNone)
1019        bufferwork->ScheduleWork(this);
1020
1021    return ret;
1022}
1023
1024OMX_ERRORTYPE ComponentBase::SetCallbacks(
1025    OMX_IN  OMX_HANDLETYPE hComponent,
1026    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
1027    OMX_IN  OMX_PTR pAppData)
1028{
1029    ComponentBase *cbase;
1030
1031    if (!hComponent)
1032        return OMX_ErrorBadParameter;
1033
1034    cbase = static_cast<ComponentBase *>
1035        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1036    if (!cbase)
1037        return OMX_ErrorBadParameter;
1038
1039    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
1040}
1041
1042OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
1043    OMX_IN  OMX_HANDLETYPE hComponent,
1044    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
1045    OMX_IN  OMX_PTR pAppData)
1046{
1047    if (hComponent != handle)
1048        return OMX_ErrorBadParameter;
1049
1050    appdata = pAppData;
1051    callbacks = pCallbacks;
1052
1053    return OMX_ErrorNone;
1054}
1055
1056OMX_ERRORTYPE ComponentBase::ComponentDeInit(
1057    OMX_IN  OMX_HANDLETYPE hComponent)
1058{
1059    ComponentBase *cbase;
1060
1061    if (!hComponent)
1062        return OMX_ErrorBadParameter;
1063
1064    cbase = static_cast<ComponentBase *>
1065        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1066    if (!cbase)
1067        return OMX_ErrorBadParameter;
1068
1069    return cbase->CBaseComponentDeInit(hComponent);
1070}
1071
1072OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit(
1073    OMX_IN  OMX_HANDLETYPE hComponent)
1074{
1075    /*
1076     * Todo
1077     */
1078
1079    return OMX_ErrorNotImplemented;
1080}
1081
1082OMX_ERRORTYPE ComponentBase::UseEGLImage(
1083    OMX_IN OMX_HANDLETYPE hComponent,
1084    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1085    OMX_IN OMX_U32 nPortIndex,
1086    OMX_IN OMX_PTR pAppPrivate,
1087    OMX_IN void* eglImage)
1088{
1089    ComponentBase *cbase;
1090
1091    if (!hComponent)
1092        return OMX_ErrorBadParameter;
1093
1094    cbase = static_cast<ComponentBase *>
1095        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1096    if (!cbase)
1097        return OMX_ErrorBadParameter;
1098
1099    return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex,
1100                                   pAppPrivate, eglImage);
1101}
1102
1103OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage(
1104    OMX_IN OMX_HANDLETYPE hComponent,
1105    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1106    OMX_IN OMX_U32 nPortIndex,
1107    OMX_IN OMX_PTR pAppPrivate,
1108    OMX_IN void* eglImage)
1109{
1110    /*
1111     * Todo
1112     */
1113
1114    return OMX_ErrorNotImplemented;
1115}
1116
1117OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1118    OMX_IN OMX_HANDLETYPE hComponent,
1119    OMX_OUT OMX_U8 *cRole,
1120    OMX_IN OMX_U32 nIndex)
1121{
1122    ComponentBase *cbase;
1123
1124    if (!hComponent)
1125        return OMX_ErrorBadParameter;
1126
1127    cbase = static_cast<ComponentBase *>
1128        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1129    if (!cbase)
1130        return OMX_ErrorBadParameter;
1131
1132    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1133}
1134
1135OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1136    OMX_IN OMX_HANDLETYPE hComponent,
1137    OMX_OUT OMX_U8 *cRole,
1138    OMX_IN OMX_U32 nIndex)
1139{
1140    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1141        return OMX_ErrorBadParameter;
1142
1143    if (nIndex > nr_roles)
1144        return OMX_ErrorBadParameter;
1145
1146    strncpy((char *)cRole, (const char *)roles[nIndex],
1147            OMX_MAX_STRINGNAME_SIZE);
1148    return OMX_ErrorNone;
1149}
1150
1151/* implement CmdHandlerInterface */
1152void ComponentBase::CmdHandler(struct cmd_s *cmd)
1153{
1154    switch (cmd->cmd) {
1155    case OMX_CommandStateSet: {
1156        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1157
1158        TransState(transition);
1159        break;
1160    }
1161    case OMX_CommandFlush:
1162        /*
1163         * Todo
1164         */
1165        break;
1166    case OMX_CommandPortDisable:
1167        /*
1168         * Todo
1169         */
1170        break;
1171    case OMX_CommandPortEnable:
1172        /*
1173         * Todo
1174         */
1175        break;
1176    case OMX_CommandMarkBuffer:
1177        /*
1178         * Todo
1179         */
1180        break;
1181    } /* switch */
1182}
1183
1184/*
1185 * SendCommand:OMX_CommandStateSet
1186 * called in CmdHandler or called in other parts of component for reporting
1187 * internal error (OMX_StateInvalid).
1188 */
1189/*
1190 * Todo
1191 *   Resource Management (OMX_StateWaitForResources)
1192 *   for now, we never notify OMX_ErrorInsufficientResources,
1193 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1194 */
1195static const char *state_name[OMX_StateWaitForResources + 1] = {
1196    "OMX_StateInvalid",
1197    "OMX_StateLoaded",
1198    "OMX_StateIdle",
1199    "OMX_StateExecuting",
1200    "OMX_StatePause",
1201    "OMX_StateWaitForResources",
1202};
1203
1204static inline const char *GetStateName(OMX_STATETYPE state)
1205{
1206    if (state > OMX_StateWaitForResources)
1207        return "UnKnown";
1208
1209    return state_name[state];
1210}
1211
1212void ComponentBase::TransState(OMX_STATETYPE transition)
1213{
1214    OMX_STATETYPE current = this->state;
1215    OMX_EVENTTYPE event;
1216    OMX_U32 data1;
1217    OMX_ERRORTYPE ret;
1218
1219    LOGD("current state = %s, transition state = %s\n",
1220         GetStateName(current), GetStateName(transition));
1221
1222    /* same state */
1223    if (current == transition) {
1224        ret = OMX_ErrorSameState;
1225        goto notify_event;
1226    }
1227
1228    /* invalid state */
1229    if (current == OMX_StateInvalid) {
1230        ret = OMX_ErrorInvalidState;
1231        goto notify_event;
1232    }
1233
1234    if (transition == OMX_StateLoaded)
1235        ret = TransStateToLoaded(current);
1236    else if (transition == OMX_StateIdle)
1237        ret = TransStateToIdle(current);
1238    else if (transition == OMX_StateExecuting)
1239        ret = TransStateToExecuting(current);
1240    else if (transition == OMX_StatePause)
1241        ret = TransStateToPause(current);
1242    else if (transition == OMX_StateInvalid)
1243        ret = TransStateToInvalid(current);
1244    else if (transition == OMX_StateWaitForResources)
1245        ret = TransStateToWaitForResources(current);
1246    else
1247        ret = OMX_ErrorIncorrectStateTransition;
1248
1249notify_event:
1250    if (ret == OMX_ErrorNone) {
1251        event = OMX_EventCmdComplete;
1252        data1 = transition;
1253
1254        state = transition;
1255        LOGD("transition from %s to %s completed\n",
1256             GetStateName(current), GetStateName(transition));
1257    }
1258    else {
1259        event = OMX_EventError;
1260        data1 = ret;
1261
1262        if (transition == OMX_StateInvalid) {
1263            state = transition;
1264            LOGD("transition from %s to %s completed\n",
1265                 GetStateName(current), GetStateName(transition));
1266        }
1267    }
1268
1269    callbacks->EventHandler(handle, appdata, event, data1, 0, NULL);
1270
1271    /* WaitForResources workaround */
1272    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1273        callbacks->EventHandler(handle, appdata,
1274                                OMX_EventResourcesAcquired, 0, 0, NULL);
1275}
1276
1277inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1278{
1279    OMX_ERRORTYPE ret;
1280
1281    if (current == OMX_StateIdle) {
1282        /*
1283         * Todo
1284         *   1. waits for completion of deallocation on each port
1285         *      wokeup by FreeBuffer()
1286         *   2. deinitialize buffer process work
1287         *   3. deinitialize component's internal processor
1288         *      (ex. deinitialize sw/hw codec)
1289         */
1290        OMX_U32 i;
1291
1292        for (i = 0; i < nr_ports; i++)
1293            ports[i]->WaitPortBufferCompletion();
1294
1295        ret = OMX_ErrorNone;
1296    }
1297    else if (current == OMX_StateWaitForResources) {
1298        LOGE("state transition's requested from WaitForResources to "
1299             "Loaded\n");
1300
1301        /*
1302         * from WaitForResources to Loaded considered from Loaded to Loaded.
1303         * do nothing
1304         */
1305
1306        ret = OMX_ErrorNone;
1307    }
1308    else
1309        ret = OMX_ErrorIncorrectStateOperation;
1310
1311    return ret;
1312}
1313
1314inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1315{
1316    OMX_ERRORTYPE ret;
1317
1318    if (current == OMX_StateLoaded) {
1319        /*
1320         * Todo
1321         *   1. waits for completion of allocation on each port.
1322         *      wokeup by Allocate/UseBuffer()
1323         *   2. initialize buffer process work.
1324         *   3. initialize component's internal processor.
1325         *      (ex. initialize sw/hw codec)
1326         */
1327        OMX_U32 i;
1328
1329        ret = ApplyWorkingRole();
1330        if (ret != OMX_ErrorNone)
1331            return ret;
1332
1333        for (i = 0; i < nr_ports; i++)
1334            ports[i]->WaitPortBufferCompletion();
1335
1336        ret = OMX_ErrorNone;
1337    }
1338    else if (current == OMX_StateExecuting) {
1339        /*
1340         * Todo
1341         *   1. returns all buffers to thier suppliers.         !
1342         *      call Fill/EmptyBufferDone() for all ports
1343         *   2. stop buffer process work                        !
1344         *   3. stop component's internal processor
1345         */
1346        OMX_U32 i;
1347
1348        pthread_mutex_lock(&ports_block);
1349        for (i = 0; i < nr_ports; i++) {
1350            ports[i]->FlushPort();
1351        }
1352        pthread_mutex_unlock(&ports_block);
1353
1354        bufferwork->StopWork();
1355
1356        ret = OMX_ErrorNone;
1357    }
1358    else if (current == OMX_StatePause) {
1359        /*
1360         * Todo
1361         *   1. returns all buffers to thier suppliers.         !
1362         *      call Fill/EmptyBufferDone() for all ports
1363         *   2. discard queued work, stop buffer process work   !
1364         *   3. stop component's internal processor
1365         */
1366        OMX_U32 i;
1367
1368        pthread_mutex_lock(&ports_block);
1369        for (i = 0; i < nr_ports; i++) {
1370            ports[i]->FlushPort();
1371        }
1372        pthread_mutex_unlock(&ports_block);
1373
1374        bufferwork->CancelScheduledWork(this);
1375        bufferwork->StopWork();
1376
1377        ret = OMX_ErrorNone;
1378    }
1379    else if (current == OMX_StateWaitForResources) {
1380        LOGE("state transition's requested from WaitForResources to Idle\n");
1381
1382        /* same as Loaded to Idle BUT DO NOTHING for now */
1383
1384        ret = OMX_ErrorNone;
1385    }
1386    else
1387        ret = OMX_ErrorIncorrectStateOperation;
1388
1389    return ret;
1390}
1391
1392inline OMX_ERRORTYPE
1393ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1394{
1395    OMX_ERRORTYPE ret;
1396
1397    if (current == OMX_StateIdle) {
1398        /*
1399         * Todo
1400         *   1. start component's internal processor
1401         *   2. start processing buffers on each port   !
1402         */
1403
1404        pthread_mutex_lock(&executing_lock);
1405        executing = true;
1406        pthread_mutex_unlock(&executing_lock);
1407
1408        bufferwork->StartWork();
1409        ret = OMX_ErrorNone;
1410    }
1411    else if (current == OMX_StatePause) {
1412        /*
1413         * Todo
1414         *   1. resume component's internal processor
1415         *   2. resume buffer process work              !
1416         */
1417
1418        pthread_mutex_lock(&executing_lock);
1419        executing = true;
1420        pthread_cond_signal(&executing_wait);
1421        pthread_mutex_unlock(&executing_lock);
1422
1423        ret = OMX_ErrorNone;
1424    }
1425    else
1426        ret = OMX_ErrorIncorrectStateOperation;
1427
1428    return ret;
1429}
1430
1431inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1432{
1433    OMX_ERRORTYPE ret;
1434
1435    if (current == OMX_StateIdle) {
1436        /*
1437         * Todo
1438         *   1. start(paused) component's internal processor
1439         *   2. start(paused) processing buffers on each port   !
1440         */
1441
1442        /* turn off executing flag */
1443        pthread_mutex_lock(&executing_lock);
1444        executing = false;
1445        pthread_mutex_unlock(&executing_lock);
1446
1447        bufferwork->StartWork();
1448
1449        ret = OMX_ErrorNone;
1450    }
1451    else if (current == OMX_StateExecuting) {
1452        /*
1453         * Todo
1454         *   1. pause buffer process work               !
1455         *   2. pause component's internal processor
1456         */
1457
1458        pthread_mutex_lock(&executing_lock);
1459        executing = false;
1460        pthread_mutex_unlock(&executing_lock);
1461
1462        ret = OMX_ErrorNone;
1463    }
1464    else
1465        ret = OMX_ErrorIncorrectStateOperation;
1466
1467    return ret;
1468}
1469
1470inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1471{
1472    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1473
1474    /*
1475     * Todo
1476     *   graceful escape
1477     */
1478
1479    return ret;
1480}
1481
1482inline OMX_ERRORTYPE
1483ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1484{
1485    OMX_ERRORTYPE ret;
1486
1487    if (current == OMX_StateLoaded) {
1488        LOGE("state transition's requested from Loaded to WaitForResources\n");
1489        ret = OMX_ErrorNone;
1490    }
1491    else
1492        ret = OMX_ErrorIncorrectStateOperation;
1493
1494    return ret;
1495}
1496
1497/* set working role */
1498OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role)
1499{
1500    OMX_U32 i;
1501
1502    if (!role) {
1503        working_role = NULL;
1504        return OMX_ErrorNone;
1505    }
1506
1507    for (i = 0; i < nr_roles; i++) {
1508        if (!strcmp((char *)&roles[i][0], role)) {
1509            working_role = (OMX_STRING)&roles[i][0];
1510            return OMX_ErrorNone;
1511        }
1512    }
1513
1514    LOGE("cannot find %s role in %s\n", role, name);
1515    return OMX_ErrorBadParameter;
1516}
1517
1518/* apply a working role for a component having multiple roles */
1519OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void)
1520{
1521    OMX_ERRORTYPE ret;
1522
1523    if (!working_role)
1524        return OMX_ErrorBadParameter;
1525
1526    ret = AllocatePorts();
1527    if (ret != OMX_ErrorNone) {
1528        LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret);
1529        return ret;
1530    }
1531
1532    return OMX_ErrorNone;
1533}
1534
1535OMX_ERRORTYPE ComponentBase::AllocatePorts(void)
1536{
1537    OMX_ERRORTYPE ret;
1538    OMX_U32 i;
1539
1540    if (ports)
1541        return OMX_ErrorBadParameter;
1542
1543    if (!callbacks || !appdata)
1544        return OMX_ErrorBadParameter;
1545
1546    ret = ComponentAllocatePorts();
1547    if (ret != OMX_ErrorNone) {
1548        LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n",
1549             name, ret);
1550        return ret;
1551    }
1552
1553    /* now we can access ports */
1554    for (i = 0; i < nr_ports; i++) {
1555        ports[i]->SetOwner(handle);
1556        ports[i]->SetCallbacks(handle, callbacks, appdata);
1557    }
1558
1559    return OMX_ErrorNone;
1560}
1561
1562/* called int FreeHandle() */
1563OMX_ERRORTYPE ComponentBase::FreePorts(void)
1564{
1565    if (ports) {
1566        OMX_U32 i, this_nr_ports = this->nr_ports;
1567
1568        for (i = 0; i < this_nr_ports; i++) {
1569            if (ports[i]) {
1570                delete ports[i];
1571                ports[i] = NULL;
1572            }
1573        }
1574        delete []ports;
1575        ports = NULL;
1576    }
1577
1578    return OMX_ErrorNone;
1579}
1580
1581/* buffer processing */
1582/* implement WorkableInterface */
1583void ComponentBase::Work(void)
1584{
1585    OMX_BUFFERHEADERTYPE **buffers = NULL;
1586    OMX_U32 i;
1587    bool avail = false;
1588
1589    pthread_mutex_lock(&executing_lock);
1590    if (!executing)
1591        pthread_cond_wait(&executing_wait, &executing_lock);
1592    pthread_mutex_unlock(&executing_lock);
1593
1594    pthread_mutex_lock(&ports_block);
1595
1596    avail = IsAllBufferAvailable();
1597    if (avail) {
1598        buffers = (OMX_BUFFERHEADERTYPE **)
1599            calloc(nr_ports, sizeof(OMX_BUFFERHEADERTYPE *));
1600        if (!buffers) {
1601            bufferwork->ScheduleWork(this);
1602            return;
1603        }
1604
1605        for (i = 0; i < nr_ports; i++)
1606            buffers[i] = ports[i]->PopBuffer();
1607    }
1608    ScheduleIfAllBufferAvailable();
1609
1610    pthread_mutex_unlock(&ports_block);
1611
1612    if (buffers) {
1613        ComponentProcessBuffers(buffers, nr_ports);
1614
1615        free(buffers);
1616        buffers = NULL;
1617    }
1618}
1619
1620bool ComponentBase::IsAllBufferAvailable(void)
1621{
1622    OMX_U32 i;
1623    OMX_U32 nr_avail = 0;
1624
1625    for (i = 0; i < nr_ports; i++) {
1626        OMX_U32 length;
1627
1628        length = ports[i]->BufferQueueLength();
1629        if (length)
1630            nr_avail++;
1631    }
1632
1633    if (nr_avail == nr_ports)
1634        return true;
1635    else
1636        return false;
1637}
1638
1639void ComponentBase::ScheduleIfAllBufferAvailable(void)
1640{
1641    bool avail;
1642
1643    avail = IsAllBufferAvailable();
1644    if (avail)
1645        bufferwork->ScheduleWork(this);
1646}
1647
1648/* end of component methods & helpers */
1649
1650/*
1651 * omx header manipuation
1652 */
1653void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
1654{
1655    OMX_U32 *nsize;
1656    OMX_VERSIONTYPE *nversion;
1657
1658    if (!type)
1659        return;
1660
1661    nsize = (OMX_U32 *)type;
1662    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1663
1664    *nsize = size;
1665    nversion->nVersion = OMX_SPEC_VERSION;
1666}
1667
1668OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size)
1669{
1670    OMX_U32 *nsize;
1671    OMX_VERSIONTYPE *nversion;
1672
1673    if (!type)
1674        return OMX_ErrorBadParameter;
1675
1676    nsize = (OMX_U32 *)type;
1677    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1678
1679    if (*nsize != size)
1680        return OMX_ErrorBadParameter;
1681
1682    if (nversion->nVersion != OMX_SPEC_VERSION)
1683        return OMX_ErrorVersionMismatch;
1684
1685    return OMX_ErrorNone;
1686}
1687
1688/*
1689 * query_roles helper
1690 */
1691OMX_ERRORTYPE ComponentBase::QueryRolesHelper(
1692    OMX_U32 nr_comp_roles,
1693    const OMX_U8 **comp_roles,
1694    OMX_U32 *nr_roles, OMX_U8 **roles)
1695{
1696    OMX_U32 i;
1697
1698    if (!roles) {
1699        *nr_roles = nr_comp_roles;
1700        return OMX_ErrorNone;
1701    }
1702
1703    if (!nr_roles || (*nr_roles != nr_comp_roles) || !roles)
1704        return OMX_ErrorBadParameter;
1705
1706    for (i = 0; i < nr_comp_roles; i++) {
1707        if (!roles[i])
1708            break;
1709
1710        strncpy((OMX_STRING)&roles[i][0],
1711                (const OMX_STRING)&comp_roles[i][0], OMX_MAX_STRINGNAME_SIZE);
1712    }
1713
1714    if (i != nr_comp_roles)
1715        return OMX_ErrorBadParameter;
1716
1717    *nr_roles = nr_comp_roles;
1718    return OMX_ErrorNone;
1719}
1720
1721/* end of ComponentBase */
1722