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