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