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