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