2 * Copyright (C) 2008-2009 Nokia Corporation.
4 * Author: Felipe Contreras <felipe.contreras@nokia.com>
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.
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.
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
23 #include <OMX_Component.h>
27 #include <stdlib.h> /* For calloc, free */
28 #include <string.h> /* For memcpy */
30 #include "async_queue.h"
32 static void *foo_thread (void *cb_data);
37 if (!g_thread_supported ()) {
50 typedef struct CompPrivate CompPrivate;
51 typedef struct CompPrivatePort CompPrivatePort;
56 OMX_CALLBACKTYPE *callbacks;
58 CompPrivatePort *ports;
63 struct CompPrivatePort
65 OMX_PARAM_PORTDEFINITIONTYPE port_def;
70 comp_GetState (OMX_HANDLETYPE handle, OMX_STATETYPE * state)
72 OMX_COMPONENTTYPE *comp;
75 /* printf ("GetState\n"); */
78 private = comp->pComponentPrivate;
80 *state = private->state;
86 comp_GetParameter (OMX_HANDLETYPE handle, OMX_INDEXTYPE index, OMX_PTR param)
88 OMX_COMPONENTTYPE *comp;
91 /* printf ("GetParameter\n"); */
94 private = comp->pComponentPrivate;
97 case OMX_IndexParamPortDefinition:
99 OMX_PARAM_PORTDEFINITIONTYPE *port_def;
101 memcpy (port_def, &private->ports[port_def->nPortIndex].port_def,
109 return OMX_ErrorNone;
113 comp_SetParameter (OMX_HANDLETYPE handle, OMX_INDEXTYPE index, OMX_PTR param)
115 OMX_COMPONENTTYPE *comp;
116 CompPrivate *private;
118 /* printf ("SetParameter\n"); */
121 private = comp->pComponentPrivate;
124 case OMX_IndexParamPortDefinition:
126 OMX_PARAM_PORTDEFINITIONTYPE *port_def;
128 memcpy (&private->ports[port_def->nPortIndex].port_def, port_def,
136 return OMX_ErrorNone;
140 comp_SendCommand (OMX_HANDLETYPE handle,
141 OMX_COMMANDTYPE command, OMX_U32 param_1, OMX_PTR data)
143 OMX_COMPONENTTYPE *comp;
144 CompPrivate *private;
146 /* printf ("SendCommand\n"); */
149 private = comp->pComponentPrivate;
152 case OMX_CommandStateSet:
154 if (private->state == OMX_StateLoaded && param_1 == OMX_StateIdle) {
155 g_thread_create (foo_thread, comp, TRUE, NULL);
157 private->state = param_1;
158 private->callbacks->EventHandler (handle,
159 private->app_data, OMX_EventCmdComplete,
160 OMX_CommandStateSet, private->state, data);
163 case OMX_CommandFlush:
165 g_mutex_lock (private->flush_mutex);
167 OMX_BUFFERHEADERTYPE *buffer;
169 while ((buffer = async_queue_pop_forced (private->ports[0].queue))) {
170 private->callbacks->EmptyBufferDone (comp, private->app_data, buffer);
173 while ((buffer = async_queue_pop_forced (private->ports[1].queue))) {
174 private->callbacks->FillBufferDone (comp, private->app_data, buffer);
177 g_mutex_unlock (private->flush_mutex);
179 private->callbacks->EventHandler (handle,
180 private->app_data, OMX_EventCmdComplete,
181 OMX_CommandFlush, param_1, data);
185 /* printf ("command: %d\n", command); */
189 return OMX_ErrorNone;
193 comp_UseBuffer (OMX_HANDLETYPE handle,
194 OMX_BUFFERHEADERTYPE ** buffer_header,
195 OMX_U32 index, OMX_PTR data, OMX_U32 size, OMX_U8 * buffer)
197 OMX_BUFFERHEADERTYPE *new;
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;
207 new->nInputPortIndex = 0;
210 new->nOutputPortIndex = 1;
216 *buffer_header = new;
218 return OMX_ErrorNone;
222 comp_FreeBuffer (OMX_HANDLETYPE handle,
223 OMX_U32 index, OMX_BUFFERHEADERTYPE * buffer_header)
225 free (buffer_header);
227 return OMX_ErrorNone;
231 foo_thread (gpointer cb_data)
233 OMX_COMPONENTTYPE *comp;
234 CompPrivate *private;
237 private = comp->pComponentPrivate;
239 while (!private->done) {
240 OMX_BUFFERHEADERTYPE *in_buffer;
241 OMX_BUFFERHEADERTYPE *out_buffer;
243 in_buffer = async_queue_pop (private->ports[0].queue);
247 out_buffer = async_queue_pop (private->ports[1].queue);
251 /* process buffers */
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;
262 g_mutex_lock (private->flush_mutex);
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);
269 g_mutex_unlock (private->flush_mutex);
276 comp_EmptyThisBuffer (OMX_HANDLETYPE handle,
277 OMX_BUFFERHEADERTYPE * buffer_header)
279 OMX_COMPONENTTYPE *comp;
280 CompPrivate *private;
282 /* printf ("EmptyThisBuffer\n"); */
285 private = comp->pComponentPrivate;
287 async_queue_push (private->ports[0].queue, buffer_header);
289 return OMX_ErrorNone;
293 comp_FillThisBuffer (OMX_HANDLETYPE handle,
294 OMX_BUFFERHEADERTYPE * buffer_header)
296 OMX_COMPONENTTYPE *comp;
297 CompPrivate *private;
299 /* printf ("FillThisBuffer\n"); */
302 private = comp->pComponentPrivate;
304 async_queue_push (private->ports[1].queue, buffer_header);
306 return OMX_ErrorNone;
310 OMX_GetHandle (OMX_HANDLETYPE * handle,
311 OMX_STRING component_name, OMX_PTR data, OMX_CALLBACKTYPE * callbacks)
313 OMX_COMPONENTTYPE *comp;
315 comp = calloc (1, sizeof (OMX_COMPONENTTYPE));
316 comp->nSize = sizeof (OMX_COMPONENTTYPE);
317 comp->nVersion.nVersion = 1;
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;
329 CompPrivate *private;
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 ();
338 private->ports[0].queue = async_queue_new ();
339 private->ports[1].queue = async_queue_new ();
342 OMX_PARAM_PORTDEFINITIONTYPE *port_def;
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;
357 OMX_PARAM_PORTDEFINITIONTYPE *port_def;
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;
370 comp->pComponentPrivate = private;
375 return OMX_ErrorNone;
379 OMX_FreeHandle (OMX_HANDLETYPE handle)
381 /** @todo Free private structure? */
382 return OMX_ErrorNone;