componentbase.cpp revision ac3429dfacf1c5a03889558006f2af0d40a7bfe8
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            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        LOGV("%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        LOGV("%s:%s: flushed all ports\n", GetName(), GetWorkingRole());
1462
1463        bufferwork->CancelScheduledWork(this);
1464        LOGV("%s:%s: discarded all scheduled buffer process work\n",
1465             GetName(), GetWorkingRole());
1466
1467        if (current == OMX_StatePause) {
1468            bufferwork->ResumeWork();
1469            LOGV("%s:%s: buffer process work resumed\n",
1470                 GetName(), GetWorkingRole());
1471        }
1472
1473        bufferwork->StopWork();
1474        LOGV("%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        LOGV("%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        LOGV("%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        LOGV("%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        LOGV("%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        LOGV("%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        LOGV("%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                                data1, 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    OMX_ERRORTYPE ret;
1859
1860    pthread_mutex_lock(&ports_block);
1861
1862    avail = IsAllBufferAvailable();
1863    if (avail) {
1864        for (i = 0; i < nr_ports; i++) {
1865            buffers[i] = ports[i]->PopBuffer();
1866            retain[i] = BUFFER_RETAIN_NOT_RETAIN;
1867        }
1868
1869        ret = ProcessorProcess(buffers, &retain[0], nr_ports);
1870
1871        if (ret == OMX_ErrorNone) {
1872            PostProcessBuffers(buffers, &retain[0]);
1873
1874            for (i = 0; i < nr_ports; i++) {
1875                if (retain[i] == BUFFER_RETAIN_GETAGAIN)
1876                    ports[i]->RetainThisBuffer(buffers[i], false);
1877                else if (retain[i] == BUFFER_RETAIN_ACCUMULATE)
1878                    ports[i]->RetainThisBuffer(buffers[i], true);
1879                else
1880                    ports[i]->ReturnThisBuffer(buffers[i]);
1881            }
1882        }
1883        else {
1884            callbacks->EventHandler(handle, appdata, OMX_EventError, ret,
1885                                    0, NULL);
1886
1887            for (i = 0; i < nr_ports; i++) {
1888                /* return buffers by hands, these buffers're not in queue */
1889                ports[i]->ReturnThisBuffer(buffers[i]);
1890                /* flush ports */
1891                ports[i]->FlushPort();
1892            }
1893        }
1894    }
1895
1896    pthread_mutex_unlock(&ports_block);
1897}
1898
1899bool ComponentBase::IsAllBufferAvailable(void)
1900{
1901    OMX_U32 i;
1902    OMX_U32 nr_avail = 0;
1903
1904    for (i = 0; i < nr_ports; i++) {
1905        OMX_U32 length = 0;
1906
1907        if (ports[i]->IsEnabled())
1908            length = ports[i]->BufferQueueLength();
1909
1910        if (length)
1911            nr_avail++;
1912    }
1913
1914    if (nr_avail == nr_ports)
1915        return true;
1916    else
1917        return false;
1918}
1919
1920inline void ComponentBase::SourcePostProcessBuffers(
1921    OMX_BUFFERHEADERTYPE **buffers,
1922    const buffer_retain_t *retain)
1923{
1924    OMX_U32 i;
1925
1926    for (i = 0; i < nr_ports; i++) {
1927        /*
1928         * in case of source component, buffers're marked when they come
1929         * from the ouput ports
1930         */
1931        if (!buffers[i]->hMarkTargetComponent) {
1932            OMX_MARKTYPE *mark;
1933
1934            mark = ports[i]->PopMark();
1935            if (mark) {
1936                buffers[i]->hMarkTargetComponent =
1937                    mark->hMarkTargetComponent;
1938                buffers[i]->pMarkData = mark->pMarkData;
1939                free(mark);
1940            }
1941        }
1942    }
1943}
1944
1945inline void ComponentBase::FilterPostProcessBuffers(
1946    OMX_BUFFERHEADERTYPE **buffers,
1947    const buffer_retain_t *retain)
1948{
1949    OMX_MARKTYPE *mark;
1950    OMX_U32 i, j;
1951
1952    for (i = 0; i < nr_ports; i++) {
1953        if (ports[i]->GetPortDirection() == OMX_DirInput) {
1954            for (j = 0; j < nr_ports; j++) {
1955                if (ports[j]->GetPortDirection() != OMX_DirOutput)
1956                    continue;
1957
1958                /* propagates EOS flag */
1959                /* clear input EOS at the end of this loop */
1960                if (retain[i] != BUFFER_RETAIN_GETAGAIN) {
1961                    if (buffers[i]->nFlags & OMX_BUFFERFLAG_EOS)
1962                        buffers[j]->nFlags |= OMX_BUFFERFLAG_EOS;
1963                }
1964
1965                /* propagates marks */
1966                /*
1967                 * if hMarkTargetComponent == handle then the mark's not
1968                 * propagated
1969                 */
1970                if (buffers[i]->hMarkTargetComponent &&
1971                    (buffers[i]->hMarkTargetComponent != handle)) {
1972                    if (buffers[j]->hMarkTargetComponent) {
1973                        mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1974                        if (mark) {
1975                            mark->hMarkTargetComponent =
1976                                buffers[i]->hMarkTargetComponent;
1977                            mark->pMarkData = buffers[i]->pMarkData;
1978                            ports[j]->PushMark(mark);
1979                            mark = NULL;
1980                            buffers[i]->hMarkTargetComponent = NULL;
1981                            buffers[i]->pMarkData = NULL;
1982                        }
1983                    }
1984                    else {
1985                        mark = ports[j]->PopMark();
1986                        if (mark) {
1987                            buffers[j]->hMarkTargetComponent =
1988                                mark->hMarkTargetComponent;
1989                            buffers[j]->pMarkData = mark->pMarkData;
1990                            free(mark);
1991
1992                            mark = (OMX_MARKTYPE *)malloc(sizeof(*mark));
1993                            if (mark) {
1994                                mark->hMarkTargetComponent =
1995                                    buffers[i]->hMarkTargetComponent;
1996                                mark->pMarkData = buffers[i]->pMarkData;
1997                                ports[j]->PushMark(mark);
1998                                mark = NULL;
1999                                buffers[i]->hMarkTargetComponent = NULL;
2000                                buffers[i]->pMarkData = NULL;
2001                            }
2002                        }
2003                        else {
2004                            buffers[j]->hMarkTargetComponent =
2005                                buffers[i]->hMarkTargetComponent;
2006                            buffers[j]->pMarkData = buffers[i]->pMarkData;
2007                            buffers[i]->hMarkTargetComponent = NULL;
2008                            buffers[i]->pMarkData = NULL;
2009                        }
2010                    }
2011                }
2012            }
2013            /* clear input buffer's EOS */
2014            if (retain[i] != BUFFER_RETAIN_GETAGAIN)
2015                buffers[i]->nFlags &= ~OMX_BUFFERFLAG_EOS;
2016        }
2017    }
2018}
2019
2020inline void ComponentBase::SinkPostProcessBuffers(
2021    OMX_BUFFERHEADERTYPE **buffers,
2022    const buffer_retain_t *retain)
2023{
2024    return;
2025}
2026
2027void ComponentBase::PostProcessBuffers(OMX_BUFFERHEADERTYPE **buffers,
2028                                       const buffer_retain_t *retain)
2029{
2030
2031    if (cvariant == CVARIANT_SOURCE)
2032        SourcePostProcessBuffers(buffers, retain);
2033    else if (cvariant == CVARIANT_FILTER)
2034        FilterPostProcessBuffers(buffers, retain);
2035    else if (cvariant == CVARIANT_SINK) {
2036        SinkPostProcessBuffers(buffers, retain);
2037    }
2038    else {
2039        LOGE("%s(): fatal error unknown component variant (%d)\n",
2040             __func__, cvariant);
2041    }
2042}
2043
2044/* processor default callbacks */
2045OMX_ERRORTYPE ComponentBase::ProcessorInit(void)
2046{
2047    return OMX_ErrorNone;
2048}
2049OMX_ERRORTYPE ComponentBase::ProcessorDeinit(void)
2050{
2051    return OMX_ErrorNone;
2052}
2053
2054OMX_ERRORTYPE ComponentBase::ProcessorStart(void)
2055{
2056    return OMX_ErrorNone;
2057}
2058
2059OMX_ERRORTYPE ComponentBase::ProcessorStop(void)
2060{
2061    return OMX_ErrorNone;
2062}
2063
2064OMX_ERRORTYPE ComponentBase::ProcessorPause(void)
2065{
2066    return OMX_ErrorNone;
2067}
2068
2069OMX_ERRORTYPE ComponentBase::ProcessorResume(void)
2070{
2071    return OMX_ErrorNone;
2072}
2073
2074OMX_ERRORTYPE ComponentBase::ProcessorFlush(OMX_U32 port_index)
2075{
2076    return OMX_ErrorNone;
2077}
2078
2079/* end of processor callbacks */
2080
2081/* helper for derived class */
2082const OMX_STRING ComponentBase::GetWorkingRole(void)
2083{
2084    return &working_role[0];
2085}
2086
2087const OMX_COMPONENTTYPE *ComponentBase::GetComponentHandle(void)
2088{
2089    return handle;
2090}
2091
2092void ComponentBase::DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader,
2093                               bool dumpdata)
2094{
2095    OMX_U8 *pbuffer = bufferheader->pBuffer, *p;
2096    OMX_U32 offset = bufferheader->nOffset;
2097    OMX_U32 alloc_len = bufferheader->nAllocLen;
2098    OMX_U32 filled_len =  bufferheader->nFilledLen;
2099    OMX_U32 left = filled_len, oneline;
2100    OMX_U32 index = 0, i;
2101    /* 0x%04lx:  %02x %02x .. (n = 16)\n\0 */
2102    char prbuffer[8 + 3 * 0x10 + 2], *pp;
2103    OMX_U32 prbuffer_len;
2104
2105    LOGD("Component %s DumpBuffer\n", name);
2106    LOGD("%s port index = %lu",
2107         (bufferheader->nInputPortIndex != 0x7fffffff) ? "input" : "output",
2108         (bufferheader->nInputPortIndex != 0x7fffffff) ?
2109         bufferheader->nInputPortIndex : bufferheader->nOutputPortIndex);
2110    LOGD("nAllocLen = %lu, nOffset = %lu, nFilledLen = %lu\n",
2111         alloc_len, offset, filled_len);
2112    LOGD("nTimeStamp = %lld, nTickCount = %lu",
2113         bufferheader->nTimeStamp,
2114         bufferheader->nTickCount);
2115    LOGD("nFlags = 0x%08lx\n", bufferheader->nFlags);
2116    LOGD("hMarkTargetComponent = %p, pMarkData = %p\n",
2117         bufferheader->hMarkTargetComponent, bufferheader->pMarkData);
2118
2119    if (!pbuffer || !alloc_len || !filled_len)
2120        return;
2121
2122    if (offset + filled_len > alloc_len)
2123        return;
2124
2125    if (!dumpdata)
2126        return;
2127
2128    p = pbuffer + offset;
2129    while (left) {
2130        oneline = left > 0x10 ? 0x10 : left; /* 16 items per 1 line */
2131        pp += sprintf(pp, "0x%04lx: ", index);
2132        for (i = 0; i < oneline; i++)
2133            pp += sprintf(pp, " %02x", *(p + i));
2134        pp += sprintf(pp, "\n");
2135        *pp = '\0';
2136
2137        index += 0x10;
2138        p += oneline;
2139        left -= oneline;
2140
2141        pp = &prbuffer[0];
2142        LOGD("%s", pp);
2143    }
2144}
2145
2146/* end of component methods & helpers */
2147
2148/*
2149 * omx header manipuation
2150 */
2151void ComponentBase::SetTypeHeader(OMX_PTR type, OMX_U32 size)
2152{
2153    OMX_U32 *nsize;
2154    OMX_VERSIONTYPE *nversion;
2155
2156    if (!type)
2157        return;
2158
2159    nsize = (OMX_U32 *)type;
2160    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2161
2162    *nsize = size;
2163    nversion->nVersion = OMX_SPEC_VERSION;
2164}
2165
2166OMX_ERRORTYPE ComponentBase::CheckTypeHeader(const OMX_PTR type, OMX_U32 size)
2167{
2168    OMX_U32 *nsize;
2169    OMX_VERSIONTYPE *nversion;
2170
2171    if (!type)
2172        return OMX_ErrorBadParameter;
2173
2174    nsize = (OMX_U32 *)type;
2175    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
2176
2177    if (*nsize != size)
2178        return OMX_ErrorBadParameter;
2179
2180    if (nversion->nVersion != OMX_SPEC_VERSION)
2181        return OMX_ErrorVersionMismatch;
2182
2183    return OMX_ErrorNone;
2184}
2185
2186/* end of ComponentBase */
2187