componentbase.cpp revision 588d2fa1495340bbd66f72a4b5a07fcfbc398a2a
1/*
2 * Copyright (c) 2009 Wind River Systems, Inc.
3 *
4 * The right to copy, distribute, modify, or otherwise make use
5 * of this software may be licensed only pursuant to the terms
6 * of an applicable Wind River license agreement.
7 */
8
9#include <stdlib.h>
10#include <string.h>
11
12#include <pthread.h>
13
14#include <OMX_Core.h>
15#include <OMX_Component.h>
16
17#include <componentbase.h>
18
19#include <queue.h>
20#include <workqueue.h>
21
22//#define LOG_NDEBUG 0
23
24#define LOG_TAG "componentbase"
25#include <log.h>
26
27/*
28 * CmdProcessWork
29 */
30CmdProcessWork::CmdProcessWork(CmdHandlerInterface *ci)
31{
32    this->ci = ci;
33
34    workq = new WorkQueue;
35
36    __queue_init(&q);
37    pthread_mutex_init(&lock, NULL);
38
39    workq->StartWork(true);
40
41    LOGV("command process workqueue started\n");
42}
43
44CmdProcessWork::~CmdProcessWork()
45{
46    struct cmd_s *temp;
47
48    workq->StopWork();
49    delete workq;
50
51    while ((temp = PopCmdQueue()))
52        free(temp);
53
54    pthread_mutex_destroy(&lock);
55
56    LOGV("command process workqueue stopped\n");
57}
58
59OMX_ERRORTYPE CmdProcessWork::PushCmdQueue(struct cmd_s *cmd)
60{
61    int ret;
62
63    pthread_mutex_lock(&lock);
64    ret = queue_push_tail(&q, cmd);
65    if (ret) {
66        pthread_mutex_unlock(&lock);
67        return OMX_ErrorInsufficientResources;
68    }
69
70    workq->ScheduleWork(this);
71    pthread_mutex_unlock(&lock);
72
73    return OMX_ErrorNone;
74}
75
76struct cmd_s *CmdProcessWork::PopCmdQueue(void)
77{
78    struct cmd_s *cmd;
79
80    pthread_mutex_lock(&lock);
81    cmd = (struct cmd_s *)queue_pop_head(&q);
82    pthread_mutex_unlock(&lock);
83
84    return cmd;
85}
86
87void CmdProcessWork::Work(void)
88{
89    struct cmd_s *cmd;
90
91    cmd = PopCmdQueue();
92    if (cmd) {
93        ci->CmdHandler(cmd);
94        free(cmd);
95    }
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    working_role = NULL;
116
117    ports = NULL;
118    nr_ports = 0;
119    memset(&portparam, 0, sizeof(portparam));
120
121    state = OMX_StateUnloaded;
122
123    cmdwork = NULL;
124
125    bufferwork = NULL;
126
127    pthread_mutex_init(&ports_block, NULL);
128}
129
130ComponentBase::ComponentBase()
131{
132    __ComponentBase();
133}
134
135ComponentBase::ComponentBase(const OMX_STRING name)
136{
137    __ComponentBase();
138    SetName(name);
139}
140
141ComponentBase::~ComponentBase()
142{
143    pthread_mutex_destroy(&ports_block);
144
145    if (roles) {
146        if (roles[0])
147            free(roles[0]);
148        free(roles);
149    }
150}
151
152/* end of constructor & destructor */
153
154/*
155 * accessor
156 */
157/* name */
158void ComponentBase::SetName(const OMX_STRING name)
159{
160    strncpy(this->name, name, OMX_MAX_STRINGNAME_SIZE);
161    this->name[OMX_MAX_STRINGNAME_SIZE-1] = '\0';
162}
163
164const OMX_STRING ComponentBase::GetName(void)
165{
166    return name;
167}
168
169/* component module */
170void ComponentBase::SetCModule(CModule *cmodule)
171{
172    this->cmodule = cmodule;
173}
174
175CModule *ComponentBase::GetCModule(void)
176{
177    return cmodule;
178}
179
180/* end of accessor */
181
182/*
183 * core methods & helpers
184 */
185/* roles */
186OMX_ERRORTYPE ComponentBase::SetRolesOfComponent(OMX_U32 nr_roles,
187                                                 const OMX_U8 **roles)
188{
189    OMX_U32 i;
190
191    if (!roles || !nr_roles)
192        return OMX_ErrorBadParameter;
193
194    if (this->roles) {
195        free(this->roles[0]);
196        free(this->roles);
197        this->roles = NULL;
198    }
199
200    this->roles = (OMX_U8 **)malloc(sizeof(OMX_STRING) * nr_roles);
201    if (!this->roles)
202        return OMX_ErrorInsufficientResources;
203
204    this->roles[0] = (OMX_U8 *)malloc(OMX_MAX_STRINGNAME_SIZE * nr_roles);
205    if (!this->roles[0]) {
206        free(this->roles);
207        this->roles = NULL;
208        return OMX_ErrorInsufficientResources;
209    }
210
211    for (i = 0; i < nr_roles; i++) {
212        if (i < nr_roles-1)
213            this->roles[i+1] = this->roles[i] + OMX_MAX_STRINGNAME_SIZE;
214
215        strncpy((OMX_STRING)&this->roles[i][0],
216                (const OMX_STRING)&roles[i][0], OMX_MAX_STRINGNAME_SIZE);
217    }
218
219    this->nr_roles = nr_roles;
220    return OMX_ErrorNone;
221}
222
223/* GetHandle & FreeHandle */
224OMX_ERRORTYPE ComponentBase::GetHandle(OMX_HANDLETYPE *pHandle,
225                                       OMX_PTR pAppData,
226                                       OMX_CALLBACKTYPE *pCallBacks)
227{
228    OMX_U32 i;
229    OMX_ERRORTYPE ret;
230
231    if (!pHandle)
232        return OMX_ErrorBadParameter;
233
234    if (handle)
235        return OMX_ErrorUndefined;
236
237    cmdwork = new CmdProcessWork(this);
238    if (!cmdwork)
239        return OMX_ErrorInsufficientResources;
240
241    bufferwork = new WorkQueue();
242    if (!bufferwork) {
243        ret = OMX_ErrorInsufficientResources;
244        goto free_cmdwork;
245    }
246
247    handle = (OMX_COMPONENTTYPE *)calloc(1, sizeof(*handle));
248    if (!handle) {
249        ret = OMX_ErrorInsufficientResources;
250        goto free_bufferwork;
251    }
252
253    /* handle initialization */
254    SetTypeHeader(handle, sizeof(*handle));
255    handle->pComponentPrivate = static_cast<OMX_PTR>(this);
256    handle->pApplicationPrivate = pAppData;
257
258    /* connect handle's functions */
259    handle->GetComponentVersion = GetComponentVersion;
260    handle->SendCommand = SendCommand;
261    handle->GetParameter = GetParameter;
262    handle->SetParameter = SetParameter;
263    handle->GetConfig = GetConfig;
264    handle->SetConfig = SetConfig;
265    handle->GetExtensionIndex = GetExtensionIndex;
266    handle->GetState = GetState;
267    handle->ComponentTunnelRequest = ComponentTunnelRequest;
268    handle->UseBuffer = UseBuffer;
269    handle->AllocateBuffer = AllocateBuffer;
270    handle->FreeBuffer = FreeBuffer;
271    handle->EmptyThisBuffer = EmptyThisBuffer;
272    handle->FillThisBuffer = FillThisBuffer;
273    handle->SetCallbacks = SetCallbacks;
274    handle->ComponentDeInit = ComponentDeInit;
275    handle->UseEGLImage = UseEGLImage;
276    handle->ComponentRoleEnum = ComponentRoleEnum;
277
278    appdata = pAppData;
279    callbacks = pCallBacks;
280
281    if (nr_roles == 1) {
282        SetWorkingRole((OMX_STRING)&roles[0][0]);
283        ret = ApplyWorkingRole();
284        if (ret != OMX_ErrorNone) {
285            SetWorkingRole(NULL);
286            goto free_handle;
287        }
288    }
289
290    *pHandle = (OMX_HANDLETYPE *)handle;
291    state = OMX_StateLoaded;
292    return OMX_ErrorNone;
293
294free_handle:
295    free(handle);
296
297    appdata = NULL;
298    callbacks = NULL;
299    *pHandle = NULL;
300
301free_bufferwork:
302    delete bufferwork;
303
304free_cmdwork:
305    delete cmdwork;
306
307    return ret;
308}
309
310OMX_ERRORTYPE ComponentBase::FreeHandle(OMX_HANDLETYPE hComponent)
311{
312    OMX_ERRORTYPE ret;
313
314    if (hComponent != handle)
315        return OMX_ErrorBadParameter;
316
317    if (state != OMX_StateLoaded)
318        return OMX_ErrorIncorrectStateOperation;
319
320    FreePorts();
321
322    free(handle);
323
324    appdata = NULL;
325    callbacks = NULL;
326
327    delete cmdwork;
328    delete bufferwork;
329
330    state = OMX_StateUnloaded;
331    return OMX_ErrorNone;
332}
333
334/* end of core methods & helpers */
335
336/*
337 * component methods & helpers
338 */
339OMX_ERRORTYPE ComponentBase::GetComponentVersion(
340    OMX_IN  OMX_HANDLETYPE hComponent,
341    OMX_OUT OMX_STRING pComponentName,
342    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
343    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
344    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
345{
346    ComponentBase *cbase;
347
348    if (!hComponent)
349        return OMX_ErrorBadParameter;
350
351    cbase = static_cast<ComponentBase *>
352        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
353    if (!cbase)
354        return OMX_ErrorBadParameter;
355
356    return cbase->CBaseGetComponentVersion(hComponent,
357                                           pComponentName,
358                                           pComponentVersion,
359                                           pSpecVersion,
360                                           pComponentUUID);
361}
362
363OMX_ERRORTYPE ComponentBase::CBaseGetComponentVersion(
364    OMX_IN  OMX_HANDLETYPE hComponent,
365    OMX_OUT OMX_STRING pComponentName,
366    OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
367    OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
368    OMX_OUT OMX_UUIDTYPE* pComponentUUID)
369{
370    /*
371     * Todo
372     */
373
374    return OMX_ErrorNotImplemented;
375}
376
377OMX_ERRORTYPE ComponentBase::SendCommand(
378    OMX_IN  OMX_HANDLETYPE hComponent,
379    OMX_IN  OMX_COMMANDTYPE Cmd,
380    OMX_IN  OMX_U32 nParam1,
381    OMX_IN  OMX_PTR pCmdData)
382{
383    ComponentBase *cbase;
384
385    if (!hComponent)
386        return OMX_ErrorBadParameter;
387
388    cbase = static_cast<ComponentBase *>
389        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
390    if (!cbase)
391        return OMX_ErrorBadParameter;
392
393    return cbase->CBaseSendCommand(hComponent, Cmd, nParam1, pCmdData);
394}
395
396OMX_ERRORTYPE ComponentBase::CBaseSendCommand(
397    OMX_IN  OMX_HANDLETYPE hComponent,
398    OMX_IN  OMX_COMMANDTYPE Cmd,
399    OMX_IN  OMX_U32 nParam1,
400    OMX_IN  OMX_PTR pCmdData)
401{
402    struct cmd_s *cmd;
403
404    if (hComponent != handle)
405        return OMX_ErrorInvalidComponent;
406
407    /* basic error check */
408    switch (Cmd) {
409    case OMX_CommandStateSet:
410        /*
411         * Todo
412         */
413        break;
414    case OMX_CommandFlush: {
415        OMX_U32 port_index = nParam1;
416
417        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
418            return OMX_ErrorBadPortIndex;
419        break;
420    }
421    case OMX_CommandPortDisable:
422    case OMX_CommandPortEnable: {
423        OMX_U32 port_index = nParam1;
424
425        if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
426            return OMX_ErrorBadPortIndex;
427        break;
428    }
429    case OMX_CommandMarkBuffer: {
430        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)pCmdData;
431        OMX_MARKTYPE *copiedmark;
432        OMX_U32 port_index = nParam1;
433
434        if (port_index > nr_ports-1)
435            return OMX_ErrorBadPortIndex;
436
437        if (!mark || !mark->hMarkTargetComponent)
438            return OMX_ErrorBadParameter;
439
440        copiedmark = (OMX_MARKTYPE *)malloc(sizeof(*copiedmark));
441        if (!copiedmark)
442            return OMX_ErrorInsufficientResources;
443
444        copiedmark->hMarkTargetComponent = mark->hMarkTargetComponent;
445        copiedmark->pMarkData = mark->pMarkData;
446        pCmdData = (OMX_PTR)copiedmark;
447        break;
448    }
449    default:
450        LOGE("command %d not supported\n", Cmd);
451        return OMX_ErrorUnsupportedIndex;
452    }
453
454    cmd = (struct cmd_s *)malloc(sizeof(*cmd));
455    if (!cmd)
456        return OMX_ErrorInsufficientResources;
457
458    cmd->cmd = Cmd;
459    cmd->param1 = nParam1;
460    cmd->cmddata = pCmdData;
461
462    return cmdwork->PushCmdQueue(cmd);
463}
464
465OMX_ERRORTYPE ComponentBase::GetParameter(
466    OMX_IN  OMX_HANDLETYPE hComponent,
467    OMX_IN  OMX_INDEXTYPE nParamIndex,
468    OMX_INOUT OMX_PTR pComponentParameterStructure)
469{
470    ComponentBase *cbase;
471
472    if (!hComponent)
473        return OMX_ErrorBadParameter;
474
475    cbase = static_cast<ComponentBase *>
476        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
477    if (!cbase)
478        return OMX_ErrorBadParameter;
479
480    return cbase->CBaseGetParameter(hComponent, nParamIndex,
481                                    pComponentParameterStructure);
482}
483
484OMX_ERRORTYPE ComponentBase::CBaseGetParameter(
485    OMX_IN  OMX_HANDLETYPE hComponent,
486    OMX_IN  OMX_INDEXTYPE nParamIndex,
487    OMX_INOUT OMX_PTR pComponentParameterStructure)
488{
489    OMX_ERRORTYPE ret = OMX_ErrorNone;
490
491    if (hComponent != handle)
492        return OMX_ErrorBadParameter;
493
494    switch (nParamIndex) {
495    case OMX_IndexParamAudioInit:
496    case OMX_IndexParamVideoInit:
497    case OMX_IndexParamImageInit:
498    case OMX_IndexParamOtherInit: {
499        OMX_PORT_PARAM_TYPE *p =
500            (OMX_PORT_PARAM_TYPE *)pComponentParameterStructure;
501
502        ret = CheckTypeHeader(p, sizeof(*p));
503        if (ret != OMX_ErrorNone)
504            return ret;
505
506        memcpy(p, &portparam, sizeof(*p));
507        break;
508    }
509    case OMX_IndexParamPortDefinition: {
510        OMX_PARAM_PORTDEFINITIONTYPE *p =
511            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
512        OMX_U32 index = p->nPortIndex;
513        PortBase *port = NULL;
514
515        ret = CheckTypeHeader(p, sizeof(*p));
516        if (ret != OMX_ErrorNone)
517            return ret;
518
519        if (index < nr_ports)
520            port = ports[index];
521
522        if (!port)
523            return OMX_ErrorBadPortIndex;
524
525        memcpy(p, port->GetPortDefinition(), sizeof(*p));
526        break;
527    }
528    case OMX_IndexParamCompBufferSupplier:
529        /*
530         * Todo
531         */
532
533        ret = OMX_ErrorUnsupportedIndex;
534        break;
535    default:
536        ret = ComponentGetParameter(nParamIndex, pComponentParameterStructure);
537    } /* switch */
538
539    return ret;
540}
541
542OMX_ERRORTYPE ComponentBase::SetParameter(
543    OMX_IN  OMX_HANDLETYPE hComponent,
544    OMX_IN  OMX_INDEXTYPE nIndex,
545    OMX_IN  OMX_PTR pComponentParameterStructure)
546{
547    ComponentBase *cbase;
548
549    if (!hComponent)
550        return OMX_ErrorBadParameter;
551
552    cbase = static_cast<ComponentBase *>
553        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
554    if (!cbase)
555        return OMX_ErrorBadParameter;
556
557    return cbase->CBaseSetParameter(hComponent, nIndex,
558                                    pComponentParameterStructure);
559}
560
561OMX_ERRORTYPE ComponentBase::CBaseSetParameter(
562    OMX_IN  OMX_HANDLETYPE hComponent,
563    OMX_IN  OMX_INDEXTYPE nIndex,
564    OMX_IN  OMX_PTR pComponentParameterStructure)
565{
566    OMX_ERRORTYPE ret = OMX_ErrorNone;
567
568    if (hComponent != handle)
569        return OMX_ErrorBadParameter;
570
571    switch (nIndex) {
572    case OMX_IndexParamAudioInit:
573    case OMX_IndexParamVideoInit:
574    case OMX_IndexParamImageInit:
575    case OMX_IndexParamOtherInit:
576        /* preventing clients from setting OMX_PORT_PARAM_TYPE */
577        ret = OMX_ErrorUnsupportedIndex;
578        break;
579    case OMX_IndexParamPortDefinition: {
580        OMX_PARAM_PORTDEFINITIONTYPE *p =
581            (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
582        OMX_U32 index = p->nPortIndex;
583        PortBase *port = NULL;
584
585        ret = CheckTypeHeader(p, sizeof(*p));
586        if (ret != OMX_ErrorNone)
587            return ret;
588
589        if (index < nr_ports)
590            port = ports[index];
591
592        if (!port)
593            return OMX_ErrorBadPortIndex;
594
595        if (port->IsEnabled()) {
596            if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
597                return OMX_ErrorIncorrectStateOperation;
598        }
599
600        port->SetPortDefinition(p, false);
601        break;
602    }
603    case OMX_IndexParamCompBufferSupplier:
604        /*
605         * Todo
606         */
607
608        ret = OMX_ErrorUnsupportedIndex;
609        break;
610    case OMX_IndexParamStandardComponentRole: {
611        OMX_PARAM_COMPONENTROLETYPE *p =
612            (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
613
614        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
615            return OMX_ErrorIncorrectStateOperation;
616
617        ret = CheckTypeHeader(p, sizeof(*p));
618        if (ret != OMX_ErrorNone)
619            return ret;
620
621        ret = SetWorkingRole((OMX_STRING)p->cRole);
622        if (ret != OMX_ErrorNone)
623            return ret;
624
625        if (ports)
626            FreePorts();
627
628        ret = ApplyWorkingRole();
629        if (ret != OMX_ErrorNone) {
630            SetWorkingRole(NULL);
631            return ret;
632        }
633        break;
634    }
635    default:
636        ret = ComponentSetParameter(nIndex, pComponentParameterStructure);
637    } /* switch */
638
639    return ret;
640}
641
642OMX_ERRORTYPE ComponentBase::GetConfig(
643    OMX_IN  OMX_HANDLETYPE hComponent,
644    OMX_IN  OMX_INDEXTYPE nIndex,
645    OMX_INOUT OMX_PTR pComponentConfigStructure)
646{
647    ComponentBase *cbase;
648
649    if (!hComponent)
650        return OMX_ErrorBadParameter;
651
652    cbase = static_cast<ComponentBase *>
653        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
654    if (!cbase)
655        return OMX_ErrorBadParameter;
656
657    return cbase->CBaseGetConfig(hComponent, nIndex,
658                                 pComponentConfigStructure);
659}
660
661OMX_ERRORTYPE ComponentBase::CBaseGetConfig(
662    OMX_IN  OMX_HANDLETYPE hComponent,
663    OMX_IN  OMX_INDEXTYPE nIndex,
664    OMX_INOUT OMX_PTR pComponentConfigStructure)
665{
666    OMX_ERRORTYPE ret;
667
668    if (hComponent != handle)
669        return OMX_ErrorBadParameter;
670
671    switch (nIndex) {
672    default:
673        ret = ComponentGetConfig(nIndex, pComponentConfigStructure);
674    }
675
676    return ret;
677}
678
679OMX_ERRORTYPE ComponentBase::SetConfig(
680    OMX_IN  OMX_HANDLETYPE hComponent,
681    OMX_IN  OMX_INDEXTYPE nIndex,
682    OMX_IN  OMX_PTR pComponentConfigStructure)
683{
684    ComponentBase *cbase;
685
686    if (!hComponent)
687        return OMX_ErrorBadParameter;
688
689    cbase = static_cast<ComponentBase *>
690        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
691    if (!cbase)
692        return OMX_ErrorBadParameter;
693
694    return cbase->CBaseSetConfig(hComponent, nIndex,
695                                 pComponentConfigStructure);
696}
697
698OMX_ERRORTYPE ComponentBase::CBaseSetConfig(
699    OMX_IN  OMX_HANDLETYPE hComponent,
700    OMX_IN  OMX_INDEXTYPE nIndex,
701    OMX_IN  OMX_PTR pComponentConfigStructure)
702{
703    OMX_ERRORTYPE ret;
704
705    if (hComponent != handle)
706        return OMX_ErrorBadParameter;
707
708    switch (nIndex) {
709    default:
710        ret = ComponentSetConfig(nIndex, pComponentConfigStructure);
711    }
712
713    return ret;
714}
715
716OMX_ERRORTYPE ComponentBase::GetExtensionIndex(
717    OMX_IN  OMX_HANDLETYPE hComponent,
718    OMX_IN  OMX_STRING cParameterName,
719    OMX_OUT OMX_INDEXTYPE* pIndexType)
720{
721    ComponentBase *cbase;
722
723    if (!hComponent)
724        return OMX_ErrorBadParameter;
725
726    cbase = static_cast<ComponentBase *>
727        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
728    if (!cbase)
729        return OMX_ErrorBadParameter;
730
731    return cbase->CBaseGetExtensionIndex(hComponent, cParameterName,
732                                         pIndexType);
733}
734
735OMX_ERRORTYPE ComponentBase::CBaseGetExtensionIndex(
736    OMX_IN  OMX_HANDLETYPE hComponent,
737    OMX_IN  OMX_STRING cParameterName,
738    OMX_OUT OMX_INDEXTYPE* pIndexType)
739{
740    /*
741     * Todo
742     */
743
744    return OMX_ErrorNotImplemented;
745}
746
747OMX_ERRORTYPE ComponentBase::GetState(
748    OMX_IN  OMX_HANDLETYPE hComponent,
749    OMX_OUT OMX_STATETYPE* pState)
750{
751    ComponentBase *cbase;
752
753    if (!hComponent)
754        return OMX_ErrorBadParameter;
755
756    cbase = static_cast<ComponentBase *>
757        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
758    if (!cbase)
759        return OMX_ErrorBadParameter;
760
761    return cbase->CBaseGetState(hComponent, pState);
762}
763
764OMX_ERRORTYPE ComponentBase::CBaseGetState(
765    OMX_IN  OMX_HANDLETYPE hComponent,
766    OMX_OUT OMX_STATETYPE* pState)
767{
768    if (hComponent != handle)
769        return OMX_ErrorBadParameter;
770
771    *pState = state;
772    return OMX_ErrorNone;
773}
774
775OMX_ERRORTYPE ComponentBase::ComponentTunnelRequest(
776    OMX_IN  OMX_HANDLETYPE hComponent,
777    OMX_IN  OMX_U32 nPort,
778    OMX_IN  OMX_HANDLETYPE hTunneledComponent,
779    OMX_IN  OMX_U32 nTunneledPort,
780    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
781{
782    ComponentBase *cbase;
783
784    if (!hComponent)
785        return OMX_ErrorBadParameter;
786
787    cbase = static_cast<ComponentBase *>
788        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
789    if (!cbase)
790        return OMX_ErrorBadParameter;
791
792    return cbase->CBaseComponentTunnelRequest(hComponent, nPort,
793                                              hTunneledComponent,
794                                              nTunneledPort, pTunnelSetup);
795}
796
797OMX_ERRORTYPE ComponentBase::CBaseComponentTunnelRequest(
798    OMX_IN  OMX_HANDLETYPE hComp,
799    OMX_IN  OMX_U32 nPort,
800    OMX_IN  OMX_HANDLETYPE hTunneledComp,
801    OMX_IN  OMX_U32 nTunneledPort,
802    OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup)
803{
804    /*
805     * Todo
806     */
807
808    return OMX_ErrorNotImplemented;
809}
810
811OMX_ERRORTYPE ComponentBase::UseBuffer(
812    OMX_IN OMX_HANDLETYPE hComponent,
813    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
814    OMX_IN OMX_U32 nPortIndex,
815    OMX_IN OMX_PTR pAppPrivate,
816    OMX_IN OMX_U32 nSizeBytes,
817    OMX_IN OMX_U8 *pBuffer)
818{
819    ComponentBase *cbase;
820
821    if (!hComponent)
822        return OMX_ErrorBadParameter;
823
824    cbase = static_cast<ComponentBase *>
825        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
826    if (!cbase)
827        return OMX_ErrorBadParameter;
828
829    return cbase->CBaseUseBuffer(hComponent, ppBufferHdr, nPortIndex,
830                                 pAppPrivate, nSizeBytes, pBuffer);
831}
832
833OMX_ERRORTYPE ComponentBase::CBaseUseBuffer(
834    OMX_IN OMX_HANDLETYPE hComponent,
835    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
836    OMX_IN OMX_U32 nPortIndex,
837    OMX_IN OMX_PTR pAppPrivate,
838    OMX_IN OMX_U32 nSizeBytes,
839    OMX_IN OMX_U8 *pBuffer)
840{
841    PortBase *port = NULL;
842    OMX_ERRORTYPE ret;
843
844    if (hComponent != handle)
845        return OMX_ErrorBadParameter;
846
847    if (!ppBufferHdr)
848        return OMX_ErrorBadParameter;
849    *ppBufferHdr = NULL;
850
851    if (!pBuffer)
852        return OMX_ErrorBadParameter;
853
854    if (ports)
855        if (nPortIndex < nr_ports)
856            port = ports[nPortIndex];
857
858    if (!port)
859        return OMX_ErrorBadParameter;
860
861    if (port->IsEnabled()) {
862        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
863            return OMX_ErrorIncorrectStateOperation;
864    }
865
866    return port->UseBuffer(ppBufferHdr, nPortIndex, pAppPrivate, nSizeBytes,
867                           pBuffer);
868}
869
870OMX_ERRORTYPE ComponentBase::AllocateBuffer(
871    OMX_IN OMX_HANDLETYPE hComponent,
872    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
873    OMX_IN OMX_U32 nPortIndex,
874    OMX_IN OMX_PTR pAppPrivate,
875    OMX_IN OMX_U32 nSizeBytes)
876{
877    ComponentBase *cbase;
878
879    if (!hComponent)
880        return OMX_ErrorBadParameter;
881
882    cbase = static_cast<ComponentBase *>
883        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
884    if (!cbase)
885        return OMX_ErrorBadParameter;
886
887    return cbase->CBaseAllocateBuffer(hComponent, ppBuffer, nPortIndex,
888                                      pAppPrivate, nSizeBytes);
889}
890
891OMX_ERRORTYPE ComponentBase::CBaseAllocateBuffer(
892    OMX_IN OMX_HANDLETYPE hComponent,
893    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
894    OMX_IN OMX_U32 nPortIndex,
895    OMX_IN OMX_PTR pAppPrivate,
896    OMX_IN OMX_U32 nSizeBytes)
897{
898    PortBase *port = NULL;
899    OMX_ERRORTYPE ret;
900
901    if (hComponent != handle)
902        return OMX_ErrorBadParameter;
903
904    if (!ppBuffer)
905        return OMX_ErrorBadParameter;
906    *ppBuffer = NULL;
907
908    if (ports)
909        if (nPortIndex < nr_ports)
910            port = ports[nPortIndex];
911
912    if (!port)
913        return OMX_ErrorBadParameter;
914
915    if (port->IsEnabled()) {
916        if (state != OMX_StateLoaded && state != OMX_StateWaitForResources)
917            return OMX_ErrorIncorrectStateOperation;
918    }
919
920    return port->AllocateBuffer(ppBuffer, nPortIndex, pAppPrivate, nSizeBytes);
921}
922
923OMX_ERRORTYPE ComponentBase::FreeBuffer(
924    OMX_IN  OMX_HANDLETYPE hComponent,
925    OMX_IN  OMX_U32 nPortIndex,
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->CBaseFreeBuffer(hComponent, nPortIndex, pBuffer);
939}
940
941OMX_ERRORTYPE ComponentBase::CBaseFreeBuffer(
942    OMX_IN  OMX_HANDLETYPE hComponent,
943    OMX_IN  OMX_U32 nPortIndex,
944    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
945{
946    PortBase *port = NULL;
947    OMX_ERRORTYPE ret;
948
949    if (hComponent != handle)
950        return OMX_ErrorBadParameter;
951
952    if (!pBuffer)
953        return OMX_ErrorBadParameter;
954
955    if (ports)
956        if (nPortIndex < nr_ports)
957            port = ports[nPortIndex];
958
959    if (!port)
960        return OMX_ErrorBadParameter;
961
962    return port->FreeBuffer(nPortIndex, pBuffer);
963}
964
965OMX_ERRORTYPE ComponentBase::EmptyThisBuffer(
966    OMX_IN  OMX_HANDLETYPE hComponent,
967    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
968{
969    ComponentBase *cbase;
970
971    if (!hComponent)
972        return OMX_ErrorBadParameter;
973
974    cbase = static_cast<ComponentBase *>
975        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
976    if (!cbase)
977        return OMX_ErrorBadParameter;
978
979    return cbase->CBaseEmptyThisBuffer(hComponent, pBuffer);
980}
981
982OMX_ERRORTYPE ComponentBase::CBaseEmptyThisBuffer(
983    OMX_IN  OMX_HANDLETYPE hComponent,
984    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
985{
986    PortBase *port = NULL;
987    OMX_U32 port_index;
988    OMX_ERRORTYPE ret;
989
990    if ((hComponent != handle) || !pBuffer)
991        return OMX_ErrorBadParameter;
992
993    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
994    if (ret != OMX_ErrorNone)
995        return ret;
996
997    port_index = pBuffer->nInputPortIndex;
998    if (port_index == (OMX_U32)-1)
999        return OMX_ErrorBadParameter;
1000
1001    if (ports)
1002        if (port_index < nr_ports)
1003            port = ports[port_index];
1004
1005    if (!port)
1006        return OMX_ErrorBadParameter;
1007
1008    if (pBuffer->pInputPortPrivate != port)
1009        return OMX_ErrorBadParameter;
1010
1011    if (port->IsEnabled()) {
1012        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1013            state != OMX_StatePause)
1014            return OMX_ErrorIncorrectStateOperation;
1015    }
1016
1017    if (!pBuffer->hMarkTargetComponent) {
1018        OMX_MARKTYPE *mark;
1019
1020        mark = port->PopMark();
1021        if (mark) {
1022            pBuffer->hMarkTargetComponent = mark->hMarkTargetComponent;
1023            pBuffer->pMarkData = mark->pMarkData;
1024            free(mark);
1025        }
1026    }
1027
1028    ret = port->PushThisBuffer(pBuffer);
1029    if (ret == OMX_ErrorNone)
1030        bufferwork->ScheduleWork(this);
1031
1032    return ret;
1033}
1034
1035OMX_ERRORTYPE ComponentBase::FillThisBuffer(
1036    OMX_IN  OMX_HANDLETYPE hComponent,
1037    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1038{
1039    ComponentBase *cbase;
1040
1041    if (!hComponent)
1042        return OMX_ErrorBadParameter;
1043
1044    cbase = static_cast<ComponentBase *>
1045        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1046    if (!cbase)
1047        return OMX_ErrorBadParameter;
1048
1049    return cbase->CBaseFillThisBuffer(hComponent, pBuffer);
1050}
1051
1052OMX_ERRORTYPE ComponentBase::CBaseFillThisBuffer(
1053    OMX_IN  OMX_HANDLETYPE hComponent,
1054    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
1055{
1056    PortBase *port = NULL;
1057    OMX_U32 port_index;
1058    OMX_ERRORTYPE ret;
1059
1060    if ((hComponent != handle) || !pBuffer)
1061        return OMX_ErrorBadParameter;
1062
1063    ret = CheckTypeHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE));
1064    if (ret != OMX_ErrorNone)
1065        return ret;
1066
1067    port_index = pBuffer->nOutputPortIndex;
1068    if (port_index == (OMX_U32)-1)
1069        return OMX_ErrorBadParameter;
1070
1071    if (ports)
1072        if (port_index < nr_ports)
1073            port = ports[port_index];
1074
1075    if (!port)
1076        return OMX_ErrorBadParameter;
1077
1078    if (pBuffer->pOutputPortPrivate != port)
1079        return OMX_ErrorBadParameter;
1080
1081    if (port->IsEnabled()) {
1082        if (state != OMX_StateIdle && state != OMX_StateExecuting &&
1083            state != OMX_StatePause)
1084            return OMX_ErrorIncorrectStateOperation;
1085    }
1086
1087    ret = port->PushThisBuffer(pBuffer);
1088    if (ret == OMX_ErrorNone)
1089        bufferwork->ScheduleWork(this);
1090
1091    return ret;
1092}
1093
1094OMX_ERRORTYPE ComponentBase::SetCallbacks(
1095    OMX_IN  OMX_HANDLETYPE hComponent,
1096    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
1097    OMX_IN  OMX_PTR pAppData)
1098{
1099    ComponentBase *cbase;
1100
1101    if (!hComponent)
1102        return OMX_ErrorBadParameter;
1103
1104    cbase = static_cast<ComponentBase *>
1105        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1106    if (!cbase)
1107        return OMX_ErrorBadParameter;
1108
1109    return cbase->CBaseSetCallbacks(hComponent, pCallbacks, pAppData);
1110}
1111
1112OMX_ERRORTYPE ComponentBase::CBaseSetCallbacks(
1113    OMX_IN  OMX_HANDLETYPE hComponent,
1114    OMX_IN  OMX_CALLBACKTYPE *pCallbacks,
1115    OMX_IN  OMX_PTR pAppData)
1116{
1117    if (hComponent != handle)
1118        return OMX_ErrorBadParameter;
1119
1120    appdata = pAppData;
1121    callbacks = pCallbacks;
1122
1123    return OMX_ErrorNone;
1124}
1125
1126OMX_ERRORTYPE ComponentBase::ComponentDeInit(
1127    OMX_IN  OMX_HANDLETYPE hComponent)
1128{
1129    ComponentBase *cbase;
1130
1131    if (!hComponent)
1132        return OMX_ErrorBadParameter;
1133
1134    cbase = static_cast<ComponentBase *>
1135        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1136    if (!cbase)
1137        return OMX_ErrorBadParameter;
1138
1139    return cbase->CBaseComponentDeInit(hComponent);
1140}
1141
1142OMX_ERRORTYPE ComponentBase::CBaseComponentDeInit(
1143    OMX_IN  OMX_HANDLETYPE hComponent)
1144{
1145    /*
1146     * Todo
1147     */
1148
1149    return OMX_ErrorNotImplemented;
1150}
1151
1152OMX_ERRORTYPE ComponentBase::UseEGLImage(
1153    OMX_IN OMX_HANDLETYPE hComponent,
1154    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1155    OMX_IN OMX_U32 nPortIndex,
1156    OMX_IN OMX_PTR pAppPrivate,
1157    OMX_IN void* eglImage)
1158{
1159    ComponentBase *cbase;
1160
1161    if (!hComponent)
1162        return OMX_ErrorBadParameter;
1163
1164    cbase = static_cast<ComponentBase *>
1165        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1166    if (!cbase)
1167        return OMX_ErrorBadParameter;
1168
1169    return cbase->CBaseUseEGLImage(hComponent, ppBufferHdr, nPortIndex,
1170                                   pAppPrivate, eglImage);
1171}
1172
1173OMX_ERRORTYPE ComponentBase::CBaseUseEGLImage(
1174    OMX_IN OMX_HANDLETYPE hComponent,
1175    OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
1176    OMX_IN OMX_U32 nPortIndex,
1177    OMX_IN OMX_PTR pAppPrivate,
1178    OMX_IN void* eglImage)
1179{
1180    /*
1181     * Todo
1182     */
1183
1184    return OMX_ErrorNotImplemented;
1185}
1186
1187OMX_ERRORTYPE ComponentBase::ComponentRoleEnum(
1188    OMX_IN OMX_HANDLETYPE hComponent,
1189    OMX_OUT OMX_U8 *cRole,
1190    OMX_IN OMX_U32 nIndex)
1191{
1192    ComponentBase *cbase;
1193
1194    if (!hComponent)
1195        return OMX_ErrorBadParameter;
1196
1197    cbase = static_cast<ComponentBase *>
1198        (((OMX_COMPONENTTYPE *)hComponent)->pComponentPrivate);
1199    if (!cbase)
1200        return OMX_ErrorBadParameter;
1201
1202    return cbase->CBaseComponentRoleEnum(hComponent, cRole, nIndex);
1203}
1204
1205OMX_ERRORTYPE ComponentBase::CBaseComponentRoleEnum(
1206    OMX_IN OMX_HANDLETYPE hComponent,
1207    OMX_OUT OMX_U8 *cRole,
1208    OMX_IN OMX_U32 nIndex)
1209{
1210    if (hComponent != (OMX_HANDLETYPE *)this->handle)
1211        return OMX_ErrorBadParameter;
1212
1213    if (nIndex > nr_roles)
1214        return OMX_ErrorBadParameter;
1215
1216    strncpy((char *)cRole, (const char *)roles[nIndex],
1217            OMX_MAX_STRINGNAME_SIZE);
1218    return OMX_ErrorNone;
1219}
1220
1221/* implement CmdHandlerInterface */
1222static const char *cmd_name[OMX_CommandMarkBuffer+2] = {
1223    "OMX_CommandStateSet",
1224    "OMX_CommandFlush",
1225    "OMX_CommandPortDisable",
1226    "OMX_CommandPortEnable",
1227    "OMX_CommandMarkBuffer",
1228    "Unknown Command",
1229};
1230
1231static inline const char *GetCmdName(OMX_COMMANDTYPE cmd)
1232{
1233    if (cmd > OMX_CommandMarkBuffer)
1234        cmd = (OMX_COMMANDTYPE)(OMX_CommandMarkBuffer+1);
1235
1236    return cmd_name[cmd];
1237}
1238
1239void ComponentBase::CmdHandler(struct cmd_s *cmd)
1240{
1241    LOGV("%s:%s: handling %s command\n",
1242         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1243
1244    switch (cmd->cmd) {
1245    case OMX_CommandStateSet: {
1246        OMX_STATETYPE transition = (OMX_STATETYPE)cmd->param1;
1247
1248        TransState(transition);
1249        break;
1250    }
1251    case OMX_CommandFlush: {
1252        OMX_U32 port_index = cmd->param1;
1253
1254        FlushPort(port_index, 1);
1255        break;
1256    }
1257    case OMX_CommandPortDisable: {
1258        OMX_U32 port_index = cmd->param1;
1259
1260        TransStatePort(port_index, PortBase::OMX_PortDisabled);
1261        break;
1262    }
1263    case OMX_CommandPortEnable: {
1264        OMX_U32 port_index = cmd->param1;
1265
1266        TransStatePort(port_index, PortBase::OMX_PortEnabled);
1267        break;
1268    }
1269    case OMX_CommandMarkBuffer: {
1270        OMX_U32 port_index = (OMX_U32)cmd->param1;
1271        OMX_MARKTYPE *mark = (OMX_MARKTYPE *)cmd->cmddata;
1272
1273        PushThisMark(port_index, mark);
1274        break;
1275    }
1276    default:
1277        LOGE("%s:%s:%s: exit failure, command %d cannot be handled\n",
1278             GetName(), GetWorkingRole(), GetCmdName(cmd->cmd), cmd->cmd);
1279        break;
1280    } /* switch */
1281
1282    LOGV("%s:%s: command %s handling done\n",
1283         GetName(), GetWorkingRole(), GetCmdName(cmd->cmd));
1284}
1285
1286/*
1287 * SendCommand:OMX_CommandStateSet
1288 * called in CmdHandler or called in other parts of component for reporting
1289 * internal error (OMX_StateInvalid).
1290 */
1291/*
1292 * Todo
1293 *   Resource Management (OMX_StateWaitForResources)
1294 *   for now, we never notify OMX_ErrorInsufficientResources,
1295 *   so IL client doesn't try to set component' state OMX_StateWaitForResources
1296 */
1297static const char *state_name[OMX_StateWaitForResources+2] = {
1298    "OMX_StateInvalid",
1299    "OMX_StateLoaded",
1300    "OMX_StateIdle",
1301    "OMX_StateExecuting",
1302    "OMX_StatePause",
1303    "OMX_StateWaitForResources",
1304    "Unknown State",
1305};
1306
1307static inline const char *GetStateName(OMX_STATETYPE state)
1308{
1309    if (state > OMX_StateWaitForResources)
1310        state = (OMX_STATETYPE)(OMX_StateWaitForResources+1);
1311
1312    return state_name[state];
1313}
1314
1315void ComponentBase::TransState(OMX_STATETYPE transition)
1316{
1317    OMX_STATETYPE current = this->state;
1318    OMX_EVENTTYPE event;
1319    OMX_U32 data1, data2;
1320    OMX_ERRORTYPE ret;
1321
1322    LOGV("%s:%s: try to transit state from %s to %s\n",
1323         GetName(), GetWorkingRole(), GetStateName(current),
1324         GetStateName(transition));
1325
1326    /* same state */
1327    if (current == transition) {
1328        ret = OMX_ErrorSameState;
1329        LOGE("%s:%s: exit failure, same state (%s)\n",
1330             GetName(), GetWorkingRole(), GetStateName(current));
1331        goto notify_event;
1332    }
1333
1334    /* invalid state */
1335    if (current == OMX_StateInvalid) {
1336        ret = OMX_ErrorInvalidState;
1337        LOGE("%s:%s: exit failure, current state is OMX_StateInvalid\n",
1338             GetName(), GetWorkingRole());
1339        goto notify_event;
1340    }
1341
1342    if (transition == OMX_StateLoaded)
1343        ret = TransStateToLoaded(current);
1344    else if (transition == OMX_StateIdle)
1345        ret = TransStateToIdle(current);
1346    else if (transition == OMX_StateExecuting)
1347        ret = TransStateToExecuting(current);
1348    else if (transition == OMX_StatePause)
1349        ret = TransStateToPause(current);
1350    else if (transition == OMX_StateInvalid)
1351        ret = TransStateToInvalid(current);
1352    else if (transition == OMX_StateWaitForResources)
1353        ret = TransStateToWaitForResources(current);
1354    else
1355        ret = OMX_ErrorIncorrectStateTransition;
1356
1357notify_event:
1358    if (ret == OMX_ErrorNone) {
1359        event = OMX_EventCmdComplete;
1360        data1 = OMX_CommandStateSet;
1361        data2 = transition;
1362
1363        state = transition;
1364        LOGD("%s:%s: transition from %s to %s completed",
1365             GetName(), GetWorkingRole(),
1366             GetStateName(current), GetStateName(transition));
1367    }
1368    else {
1369        event = OMX_EventError;
1370        data1 = ret;
1371        data2 = 0;
1372
1373        if (transition == OMX_StateInvalid || ret == OMX_ErrorInvalidState) {
1374            state = OMX_StateInvalid;
1375            LOGE("%s:%s: exit failure, transition from %s to %s, "
1376                 "current state is %s\n",
1377                 GetName(), GetWorkingRole(), GetStateName(current),
1378                 GetStateName(transition), GetStateName(state));
1379        }
1380    }
1381
1382    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1383
1384    /* WaitForResources workaround */
1385    if (ret == OMX_ErrorNone && transition == OMX_StateWaitForResources)
1386        callbacks->EventHandler(handle, appdata,
1387                                OMX_EventResourcesAcquired, 0, 0, NULL);
1388}
1389
1390inline OMX_ERRORTYPE ComponentBase::TransStateToLoaded(OMX_STATETYPE current)
1391{
1392    OMX_ERRORTYPE ret;
1393
1394    if (current == OMX_StateIdle) {
1395        OMX_U32 i;
1396
1397        for (i = 0; i < nr_ports; i++)
1398            ports[i]->WaitPortBufferCompletion();
1399
1400        ret = ProcessorDeinit();
1401        if (ret != OMX_ErrorNone) {
1402            LOGE("%s:%s: ProcessorDeinit() failed "
1403                 "(ret : 0x%08x)\n", GetName(), GetWorkingRole(),
1404                 ret);
1405            goto out;
1406        }
1407    }
1408    else if (current == OMX_StateWaitForResources) {
1409        LOGV("%s:%s: "
1410             "state transition's requested from WaitForResources to Loaded\n",
1411             GetName(), GetWorkingRole());
1412
1413        /*
1414         * from WaitForResources to Loaded considered from Loaded to Loaded.
1415         * do nothing
1416         */
1417
1418        ret = OMX_ErrorNone;
1419    }
1420    else
1421        ret = OMX_ErrorIncorrectStateTransition;
1422
1423out:
1424    return ret;
1425}
1426
1427inline OMX_ERRORTYPE ComponentBase::TransStateToIdle(OMX_STATETYPE current)
1428{
1429    OMX_ERRORTYPE ret;
1430
1431    if (current == OMX_StateLoaded) {
1432        OMX_U32 i;
1433
1434        ret = ProcessorInit();
1435        if (ret != OMX_ErrorNone) {
1436            LOGE("%s:%s: ProcessorInit() failed (ret : 0x%08x)\n",
1437                 GetName(), GetWorkingRole(), ret);
1438            goto out;
1439        }
1440
1441        for (i = 0; i < nr_ports; i++) {
1442            if (ports[i]->IsEnabled())
1443                ports[i]->WaitPortBufferCompletion();
1444        }
1445    }
1446    else if ((current == OMX_StatePause) || (current == OMX_StateExecuting)) {
1447        FlushPort(OMX_ALL, 0);
1448        LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole());
1449
1450        bufferwork->CancelScheduledWork(this);
1451        LOGV("%s:%s: discarded all scheduled buffer process work\n",
1452             GetName(), GetWorkingRole());
1453
1454        if (current == OMX_StatePause) {
1455            bufferwork->ResumeWork();
1456            LOGV("%s:%s: buffer process work resumed\n",
1457                 GetName(), GetWorkingRole());
1458        }
1459
1460        bufferwork->StopWork();
1461        LOGV("%s:%s: buffer process work stopped\n",
1462             GetName(), GetWorkingRole());
1463
1464        ret = ProcessorStop();
1465        if (ret != OMX_ErrorNone) {
1466            LOGE("%s:%s: ProcessorStop() failed (ret : 0x%08x)\n",
1467                 GetName(), GetWorkingRole(), ret);
1468            goto out;
1469        }
1470    }
1471    else if (current == OMX_StateWaitForResources) {
1472        LOGV("%s:%s: "
1473             "state transition's requested from WaitForResources to Idle\n",
1474             GetName(), GetWorkingRole());
1475
1476        /* same as Loaded to Idle BUT DO NOTHING for now */
1477
1478        ret = OMX_ErrorNone;
1479    }
1480    else
1481        ret = OMX_ErrorIncorrectStateTransition;
1482
1483out:
1484    return ret;
1485}
1486
1487inline OMX_ERRORTYPE
1488ComponentBase::TransStateToExecuting(OMX_STATETYPE current)
1489{
1490    OMX_ERRORTYPE ret;
1491
1492    if (current == OMX_StateIdle) {
1493        bufferwork->StartWork(true);
1494        LOGV("%s:%s: buffer process work started with executing state\n",
1495             GetName(), GetWorkingRole());
1496
1497        ret = ProcessorStart();
1498        if (ret != OMX_ErrorNone) {
1499            LOGE("%s:%s: ProcessorStart() failed (ret : 0x%08x)\n",
1500                 GetName(), GetWorkingRole(), ret);
1501            goto out;
1502        }
1503    }
1504    else if (current == OMX_StatePause) {
1505        bufferwork->ResumeWork();
1506        LOGV("%s:%s: buffer process work resumed\n",
1507             GetName(), GetWorkingRole());
1508
1509        ret = ProcessorResume();
1510        if (ret != OMX_ErrorNone) {
1511            LOGE("%s:%s: ProcessorResume() failed (ret : 0x%08x)\n",
1512                 GetName(), GetWorkingRole(), ret);
1513            goto out;
1514        }
1515    }
1516    else
1517        ret = OMX_ErrorIncorrectStateTransition;
1518
1519out:
1520    return ret;
1521}
1522
1523inline OMX_ERRORTYPE ComponentBase::TransStateToPause(OMX_STATETYPE current)
1524{
1525    OMX_ERRORTYPE ret;
1526
1527    if (current == OMX_StateIdle) {
1528        bufferwork->StartWork(false);
1529        LOGV("%s:%s: buffer process work started with paused state\n",
1530             GetName(), GetWorkingRole());
1531
1532        ret = ProcessorStart();
1533        if (ret != OMX_ErrorNone) {
1534            LOGE("%s:%s: ProcessorSart() failed (ret : 0x%08x)\n",
1535                 GetName(), GetWorkingRole(), ret);
1536            goto out;
1537        }
1538    }
1539    else if (current == OMX_StateExecuting) {
1540        bufferwork->PauseWork();
1541        LOGV("%s:%s: buffer process work paused\n",
1542             GetName(), GetWorkingRole());
1543
1544        ret = ProcessorPause();
1545        if (ret != OMX_ErrorNone) {
1546            LOGE("%s:%s: ProcessorPause() failed (ret : 0x%08x)\n",
1547                 GetName(), GetWorkingRole(), ret);
1548            goto out;
1549        }
1550    }
1551    else
1552        ret = OMX_ErrorIncorrectStateTransition;
1553
1554out:
1555    return ret;
1556}
1557
1558inline OMX_ERRORTYPE ComponentBase::TransStateToInvalid(OMX_STATETYPE current)
1559{
1560    OMX_ERRORTYPE ret = OMX_ErrorInvalidState;
1561
1562    /*
1563     * Todo
1564     *   graceful escape
1565     */
1566
1567    return ret;
1568}
1569
1570inline OMX_ERRORTYPE
1571ComponentBase::TransStateToWaitForResources(OMX_STATETYPE current)
1572{
1573    OMX_ERRORTYPE ret;
1574
1575    if (current == OMX_StateLoaded) {
1576        LOGV("%s:%s: "
1577             "state transition's requested from Loaded to WaitForResources\n",
1578             GetName(), GetWorkingRole());
1579        ret = OMX_ErrorNone;
1580    }
1581    else
1582        ret = OMX_ErrorIncorrectStateTransition;
1583
1584    return ret;
1585}
1586
1587/* mark buffer */
1588void ComponentBase::PushThisMark(OMX_U32 port_index, OMX_MARKTYPE *mark)
1589{
1590    PortBase *port = NULL;
1591    OMX_EVENTTYPE event;
1592    OMX_U32 data1, data2;
1593    OMX_ERRORTYPE ret;
1594
1595    if (ports)
1596        if (port_index < nr_ports)
1597            port = ports[port_index];
1598
1599    if (!port) {
1600        ret = OMX_ErrorBadPortIndex;
1601        goto notify_event;
1602    }
1603
1604    ret = port->PushMark(mark);
1605    if (ret != OMX_ErrorNone) {
1606        /* don't report OMX_ErrorInsufficientResources */
1607        ret = OMX_ErrorUndefined;
1608        goto notify_event;
1609    }
1610
1611notify_event:
1612    if (ret == OMX_ErrorNone) {
1613        event = OMX_EventCmdComplete;
1614        data1 = OMX_CommandMarkBuffer;
1615        data2 = port_index;
1616    }
1617    else {
1618        event = OMX_EventError;
1619        data1 = ret;
1620        data2 = 0;
1621    }
1622
1623    callbacks->EventHandler(handle, appdata, event, data1, data2, NULL);
1624}
1625
1626void ComponentBase::FlushPort(OMX_U32 port_index, bool notify)
1627{
1628    OMX_U32 i, from_index, to_index;
1629
1630    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1631        return;
1632
1633    if (port_index == OMX_ALL) {
1634        from_index = 0;
1635        to_index = nr_ports - 1;
1636    }
1637    else {
1638        from_index = port_index;
1639        to_index = port_index;
1640    }
1641
1642    LOGV("%s:%s: flush ports (from index %lu to %lu)\n",
1643         GetName(), GetWorkingRole(), from_index, to_index);
1644
1645    pthread_mutex_lock(&ports_block);
1646    for (i = from_index; i <= to_index; i++) {
1647        ports[i]->FlushPort();
1648        if (notify)
1649            callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1650                                    OMX_CommandFlush, i, NULL);
1651    }
1652    pthread_mutex_unlock(&ports_block);
1653
1654    LOGV("%s:%s: flush ports done\n", GetName(), GetWorkingRole());
1655}
1656
1657extern const char *GetPortStateName(OMX_U8 state); //portbase.cpp
1658
1659void ComponentBase::TransStatePort(OMX_U32 port_index, OMX_U8 state)
1660{
1661    OMX_EVENTTYPE event;
1662    OMX_U32 data1, data2;
1663    OMX_U32 i, from_index, to_index;
1664    OMX_ERRORTYPE ret;
1665
1666    if ((port_index != OMX_ALL) && (port_index > nr_ports-1))
1667        return;
1668
1669    if (port_index == OMX_ALL) {
1670        from_index = 0;
1671        to_index = nr_ports - 1;
1672    }
1673    else {
1674        from_index = port_index;
1675        to_index = port_index;
1676    }
1677
1678    LOGV("%s:%s: transit ports state to %s (from index %lu to %lu)\n",
1679         GetName(), GetWorkingRole(), GetPortStateName(state),
1680         from_index, to_index);
1681
1682    pthread_mutex_lock(&ports_block);
1683    for (i = from_index; i <= to_index; i++) {
1684        ret = ports[i]->TransState(state);
1685        if (ret == OMX_ErrorNone) {
1686            event = OMX_EventCmdComplete;
1687            if (state == PortBase::OMX_PortEnabled)
1688                data1 = OMX_CommandPortEnable;
1689            else
1690                data1 = OMX_CommandPortDisable;
1691            data2 = i;
1692        }
1693        else {
1694            event = OMX_EventError;
1695            data1 = ret;
1696            data2 = 0;
1697        }
1698        callbacks->EventHandler(handle, appdata, OMX_EventCmdComplete,
1699                                data1, data2, NULL);
1700    }
1701    pthread_mutex_unlock(&ports_block);
1702
1703    LOGV("%s:%s: transit ports state to %s completed\n",
1704         GetName(), GetWorkingRole(), GetPortStateName(state));
1705}
1706
1707/* set working role */
1708OMX_ERRORTYPE ComponentBase::SetWorkingRole(const OMX_STRING role)
1709{
1710    OMX_U32 i;
1711
1712    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1713        return OMX_ErrorIncorrectStateOperation;
1714
1715    if (!role) {
1716        working_role = NULL;
1717        return OMX_ErrorNone;
1718    }
1719
1720    for (i = 0; i < nr_roles; i++) {
1721        if (!strcmp((char *)&roles[i][0], role)) {
1722            working_role = (OMX_STRING)&roles[i][0];
1723            return OMX_ErrorNone;
1724        }
1725    }
1726
1727    LOGE("%s: cannot find %s role\n", GetName(), role);
1728    return OMX_ErrorBadParameter;
1729}
1730
1731/* apply a working role for a component having multiple roles */
1732OMX_ERRORTYPE ComponentBase::ApplyWorkingRole(void)
1733{
1734    OMX_U32 i;
1735    OMX_ERRORTYPE ret;
1736
1737    if (state != OMX_StateUnloaded && state != OMX_StateLoaded)
1738        return OMX_ErrorIncorrectStateOperation;
1739
1740    if (!working_role)
1741        return OMX_ErrorBadParameter;
1742
1743    if (!callbacks || !appdata)
1744        return OMX_ErrorBadParameter;
1745
1746    ret = AllocatePorts();
1747    if (ret != OMX_ErrorNone) {
1748        LOGE("failed to AllocatePorts() (ret = 0x%08x)\n", ret);
1749        return ret;
1750    }
1751
1752    /* now we can access ports */
1753    for (i = 0; i < nr_ports; i++) {
1754        ports[i]->SetOwner(handle);
1755        ports[i]->SetCallbacks(handle, callbacks, appdata);
1756    }
1757
1758    LOGI("%s: set working role %s:", GetName(), GetWorkingRole());
1759    return OMX_ErrorNone;
1760}
1761
1762OMX_ERRORTYPE ComponentBase::AllocatePorts(void)
1763{
1764    OMX_DIRTYPE dir;
1765    bool has_input, has_output;
1766    OMX_U32 i;
1767    OMX_ERRORTYPE ret;
1768
1769    if (ports)
1770        return OMX_ErrorBadParameter;
1771
1772    ret = ComponentAllocatePorts();
1773    if (ret != OMX_ErrorNone) {
1774        LOGE("failed to %s::ComponentAllocatePorts(), ret = 0x%08x\n",
1775             name, ret);
1776        return ret;
1777    }
1778
1779    has_input = false;
1780    has_output = false;
1781    ret = OMX_ErrorNone;
1782    for (i = 0; i < nr_ports; i++) {
1783        dir = ports[i]->GetPortDirection();
1784        if (dir == OMX_DirInput)
1785            has_input = true;
1786        else if (dir == OMX_DirOutput)
1787            has_output = true;
1788        else {
1789            ret = OMX_ErrorUndefined;
1790            break;
1791        }
1792    }
1793    if (ret != OMX_ErrorNone)
1794        goto free_ports;
1795
1796    if ((has_input == false) && (has_output == true))
1797        cvariant = CVARIANT_SOURCE;
1798    else if ((has_input == true) && (has_output == true))
1799        cvariant = CVARIANT_FILTER;
1800    else if ((has_input == true) && (has_output == false))
1801        cvariant = CVARIANT_SINK;
1802    else
1803        goto free_ports;
1804
1805    return OMX_ErrorNone;
1806
1807free_ports:
1808    LOGE("%s(): exit, unknown component variant\n", __func__);
1809    FreePorts();
1810    return ret;
1811}
1812
1813/* called int FreeHandle() */
1814OMX_ERRORTYPE ComponentBase::FreePorts(void)
1815{
1816    if (ports) {
1817        OMX_U32 i, this_nr_ports = this->nr_ports;
1818
1819        for (i = 0; i < this_nr_ports; i++) {
1820            if (ports[i]) {
1821                OMX_MARKTYPE *mark;
1822                /* it should be empty before this */
1823                while ((mark = ports[i]->PopMark()))
1824                    free(mark);
1825
1826                delete ports[i];
1827                ports[i] = NULL;
1828            }
1829        }
1830        delete []ports;
1831        ports = NULL;
1832    }
1833
1834    return OMX_ErrorNone;
1835}
1836
1837/* buffer processing */
1838/* implement WorkableInterface */
1839void ComponentBase::Work(void)
1840{
1841    OMX_BUFFERHEADERTYPE *buffers[nr_ports];
1842    buffer_retain_t retain[nr_ports];
1843    OMX_U32 i;
1844    bool avail = false;
1845    OMX_ERRORTYPE ret;
1846
1847    pthread_mutex_lock(&ports_block);
1848
1849    avail = IsAllBufferAvailable();
1850    if (avail) {
1851        for (i = 0; i < nr_ports; i++) {
1852            buffers[i] = ports[i]->PopBuffer();
1853            retain[i] = BUFFER_RETAIN_NOT_RETAIN;
1854        }
1855
1856        ret = ProcessorProcess(buffers, &retain[0], nr_ports);
1857
1858        if (ret == OMX_ErrorNone) {
1859            PostProcessBuffers(buffers, &retain[0]);
1860
1861            for (i = 0; i < nr_ports; i++) {
1862                if (retain[i] == BUFFER_RETAIN_GETAGAIN)
1863                    ports[i]->RetainThisBuffer(buffers[i], false);
1864                else if (retain[i] == BUFFER_RETAIN_ACCUMULATE)
1865                    ports[i]->RetainThisBuffer(buffers[i], true);
1866                else
1867                    ports[i]->ReturnThisBuffer(buffers[i]);
1868            }
1869        }
1870        else {
1871            callbacks->EventHandler(handle, appdata, OMX_EventError, ret,
1872                                    0, NULL);
1873
1874            for (i = 0; i < nr_ports; i++) {
1875                /* return buffers by hands, these buffers're not in queue */
1876                ports[i]->ReturnThisBuffer(buffers[i]);
1877                /* flush ports */
1878                ports[i]->FlushPort();
1879            }
1880        }
1881    }
1882
1883    pthread_mutex_unlock(&ports_block);
1884}
1885
1886bool ComponentBase::IsAllBufferAvailable(void)
1887{
1888    OMX_U32 i;
1889    OMX_U32 nr_avail = 0;
1890
1891    for (i = 0; i < nr_ports; i++) {
1892        OMX_U32 length = 0;
1893
1894        if (ports[i]->IsEnabled())
1895            length = ports[i]->BufferQueueLength();
1896
1897        if (length)
1898            nr_avail++;
1899    }
1900
1901    if (nr_avail == nr_ports)
1902        return true;
1903    else
1904        return false;
1905}
1906
1907inline void ComponentBase::SourcePostProcessBuffers(
1908    OMX_BUFFERHEADERTYPE **buffers,
1909    const buffer_retain_t *retain)
1910{
1911    OMX_U32 i;
1912
1913    for (i = 0; i < nr_ports; i++) {
1914        /*
1915         * in case of source component, buffers're marked when they come
1916         * from the ouput ports
1917         */
1918        if (!buffers[i]->hMarkTargetComponent) {
1919            OMX_MARKTYPE *mark;
1920
1921            mark = ports[i]->PopMark();
1922            if (mark) {
1923                buffers[i]->hMarkTargetComponent =
1924                    mark->hMarkTargetComponent;
1925                buffers[i]->pMarkData = mark->pMarkData;
1926                free(mark);
1927            }
1928        }
1929    }
1930}
1931
1932inline void ComponentBase::FilterPostProcessBuffers(
1933    OMX_BUFFERHEADERTYPE **buffers,
1934    const buffer_retain_t *retain)
1935{
1936    OMX_MARKTYPE *mark;
1937    OMX_U32 i, j;
1938
1939    for (i = 0; i < nr_ports; i++) {
1940        if (ports[i]->GetPortDirection() == OMX_DirInput) {
1941            for (j = 0; j < nr_ports; j++) {
1942                if (ports[j]->GetPortDirection() != OMX_DirOutput)
1943                    continue;
1944
1945                /* propagates EOS flag */
1946                /* clear input EOS at the end of this loop */
1947                if (retain[i] != BUFFER_RETAIN_GETAGAIN) {
1948                    if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS)
1949                        buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS;
1950                }
1951
1952                /* propagates marks */
1953                /*
1954                 * if hMarkTargetComponent == handle then the mark's not
1955                 * propagated
1956                 */
1957                if (buffers[i]->hMarkTargetComponent &&
1958                    (buffers[i]->hMarkTargetComponent != handle)) {
1959                    if (buffers[j]->hMarkTargetComponent) {
1960                        mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1961                        if (mark) {
1962                            mark->hMarkTargetComponent =
1963                                buffers[i]->hMarkTargetComponent;
1964                            mark->pMarkData = buffers[i]->pMarkData;
1965                            ports[j]->PushMark(mark);
1966                            mark = NULL;
1967                            buffers[i]->hMarkTargetComponent = NULL;
1968                            buffers[i]->pMarkData = NULL;
1969                        }
1970                    }
1971                    else {
1972                        mark = ports[j]->PopMark();
1973                        if (mark) {
1974                            buffers[j]->hMarkTargetComponent =
1975                                mark->hMarkTargetComponent;
1976                            buffers[j]->pMarkData = mark->pMarkData;
1977                            free(mark);
1978
1979                            mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1980                            if (mark) {
1981                                mark->hMarkTargetComponent =
1982                                    buffers[i]->hMarkTargetComponent;
1983                                mark->pMarkData = buffers[i]->pMarkData;
1984                                ports[j]->PushMark(mark);
1985                                mark = NULL;
1986                                buffers[i]->hMarkTargetComponent = NULL;
1987                                buffers[i]->pMarkData = NULL;
1988                            }
1989                        }
1990                        else {
1991                            buffers[j]->hMarkTargetComponent =
1992                                buffers[i]->hMarkTargetComponent;
1993                            buffers[j]->pMarkData = buffers[i]->pMarkData;
1994                            buffers[i]->hMarkTargetComponent = NULL;
1995                            buffers[i]->pMarkData = NULL;
1996                        }
1997                    }
1998                }
1999            }
2000            /* clear input buffer's EOS */
2001            if (retain[i] != BUFFER_RETAIN_GETAGAIN)
2002                buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS;
2003        }
2004    }
2005}
2006
2007inline void ComponentBase::SinkPostProcessBuffers(
2008    OMX_BUFFERHEADERTYPE **buffers,
2009    const buffer_retain_t *retain)
2010{
2011    return;
2012}
2013
2014void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE **buffers,
2015                                       const buffer_retain_t *retain)
2016{
2017
2018    if (cvariant == CVARIANT_SOURCE)
2019        SourcePostProcessBuffers(buffers, retain);
2020    else if (cvariant == CVARIANT_FILTER)
2021        FilterPostProcessBuffers(buffers, retain);
2022    else if (cvariant == CVARIANT_SINK) {
2023        SinkPostProcessBuffers(buffers, retain);
2024    }
2025    else {
2026        LOGE("%s(): fatal error unknown component variant (%d)\n",
2027             __func__, cvariant);
2028    }
2029}
2030
2031/* processor default callbacks */
2032OMX_ERRORTYPE ComponentBase::ProcessorInit(void)
2033{
2034    return OMX_ErrorNone;
2035}
2036OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void)
2037{
2038    return OMX_ErrorNone;
2039}
2040
2041OMX_ERRORTYPE ComponentBase::ProcessorStart(void)
2042{
2043    return OMX_ErrorNone;
2044}
2045
2046OMX_ERRORTYPE ComponentBase::ProcessorStop(void)
2047{
2048    return OMX_ErrorNone;
2049}
2050
2051OMX_ERRORTYPE ComponentBase::ProcessorPause(void)
2052{
2053    return OMX_ErrorNone;
2054}
2055
2056OMX_ERRORTYPE ComponentBase::ProcessorResume(void)
2057{
2058    return OMX_ErrorNone;
2059}
2060
2061/* end of processor callbacks */
2062
2063/* helper for derived class */
2064const OMX_STRING ComponentBase::GetWorkingRole(void)
2065{
2066    return &working_role[0];
2067}
2068
2069const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void)
2070{
2071    return handle;
2072}
2073
2074void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader,
2075                               bool dumpdata)
2076{
2077    OMX_U8 *pbuffer = bufferheader->pBuffer, *p;
2078    OMX_U32 offset = bufferheader->nOffset;
2079    OMX_U32 alloc_len = bufferheader->nAllocLen;
2080    OMX_U32 filled_len =  bufferheader->nFilledLen;
2081    OMX_U32 left = filled_len, oneline;
2082    OMX_U32 index = 0, i;
2083    /* 0x%04lx:  %02x %02x .. (n = 16)\n\0 */
2084    char prbuffer[8 + 3 * 0x10 + 2], *pp;
2085    OMX_U32 prbuffer_len;
2086
2087    LOGD("Component %s DumpBuffer\n", name);
2088    LOGD("%s port index = %lu",
2089         (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output",
2090         (bufferheader->nInputPortIndex != 0x7fffffff) ?
2091         bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex);
2092    LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n",
2093         alloc_len, offset, filled_len);
2094    LOGD("nTimeStamp = %lld, nTickCount = %lu",
2095         bufferheader->nTimeStamp,
2096         bufferheader->nTickCount);
2097    LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags);
2098    LOGD("hMarkTargetComponent = %p, pMarkData = %p\n",
2099         bufferheader->hMarkTargetComponent, bufferheader->pMarkData);
2100
2101    if (!pbuffer || !alloc_len || !filled_len)
2102        return;
2103
2104    if (offset + filled_len > alloc_len)
2105        return;
2106
2107    if (!dumpdata)
2108        return;
2109
2110    p = pbuffer + offset;
2111    while (left) {
2112        oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */
2113        pp += sprintf(pp, "0x%04lx: ", index);
2114        for (i = 0; i < oneline; i++)
2115            pp += sprintf(pp, " %02x", *(p + i));
2116        pp += sprintf(pp, "\n");
2117        *pp = '\0';
2118
2119        index += 0x10;
2120        p += oneline;
2121        left -= oneline;
2122
2123        pp = &prbuffer[0];
2124        LOGD("%s", pp);
2125    }
2126}
2127
2128/* end of component methods & helpers */
2129
2130/*
2131 * omx header manipuation
2132 */
2133void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
2134{
2135    OMX_U32 *nsize;
2136    OMX_VERSIONTYPE *nversion;
2137
2138    if (!type)
2139        return;
2140
2141    nsize = (OMX_U32 *)type;
2142    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2143
2144    *nsize = size;
2145    nversion->nVersion = OMX_SPEC_VERSION;
2146}
2147
2148OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size)
2149{
2150    OMX_U32 *nsize;
2151    OMX_VERSIONTYPE *nversion;
2152
2153    if (!type)
2154        return OMX_ErrorBadParameter;
2155
2156    nsize = (OMX_U32 *)type;
2157    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2158
2159    if (*nsize != size)
2160        return OMX_ErrorBadParameter;
2161
2162    if (nversion->nVersion != OMX_SPEC_VERSION)
2163        return OMX_ErrorVersionMismatch;
2164
2165    return OMX_ErrorNone;
2166}
2167
2168/* end of ComponentBase */
2169