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