componentbase.cpp revision 074aeb8c3193c729c3e1050b970a2315608d0a24
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    *pState = state;
728    return OMX_ErrorNone;
729}
730
731OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest(
732    OMX_IN  OMX_HANDLETYPE hComponent,
733    OMX_IN  OMX_U32 nPort,
734    OMX_IN  OMX_HANDLETYPE hTunneledComponent,
735    OMX_IN  OMX_U32 nTunneledPort,
736    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
737{
738    ComponentBase *cbase;
739
740    if (!hComponent)
741        return OMX_ErrorBadParameter;
742
743    cbase = static_cast<ComponentBase *>
744        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
745    if (!cbase)
746        return OMX_ErrorBadParameter;
747
748    return cbase->CBaseComponentTunnelRequest(hComponent, nPort,
749                                              hTunneledComponent,
750                                              nTunneledPort, pTunnelSetup);
751}
752
753OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest(
754    OMX_IN  OMX_HANDLETYPE hComp,
755    OMX_IN  OMX_U32 nPort,
756    OMX_IN  OMX_HANDLETYPE hTunneledComp,
757    OMX_IN  OMX_U32 nTunneledPort,
758    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
759{
760    /*
761     * Todo
762     */
763
764    return OMX_ErrorNotImplemented;
765}
766
767OMX_ERRORTYPE ComponentBase::UseBuffer(
768    OMX_IN OMX_HANDLETYPE hComponent,
769    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
770    OMX_IN OMX_U32 nPortIndex,
771    OMX_IN OMX_PTR pAppPrivate,
772    OMX_IN OMX_U32 nSizeBytes,
773    OMX_IN OMX_U8 *pBuffer)
774{
775    ComponentBase *cbase;
776
777    if (!hComponent)
778        return OMX_ErrorBadParameter;
779
780    cbase = static_cast<ComponentBase *>
781        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
782    if (!cbase)
783        return OMX_ErrorBadParameter;
784
785    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
786                                 pAppPrivate, nSizeBytes, pBuffer);
787}
788
789OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
790    OMX_IN OMX_HANDLETYPE hComponent,
791    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
792    OMX_IN OMX_U32 nPortIndex,
793    OMX_IN OMX_PTR pAppPrivate,
794    OMX_IN OMX_U32 nSizeBytes,
795    OMX_IN OMX_U8 *pBuffer)
796{
797    PortBase *port = NULL;
798    OMX_ERRORTYPE ret;
799
800    if (hComponent != handle)
801        return OMX_ErrorBadParameter;
802
803    if (ports)
804        if (nPortIndex <= nr_ports-1)
805            port = ports[nPortIndex];
806
807    if (!port)
808        return OMX_ErrorBadParameter;
809
810    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
811                           pBuffer);
812}
813
814OMX_ERRORTYPE ComponentBase::AllocateBuffer(
815    OMX_IN OMX_HANDLETYPE hComponent,
816    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
817    OMX_IN OMX_U32 nPortIndex,
818    OMX_IN OMX_PTR pAppPrivate,
819    OMX_IN OMX_U32 nSizeBytes)
820{
821    ComponentBase *cbase;
822
823    if (!hComponent)
824        return OMX_ErrorBadParameter;
825
826    cbase = static_cast<ComponentBase *>
827        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
828    if (!cbase)
829        return OMX_ErrorBadParameter;
830
831    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
832                                      pAppPrivate, nSizeBytes);
833}
834
835OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
836    OMX_IN OMX_HANDLETYPE hComponent,
837    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
838    OMX_IN OMX_U32 nPortIndex,
839    OMX_IN OMX_PTR pAppPrivate,
840    OMX_IN OMX_U32 nSizeBytes)
841{
842    PortBase *port = NULL;
843    OMX_ERRORTYPE ret;
844
845    if (hComponent != handle)
846        return OMX_ErrorBadParameter;
847
848    if (ports)
849        if (nPortIndex <= nr_ports)
850            port = ports[nPortIndex];
851
852    if (!port)
853        return OMX_ErrorBadParameter;
854
855    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
856}
857
858OMX_ERRORTYPE ComponentBase::FreeBuffer(
859    OMX_IN  OMX_HANDLETYPE hComponent,
860    OMX_IN  OMX_U32 nPortIndex,
861    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
862{
863    ComponentBase *cbase;
864
865    if (!hComponent)
866        return OMX_ErrorBadParameter;
867
868    cbase = static_cast<ComponentBase *>
869        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
870    if (!cbase)
871        return OMX_ErrorBadParameter;
872
873    return cbase->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
874}
875
876OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
877    OMX_IN  OMX_HANDLETYPE hComponent,
878    OMX_IN  OMX_U32 nPortIndex,
879    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
880{
881    PortBase *port = NULL;
882    OMX_ERRORTYPE ret;
883
884    if (hComponent != handle)
885        return OMX_ErrorBadParameter;
886
887    if (ports)
888        if (nPortIndex <= nr_ports)
889            port = ports[nPortIndex];
890
891    if (!port)
892        return OMX_ErrorBadParameter;
893
894    return port->FreeBuffer(nPortIndex, pBuffer);
895}
896
897OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
898    OMX_IN  OMX_HANDLETYPE hComponent,
899    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
900{
901    ComponentBase *cbase;
902
903    if (!hComponent)
904        return OMX_ErrorBadParameter;
905
906    cbase = static_cast<ComponentBase *>
907        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
908    if (!cbase)
909        return OMX_ErrorBadParameter;
910
911    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
912}
913
914OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
915    OMX_IN  OMX_HANDLETYPE hComponent,
916    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
917{
918    /*
919     * Todo
920     */
921
922    return OMX_ErrorNotImplemented;
923}
924
925OMX_ERRORTYPE ComponentBase::FillThisBuffer(
926    OMX_IN  OMX_HANDLETYPE hComponent,
927    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
928{
929    ComponentBase *cbase;
930
931    if (!hComponent)
932        return OMX_ErrorBadParameter;
933
934    cbase = static_cast<ComponentBase *>
935        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
936    if (!cbase)
937        return OMX_ErrorBadParameter;
938
939    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
940}
941
942OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
943    OMX_IN  OMX_HANDLETYPE hComponent,
944    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
945{
946    /*
947     * Todo
948     */
949
950    return OMX_ErrorNotImplemented;
951}
952
953OMX_ERRORTYPE ComponentBase::SetCallbacks(
954    OMX_IN  OMX_HANDLETYPE hComponent,
955    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
956    OMX_IN  OMX_PTR pAppData)
957{
958    ComponentBase *cbase;
959
960    if (!hComponent)
961        return OMX_ErrorBadParameter;
962
963    cbase = static_cast<ComponentBase *>
964        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
965    if (!cbase)
966        return OMX_ErrorBadParameter;
967
968    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
969}
970
971OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
972    OMX_IN  OMX_HANDLETYPE hComponent,
973    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
974    OMX_IN  OMX_PTR pAppData)
975{
976    if (hComponent != handle)
977        return OMX_ErrorBadParameter;
978
979    appdata = pAppData;
980    callbacks = pCallbacks;
981
982    return OMX_ErrorNone;
983}
984
985OMX_ERRORTYPE ComponentBase::ComponentDeInit(
986    OMX_IN  OMX_HANDLETYPE hComponent)
987{
988    ComponentBase *cbase;
989
990    if (!hComponent)
991        return OMX_ErrorBadParameter;
992
993    cbase = static_cast<ComponentBase *>
994        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
995    if (!cbase)
996        return OMX_ErrorBadParameter;
997
998    return cbase->CBaseComponentDeInit(hComponent);
999}
1000
1001OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit(
1002    OMX_IN  OMX_HANDLETYPE hComponent)
1003{
1004    /*
1005     * Todo
1006     */
1007
1008    return OMX_ErrorNotImplemented;
1009}
1010
1011OMX_ERRORTYPE ComponentBase::UseEGLImage(
1012    OMX_IN OMX_HANDLETYPE hComponent,
1013    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1014    OMX_IN OMX_U32 nPortIndex,
1015    OMX_IN OMX_PTR pAppPrivate,
1016    OMX_IN void* eglImage)
1017{
1018    ComponentBase *cbase;
1019
1020    if (!hComponent)
1021        return OMX_ErrorBadParameter;
1022
1023    cbase = static_cast<ComponentBase *>
1024        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1025    if (!cbase)
1026        return OMX_ErrorBadParameter;
1027
1028    return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex,
1029                                   pAppPrivate, eglImage);
1030}
1031
1032OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage(
1033    OMX_IN OMX_HANDLETYPE hComponent,
1034    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1035    OMX_IN OMX_U32 nPortIndex,
1036    OMX_IN OMX_PTR pAppPrivate,
1037    OMX_IN void* eglImage)
1038{
1039    /*
1040     * Todo
1041     */
1042
1043    return OMX_ErrorNotImplemented;
1044}
1045
1046OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1047    OMX_IN OMX_HANDLETYPE hComponent,
1048    OMX_OUT OMX_U8 *cRole,
1049    OMX_IN OMX_U32 nIndex)
1050{
1051    ComponentBase *cbase;
1052
1053    if (!hComponent)
1054        return OMX_ErrorBadParameter;
1055
1056    cbase = static_cast<ComponentBase *>
1057        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1058    if (!cbase)
1059        return OMX_ErrorBadParameter;
1060
1061    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1062}
1063
1064OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1065    OMX_IN OMX_HANDLETYPE hComponent,
1066    OMX_OUT OMX_U8 *cRole,
1067    OMX_IN OMX_U32 nIndex)
1068{
1069    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1070        return OMX_ErrorBadParameter;
1071
1072    if (nIndex > nr_roles)
1073        return OMX_ErrorBadParameter;
1074
1075    strncpy((char *)cRole, (const char *)roles[nIndex],
1076            OMX_MAX_STRINGNAME_SIZE);
1077    return OMX_ErrorNone;
1078}
1079
1080/* implement CmdHandlerInterface */
1081void ComponentBase::CmdHandler(struct cmd_s *cmd)
1082{
1083    switch (cmd->cmd) {
1084    case OMX_CommandStateSet: {
1085        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1086
1087        TransState(transition);
1088        break;
1089    }
1090    case OMX_CommandFlush:
1091        /*
1092         * Todo
1093         */
1094        break;
1095    case OMX_CommandPortDisable:
1096        /*
1097         * Todo
1098         */
1099        break;
1100    case OMX_CommandPortEnable:
1101        /*
1102         * Todo
1103         */
1104        break;
1105    case OMX_CommandMarkBuffer:
1106        /*
1107         * Todo
1108         */
1109        break;
1110    } /* switch */
1111}
1112
1113/*
1114 * SendCommand:OMX_CommandStateSet
1115 * called in CmdHandler or called in other parts of component for reporting
1116 * internal error (OMX_StateInvalid).
1117 */
1118/*
1119 * Todo
1120 *   Resource Management (OMX_StateWaitForResources)
1121 *   for now, we never notify OMX_ErrorInsufficientResources,
1122 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1123 */
1124static const char *state_name[OMX_StateWaitForResources + 1] = {
1125    "OMX_StateInvalid",
1126    "OMX_StateLoaded",
1127    "OMX_StateIdle",
1128    "OMX_StateExecuting",
1129    "OMX_StatePause",
1130    "OMX_StateWaitForResources",
1131};
1132
1133static inline const char *GetStateName(OMX_STATETYPE state)
1134{
1135    if (state > OMX_StateWaitForResources)
1136        return "UnKnown";
1137
1138    return state_name[state];
1139}
1140
1141void ComponentBase::TransState(OMX_STATETYPE transition)
1142{
1143    OMX_STATETYPE current = this->state;
1144    OMX_EVENTTYPE event;
1145    OMX_U32 data1;
1146    OMX_ERRORTYPE ret;
1147
1148    LOGD("current state = %s, transition state = %s\n",
1149         GetStateName(current), GetStateName(transition));
1150
1151    /* same state */
1152    if (current == transition) {
1153        ret = OMX_ErrorSameState;
1154        goto notify_event;
1155    }
1156
1157    /* invalid state */
1158    if (current == OMX_StateInvalid) {
1159        ret = OMX_ErrorInvalidState;
1160        goto notify_event;
1161    }
1162
1163    if (transition == OMX_StateLoaded)
1164        ret = TransStateToLoaded(current);
1165    else if (transition == OMX_StateIdle)
1166        ret = TransStateToIdle(current);
1167    else if (transition == OMX_StateExecuting)
1168        ret = TransStateToExecuting(current);
1169    else if (transition == OMX_StatePause)
1170        ret = TransStateToPause(current);
1171    else if (transition == OMX_StateInvalid)
1172        ret = TransStateToInvalid(current);
1173    else if (transition == OMX_StateWaitForResources)
1174        ret = TransStateToWaitForResources(current);
1175    else
1176        ret = OMX_ErrorIncorrectStateTransition;
1177
1178notify_event:
1179    if (ret == OMX_ErrorNone) {
1180        event = OMX_EventCmdComplete;
1181        data1 = transition;
1182
1183        state = transition;
1184        LOGD("transition from %s to %s completed\n",
1185             GetStateName(current), GetStateName(transition));
1186    }
1187    else {
1188        event = OMX_EventError;
1189        data1 = ret;
1190
1191        if (transition == OMX_StateInvalid) {
1192            state = transition;
1193            LOGD("transition from %s to %s completed\n",
1194                 GetStateName(current), GetStateName(transition));
1195        }
1196    }
1197
1198    callbacks->EventHandler(handle, appdata, event, data1, 0, NULL);
1199
1200    /* WaitForResources workaround */
1201    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1202        callbacks->EventHandler(handle, appdata,
1203                                OMX_EventResourcesAcquired, 0, 0, NULL);
1204}
1205
1206inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1207{
1208    OMX_ERRORTYPE ret;
1209
1210    if (current == OMX_StateIdle) {
1211        /*
1212         * Todo
1213         *   1. waits for completion of deallocation on each port
1214         *      wokeup by FreeBuffer()
1215         *   2. deinitialize buffer process work
1216         *   3. deinitialize component's internal processor
1217         *      (ex. deinitialize sw/hw codec)
1218         */
1219        ret = OMX_ErrorNone;
1220    }
1221    else if (current == OMX_StateWaitForResources) {
1222        LOGE("state transition's requested from WaitForResources to "
1223             "Loaded\n");
1224
1225        /*
1226         * from WaitForResources to Loaded considered from Loaded to Loaded.
1227         * do nothing
1228         */
1229
1230        ret = OMX_ErrorNone;
1231    }
1232    else
1233        ret = OMX_ErrorIncorrectStateOperation;
1234
1235    return ret;
1236}
1237
1238inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1239{
1240    OMX_ERRORTYPE ret;
1241
1242    if (current == OMX_StateLoaded) {
1243        /*
1244         * Todo
1245         *   1. waits for completion of allocation on each port.
1246         *      wokeup by Allocate/UseBuffer()
1247         *   2. initialize buffer process work.
1248         *   3. initialize component's internal processor.
1249         *      (ex. initialize sw/hw codec)
1250         */
1251        ret = OMX_ErrorNone;
1252    }
1253    else if (current == OMX_StateExecuting) {
1254        /*
1255         * Todo
1256         *   1. returns all buffers to thier suppliers.
1257         *      call Fill/EmptyThisBuffer() for all ports
1258         *   2. stop buffer process work
1259         *   3. stop component's internal processor
1260         */
1261        ret = OMX_ErrorNone;
1262    }
1263    else if (current == OMX_StatePause) {
1264
1265        /* same as Executing to Idle */
1266
1267        ret = OMX_ErrorNone;
1268    }
1269    else if (current == OMX_StateWaitForResources) {
1270        LOGE("state transition's requested from WaitForResources to Idle\n");
1271
1272        /* same as Loaded to Idle BUT DO NOTHING for now */
1273
1274        ret = OMX_ErrorNone;
1275    }
1276    else
1277        ret = OMX_ErrorIncorrectStateOperation;
1278
1279    return ret;
1280}
1281
1282inline OMX_ERRORTYPE
1283ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1284{
1285    OMX_ERRORTYPE ret;
1286
1287    if (current == OMX_StateIdle) {
1288        /*
1289         * Todo
1290         *   1. start component's internal processor
1291         *   2. start processing buffers on each port
1292         */
1293        ret = OMX_ErrorNone;
1294    }
1295    else if (current == OMX_StatePause) {
1296        /*
1297         * Todo
1298         *   1. resume buffer process woraek
1299         *   2. resume component's internal processor
1300         */
1301        ret = OMX_ErrorNone;
1302    }
1303    else
1304        ret = OMX_ErrorIncorrectStateOperation;
1305
1306    return ret;
1307}
1308
1309inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1310{
1311    OMX_ERRORTYPE ret;
1312
1313    if (current == OMX_StateIdle) {
1314        /*
1315         * same as Idle to Executing,
1316         * except for not starting buffer processing and internal processor
1317         */
1318        ret = OMX_ErrorNone;
1319    }
1320    else if (current == OMX_StateExecuting) {
1321        /*
1322         * Todo
1323         *   1. pause buffer process work
1324         *   2. pause component's internal processor
1325         */
1326        ret = OMX_ErrorNone;
1327    }
1328    else
1329        ret = OMX_ErrorIncorrectStateOperation;
1330
1331    return ret;
1332}
1333
1334inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1335{
1336    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1337
1338    /*
1339     * Todo
1340     *   graceful escape
1341     */
1342
1343    return ret;
1344}
1345
1346inline OMX_ERRORTYPE
1347ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1348{
1349    OMX_ERRORTYPE ret;
1350
1351    if (current == OMX_StateLoaded) {
1352        LOGE("state transition's requested from Loaded to WaitForResources\n");
1353        ret = OMX_ErrorNone;
1354    }
1355    else
1356        ret = OMX_ErrorIncorrectStateOperation;
1357
1358    return ret;
1359}
1360
1361/* end of component methods & helpers */
1362
1363/*
1364 * omx header manipuation
1365 */
1366void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
1367{
1368    OMX_U32 *nsize;
1369    OMX_VERSIONTYPE *nversion;
1370
1371    if (!type)
1372        return;
1373
1374    nsize = (OMX_U32 *)type;
1375    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1376
1377    *nsize = size;
1378    nversion->nVersion = OMX_SPEC_VERSION;
1379}
1380
1381OMX_ERRORTYPE ComponentBase::CheckTypeHeader(OMX_PTR type, OMX_U32 size)
1382{
1383    OMX_U32 *nsize;
1384    OMX_VERSIONTYPE *nversion;
1385
1386    if (!type)
1387        return OMX_ErrorBadParameter;
1388
1389    nsize = (OMX_U32 *)type;
1390    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
1391
1392    if (*nsize != size)
1393        return OMX_ErrorBadParameter;
1394
1395    if (nversion->nVersion != OMX_SPEC_VERSION)
1396        return OMX_ErrorVersionMismatch;
1397
1398    return OMX_ErrorNone;
1399}
1400
1401/* end of ComponentBase */
1402