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