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