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