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