componentbase.h revision ecc877a1dd44921dff3f300bc5559841f0c44ac6
1/*
2 * componentbase.h, 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#ifndef __COMPONENTBASE_H
20#define __COMPONENTBASE_H
21
22#include <OMX_Core.h>
23#include <OMX_Component.h>
24
25#include <cmodule.h>
26#include <portbase.h>
27
28#include <queue.h>
29#include <workqueue.h>
30
31/* retain buffers */
32typedef enum buffer_retain_e {
33    BUFFER_RETAIN_NOT_RETAIN = 0,
34    BUFFER_RETAIN_GETAGAIN,
35    BUFFER_RETAIN_ACCUMULATE,
36    BUFFER_RETAIN_OVERRIDDEN,
37} buffer_retain_t;
38
39/* ProcessCmdWork */
40struct cmd_s {
41    OMX_COMMANDTYPE cmd;
42    OMX_U32 param1;
43    OMX_PTR cmddata;
44};
45
46class CmdHandlerInterface
47{
48public:
49    virtual ~CmdHandlerInterface() {};
50    virtual void CmdHandler(struct cmd_s *cmd) = 0;
51};
52
53class CmdProcessWork : public WorkableInterface
54{
55public:
56    CmdProcessWork(CmdHandlerInterface *ci);
57    ~CmdProcessWork();
58
59    OMX_ERRORTYPE PushCmdQueue(struct cmd_s *cmd);
60
61private:
62    struct cmd_s *PopCmdQueue(void);
63
64    virtual void Work(void); /* call ci->CmdHandler() */
65
66    WorkQueue *workq;
67
68    struct queue q;
69    pthread_mutex_t lock;
70
71    CmdHandlerInterface *ci; /* to run ComponentBase::CmdHandler() */
72};
73
74class ComponentBase : public CmdHandlerInterface, public WorkableInterface
75{
76public:
77    /*
78     * constructor & destructor
79     */
80    ComponentBase();
81    ComponentBase(const OMX_STRING name);
82    virtual ~ComponentBase();
83
84    /*
85     * accessor
86     */
87    /* name */
88    void SetName(const OMX_STRING name);
89    const OMX_STRING GetName(void);
90
91    /* working role */
92    const OMX_STRING GetWorkingRole(void);
93
94    /* cmodule */
95    void SetCModule(CModule *cmodule);
96    CModule *GetCModule(void);
97
98    /* end of accessor */
99
100    /*
101     * core methods & helpers
102     */
103    /* roles */
104    OMX_ERRORTYPE SetRolesOfComponent(OMX_U32 nr_roles, const OMX_U8 **roles);
105
106    /* GetHandle & FreeHandle */
107    OMX_ERRORTYPE GetHandle(OMX_HANDLETYPE* pHandle,
108                            OMX_PTR pAppData,
109                            OMX_CALLBACKTYPE *pCallBacks);
110    OMX_ERRORTYPE FreeHandle(OMX_HANDLETYPE hComponent);
111
112    /* end of core methods & helpers */
113
114    /*
115     * component methods & helpers
116     */
117    static OMX_ERRORTYPE GetComponentVersion(
118        OMX_IN  OMX_HANDLETYPE hComponent,
119        OMX_OUT OMX_STRING pComponentName,
120        OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
121        OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
122        OMX_OUT OMX_UUIDTYPE* pComponentUUID);
123    OMX_ERRORTYPE CBaseGetComponentVersion(
124        OMX_IN  OMX_HANDLETYPE hComponent,
125        OMX_OUT OMX_STRING pComponentName,
126        OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
127        OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
128        OMX_OUT OMX_UUIDTYPE* pComponentUUID);
129
130    static OMX_ERRORTYPE SendCommand(
131        OMX_IN  OMX_HANDLETYPE hComponent,
132        OMX_IN  OMX_COMMANDTYPE Cmd,
133        OMX_IN  OMX_U32 nParam1,
134        OMX_IN  OMX_PTR pCmdData);
135    OMX_ERRORTYPE CBaseSendCommand(
136        OMX_IN  OMX_HANDLETYPE hComponent,
137        OMX_IN  OMX_COMMANDTYPE Cmd,
138        OMX_IN  OMX_U32 nParam1,
139        OMX_IN  OMX_PTR pCmdData);
140
141    static OMX_ERRORTYPE GetParameter(
142        OMX_IN  OMX_HANDLETYPE hComponent,
143        OMX_IN  OMX_INDEXTYPE nParamIndex,
144        OMX_INOUT OMX_PTR pComponentParameterStructure);
145    OMX_ERRORTYPE CBaseGetParameter(
146        OMX_IN  OMX_HANDLETYPE hComponent,
147        OMX_IN  OMX_INDEXTYPE nParamIndex,
148        OMX_INOUT OMX_PTR pComponentParameterStructure);
149
150    static OMX_ERRORTYPE SetParameter(
151        OMX_IN  OMX_HANDLETYPE hComponent,
152        OMX_IN  OMX_INDEXTYPE nIndex,
153        OMX_IN  OMX_PTR pComponentParameterStructure);
154    OMX_ERRORTYPE CBaseSetParameter(
155        OMX_IN  OMX_HANDLETYPE hComponent,
156        OMX_IN  OMX_INDEXTYPE nIndex,
157        OMX_IN  OMX_PTR pComponentParameterStructure);
158
159    static OMX_ERRORTYPE GetConfig(
160        OMX_IN  OMX_HANDLETYPE hComponent,
161        OMX_IN  OMX_INDEXTYPE nIndex,
162        OMX_INOUT OMX_PTR pComponentConfigStructure);
163    OMX_ERRORTYPE CBaseGetConfig(
164        OMX_IN  OMX_HANDLETYPE hComponent,
165        OMX_IN  OMX_INDEXTYPE nIndex,
166        OMX_INOUT OMX_PTR pComponentConfigStructure);
167
168    static OMX_ERRORTYPE SetConfig(
169        OMX_IN  OMX_HANDLETYPE hComponent,
170        OMX_IN  OMX_INDEXTYPE nIndex,
171        OMX_IN  OMX_PTR pComponentConfigStructure);
172    OMX_ERRORTYPE CBaseSetConfig(
173        OMX_IN  OMX_HANDLETYPE hComponent,
174        OMX_IN  OMX_INDEXTYPE nIndex,
175        OMX_IN  OMX_PTR pComponentConfigStructure);
176
177    static OMX_ERRORTYPE GetExtensionIndex(
178        OMX_IN  OMX_HANDLETYPE hComponent,
179        OMX_IN  OMX_STRING cParameterName,
180        OMX_OUT OMX_INDEXTYPE* pIndexType);
181    OMX_ERRORTYPE CBaseGetExtensionIndex(
182        OMX_IN  OMX_HANDLETYPE hComponent,
183        OMX_IN  OMX_STRING cParameterName,
184        OMX_OUT OMX_INDEXTYPE* pIndexType);
185
186    static OMX_ERRORTYPE GetState(
187        OMX_IN  OMX_HANDLETYPE hComponent,
188        OMX_OUT OMX_STATETYPE* pState);
189    OMX_ERRORTYPE CBaseGetState(
190        OMX_IN  OMX_HANDLETYPE hComponent,
191        OMX_OUT OMX_STATETYPE* pState);
192
193    static OMX_ERRORTYPE ComponentTunnelRequest(
194        OMX_IN  OMX_HANDLETYPE hComp,
195        OMX_IN  OMX_U32 nPort,
196        OMX_IN  OMX_HANDLETYPE hTunneledComp,
197        OMX_IN  OMX_U32 nTunneledPort,
198        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup);
199    OMX_ERRORTYPE CBaseComponentTunnelRequest(
200        OMX_IN  OMX_HANDLETYPE hComp,
201        OMX_IN  OMX_U32 nPort,
202        OMX_IN  OMX_HANDLETYPE hTunneledComp,
203        OMX_IN  OMX_U32 nTunneledPort,
204        OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup);
205
206    static OMX_ERRORTYPE UseBuffer(
207        OMX_IN OMX_HANDLETYPE hComponent,
208        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
209        OMX_IN OMX_U32 nPortIndex,
210        OMX_IN OMX_PTR pAppPrivate,
211        OMX_IN OMX_U32 nSizeBytes,
212        OMX_IN OMX_U8* pBuffer);
213    OMX_ERRORTYPE CBaseUseBuffer(
214        OMX_IN OMX_HANDLETYPE hComponent,
215        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
216        OMX_IN OMX_U32 nPortIndex,
217        OMX_IN OMX_PTR pAppPrivate,
218        OMX_IN OMX_U32 nSizeBytes,
219        OMX_IN OMX_U8* pBuffer);
220
221    static OMX_ERRORTYPE AllocateBuffer(
222        OMX_IN OMX_HANDLETYPE hComponent,
223        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
224        OMX_IN OMX_U32 nPortIndex,
225        OMX_IN OMX_PTR pAppPrivate,
226        OMX_IN OMX_U32 nSizeBytes);
227    OMX_ERRORTYPE CBaseAllocateBuffer(
228        OMX_IN OMX_HANDLETYPE hComponent,
229        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
230        OMX_IN OMX_U32 nPortIndex,
231        OMX_IN OMX_PTR pAppPrivate,
232        OMX_IN OMX_U32 nSizeBytes);
233
234    static OMX_ERRORTYPE FreeBuffer(
235        OMX_IN  OMX_HANDLETYPE hComponent,
236        OMX_IN  OMX_U32 nPortIndex,
237        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
238    OMX_ERRORTYPE CBaseFreeBuffer(
239        OMX_IN  OMX_HANDLETYPE hComponent,
240        OMX_IN  OMX_U32 nPortIndex,
241        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
242
243    static OMX_ERRORTYPE EmptyThisBuffer(
244        OMX_IN  OMX_HANDLETYPE hComponent,
245        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
246    OMX_ERRORTYPE CBaseEmptyThisBuffer(
247        OMX_IN  OMX_HANDLETYPE hComponent,
248        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
249
250    static OMX_ERRORTYPE FillThisBuffer(
251        OMX_IN  OMX_HANDLETYPE hComponent,
252        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
253    OMX_ERRORTYPE CBaseFillThisBuffer(
254        OMX_IN  OMX_HANDLETYPE hComponent,
255        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
256
257    static OMX_ERRORTYPE SetCallbacks(
258        OMX_IN  OMX_HANDLETYPE hComponent,
259        OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
260        OMX_IN  OMX_PTR pAppData);
261    OMX_ERRORTYPE CBaseSetCallbacks(
262        OMX_IN  OMX_HANDLETYPE hComponent,
263        OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
264        OMX_IN  OMX_PTR pAppData);
265
266    static OMX_ERRORTYPE ComponentDeInit(
267        OMX_IN  OMX_HANDLETYPE hComponent);
268    OMX_ERRORTYPE CBaseComponentDeInit(
269        OMX_IN  OMX_HANDLETYPE hComponent);
270
271    static OMX_ERRORTYPE UseEGLImage(
272        OMX_IN OMX_HANDLETYPE hComponent,
273        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
274        OMX_IN OMX_U32 nPortIndex,
275        OMX_IN OMX_PTR pAppPrivate,
276        OMX_IN void* eglImage);
277    OMX_ERRORTYPE CBaseUseEGLImage(
278        OMX_IN OMX_HANDLETYPE hComponent,
279        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
280        OMX_IN OMX_U32 nPortIndex,
281        OMX_IN OMX_PTR pAppPrivate,
282        OMX_IN void* eglImage);
283
284    static OMX_ERRORTYPE ComponentRoleEnum(
285        OMX_IN OMX_HANDLETYPE hComponent,
286        OMX_OUT OMX_U8 *cRole,
287        OMX_IN OMX_U32 nIndex);
288    OMX_ERRORTYPE CBaseComponentRoleEnum(
289        OMX_IN OMX_HANDLETYPE hComponent,
290        OMX_OUT OMX_U8 *cRole,
291        OMX_IN OMX_U32 nIndex);
292
293    /* end of component methods & helpers */
294
295    /*
296     * omx header manipuation
297     */
298    static void SetTypeHeader(OMX_PTR type, OMX_U32 size);
299    static OMX_ERRORTYPE CheckTypeHeader(const OMX_PTR type, OMX_U32 size);
300
301    /* end of omx header manipuation */
302
303    /*
304     * helper method for queury_roles()
305     */
306    static OMX_ERRORTYPE QueryRolesHelper(OMX_U32 nr_comp_roles,
307                                          const OMX_U8 **comp_roles,
308                                          OMX_U32 *nr_roles, OMX_U8 **roles);
309
310    /* end of helper method for queury_roles() */
311
312protected:
313    /* helpers for derived class */
314    const OMX_COMPONENTTYPE *GetComponentHandle(void);
315
316    void DumpBuffer(const OMX_BUFFERHEADERTYPE *bufferheader, bool dumpdata);
317
318    /* check if all port has own pending buffer */
319    virtual bool IsAllBufferAvailable(void);
320
321    /* end of helpers for derived class */
322
323    /* ports */
324    /*
325     * allocated with derived port classes by derived component classes
326     */
327    PortBase **ports;
328    OMX_U32 nr_ports;
329    OMX_PORT_PARAM_TYPE portparam;
330
331    /* ports big lock, must be held when accessing all ports at one time */
332    pthread_mutex_t ports_block;
333
334
335private:
336    /* common routines for constructor */
337    void __ComponentBase(void);
338
339    /*
340     * core methods & helpers
341     */
342    /* called in GetHandle (nr_roles == 1) or SetParameter(ComponentRole) */
343    OMX_ERRORTYPE SetWorkingRole(const OMX_STRING role);
344    /* called int FreeHandle() */
345    OMX_ERRORTYPE FreePorts(void);
346
347    /* end of core methods & helpers */
348
349    /*
350     * component methods & helpers
351     */
352    /* SendCommand */
353    /* implement CmdHandlerInterface */
354    virtual void CmdHandler(struct cmd_s *cmd);
355
356    /* SendCommand:OMX_CommandStateSet */
357    /* called in CmdHandler() thread context or by component itself */
358    void TransState(OMX_STATETYPE transition);
359    inline OMX_ERRORTYPE TransStateToLoaded(OMX_STATETYPE current);
360    inline OMX_ERRORTYPE TransStateToIdle(OMX_STATETYPE current);
361    inline OMX_ERRORTYPE TransStateToExecuting(OMX_STATETYPE current);
362    inline OMX_ERRORTYPE TransStateToPause(OMX_STATETYPE current);
363    inline OMX_ERRORTYPE TransStateToWaitForResources(OMX_STATETYPE current);
364    inline OMX_ERRORTYPE TransStateToInvalid(OMX_STATETYPE current);
365
366    /* called in TransStateToIdle(Loaded) */
367    OMX_ERRORTYPE ApplyWorkingRole(void);
368    /* called in ApplyWorkingRole() */
369    OMX_ERRORTYPE AllocatePorts(void);
370    /* allocate specific port type derived from portbase */
371    virtual OMX_ERRORTYPE ComponentAllocatePorts(void) = 0;
372
373    /* SendCommand:OMX_CommandMarkBuffer */
374    /* called in CmdHandler() thread context */
375    void PushThisMark(OMX_U32 portindex, OMX_MARKTYPE *mark);
376    /* SendCommand:OMX_CommandFlush (notify:1) or other parts (notify:0) */
377    void FlushPort(OMX_U32 port_index, bool notify);
378    /* SendCommand:OMX_CommandPortDisable/Enable */
379    /* state: PortBase::OMX_PortEnabled/Disabled */
380    void TransStatePort(OMX_U32 port_index, OMX_U8 state);
381
382    /* Get/SetParameter */
383    virtual OMX_ERRORTYPE
384        ComponentGetParameter(OMX_INDEXTYPE nParamIndex,
385                              OMX_PTR pComponentParameterStructure) = 0;
386    virtual OMX_ERRORTYPE
387        ComponentSetParameter(OMX_INDEXTYPE nIndex,
388                              OMX_PTR pComponentParameterStructure) = 0;
389
390    /* Get/SetConfig */
391    virtual OMX_ERRORTYPE
392        ComponentGetConfig(OMX_INDEXTYPE nIndex,
393                           OMX_PTR pComponentConfigStructure) = 0;
394    virtual OMX_ERRORTYPE
395        ComponentSetConfig(OMX_INDEXTYPE nIndex,
396                           OMX_PTR pComponentConfigStructure) = 0;
397
398    /* buffer processing */
399    /* implement WorkableInterface */
400    virtual void Work(void); /* handle this->ports, hold ports_block */
401
402    /* called in Work() after ProcessorProcess() */
403    void PostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
404                            const buffer_retain_t *retain);
405    void SourcePostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
406                                  const buffer_retain_t *retain);
407    void FilterPostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
408                                  const buffer_retain_t *retain);
409    void SinkPostProcessBuffers(OMX_BUFFERHEADERTYPE ***buffers,
410                                const buffer_retain_t *retain);
411
412    /* processor callbacks */
413    /* TransState */
414    virtual OMX_ERRORTYPE ProcessorInit(void);  /* Loaded to Idle */
415    virtual OMX_ERRORTYPE ProcessorDeinit(void);/* Idle to Loaded */
416    virtual OMX_ERRORTYPE ProcessorStart(void); /* Idle to Executing/Pause */
417    virtual OMX_ERRORTYPE ProcessorReset(void); /* Reset */
418    virtual OMX_ERRORTYPE ProcessorStop(void);  /* Executing/Pause to Idle */
419    virtual OMX_ERRORTYPE ProcessorPause(void); /* Executing to Pause */
420    virtual OMX_ERRORTYPE ProcessorResume(void);/* Pause to Executing */
421    virtual OMX_ERRORTYPE ProcessorFlush(OMX_U32 port_index); /* Flush */
422    virtual OMX_ERRORTYPE ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer);
423
424    /* invoked when buffer is to be freed */
425    virtual OMX_ERRORTYPE ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OMX_BUFFERHEADERTYPE* pBuffer);
426    /* Work */
427    virtual OMX_ERRORTYPE ProcessorProcess(OMX_BUFFERHEADERTYPE ***pBuffers,
428                                           buffer_retain_t *retain,
429                                           OMX_U32 nr_buffers);
430    virtual OMX_ERRORTYPE ProcessorProcess(OMX_BUFFERHEADERTYPE **pBuffers,
431                                           buffer_retain_t *retain,
432                                           OMX_U32 nr_buffers);
433
434    /* end of component methods & helpers */
435
436    /* process component's commands work */
437    CmdProcessWork *cmdwork;
438
439    /* buffer processing work */
440    WorkQueue *bufferwork;
441
442    /* component variant */
443    typedef enum component_variant_e {
444        CVARIANT_NULL = 0,
445        CVARIANT_SOURCE,
446        CVARIANT_FILTER,
447        CVARIANT_SINK,
448    } component_variant_t;
449
450    component_variant_t cvariant;
451
452    /* roles */
453    OMX_U8 **roles;
454    OMX_U32 nr_roles;
455
456    OMX_STRING working_role;
457
458    /* omx standard handle */
459    /* allocated at GetHandle, freed at FreeHandle */
460    OMX_COMPONENTTYPE *handle;
461
462    /* component module */
463    CModule *cmodule;
464
465    OMX_STATETYPE state;
466
467    const static OMX_STATETYPE OMX_StateUnloaded = OMX_StateVendorStartUnused;
468
469    /* omx standard callbacks */
470    OMX_PTR appdata;
471    OMX_CALLBACKTYPE *callbacks;
472
473    /* component name */
474    char name[OMX_MAX_STRINGNAME_SIZE];
475
476    /* omx specification version */
477#ifndef ANDROID
478    const static OMX_U8 OMX_SPEC_VERSION_MAJOR = 1;
479    const static OMX_U8 OMX_SPEC_VERSION_MINOR = 1;
480    const static OMX_U8 OMX_SPEC_VERSION_REVISION = 2;
481    const static OMX_U8 OMX_SPEC_VERSION_STEP = 0;
482#else
483    const static OMX_U8 OMX_SPEC_VERSION_MAJOR = 1;
484    const static OMX_U8 OMX_SPEC_VERSION_MINOR = 0;
485    const static OMX_U8 OMX_SPEC_VERSION_REVISION = 0;
486    const static OMX_U8 OMX_SPEC_VERSION_STEP = 0;
487#endif
488
489    const static OMX_U32 OMX_SPEC_VERSION = 0
490        | (OMX_SPEC_VERSION_MAJOR << 0)
491        | (OMX_SPEC_VERSION_MINOR << 8)
492        | (OMX_SPEC_VERSION_REVISION << 16)
493        | (OMX_SPEC_VERSION_STEP << 24);
494};
495
496#endif /* __COMPONENTBASE_H */
497