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