tizen beta release
[profile/ivi/gst-openmax0.10.git] / tests / standalone / core.c
1 /*
2  * Copyright (C) 2008-2009 Nokia Corporation.
3  *
4  * Author: Felipe Contreras <felipe.contreras@nokia.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation
9  * version 2.1 of the License.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include <OMX_Core.h>
23 #include <OMX_Component.h>
24
25 #include <glib.h>
26
27 #include <stdlib.h>             /* For calloc, free */
28 #include <string.h>             /* For memcpy */
29
30 #include "async_queue.h"
31
32 static void *foo_thread (void *cb_data);
33
34 OMX_ERRORTYPE
35 OMX_Init (void)
36 {
37   if (!g_thread_supported ()) {
38     g_thread_init (NULL);
39   }
40
41   return OMX_ErrorNone;
42 }
43
44 OMX_ERRORTYPE
45 OMX_Deinit (void)
46 {
47   return OMX_ErrorNone;
48 }
49
50 typedef struct CompPrivate CompPrivate;
51 typedef struct CompPrivatePort CompPrivatePort;
52
53 struct CompPrivate
54 {
55   OMX_STATETYPE state;
56   OMX_CALLBACKTYPE *callbacks;
57   OMX_PTR app_data;
58   CompPrivatePort *ports;
59   gboolean done;
60   GMutex *flush_mutex;
61 };
62
63 struct CompPrivatePort
64 {
65   OMX_PARAM_PORTDEFINITIONTYPE port_def;
66   AsyncQueue *queue;
67 };
68
69 static OMX_ERRORTYPE
70 comp_GetState (OMX_HANDLETYPE handle, OMX_STATETYPE * state)
71 {
72   OMX_COMPONENTTYPE *comp;
73   CompPrivate *private;
74
75   /* printf ("GetState\n"); */
76
77   comp = handle;
78   private = comp->pComponentPrivate;
79
80   *state = private->state;
81
82   return OMX_ErrorNone;
83 }
84
85 static OMX_ERRORTYPE
86 comp_GetParameter (OMX_HANDLETYPE handle, OMX_INDEXTYPE index, OMX_PTR param)
87 {
88   OMX_COMPONENTTYPE *comp;
89   CompPrivate *private;
90
91   /* printf ("GetParameter\n"); */
92
93   comp = handle;
94   private = comp->pComponentPrivate;
95
96   switch (index) {
97     case OMX_IndexParamPortDefinition:
98     {
99       OMX_PARAM_PORTDEFINITIONTYPE *port_def;
100       port_def = param;
101       memcpy (port_def, &private->ports[port_def->nPortIndex].port_def,
102           port_def->nSize);
103       break;
104     }
105     default:
106       break;
107   }
108
109   return OMX_ErrorNone;
110 }
111
112 static OMX_ERRORTYPE
113 comp_SetParameter (OMX_HANDLETYPE handle, OMX_INDEXTYPE index, OMX_PTR param)
114 {
115   OMX_COMPONENTTYPE *comp;
116   CompPrivate *private;
117
118   /* printf ("SetParameter\n"); */
119
120   comp = handle;
121   private = comp->pComponentPrivate;
122
123   switch (index) {
124     case OMX_IndexParamPortDefinition:
125     {
126       OMX_PARAM_PORTDEFINITIONTYPE *port_def;
127       port_def = param;
128       memcpy (&private->ports[port_def->nPortIndex].port_def, port_def,
129           port_def->nSize);
130       break;
131     }
132     default:
133       break;
134   }
135
136   return OMX_ErrorNone;
137 }
138
139 static OMX_ERRORTYPE
140 comp_SendCommand (OMX_HANDLETYPE handle,
141     OMX_COMMANDTYPE command, OMX_U32 param_1, OMX_PTR data)
142 {
143   OMX_COMPONENTTYPE *comp;
144   CompPrivate *private;
145
146   /* printf ("SendCommand\n"); */
147
148   comp = handle;
149   private = comp->pComponentPrivate;
150
151   switch (command) {
152     case OMX_CommandStateSet:
153     {
154       if (private->state == OMX_StateLoaded && param_1 == OMX_StateIdle) {
155         g_thread_create (foo_thread, comp, TRUE, NULL);
156       }
157       private->state = param_1;
158       private->callbacks->EventHandler (handle,
159           private->app_data, OMX_EventCmdComplete,
160           OMX_CommandStateSet, private->state, data);
161     }
162       break;
163     case OMX_CommandFlush:
164     {
165       g_mutex_lock (private->flush_mutex);
166       {
167         OMX_BUFFERHEADERTYPE *buffer;
168
169         while ((buffer = async_queue_pop_forced (private->ports[0].queue))) {
170           private->callbacks->EmptyBufferDone (comp, private->app_data, buffer);
171         }
172
173         while ((buffer = async_queue_pop_forced (private->ports[1].queue))) {
174           private->callbacks->FillBufferDone (comp, private->app_data, buffer);
175         }
176       }
177       g_mutex_unlock (private->flush_mutex);
178
179       private->callbacks->EventHandler (handle,
180           private->app_data, OMX_EventCmdComplete,
181           OMX_CommandFlush, param_1, data);
182     }
183       break;
184     default:
185       /* printf ("command: %d\n", command); */
186       break;
187   }
188
189   return OMX_ErrorNone;
190 }
191
192 static OMX_ERRORTYPE
193 comp_UseBuffer (OMX_HANDLETYPE handle,
194     OMX_BUFFERHEADERTYPE ** buffer_header,
195     OMX_U32 index, OMX_PTR data, OMX_U32 size, OMX_U8 * buffer)
196 {
197   OMX_BUFFERHEADERTYPE *new;
198
199   new = calloc (1, sizeof (OMX_BUFFERHEADERTYPE));
200   new->nSize = sizeof (OMX_BUFFERHEADERTYPE);
201   new->nVersion.nVersion = 1;
202   new->pBuffer = buffer;
203   new->nAllocLen = size;
204
205   switch (index) {
206     case 0:
207       new->nInputPortIndex = 0;
208       break;
209     case 1:
210       new->nOutputPortIndex = 1;
211       break;
212     default:
213       break;
214   }
215
216   *buffer_header = new;
217
218   return OMX_ErrorNone;
219 }
220
221 static OMX_ERRORTYPE
222 comp_FreeBuffer (OMX_HANDLETYPE handle,
223     OMX_U32 index, OMX_BUFFERHEADERTYPE * buffer_header)
224 {
225   free (buffer_header);
226
227   return OMX_ErrorNone;
228 }
229
230 static gpointer
231 foo_thread (gpointer cb_data)
232 {
233   OMX_COMPONENTTYPE *comp;
234   CompPrivate *private;
235
236   comp = cb_data;
237   private = comp->pComponentPrivate;
238
239   while (!private->done) {
240     OMX_BUFFERHEADERTYPE *in_buffer;
241     OMX_BUFFERHEADERTYPE *out_buffer;
242
243     in_buffer = async_queue_pop (private->ports[0].queue);
244     if (!in_buffer)
245       continue;
246
247     out_buffer = async_queue_pop (private->ports[1].queue);
248     if (!out_buffer)
249       continue;
250
251     /* process buffers */
252     {
253       unsigned long size;
254       size = MIN (in_buffer->nFilledLen, out_buffer->nAllocLen);
255       memcpy (out_buffer->pBuffer, in_buffer->pBuffer, size);
256       out_buffer->nFilledLen = size;
257       in_buffer->nFilledLen -= size;
258       out_buffer->nTimeStamp = in_buffer->nTimeStamp;
259       out_buffer->nFlags = in_buffer->nFlags;
260     }
261
262     g_mutex_lock (private->flush_mutex);
263
264     private->callbacks->FillBufferDone (comp, private->app_data, out_buffer);
265     if (in_buffer->nFilledLen == 0) {
266       private->callbacks->EmptyBufferDone (comp, private->app_data, in_buffer);
267     }
268
269     g_mutex_unlock (private->flush_mutex);
270   }
271
272   return NULL;
273 }
274
275 static OMX_ERRORTYPE
276 comp_EmptyThisBuffer (OMX_HANDLETYPE handle,
277     OMX_BUFFERHEADERTYPE * buffer_header)
278 {
279   OMX_COMPONENTTYPE *comp;
280   CompPrivate *private;
281
282   /* printf ("EmptyThisBuffer\n"); */
283
284   comp = handle;
285   private = comp->pComponentPrivate;
286
287   async_queue_push (private->ports[0].queue, buffer_header);
288
289   return OMX_ErrorNone;
290 }
291
292 static OMX_ERRORTYPE
293 comp_FillThisBuffer (OMX_HANDLETYPE handle,
294     OMX_BUFFERHEADERTYPE * buffer_header)
295 {
296   OMX_COMPONENTTYPE *comp;
297   CompPrivate *private;
298
299   /* printf ("FillThisBuffer\n"); */
300
301   comp = handle;
302   private = comp->pComponentPrivate;
303
304   async_queue_push (private->ports[1].queue, buffer_header);
305
306   return OMX_ErrorNone;
307 }
308
309 OMX_ERRORTYPE
310 OMX_GetHandle (OMX_HANDLETYPE * handle,
311     OMX_STRING component_name, OMX_PTR data, OMX_CALLBACKTYPE * callbacks)
312 {
313   OMX_COMPONENTTYPE *comp;
314
315   comp = calloc (1, sizeof (OMX_COMPONENTTYPE));
316   comp->nSize = sizeof (OMX_COMPONENTTYPE);
317   comp->nVersion.nVersion = 1;
318
319   comp->GetState = comp_GetState;
320   comp->GetParameter = comp_GetParameter;
321   comp->SetParameter = comp_SetParameter;
322   comp->SendCommand = comp_SendCommand;
323   comp->UseBuffer = comp_UseBuffer;
324   comp->FreeBuffer = comp_FreeBuffer;
325   comp->EmptyThisBuffer = comp_EmptyThisBuffer;
326   comp->FillThisBuffer = comp_FillThisBuffer;
327
328   {
329     CompPrivate *private;
330
331     private = calloc (1, sizeof (CompPrivate));
332     private->state = OMX_StateLoaded;
333     private->callbacks = callbacks;
334     private->app_data = data;
335     private->ports = calloc (2, sizeof (CompPrivatePort));
336     private->flush_mutex = g_mutex_new ();
337
338     private->ports[0].queue = async_queue_new ();
339     private->ports[1].queue = async_queue_new ();
340
341     {
342       OMX_PARAM_PORTDEFINITIONTYPE *port_def;
343
344       port_def = &private->ports[0].port_def;
345       port_def->nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
346       port_def->nVersion.nVersion = 1;
347       port_def->nPortIndex = 0;
348       port_def->eDir = OMX_DirInput;
349       port_def->nBufferCountActual = 1;
350       port_def->nBufferCountMin = 1;
351       port_def->nBufferSize = 0x1000;
352       port_def->eDomain = OMX_PortDomainAudio;
353
354     }
355
356     {
357       OMX_PARAM_PORTDEFINITIONTYPE *port_def;
358
359       port_def = &private->ports[1].port_def;
360       port_def->nSize = sizeof (OMX_PARAM_PORTDEFINITIONTYPE);
361       port_def->nVersion.nVersion = 1;
362       port_def->nPortIndex = 1;
363       port_def->eDir = OMX_DirOutput;
364       port_def->nBufferCountActual = 1;
365       port_def->nBufferCountMin = 1;
366       port_def->nBufferSize = 0x1000;
367       port_def->eDomain = OMX_PortDomainAudio;
368     }
369
370     comp->pComponentPrivate = private;
371   }
372
373   *handle = comp;
374
375   return OMX_ErrorNone;
376 }
377
378 OMX_ERRORTYPE
379 OMX_FreeHandle (OMX_HANDLETYPE handle)
380 {
381     /** @todo Free private structure? */
382   return OMX_ErrorNone;
383 }