componentbase.cpp revision 9a24011eec9b06ae84b9335c651999b9d5e25329
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    ports = NULL;
118    nr_ports = 0;
119    memset(&portparam, 0, sizeof(portparam));
120
121    state = OMX_StateUnloaded;
122
123    cmdwork = new CmdProcessWork(this);
124}
125
126ComponentBase::ComponentBase()
127{
128    __ComponentBase();
129}
130
131ComponentBase::ComponentBase(const OMX_STRING name)
132{
133    __ComponentBase();
134    SetName(name);
135}
136
137ComponentBase::~ComponentBase()
138{
139    delete cmdwork;
140
141    if (roles) {
142        OMX_U32 i;
143
144        for (i = 0; i < nr_roles; i++)
145            free(roles[i]);
146
147        free(roles);
148    }
149}
150
151/* end of constructor & destructor */
152
153/*
154 * accessor
155 */
156/* name */
157void ComponentBase::SetName(const OMX_STRING name)
158{
159    strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
160    this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
161}
162
163const OMX_STRING ComponentBase::GetName(void)
164{
165    return name;
166}
167
168/* component module */
169void ComponentBase::SetCModule(CModule *cmodule)
170{
171    this->cmodule = cmodule;
172}
173
174CModule *ComponentBase::GetCModule(void)
175{
176    return cmodule;
177}
178
179/* end of accessor */
180
181/*
182 * core methods & helpers
183 */
184/* roles */
185OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles,
186                                                 const OMX_U8 **roles)
187{
188    OMX_U32 i;
189
190    this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
191    if (!this->roles)
192        return OMX_ErrorInsufficientResources;
193
194    for (i = 0; i < nr_roles; i++) {
195        this->roles[i] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE);
196        if (!this->roles[i]) {
197            int j;
198
199            for (j = (int )i-1; j >= 0; j--)
200                free(this->roles[j]);
201            free(this->roles);
202
203            return OMX_ErrorInsufficientResources;
204        }
205
206        strncpy((OMX_STRING)&this->roles[i][0],
207                (const OMX_STRING)&roles[i][0],
208                OMX_MAX_STRINGNAME_SIZE);
209    }
210
211    this->nr_roles = nr_roles;
212    return OMX_ErrorNone;
213}
214
215OMX_ERRORTYPE ComponentBase::GetRolesOfComponent(OMX_U32 *nr_roles,
216                                                 OMX_U8 **roles)
217{
218    OMX_U32 i;
219    OMX_U32 this_nr_roles = this->nr_roles;
220
221    if (!roles) {
222        *nr_roles = this_nr_roles;
223        return OMX_ErrorNone;
224    }
225
226    if (!nr_roles || (*nr_roles != this_nr_roles))
227        return OMX_ErrorBadParameter;
228
229    for (i = 0; i < this_nr_roles; i++) {
230        if (!roles[i])
231            break;
232
233        if (roles && roles[i])
234            strncpy((OMX_STRING)&roles[i][0],
235                    (const OMX_STRING)&this->roles[i][0],
236                    OMX_MAX_STRINGNAME_SIZE);
237    }
238
239    if (i != this_nr_roles)
240        return OMX_ErrorBadParameter;
241
242    *nr_roles = this_nr_roles;
243    return OMX_ErrorNone;
244}
245
246bool ComponentBase::QueryHavingThisRole(const OMX_STRING role)
247{
248    OMX_U32 i;
249
250    if (!roles || !role)
251        return false;
252
253    for (i = 0; i < nr_roles; i++) {
254        if (!strcmp((OMX_STRING)&roles[i][0], role))
255            return true;
256    }
257
258    return false;
259}
260
261/* GetHandle & FreeHandle */
262OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle,
263                                       OMX_PTR pAppData,
264                                       OMX_CALLBACKTYPE *pCallBacks)
265{
266    OMX_U32 i;
267    OMX_ERRORTYPE ret;
268
269    if (handle)
270        return OMX_ErrorUndefined;
271
272    handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle));
273    if (!handle)
274        return OMX_ErrorInsufficientResources;
275
276    /* handle initialization */
277    SetTypeHeader(handle, sizeof(*handle));
278    handle->pComponentPrivate = static_cast<OMX_PTR>(this);
279    handle->pApplicationPrivate = pAppData;
280
281    /* virtual - see derived class */
282    ret = InitComponent();
283    if (ret != OMX_ErrorNone) {
284        LOGE("failed to %s::InitComponent(), ret = 0x%08x\n",
285             name, ret);
286        goto free_handle;
287    }
288
289    for (i = 0; i < nr_ports; i++) {
290        ports[i]->SetOwner(handle);
291        ports[i]->SetCallbacks(handle, pCallBacks, pAppData);
292    }
293
294    /* connect handle's functions */
295    handle->GetComponentVersion = GetComponentVersion;
296    handle->SendCommand = SendCommand;
297    handle->GetParameter = GetParameter;
298    handle->SetParameter = SetParameter;
299    handle->GetConfig = GetConfig;
300    handle->SetConfig = SetConfig;
301    handle->GetExtensionIndex = GetExtensionIndex;
302    handle->GetState = GetState;
303    handle->ComponentTunnelRequest = ComponentTunnelRequest;
304    handle->UseBuffer = UseBuffer;
305    handle->AllocateBuffer = AllocateBuffer;
306    handle->FreeBuffer = FreeBuffer;
307    handle->EmptyThisBuffer = EmptyThisBuffer;
308    handle->FillThisBuffer = FillThisBuffer;
309    handle->SetCallbacks = SetCallbacks;
310    handle->ComponentDeInit = ComponentDeInit;
311    handle->UseEGLImage = UseEGLImage;
312    handle->ComponentRoleEnum = ComponentRoleEnum;
313
314    appdata = pAppData;
315    callbacks = pCallBacks;
316    *pHandle = (OMX_HANDLETYPE *)handle;
317
318    state = OMX_StateLoaded;
319    return OMX_ErrorNone;
320
321free_handle:
322    free(this->handle);
323    this->handle = NULL;
324
325    return ret;
326}
327
328OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent)
329{
330    OMX_ERRORTYPE ret;
331
332    if (hComponent != handle)
333        return OMX_ErrorBadParameter;
334
335    /* virtual - see derived class */
336    ret = ExitComponent();
337    if (ret != OMX_ErrorNone)
338        return ret;
339
340    free(handle);
341
342    appdata = NULL;
343    callbacks = NULL;
344
345    state = OMX_StateUnloaded;
346    return OMX_ErrorNone;
347}
348
349/* end of core methods & helpers */
350
351/*
352 * component methods & helpers
353 */
354OMX_ERRORTYPE ComponentBase::GetComponentVersion(
355    OMX_IN  OMX_HANDLETYPE hComponent,
356    OMX_OUT OMX_STRING pComponentName,
357    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
358    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
359    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
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->CBaseGetComponentVersion(hComponent,
372                                           pComponentName,
373                                           pComponentVersion,
374                                           pSpecVersion,
375                                           pComponentUUID);
376}
377
378OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion(
379    OMX_IN  OMX_HANDLETYPE hComponent,
380    OMX_OUT OMX_STRING pComponentName,
381    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
382    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
383    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
384{
385    /*
386     * Todo
387     */
388
389    return OMX_ErrorNotImplemented;
390}
391
392OMX_ERRORTYPE ComponentBase::SendCommand(
393    OMX_IN  OMX_HANDLETYPE hComponent,
394    OMX_IN  OMX_COMMANDTYPE Cmd,
395    OMX_IN  OMX_U32 nParam1,
396    OMX_IN  OMX_PTR pCmdData)
397{
398    ComponentBase *cbase;
399
400    if (!hComponent)
401        return OMX_ErrorBadParameter;
402
403    cbase = static_cast<ComponentBase *>
404        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
405    if (!cbase)
406        return OMX_ErrorBadParameter;
407
408    return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData);
409}
410
411OMX_ERRORTYPE ComponentBase::CBaseSendCommand(
412    OMX_IN  OMX_HANDLETYPE hComponent,
413    OMX_IN  OMX_COMMANDTYPE Cmd,
414    OMX_IN  OMX_U32 nParam1,
415    OMX_IN  OMX_PTR pCmdData)
416{
417    struct cmd_s *cmd;
418
419    if (hComponent != handle)
420        return OMX_ErrorInvalidComponent;
421
422    /* basic error check */
423    switch (Cmd) {
424    case OMX_CommandStateSet:
425        /*
426         * Todo
427         */
428        break;
429    case OMX_CommandFlush:
430        /*
431         * Todo
432         */
433        //break;
434    case OMX_CommandPortDisable:
435        /*
436         * Todo
437         */
438        //break;
439    case OMX_CommandPortEnable:
440        /*
441         * Todo
442         */
443        //break;
444    case OMX_CommandMarkBuffer:
445        /*
446         * Todo
447         */
448        //break;
449    default:
450        LOGE("command %d not supported\n", Cmd);
451        return OMX_ErrorUnsupportedIndex;
452    }
453
454    cmd = (struct cmd_s *)malloc(sizeof(*cmd));
455    if (!cmd)
456        return OMX_ErrorInsufficientResources;
457
458    cmd->cmd = Cmd;
459    cmd->param1 = nParam1;
460    cmd->cmddata = pCmdData;
461
462    return cmdwork->PushCmdQueue(cmd);
463}
464
465OMX_ERRORTYPE ComponentBase::GetParameter(
466    OMX_IN  OMX_HANDLETYPE hComponent,
467    OMX_IN  OMX_INDEXTYPE nParamIndex,
468    OMX_INOUT OMX_PTR pComponentParameterStructure)
469{
470    ComponentBase *cbase;
471
472    if (!hComponent)
473        return OMX_ErrorBadParameter;
474
475    cbase = static_cast<ComponentBase *>
476        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
477    if (!cbase)
478        return OMX_ErrorBadParameter;
479
480    return cbase->CBaseGetParameter(hComponent, nParamIndex,
481                                    pComponentParameterStructure);
482}
483
484OMX_ERRORTYPE ComponentBase::CBaseGetParameter(
485    OMX_IN  OMX_HANDLETYPE hComponent,
486    OMX_IN  OMX_INDEXTYPE nParamIndex,
487    OMX_INOUT OMX_PTR pComponentParameterStructure)
488{
489    OMX_ERRORTYPE ret = OMX_ErrorNone;
490
491    if (hComponent != handle)
492        return OMX_ErrorBadParameter;
493
494    switch (nParamIndex) {
495    case OMX_IndexParamAudioInit:
496    case OMX_IndexParamVideoInit:
497    case OMX_IndexParamImageInit:
498    case OMX_IndexParamOtherInit: {
499        OMX_PORT_PARAM_TYPE *p =
500            (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
501
502        memcpy(p, &portparam, sizeof(*p));
503        break;
504    }
505    case OMX_IndexParamPortDefinition: {
506        OMX_PARAM_PORTDEFINITIONTYPE *p =
507            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
508        OMX_U32 index = p->nPortIndex;
509        PortBase *port = ports[index];
510
511        memcpy(p, port->GetPortParam(), sizeof(*p));
512        break;
513    }
514    case OMX_IndexParamAudioPortFormat: {
515        OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
516            (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
517        OMX_U32 index = p->nPortIndex;
518        PortBase *port = ports[index];
519
520        memcpy(p, port->GetAudioPortParam(), sizeof(*p));
521        break;
522    }
523    case OMX_IndexParamCompBufferSupplier:
524        /*
525         * Todo
526         */
527
528        ret = OMX_ErrorUnsupportedIndex;
529        break;
530    default:
531        ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure);
532    } /* switch */
533
534    return ret;
535}
536
537OMX_ERRORTYPE ComponentBase::SetParameter(
538    OMX_IN  OMX_HANDLETYPE hComponent,
539    OMX_IN  OMX_INDEXTYPE nIndex,
540    OMX_IN  OMX_PTR pComponentParameterStructure)
541{
542    ComponentBase *cbase;
543
544    if (!hComponent)
545        return OMX_ErrorBadParameter;
546
547    cbase = static_cast<ComponentBase *>
548        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
549    if (!cbase)
550        return OMX_ErrorBadParameter;
551
552    return cbase->CBaseSetParameter(hComponent, nIndex,
553                                    pComponentParameterStructure);
554}
555
556OMX_ERRORTYPE ComponentBase::CBaseSetParameter(
557    OMX_IN  OMX_HANDLETYPE hComponent,
558    OMX_IN  OMX_INDEXTYPE nIndex,
559    OMX_IN  OMX_PTR pComponentParameterStructure)
560{
561    OMX_ERRORTYPE ret = OMX_ErrorNone;
562
563    if (hComponent != handle)
564        return OMX_ErrorBadParameter;
565
566    switch (nIndex) {
567    case OMX_IndexParamAudioInit:
568    case OMX_IndexParamVideoInit:
569    case OMX_IndexParamImageInit:
570    case OMX_IndexParamOtherInit: {
571        OMX_PORT_PARAM_TYPE *p = (OMX_PORT_PARAM_TYPE *)
572            pComponentParameterStructure;
573
574        memcpy(&portparam, p, sizeof(*p));
575        break;
576    }
577    case OMX_IndexParamPortDefinition: {
578        OMX_PARAM_PORTDEFINITIONTYPE *p =
579            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
580        OMX_U32 index = p->nPortIndex;
581        PortBase *port = ports[index];
582
583        port->SetPortParam(p);
584        break;
585    }
586    case OMX_IndexParamAudioPortFormat: {
587        OMX_AUDIO_PARAM_PORTFORMATTYPE *p =
588            (OMX_AUDIO_PARAM_PORTFORMATTYPE *)pComponentParameterStructure;
589        OMX_U32 index = p->nPortIndex;
590        PortBase *port = ports[index];
591
592        port->SetAudioPortParam(p);
593        break;
594    }
595    case OMX_IndexParamCompBufferSupplier:
596        /*
597         * Todo
598         */
599
600        ret = OMX_ErrorUnsupportedIndex;
601        break;
602    default:
603        ret = ComponentSetParameter(nIndex, pComponentParameterStructure);
604    } /* switch */
605
606    return ret;
607}
608
609OMX_ERRORTYPE ComponentBase::GetConfig(
610    OMX_IN  OMX_HANDLETYPE hComponent,
611    OMX_IN  OMX_INDEXTYPE nIndex,
612    OMX_INOUT OMX_PTR pComponentConfigStructure)
613{
614    ComponentBase *cbase;
615
616    if (!hComponent)
617        return OMX_ErrorBadParameter;
618
619    cbase = static_cast<ComponentBase *>
620        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
621    if (!cbase)
622        return OMX_ErrorBadParameter;
623
624    return cbase->CBaseGetConfig(hComponent, nIndex,
625                                 pComponentConfigStructure);
626}
627
628OMX_ERRORTYPE ComponentBase::CBaseGetConfig(
629    OMX_IN  OMX_HANDLETYPE hComponent,
630    OMX_IN  OMX_INDEXTYPE nIndex,
631    OMX_INOUT OMX_PTR pComponentConfigStructure)
632{
633    OMX_ERRORTYPE ret;
634
635    if (hComponent != handle)
636        return OMX_ErrorBadParameter;
637
638    switch (nIndex) {
639    default:
640        ret = ComponentGetConfig(nIndex, pComponentConfigStructure);
641    }
642
643    return ret;
644}
645
646OMX_ERRORTYPE ComponentBase::SetConfig(
647    OMX_IN  OMX_HANDLETYPE hComponent,
648    OMX_IN  OMX_INDEXTYPE nIndex,
649    OMX_IN  OMX_PTR pComponentConfigStructure)
650{
651    ComponentBase *cbase;
652
653    if (!hComponent)
654        return OMX_ErrorBadParameter;
655
656    cbase = static_cast<ComponentBase *>
657        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
658    if (!cbase)
659        return OMX_ErrorBadParameter;
660
661    return cbase->CBaseSetConfig(hComponent, nIndex,
662                                 pComponentConfigStructure);
663}
664
665OMX_ERRORTYPE ComponentBase::CBaseSetConfig(
666    OMX_IN  OMX_HANDLETYPE hComponent,
667    OMX_IN  OMX_INDEXTYPE nIndex,
668    OMX_IN  OMX_PTR pComponentConfigStructure)
669{
670    OMX_ERRORTYPE ret;
671
672    if (hComponent != handle)
673        return OMX_ErrorBadParameter;
674
675    switch (nIndex) {
676    default:
677        ret = ComponentSetConfig(nIndex, pComponentConfigStructure);
678    }
679
680    return ret;
681}
682
683OMX_ERRORTYPE ComponentBase::GetExtensionIndex(
684    OMX_IN  OMX_HANDLETYPE hComponent,
685    OMX_IN  OMX_STRING cParameterName,
686    OMX_OUT OMX_INDEXTYPE* pIndexType)
687{
688    ComponentBase *cbase;
689
690    if (!hComponent)
691        return OMX_ErrorBadParameter;
692
693    cbase = static_cast<ComponentBase *>
694        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
695    if (!cbase)
696        return OMX_ErrorBadParameter;
697
698    return cbase->CBaseGetExtensionIndex(hComponent, cParameterName,
699                                         pIndexType);
700}
701
702OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex(
703    OMX_IN  OMX_HANDLETYPE hComponent,
704    OMX_IN  OMX_STRING cParameterName,
705    OMX_OUT OMX_INDEXTYPE* pIndexType)
706{
707    /*
708     * Todo
709     */
710
711    return OMX_ErrorNotImplemented;
712}
713
714OMX_ERRORTYPE ComponentBase::GetState(
715    OMX_IN  OMX_HANDLETYPE hComponent,
716    OMX_OUT OMX_STATETYPE* pState)
717{
718    ComponentBase *cbase;
719
720    if (!hComponent)
721        return OMX_ErrorBadParameter;
722
723    cbase = static_cast<ComponentBase *>
724        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
725    if (!cbase)
726        return OMX_ErrorBadParameter;
727
728    return cbase->CBaseGetState(hComponent, pState);
729}
730
731OMX_ERRORTYPE ComponentBase::CBaseGetState(
732    OMX_IN  OMX_HANDLETYPE hComponent,
733    OMX_OUT OMX_STATETYPE* pState)
734{
735    if (hComponent != handle)
736        return OMX_ErrorBadParameter;
737
738    *pState = state;
739    return OMX_ErrorNone;
740}
741
742OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest(
743    OMX_IN  OMX_HANDLETYPE hComponent,
744    OMX_IN  OMX_U32 nPort,
745    OMX_IN  OMX_HANDLETYPE hTunneledComponent,
746    OMX_IN  OMX_U32 nTunneledPort,
747    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
748{
749    ComponentBase *cbase;
750
751    if (!hComponent)
752        return OMX_ErrorBadParameter;
753
754    cbase = static_cast<ComponentBase *>
755        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
756    if (!cbase)
757        return OMX_ErrorBadParameter;
758
759    return cbase->CBaseComponentTunnelRequest(hComponent, nPort,
760                                              hTunneledComponent,
761                                              nTunneledPort, pTunnelSetup);
762}
763
764OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest(
765    OMX_IN  OMX_HANDLETYPE hComp,
766    OMX_IN  OMX_U32 nPort,
767    OMX_IN  OMX_HANDLETYPE hTunneledComp,
768    OMX_IN  OMX_U32 nTunneledPort,
769    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
770{
771    /*
772     * Todo
773     */
774
775    return OMX_ErrorNotImplemented;
776}
777
778OMX_ERRORTYPE ComponentBase::UseBuffer(
779    OMX_IN OMX_HANDLETYPE hComponent,
780    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
781    OMX_IN OMX_U32 nPortIndex,
782    OMX_IN OMX_PTR pAppPrivate,
783    OMX_IN OMX_U32 nSizeBytes,
784    OMX_IN OMX_U8 *pBuffer)
785{
786    ComponentBase *cbase;
787
788    if (!hComponent)
789        return OMX_ErrorBadParameter;
790
791    cbase = static_cast<ComponentBase *>
792        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
793    if (!cbase)
794        return OMX_ErrorBadParameter;
795
796    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
797                                 pAppPrivate, nSizeBytes, pBuffer);
798}
799
800OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
801    OMX_IN OMX_HANDLETYPE hComponent,
802    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
803    OMX_IN OMX_U32 nPortIndex,
804    OMX_IN OMX_PTR pAppPrivate,
805    OMX_IN OMX_U32 nSizeBytes,
806    OMX_IN OMX_U8 *pBuffer)
807{
808    PortBase *port = NULL;
809    OMX_ERRORTYPE ret;
810
811    if (hComponent != handle)
812        return OMX_ErrorBadParameter;
813
814    if (ports)
815        if (nPortIndex < nr_ports)
816            port = ports[nPortIndex];
817
818    if (!port)
819        return OMX_ErrorBadParameter;
820
821    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
822                           pBuffer);
823}
824
825OMX_ERRORTYPE ComponentBase::AllocateBuffer(
826    OMX_IN OMX_HANDLETYPE hComponent,
827    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
828    OMX_IN OMX_U32 nPortIndex,
829    OMX_IN OMX_PTR pAppPrivate,
830    OMX_IN OMX_U32 nSizeBytes)
831{
832    ComponentBase *cbase;
833
834    if (!hComponent)
835        return OMX_ErrorBadParameter;
836
837    cbase = static_cast<ComponentBase *>
838        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
839    if (!cbase)
840        return OMX_ErrorBadParameter;
841
842    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
843                                      pAppPrivate, nSizeBytes);
844}
845
846OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
847    OMX_IN OMX_HANDLETYPE hComponent,
848    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
849    OMX_IN OMX_U32 nPortIndex,
850    OMX_IN OMX_PTR pAppPrivate,
851    OMX_IN OMX_U32 nSizeBytes)
852{
853    PortBase *port = NULL;
854    OMX_ERRORTYPE ret;
855
856    if (hComponent != handle)
857        return OMX_ErrorBadParameter;
858
859    if (ports)
860        if (nPortIndex < nr_ports)
861            port = ports[nPortIndex];
862
863    if (!port)
864        return OMX_ErrorBadParameter;
865
866    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
867}
868
869OMX_ERRORTYPE ComponentBase::FreeBuffer(
870    OMX_IN  OMX_HANDLETYPE hComponent,
871    OMX_IN  OMX_U32 nPortIndex,
872    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
873{
874    ComponentBase *cbase;
875
876    if (!hComponent)
877        return OMX_ErrorBadParameter;
878
879    cbase = static_cast<ComponentBase *>
880        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
881    if (!cbase)
882        return OMX_ErrorBadParameter;
883
884    return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
885}
886
887OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
888    OMX_IN  OMX_HANDLETYPE hComponent,
889    OMX_IN  OMX_U32 nPortIndex,
890    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
891{
892    PortBase *port = NULL;
893    OMX_ERRORTYPE ret;
894
895    if (hComponent != handle)
896        return OMX_ErrorBadParameter;
897
898    if (ports)
899        if (nPortIndex < nr_ports)
900            port = ports[nPortIndex];
901
902    if (!port)
903        return OMX_ErrorBadParameter;
904
905    return port->FreeBuffer(nPortIndex, pBuffer);
906}
907
908OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
909    OMX_IN  OMX_HANDLETYPE hComponent,
910    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
911{
912    ComponentBase *cbase;
913
914    if (!hComponent)
915        return OMX_ErrorBadParameter;
916
917    cbase = static_cast<ComponentBase *>
918        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
919    if (!cbase)
920        return OMX_ErrorBadParameter;
921
922    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
923}
924
925OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
926    OMX_IN  OMX_HANDLETYPE hComponent,
927    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
928{
929    PortBase *port = NULL;
930    OMX_U32 port_index;
931    OMX_ERRORTYPE ret;
932
933    if ((hComponent != handle) || !pBuffer)
934        return OMX_ErrorBadParameter;
935
936    port_index = pBuffer->nInputPortIndex;
937    if (port_index == (OMX_U32)-1)
938        return OMX_ErrorBadParameter;
939
940    if (ports)
941        if (port_index < nr_ports)
942            port = ports[port_index];
943
944    if (!port)
945        return OMX_ErrorBadParameter;
946
947    return port->PushThisBuffer(pBuffer);
948}
949
950OMX_ERRORTYPE ComponentBase::FillThisBuffer(
951    OMX_IN  OMX_HANDLETYPE hComponent,
952    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
953{
954    ComponentBase *cbase;
955
956    if (!hComponent)
957        return OMX_ErrorBadParameter;
958
959    cbase = static_cast<ComponentBase *>
960        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
961    if (!cbase)
962        return OMX_ErrorBadParameter;
963
964    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
965}
966
967OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
968    OMX_IN  OMX_HANDLETYPE hComponent,
969    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
970{
971    PortBase *port = NULL;
972    OMX_U32 port_index;
973    OMX_ERRORTYPE ret;
974
975    if ((hComponent != handle) || !pBuffer)
976        return OMX_ErrorBadParameter;
977
978    port_index = pBuffer->nOutputPortIndex;
979    if (port_index == (OMX_U32)-1)
980        return OMX_ErrorBadParameter;
981
982    if (ports)
983        if (port_index < nr_ports)
984            port = ports[port_index];
985
986    if (!port)
987        return OMX_ErrorBadParameter;
988
989    return port->PushThisBuffer(pBuffer);
990}
991
992OMX_ERRORTYPE ComponentBase::SetCallbacks(
993    OMX_IN  OMX_HANDLETYPE hComponent,
994    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
995    OMX_IN  OMX_PTR pAppData)
996{
997    ComponentBase *cbase;
998
999    if (!hComponent)
1000        return OMX_ErrorBadParameter;
1001
1002    cbase = static_cast<ComponentBase *>
1003        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1004    if (!cbase)
1005        return OMX_ErrorBadParameter;
1006
1007    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
1008}
1009
1010OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
1011    OMX_IN  OMX_HANDLETYPE hComponent,
1012    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
1013    OMX_IN  OMX_PTR pAppData)
1014{
1015    if (hComponent != handle)
1016        return OMX_ErrorBadParameter;
1017
1018    appdata = pAppData;
1019    callbacks = pCallbacks;
1020
1021    return OMX_ErrorNone;
1022}
1023
1024OMX_ERRORTYPE ComponentBase::ComponentDeInit(
1025    OMX_IN  OMX_HANDLETYPE hComponent)
1026{
1027    ComponentBase *cbase;
1028
1029    if (!hComponent)
1030        return OMX_ErrorBadParameter;
1031
1032    cbase = static_cast<ComponentBase *>
1033        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1034    if (!cbase)
1035        return OMX_ErrorBadParameter;
1036
1037    return cbase->CBaseComponentDeInit(hComponent);
1038}
1039
1040OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit(
1041    OMX_IN  OMX_HANDLETYPE hComponent)
1042{
1043    /*
1044     * Todo
1045     */
1046
1047    return OMX_ErrorNotImplemented;
1048}
1049
1050OMX_ERRORTYPE ComponentBase::UseEGLImage(
1051    OMX_IN OMX_HANDLETYPE hComponent,
1052    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1053    OMX_IN OMX_U32 nPortIndex,
1054    OMX_IN OMX_PTR pAppPrivate,
1055    OMX_IN void* eglImage)
1056{
1057    ComponentBase *cbase;
1058
1059    if (!hComponent)
1060        return OMX_ErrorBadParameter;
1061
1062    cbase = static_cast<ComponentBase *>
1063        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1064    if (!cbase)
1065        return OMX_ErrorBadParameter;
1066
1067    return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex,
1068                                   pAppPrivate, eglImage);
1069}
1070
1071OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage(
1072    OMX_IN OMX_HANDLETYPE hComponent,
1073    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1074    OMX_IN OMX_U32 nPortIndex,
1075    OMX_IN OMX_PTR pAppPrivate,
1076    OMX_IN void* eglImage)
1077{
1078    /*
1079     * Todo
1080     */
1081
1082    return OMX_ErrorNotImplemented;
1083}
1084
1085OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1086    OMX_IN OMX_HANDLETYPE hComponent,
1087    OMX_OUT OMX_U8 *cRole,
1088    OMX_IN OMX_U32 nIndex)
1089{
1090    ComponentBase *cbase;
1091
1092    if (!hComponent)
1093        return OMX_ErrorBadParameter;
1094
1095    cbase = static_cast<ComponentBase *>
1096        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1097    if (!cbase)
1098        return OMX_ErrorBadParameter;
1099
1100    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1101}
1102
1103OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1104    OMX_IN OMX_HANDLETYPE hComponent,
1105    OMX_OUT OMX_U8 *cRole,
1106    OMX_IN OMX_U32 nIndex)
1107{
1108    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1109        return OMX_ErrorBadParameter;
1110
1111    if (nIndex > nr_roles)
1112        return OMX_ErrorBadParameter;
1113
1114    strncpy((char *)cRole, (const char *)roles[nIndex],
1115            OMX_MAX_STRINGNAME_SIZE);
1116    return OMX_ErrorNone;
1117}
1118
1119/* implement CmdHandlerInterface */
1120void ComponentBase::CmdHandler(struct cmd_s *cmd)
1121{
1122    switch (cmd->cmd) {
1123    case OMX_CommandStateSet: {
1124        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1125
1126        TransState(transition);
1127        break;
1128    }
1129    case OMX_CommandFlush:
1130        /*
1131         * Todo
1132         */
1133        break;
1134    case OMX_CommandPortDisable:
1135        /*
1136         * Todo
1137         */
1138        break;
1139    case OMX_CommandPortEnable:
1140        /*
1141         * Todo
1142         */
1143        break;
1144    case OMX_CommandMarkBuffer:
1145        /*
1146         * Todo
1147         */
1148        break;
1149    } /* switch */
1150}
1151
1152/*
1153 * SendCommand:OMX_CommandStateSet
1154 * called in CmdHandler or called in other parts of component for reporting
1155 * internal error (OMX_StateInvalid).
1156 */
1157/*
1158 * Todo
1159 *   Resource Management (OMX_StateWaitForResources)
1160 *   for now, we never notify OMX_ErrorInsufficientResources,
1161 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1162 */
1163static const char *state_name[OMX_StateWaitForResources + 1] = {
1164    "OMX_StateInvalid",
1165    "OMX_StateLoaded",
1166    "OMX_StateIdle",
1167    "OMX_StateExecuting",
1168    "OMX_StatePause",
1169    "OMX_StateWaitForResources",
1170};
1171
1172static inline const char *GetStateName(OMX_STATETYPE state)
1173{
1174    if (state > OMX_StateWaitForResources)
1175        return "UnKnown";
1176
1177    return state_name[state];
1178}
1179
1180void ComponentBase::TransState(OMX_STATETYPE transition)
1181{
1182    OMX_STATETYPE current = this->state;
1183    OMX_EVENTTYPE event;
1184    OMX_U32 data1;
1185    OMX_ERRORTYPE ret;
1186
1187    LOGD("current state = %s, transition state = %s\n",
1188         GetStateName(current), GetStateName(transition));
1189
1190    /* same state */
1191    if (current == transition) {
1192        ret = OMX_ErrorSameState;
1193        goto notify_event;
1194    }
1195
1196    /* invalid state */
1197    if (current == OMX_StateInvalid) {
1198        ret = OMX_ErrorInvalidState;
1199        goto notify_event;
1200    }
1201
1202    if (transition == OMX_StateLoaded)
1203        ret = TransStateToLoaded(current);
1204    else if (transition == OMX_StateIdle)
1205        ret = TransStateToIdle(current);
1206    else if (transition == OMX_StateExecuting)
1207        ret = TransStateToExecuting(current);
1208    else if (transition == OMX_StatePause)
1209        ret = TransStateToPause(current);
1210    else if (transition == OMX_StateInvalid)
1211        ret = TransStateToInvalid(current);
1212    else if (transition == OMX_StateWaitForResources)
1213        ret = TransStateToWaitForResources(current);
1214    else
1215        ret = OMX_ErrorIncorrectStateTransition;
1216
1217notify_event:
1218    if (ret == OMX_ErrorNone) {
1219        event = OMX_EventCmdComplete;
1220        data1 = transition;
1221
1222        state = transition;
1223        LOGD("transition from %s to %s completed\n",
1224             GetStateName(current), GetStateName(transition));
1225    }
1226    else {
1227        event = OMX_EventError;
1228        data1 = ret;
1229
1230        if (transition == OMX_StateInvalid) {
1231            state = transition;
1232            LOGD("transition from %s to %s completed\n",
1233                 GetStateName(current), GetStateName(transition));
1234        }
1235    }
1236
1237    callbacks->EventHandler(handle, appdata, event, data1, 0, NULL);
1238
1239    /* WaitForResources workaround */
1240    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1241        callbacks->EventHandler(handle, appdata,
1242                                OMX_EventResourcesAcquired, 0, 0, NULL);
1243}
1244
1245inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1246{
1247    OMX_ERRORTYPE ret;
1248
1249    if (current == OMX_StateIdle) {
1250        /*
1251         * Todo
1252         *   1. waits for completion of deallocation on each port
1253         *      wokeup by FreeBuffer()
1254         *   2. deinitialize buffer process work
1255         *   3. deinitialize component's internal processor
1256         *      (ex. deinitialize sw/hw codec)
1257         */
1258        OMX_U32 i;
1259
1260        for (i = 0; i < nr_ports; i++)
1261            ports[i]->WaitPortBufferCompletion();
1262
1263        ret = OMX_ErrorNone;
1264    }
1265    else if (current == OMX_StateWaitForResources) {
1266        LOGE("state transition's requested from WaitForResources to "
1267             "Loaded\n");
1268
1269        /*
1270         * from WaitForResources to Loaded considered from Loaded to Loaded.
1271         * do nothing
1272         */
1273
1274        ret = OMX_ErrorNone;
1275    }
1276    else
1277        ret = OMX_ErrorIncorrectStateOperation;
1278
1279    return ret;
1280}
1281
1282inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1283{
1284    OMX_ERRORTYPE ret;
1285
1286    if (current == OMX_StateLoaded) {
1287        /*
1288         * Todo
1289         *   1. waits for completion of allocation on each port.
1290         *      wokeup by Allocate/UseBuffer()
1291         *   2. initialize buffer process work.
1292         *   3. initialize component's internal processor.
1293         *      (ex. initialize sw/hw codec)
1294         */
1295        OMX_U32 i;
1296
1297        for (i = 0; i < nr_ports; i++)
1298            ports[i]->WaitPortBufferCompletion();
1299
1300        ret = OMX_ErrorNone;
1301    }
1302    else if (current == OMX_StateExecuting) {
1303        /*
1304         * Todo
1305         *   1. returns all buffers to thier suppliers.
1306         *      call Fill/EmptyThisBuffer() for all ports
1307         *   2. stop buffer process work
1308         *   3. stop component's internal processor
1309         */
1310        ret = OMX_ErrorNone;
1311    }
1312    else if (current == OMX_StatePause) {
1313
1314        /* same as Executing to Idle */
1315
1316        ret = OMX_ErrorNone;
1317    }
1318    else if (current == OMX_StateWaitForResources) {
1319        LOGE("state transition's requested from WaitForResources to Idle\n");
1320
1321        /* same as Loaded to Idle BUT DO NOTHING for now */
1322
1323        ret = OMX_ErrorNone;
1324    }
1325    else
1326        ret = OMX_ErrorIncorrectStateOperation;
1327
1328    return ret;
1329}
1330
1331inline OMX_ERRORTYPE
1332ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1333{
1334    OMX_ERRORTYPE ret;
1335
1336    if (current == OMX_StateIdle) {
1337        /*
1338         * Todo
1339         *   1. start component's internal processor
1340         *   2. start processing buffers on each port
1341         */
1342        ret = OMX_ErrorNone;
1343    }
1344    else if (current == OMX_StatePause) {
1345        /*
1346         * Todo
1347         *   1. resume buffer process woraek
1348         *   2. resume component's internal processor
1349         */
1350        ret = OMX_ErrorNone;
1351    }
1352    else
1353        ret = OMX_ErrorIncorrectStateOperation;
1354
1355    return ret;
1356}
1357
1358inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1359{
1360    OMX_ERRORTYPE ret;
1361
1362    if (current == OMX_StateIdle) {
1363        /*
1364         * same as Idle to Executing,
1365         * except for not starting buffer processing and internal processor
1366         */
1367        ret = OMX_ErrorNone;
1368    }
1369    else if (current == OMX_StateExecuting) {
1370        /*
1371         * Todo
1372         *   1. pause buffer process work
1373         *   2. pause component's internal processor
1374         */
1375        ret = OMX_ErrorNone;
1376    }
1377    else
1378        ret = OMX_ErrorIncorrectStateOperation;
1379
1380    return ret;
1381}
1382
1383inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1384{
1385    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1386
1387    /*
1388     * Todo
1389     *   graceful escape
1390     */
1391
1392    return ret;
1393}
1394
1395inline OMX_ERRORTYPE
1396ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1397{
1398    OMX_ERRORTYPE ret;
1399
1400    if (current == OMX_StateLoaded) {
1401        LOGE("state transition's requested from Loaded to WaitForResources\n");
1402        ret = OMX_ErrorNone;
1403    }
1404    else
1405        ret = OMX_ErrorIncorrectStateOperation;
1406
1407    return ret;
1408}
1409
1410/* end of component methods & helpers */
1411
1412/*
1413 * omx header manipuation
1414 */
1415void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
1416{
1417    OMX_U32 *nsize;
1418    OMX_VERSIONTYPE *nversion;
1419
1420    if (!type)
1421        return;
1422
1423    nsize = (OMX_U32 *)type;
1424    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1425
1426    *nsize = size;
1427    nversion->nVersion = OMX_SPEC_VERSION;
1428}
1429
1430OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size)
1431{
1432    OMX_U32 *nsize;
1433    OMX_VERSIONTYPE *nversion;
1434
1435    if (!type)
1436        return OMX_ErrorBadParameter;
1437
1438    nsize = (OMX_U32 *)type;
1439    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1440
1441    if (*nsize != size)
1442        return OMX_ErrorBadParameter;
1443
1444    if (nversion->nVersion != OMX_SPEC_VERSION)
1445        return OMX_ErrorVersionMismatch;
1446
1447    return OMX_ErrorNone;
1448}
1449
1450/* end of ComponentBase */
1451