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