2 * Copyright (C) 2006-2007 Texas Instruments, Incorporated
3 * Copyright (C) 2007-2009 Nokia Corporation.
5 * Author: Felipe Contreras <felipe.contreras@nokia.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation
10 * version 2.1 of the License.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "gstomx_util.h"
28 GST_DEBUG_CATEGORY (gstomx_util_debug);
31 * Forward declarations
34 static inline void change_state (GOmxCore * core, OMX_STATETYPE state);
36 static inline void wait_for_state (GOmxCore * core, OMX_STATETYPE state);
39 in_port_cb (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer);
42 out_port_cb (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer);
45 got_buffer (GOmxCore * core,
46 GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer);
49 EventHandler (OMX_HANDLETYPE omx_handle,
51 OMX_EVENTTYPE event, OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data);
54 EmptyBufferDone (OMX_HANDLETYPE omx_handle,
55 OMX_PTR app_data, OMX_BUFFERHEADERTYPE * omx_buffer);
58 FillBufferDone (OMX_HANDLETYPE omx_handle,
59 OMX_PTR app_data, OMX_BUFFERHEADERTYPE * omx_buffer);
61 static inline const char *omx_state_to_str (OMX_STATETYPE omx_state);
63 static inline const char *omx_error_to_str (OMX_ERRORTYPE omx_error);
65 static inline GOmxPort *get_port (GOmxCore * core, guint index);
67 static void core_deinit (GOmxCore * core);
69 static inline void port_free_buffers (GOmxPort * port);
71 static inline void port_allocate_buffers (GOmxPort * port);
73 static inline void port_start_buffers (GOmxPort * port);
75 static OMX_CALLBACKTYPE callbacks =
76 { EventHandler, EmptyBufferDone, FillBufferDone };
78 /* protect implementations hash_table */
79 static GMutex *imp_mutex;
80 static GHashTable *implementations;
81 static gboolean initialized;
88 g_ptr_array_clear (GPtrArray * array)
91 for (index = 0; index < array->len; index++)
92 array->pdata[index] = NULL;
96 g_ptr_array_insert (GPtrArray * array, guint index, gpointer data)
98 if (index + 1 > array->len) {
99 g_ptr_array_set_size (array, index + 1);
102 array->pdata[index] = data;
105 typedef void (*GOmxPortFunc) (GOmxPort * port);
108 core_for_each_port (GOmxCore * core, GOmxPortFunc func)
112 for (index = 0; index < core->ports->len; index++) {
115 port = get_port (core, index);
126 static GOmxImp *imp_new (const gchar * name);
127 static void imp_free (GOmxImp * imp);
130 imp_new (const gchar * name)
134 imp = g_new0 (GOmxImp, 1);
136 /* Load the OpenMAX IL symbols */
140 GST_DEBUG ("loading: %s", name);
142 imp->dl_handle = handle = dlopen (name, RTLD_LAZY);
144 GST_DEBUG ("dlopen(%s) -> %p", name, handle);
147 g_warning ("%s\n", dlerror ());
152 imp->mutex = g_mutex_new ();
153 imp->sym_table.init = dlsym (handle, "OMX_Init");
154 imp->sym_table.deinit = dlsym (handle, "OMX_Deinit");
155 imp->sym_table.get_handle = dlsym (handle, "OMX_GetHandle");
156 imp->sym_table.free_handle = dlsym (handle, "OMX_FreeHandle");
163 imp_free (GOmxImp * imp)
165 if (imp->dl_handle) {
166 dlclose (imp->dl_handle);
168 g_mutex_free (imp->mutex);
172 static inline GOmxImp *
173 request_imp (const gchar * name)
177 g_mutex_lock (imp_mutex);
178 imp = g_hash_table_lookup (implementations, name);
180 imp = imp_new (name);
182 g_hash_table_insert (implementations, g_strdup (name), imp);
184 g_mutex_unlock (imp_mutex);
189 g_mutex_lock (imp->mutex);
190 if (imp->client_count == 0) {
191 OMX_ERRORTYPE omx_error;
192 omx_error = imp->sym_table.init ();
194 g_mutex_unlock (imp->mutex);
199 g_mutex_unlock (imp->mutex);
205 release_imp (GOmxImp * imp)
207 g_mutex_lock (imp->mutex);
209 if (imp->client_count == 0) {
210 imp->sym_table.deinit ();
212 g_mutex_unlock (imp->mutex);
219 /* safe as plugin_init is safe */
220 imp_mutex = g_mutex_new ();
221 implementations = g_hash_table_new_full (g_str_hash,
222 g_str_equal, g_free, (GDestroyNotify) imp_free);
231 g_hash_table_destroy (implementations);
232 g_mutex_free (imp_mutex);
242 g_omx_core_new (void *object)
246 core = g_new0 (GOmxCore, 1);
248 core->object = object;
249 core->ports = g_ptr_array_new ();
251 core->omx_state_condition = g_cond_new ();
252 core->omx_state_mutex = g_mutex_new ();
254 core->done_sem = g_sem_new ();
255 core->flush_sem = g_sem_new ();
256 core->port_sem = g_sem_new ();
258 core->omx_state = OMX_StateInvalid;
264 g_omx_core_free (GOmxCore * core)
268 g_sem_free (core->port_sem);
269 g_sem_free (core->flush_sem);
270 g_sem_free (core->done_sem);
272 g_mutex_free (core->omx_state_mutex);
273 g_cond_free (core->omx_state_condition);
275 g_ptr_array_free (core->ports, TRUE);
282 g_omx_core_init (GOmxCore * core)
284 GST_DEBUG_OBJECT (core->object, "loading: %s %s (%s)",
285 core->component_name,
286 core->component_role ? core->component_role : "", core->library_name);
288 core->imp = request_imp (core->library_name);
293 core->omx_error = core->imp->sym_table.get_handle (&core->omx_handle,
294 (char *) core->component_name, core, &callbacks);
296 GST_DEBUG_OBJECT (core->object, "OMX_GetHandle(&%p) -> %d",
297 core->omx_handle, core->omx_error);
299 if (!core->omx_error) {
300 core->omx_state = OMX_StateLoaded;
302 if (core->component_role) {
303 OMX_PARAM_COMPONENTROLETYPE param;
305 GST_DEBUG_OBJECT (core->object, "setting component role: %s",
306 core->component_role);
308 G_OMX_INIT_PARAM (param);
310 strncpy ((char *) param.cRole, core->component_role,
311 OMX_MAX_STRINGNAME_SIZE - 1);
313 OMX_SetParameter (core->omx_handle, OMX_IndexParamStandardComponentRole,
317 /* MODIFICATION: Add_component_vendor */
318 if (strncmp(core->component_name+4, "SEC", 3) == 0)
320 core->component_vendor = GOMX_VENDOR_SLSI;
322 else if (strncmp(core->component_name+4, "qcom", 4) == 0)
324 core->component_vendor = GOMX_VENDOR_QCT;
328 core->component_vendor = GOMX_VENDOR_DEFAULT;
334 core_deinit (GOmxCore * core)
339 if (core->omx_state == OMX_StateLoaded || core->omx_state == OMX_StateInvalid) {
340 if (core->omx_handle) {
341 core->omx_error = core->imp->sym_table.free_handle (core->omx_handle);
342 GST_DEBUG_OBJECT (core->object, "OMX_FreeHandle(%p) -> %d",
343 core->omx_handle, core->omx_error);
346 GST_WARNING_OBJECT (core->object, "Incorrect state: %s",
347 omx_state_to_str (core->omx_state));
350 g_free (core->library_name);
351 g_free (core->component_name);
352 g_free (core->component_role);
353 core->library_name = NULL;
354 core->component_name = NULL;
355 core->component_role = NULL;
357 release_imp (core->imp);
362 g_omx_core_prepare (GOmxCore * core)
364 change_state (core, OMX_StateIdle);
366 /* Allocate buffers. */
367 core_for_each_port (core, port_allocate_buffers);
369 wait_for_state (core, OMX_StateIdle);
373 g_omx_core_start (GOmxCore * core)
375 change_state (core, OMX_StateExecuting);
376 wait_for_state (core, OMX_StateExecuting);
378 if (core->omx_state == OMX_StateExecuting)
379 core_for_each_port (core, port_start_buffers);
383 g_omx_core_stop (GOmxCore * core)
385 if (core->omx_state == OMX_StateExecuting ||
386 core->omx_state == OMX_StatePause) {
387 change_state (core, OMX_StateIdle);
388 wait_for_state (core, OMX_StateIdle);
393 g_omx_core_pause (GOmxCore * core)
395 change_state (core, OMX_StatePause);
396 wait_for_state (core, OMX_StatePause);
400 g_omx_core_unload (GOmxCore * core)
402 if (core->omx_state == OMX_StateIdle ||
403 core->omx_state == OMX_StateWaitForResources ||
404 core->omx_state == OMX_StateInvalid) {
405 if (core->omx_state != OMX_StateInvalid)
406 change_state (core, OMX_StateLoaded);
408 core_for_each_port (core, port_free_buffers);
410 if (core->omx_state != OMX_StateInvalid)
411 wait_for_state (core, OMX_StateLoaded);
414 core_for_each_port (core, g_omx_port_free);
415 g_ptr_array_clear (core->ports);
418 static inline GOmxPort *
419 get_port (GOmxCore * core, guint index)
421 if (G_LIKELY (index < core->ports->len)) {
422 return g_ptr_array_index (core->ports, index);
429 g_omx_core_new_port (GOmxCore * core, guint index)
431 GOmxPort *port = get_port (core, index);
434 GST_WARNING_OBJECT (core->object, "port %d already exists", index);
438 port = g_omx_port_new (core, index);
439 g_ptr_array_insert (core->ports, index, port);
445 g_omx_core_set_done (GOmxCore * core)
447 g_sem_up (core->done_sem);
451 g_omx_core_wait_for_done (GOmxCore * core)
453 g_sem_down (core->done_sem);
457 g_omx_core_flush_start (GOmxCore * core)
459 core_for_each_port (core, g_omx_port_pause);
463 g_omx_core_flush_stop (GOmxCore * core)
465 core_for_each_port (core, g_omx_port_flush);
466 core_for_each_port (core, g_omx_port_resume);
474 * note: this is not intended to be called directly by elements (which should
475 * instead use g_omx_core_new_port())
478 g_omx_port_new (GOmxCore * core, guint index)
481 port = g_new0 (GOmxPort, 1);
484 port->port_index = index;
485 port->num_buffers = 0;
486 port->buffer_size = 0;
487 port->buffers = NULL;
488 port->shared_buffer = FALSE;
490 port->enabled = TRUE;
491 port->queue = async_queue_new ();
492 port->mutex = g_mutex_new ();
498 g_omx_port_free (GOmxPort * port)
500 g_mutex_free (port->mutex);
501 async_queue_free (port->queue);
503 g_free (port->buffers);
504 port->buffers = NULL;
510 g_omx_port_setup (GOmxPort * port)
512 GOmxPortType type = -1;
513 OMX_PARAM_PORTDEFINITIONTYPE param;
515 G_OMX_INIT_PARAM (param);
517 param.nPortIndex = port->port_index;
518 OMX_GetParameter (port->core->omx_handle, OMX_IndexParamPortDefinition,
521 switch (param.eDir) {
523 type = GOMX_PORT_INPUT;
526 type = GOMX_PORT_OUTPUT;
533 /** @todo should it be nBufferCountMin? */
534 port->num_buffers = param.nBufferCountActual;
535 port->buffer_size = param.nBufferSize;
537 GST_DEBUG_OBJECT (port->core->object,
538 "type=%d, num_buffers=%d, buffer_size=%ld, port_index=%d",
539 port->type, port->num_buffers, port->buffer_size, port->port_index);
541 g_free (port->buffers);
542 port->buffers = g_new0 (OMX_BUFFERHEADERTYPE *, port->num_buffers);
546 port_allocate_buffers (GOmxPort * port)
551 size = port->buffer_size;
553 for (i = 0; i < port->num_buffers; i++) {
554 if (port->omx_allocate) {
555 GST_DEBUG_OBJECT (port->core->object,
556 "%d: OMX_AllocateBuffer(), size=%" G_GSIZE_FORMAT, i, size);
557 OMX_AllocateBuffer (port->core->omx_handle, &port->buffers[i],
558 port->port_index, NULL, size);
560 gpointer buffer_data;
561 buffer_data = g_malloc (size);
562 GST_DEBUG_OBJECT (port->core->object,
563 "%d: OMX_UseBuffer(), size=%" G_GSIZE_FORMAT, i, size);
564 OMX_UseBuffer (port->core->omx_handle, &port->buffers[i],
565 port->port_index, NULL, size, buffer_data);
571 port_free_buffers (GOmxPort * port)
575 if (port->type == GOMX_PORT_INPUT) {
576 GST_INFO_OBJECT(port->core->object, "Input port free buffers.");
578 GST_INFO_OBJECT(port->core->object, "Output port free buffers.");
581 for (i = 0; i < port->num_buffers; i++) {
582 OMX_BUFFERHEADERTYPE *omx_buffer;
584 omx_buffer = port->buffers[i];
588 if (port->shared_buffer) {
589 /* Modification: free pAppPrivate when input/output buffer is shared */
591 if (!omx_buffer->pAppPrivate && port->type == GOMX_PORT_OUTPUT && omx_buffer->pBuffer) {
592 GST_INFO_OBJECT(port->core->object,
593 " %d: g_free shared buffer (pBuffer) %p", i, omx_buffer->pBuffer);
594 g_free (omx_buffer->pBuffer);
595 omx_buffer->pBuffer = NULL;
598 if (omx_buffer->pAppPrivate) {
599 GST_INFO_OBJECT(port->core->object,
600 " %d: unref shared buffer (pAppPrivate) %p", i, omx_buffer->pAppPrivate);
601 gst_buffer_unref(omx_buffer->pAppPrivate);
602 omx_buffer->pAppPrivate = NULL;
605 } else { /* this is not shared buffer */
606 if (!port->omx_allocate) {
607 /* Modification: free pBuffer allocated in plugin when OMX_UseBuffer.
608 * the component shall free only buffer header if it allocated only buffer header.*/
609 GST_INFO_OBJECT(port->core->object,
610 " %d: free buffer (pBuffer) %p", i, omx_buffer->pBuffer);
611 if (omx_buffer->pBuffer) {
612 g_free (omx_buffer->pBuffer);
613 omx_buffer->pBuffer = NULL;
618 OMX_FreeBuffer (port->core->omx_handle, port->port_index, omx_buffer);
619 port->buffers[i] = NULL;
625 port_start_buffers (GOmxPort * port)
629 for (i = 0; i < port->num_buffers; i++) {
630 OMX_BUFFERHEADERTYPE *omx_buffer;
632 omx_buffer = port->buffers[i];
634 /* If it's an input port we will need to fill the buffer, so put it in
635 * the queue, otherwise send to omx for processing (fill it up). */
636 if (port->type == GOMX_PORT_INPUT)
637 got_buffer (port->core, port, omx_buffer);
639 g_omx_port_release_buffer (port, omx_buffer);
644 g_omx_port_push_buffer (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer)
646 async_queue_push (port->queue, omx_buffer);
649 OMX_BUFFERHEADERTYPE *
650 g_omx_port_request_buffer (GOmxPort * port)
652 return async_queue_pop (port->queue);
656 g_omx_port_release_buffer (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer)
658 switch (port->type) {
659 case GOMX_PORT_INPUT:
660 OMX_EmptyThisBuffer (port->core->omx_handle, omx_buffer);
662 case GOMX_PORT_OUTPUT:
663 OMX_FillThisBuffer (port->core->omx_handle, omx_buffer);
671 g_omx_port_resume (GOmxPort * port)
673 async_queue_enable (port->queue);
677 g_omx_port_pause (GOmxPort * port)
679 async_queue_disable (port->queue);
683 g_omx_port_flush (GOmxPort * port)
685 if (port->type == GOMX_PORT_OUTPUT) {
686 OMX_BUFFERHEADERTYPE *omx_buffer;
687 while ((omx_buffer = async_queue_pop_forced (port->queue))) {
688 omx_buffer->nFilledLen = 0;
689 g_omx_port_release_buffer (port, omx_buffer);
692 OMX_SendCommand (port->core->omx_handle, OMX_CommandFlush, port->port_index,
694 g_sem_down (port->core->flush_sem);
699 g_omx_port_enable (GOmxPort * port)
705 OMX_SendCommand (core->omx_handle, OMX_CommandPortEnable, port->port_index,
707 port_allocate_buffers (port);
708 if (core->omx_state != OMX_StateLoaded)
709 port_start_buffers (port);
710 g_omx_port_resume (port);
712 g_sem_down (core->port_sem);
716 g_omx_port_disable (GOmxPort * port)
722 OMX_SendCommand (core->omx_handle, OMX_CommandPortDisable, port->port_index,
724 g_omx_port_pause (port);
725 g_omx_port_flush (port);
726 port_free_buffers (port);
728 g_sem_down (core->port_sem);
732 g_omx_port_finish (GOmxPort * port)
734 port->enabled = FALSE;
735 async_queue_disable (port->queue);
743 change_state (GOmxCore * core, OMX_STATETYPE state)
745 GST_DEBUG_OBJECT (core->object, "state=%d", state);
746 OMX_SendCommand (core->omx_handle, OMX_CommandStateSet, state, NULL);
750 complete_change_state (GOmxCore * core, OMX_STATETYPE state)
752 g_mutex_lock (core->omx_state_mutex);
754 core->omx_state = state;
755 g_cond_signal (core->omx_state_condition);
756 GST_DEBUG_OBJECT (core->object, "state=%d", state);
758 g_mutex_unlock (core->omx_state_mutex);
762 wait_for_state (GOmxCore * core, OMX_STATETYPE state)
767 g_mutex_lock (core->omx_state_mutex);
769 if (core->omx_error != OMX_ErrorNone)
772 g_get_current_time (&tv);
773 g_time_val_add (&tv, 15 * G_USEC_PER_SEC);
776 if (core->omx_state != state) {
778 g_cond_timed_wait (core->omx_state_condition, core->omx_state_mutex,
782 GST_ERROR_OBJECT (core->object, "timed out switching from '%s' to '%s'",
783 omx_state_to_str (core->omx_state), omx_state_to_str (state));
787 if (core->omx_error != OMX_ErrorNone)
790 if (core->omx_state != state) {
791 GST_ERROR_OBJECT (core->object,
792 "wrong state received: state=%d, expected=%d", core->omx_state, state);
796 g_mutex_unlock (core->omx_state_mutex);
804 in_port_cb (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer)
806 /** @todo remove this */
813 out_port_cb (GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer)
815 /** @todo remove this */
821 if (omx_buffer->nFlags & OMX_BUFFERFLAG_EOS) {
822 g_omx_port_set_done (port);
829 got_buffer (GOmxCore * core, GOmxPort * port, OMX_BUFFERHEADERTYPE * omx_buffer)
831 if (G_UNLIKELY (!omx_buffer)) {
835 if (G_LIKELY (port)) {
836 g_omx_port_push_buffer (port, omx_buffer);
838 switch (port->type) {
839 case GOMX_PORT_INPUT:
840 in_port_cb (port, omx_buffer);
842 case GOMX_PORT_OUTPUT:
843 out_port_cb (port, omx_buffer);
852 * OpenMAX IL callbacks.
856 EventHandler (OMX_HANDLETYPE omx_handle,
858 OMX_EVENTTYPE event, OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data)
862 core = (GOmxCore *) app_data;
865 case OMX_EventCmdComplete:
869 cmd = (OMX_COMMANDTYPE) data_1;
871 GST_DEBUG_OBJECT (core->object, "OMX_EventCmdComplete: %d", cmd);
874 case OMX_CommandStateSet:
875 complete_change_state (core, data_2);
877 case OMX_CommandFlush:
878 g_sem_up (core->flush_sem);
880 case OMX_CommandPortDisable:
881 case OMX_CommandPortEnable:
882 g_sem_up (core->port_sem);
888 case OMX_EventBufferFlag:
890 GST_DEBUG_OBJECT (core->object, "OMX_EventBufferFlag");
891 if (data_2 & OMX_BUFFERFLAG_EOS) {
892 g_omx_core_set_done (core);
896 case OMX_EventPortSettingsChanged:
898 GST_DEBUG_OBJECT (core->object, "OMX_EventPortSettingsChanged");
899 /** @todo only on the relevant port. */
900 if (core->settings_changed_cb) {
901 core->settings_changed_cb (core);
907 core->omx_error = data_1;
908 GST_ERROR_OBJECT (core->object, "unrecoverable error: %s (0x%lx)",
909 omx_error_to_str (data_1), data_1);
910 /* component might leave us waiting for buffers, unblock */
911 g_omx_core_flush_start (core);
912 /* unlock wait_for_state */
913 g_mutex_lock (core->omx_state_mutex);
914 g_cond_signal (core->omx_state_condition);
915 g_mutex_unlock (core->omx_state_mutex);
922 return OMX_ErrorNone;
926 EmptyBufferDone (OMX_HANDLETYPE omx_handle,
927 OMX_PTR app_data, OMX_BUFFERHEADERTYPE * omx_buffer)
932 core = (GOmxCore *) app_data;
933 port = get_port (core, omx_buffer->nInputPortIndex);
935 GST_CAT_LOG_OBJECT (gstomx_util_debug, core->object, "omx_buffer=%p",
937 omx_buffer->nFlags = 0x00000000;
938 got_buffer (core, port, omx_buffer);
940 return OMX_ErrorNone;
944 FillBufferDone (OMX_HANDLETYPE omx_handle,
945 OMX_PTR app_data, OMX_BUFFERHEADERTYPE * omx_buffer)
950 core = (GOmxCore *) app_data;
951 port = get_port (core, omx_buffer->nOutputPortIndex);
953 GST_CAT_LOG_OBJECT (gstomx_util_debug, core->object, "omx_buffer=%p",
955 got_buffer (core, port, omx_buffer);
957 return OMX_ErrorNone;
960 static inline const char *
961 omx_state_to_str (OMX_STATETYPE omx_state)
964 case OMX_StateInvalid:
966 case OMX_StateLoaded:
970 case OMX_StateExecuting:
974 case OMX_StateWaitForResources:
975 return "wait for resources";
981 static inline const char *
982 omx_error_to_str (OMX_ERRORTYPE omx_error)
988 case OMX_ErrorInsufficientResources:
990 "There were insufficient resources to perform the requested operation";
992 case OMX_ErrorUndefined:
993 return "The cause of the error could not be determined";
995 case OMX_ErrorInvalidComponentName:
996 return "The component name string was not valid";
998 case OMX_ErrorComponentNotFound:
999 return "No component with the specified name string was found";
1001 case OMX_ErrorInvalidComponent:
1002 return "The component specified did not have an entry point";
1004 case OMX_ErrorBadParameter:
1005 return "One or more parameters were not valid";
1007 case OMX_ErrorNotImplemented:
1008 return "The requested function is not implemented";
1010 case OMX_ErrorUnderflow:
1011 return "The buffer was emptied before the next buffer was ready";
1013 case OMX_ErrorOverflow:
1014 return "The buffer was not available when it was needed";
1016 case OMX_ErrorHardware:
1017 return "The hardware failed to respond as expected";
1019 case OMX_ErrorInvalidState:
1020 return "The component is in invalid state";
1022 case OMX_ErrorStreamCorrupt:
1023 return "Stream is found to be corrupt";
1025 case OMX_ErrorPortsNotCompatible:
1026 return "Ports being connected are not compatible";
1028 case OMX_ErrorResourcesLost:
1029 return "Resources allocated to an idle component have been lost";
1031 case OMX_ErrorNoMore:
1032 return "No more indices can be enumerated";
1034 case OMX_ErrorVersionMismatch:
1035 return "The component detected a version mismatch";
1037 case OMX_ErrorNotReady:
1038 return "The component is not ready to return data at this time";
1040 case OMX_ErrorTimeout:
1041 return "There was a timeout that occurred";
1043 case OMX_ErrorSameState:
1045 "This error occurs when trying to transition into the state you are already in";
1047 case OMX_ErrorResourcesPreempted:
1049 "Resources allocated to an executing or paused component have been preempted";
1051 case OMX_ErrorPortUnresponsiveDuringAllocation:
1053 "Waited an unusually long time for the supplier to allocate buffers";
1055 case OMX_ErrorPortUnresponsiveDuringDeallocation:
1057 "Waited an unusually long time for the supplier to de-allocate buffers";
1059 case OMX_ErrorPortUnresponsiveDuringStop:
1061 "Waited an unusually long time for the non-supplier to return a buffer during stop";
1063 case OMX_ErrorIncorrectStateTransition:
1064 return "Attempting a state transition that is not allowed";
1066 case OMX_ErrorIncorrectStateOperation:
1068 "Attempting a command that is not allowed during the present state";
1070 case OMX_ErrorUnsupportedSetting:
1072 "The values encapsulated in the parameter or config structure are not supported";
1074 case OMX_ErrorUnsupportedIndex:
1076 "The parameter or config indicated by the given index is not supported";
1078 case OMX_ErrorBadPortIndex:
1079 return "The port index supplied is incorrect";
1081 case OMX_ErrorPortUnpopulated:
1083 "The port has lost one or more of its buffers and it thus unpopulated";
1085 case OMX_ErrorComponentSuspended:
1086 return "Component suspended due to temporary loss of resources";
1088 case OMX_ErrorDynamicResourcesUnavailable:
1090 "Component suspended due to an inability to acquire dynamic resources";
1092 case OMX_ErrorMbErrorsInFrame:
1093 return "Frame generated macroblock error";
1095 case OMX_ErrorFormatNotDetected:
1096 return "Cannot parse or determine the format of an input stream";
1098 case OMX_ErrorContentPipeOpenFailed:
1099 return "The content open operation failed";
1101 case OMX_ErrorContentPipeCreationFailed:
1102 return "The content creation operation failed";
1104 case OMX_ErrorSeperateTablesUsed:
1105 return "Separate table information is being used";
1107 case OMX_ErrorTunnelingUnsupported:
1108 return "Tunneling is unsupported by the component";
1111 return "Unknown error";