2 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
3 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
4 * Copyright (C) 2013, Collabora Ltd.
5 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
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
28 #include <gst/video/video.h>
35 #ifdef GST_OMX_STRUCT_PACKING
36 # if GST_OMX_STRUCT_PACKING == 1
38 # elif GST_OMX_STRUCT_PACKING == 2
40 # elif GST_OMX_STRUCT_PACKING == 4
42 # elif GST_OMX_STRUCT_PACKING == 8
45 # error "Unsupported struct packing value"
49 /* If the component may signal EOS before it has finished pushing
50 * out all of its buffers. Happens with egl_render on the rpi.
52 #define GST_OMX_HACK_SIGNALS_PREMATURE_EOS G_GUINT64_CONSTANT (0x0000000000000400)
55 #include <OMX_Component.h>
57 #ifdef USE_OMX_TARGET_RPI
58 #include <OMX_Broadcom.h>
62 #include <OMX_VideoExt.h>
66 #include <OMX_IndexExt.h>
69 #ifdef HAVE_COMPONENT_EXT
70 #include <OMX_ComponentExt.h>
74 #include <OMX_CoreExt.h>
78 #include <OMX_AudioExt.h>
81 #ifdef HAVE_IV_COMMON_EXT
82 #include <OMX_IVCommonExt.h>
86 #include <OMX_ImageExt.h>
90 #include <OMX_OtherExt.h>
93 #ifdef GST_OMX_STRUCT_PACKING
99 #define GST_OMX_INIT_STRUCT(st) G_STMT_START { \
100 memset ((st), 0, sizeof (*(st))); \
101 (st)->nSize = sizeof (*(st)); \
102 (st)->nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
103 (st)->nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
104 (st)->nVersion.s.nRevision = OMX_VERSION_REVISION; \
105 (st)->nVersion.s.nStep = OMX_VERSION_STEP; \
109 #define GST_OMX_GET_TICKS(ticks) ((((guint64) (ticks).nHighPart) << 32) | ((ticks).nLowPart))
110 #define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
111 ticks.nLowPart = ((guint64) (i)) & 0xffffffff; \
112 ticks.nHighPart = ((guint64) (i)) >> 32; \
115 #define GST_OMX_GET_TICKS(ticks) (ticks)
116 #define GST_OMX_SET_TICKS(ticks, i) G_STMT_START { \
121 /* If set on an element property means "use the OMX default value".
122 * If set on a default_* variable means that the default values hasn't been
123 * retrieved from OMX yet. */
124 #define GST_OMX_PROP_OMX_DEFAULT G_MAXUINT32
126 /* OMX_StateInvalid does not exist in 1.2.0 spec. The initial state is now
127 * StateLoaded. Problem is that gst-omx still needs an initial state different
128 * than StateLoaded. Otherwise gst_omx_component_set_state(StateLoaded) will
129 * early return because it will think it is already in StateLoaded. Also note
130 * that there is no call to gst_omx_component_set_state(StateInvalid) so this
131 * also shows that StateInvalid is used as a helper in gst-omx.
133 #if OMX_VERSION_MINOR == 2
134 #define OMX_StateInvalid OMX_StateReserved_0x00000000
137 /* Different hacks that are required to work around
138 * bugs in different OpenMAX implementations
140 /* In the EventSettingsChanged callback use nData2 instead of nData1 for
141 * the port index. Happens with Bellagio.
143 #define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_NDATA_PARAMETER_SWAP G_GUINT64_CONSTANT (0x0000000000000001)
144 /* In the EventSettingsChanged callback assume that port index 0 really
145 * means port index 1. Happens with the Bellagio ffmpegdist video decoder.
147 #define GST_OMX_HACK_EVENT_PORT_SETTINGS_CHANGED_PORT_0_TO_1 G_GUINT64_CONSTANT (0x0000000000000002)
148 /* If the video framerate is not specified as fraction (Q.16) but as
149 * integer number. Happens with the Bellagio ffmpegdist video encoder.
151 #define GST_OMX_HACK_VIDEO_FRAMERATE_INTEGER G_GUINT64_CONSTANT (0x0000000000000004)
152 /* If the SYNCFRAME flag on encoder output buffers is not used and we
153 * have to assume that all frames are sync frames.
154 * Happens with the Bellagio ffmpegdist video encoder.
156 #define GST_OMX_HACK_SYNCFRAME_FLAG_NOT_USED G_GUINT64_CONSTANT (0x0000000000000008)
157 /* If the component needs to be re-created if the caps change.
158 * Happens with Qualcomm's OpenMAX implementation.
160 #define GST_OMX_HACK_NO_COMPONENT_RECONFIGURE G_GUINT64_CONSTANT (0x0000000000000010)
162 /* If the component does not accept empty EOS buffers.
163 * Happens with Qualcomm's OpenMAX implementation.
165 #define GST_OMX_HACK_NO_EMPTY_EOS_BUFFER G_GUINT64_CONSTANT (0x0000000000000020)
167 /* If the component might not acknowledge a drain.
168 * Happens with TI's Ducati OpenMAX implementation.
170 #define GST_OMX_HACK_DRAIN_MAY_NOT_RETURN G_GUINT64_CONSTANT (0x0000000000000040)
172 /* If the component doesn't allow any component role to be set.
173 * Happens with Broadcom's OpenMAX implementation.
175 #define GST_OMX_HACK_NO_COMPONENT_ROLE G_GUINT64_CONSTANT (0x0000000000000080)
177 /* If the component doesn't allow disabling the outport while
178 * when setting the format until the output format is known.
180 #define GST_OMX_HACK_NO_DISABLE_OUTPORT G_GUINT64_CONSTANT (0x0000000000000100)
182 /* If the encoder requires input buffers that have a height
183 * which is a multiple of 16 pixels
185 #define GST_OMX_HACK_HEIGHT_MULTIPLE_16 G_GUINT64_CONSTANT (0x0000000000000200)
187 /* If we should pass the profile/level information from upstream to the
188 * OMX decoder. This is a violation of the OMX spec as
189 * OMX_IndexParamVideoProfileLevelCurrent is supposed to be r-o so
190 * do it as a platform specific hack.
192 #define GST_OMX_HACK_PASS_PROFILE_TO_DECODER G_GUINT64_CONSTANT (0x0000000000000800)
194 /* If we should pass the color format information from upstream to the
195 * OMX decoder input. This is a violation of the OMX spec as
196 * the eColorFormat field is supposed to only be used if eCompressionFormat is
197 * set to OMX_IMAGE_CodingUnused.
198 * Do this as a platform specific hack for OMX implementation which may use
199 * this information to pre-allocate internal buffers for example.
201 #define GST_OMX_HACK_PASS_COLOR_FORMAT_TO_DECODER G_GUINT64_CONSTANT (0x0000000000001000)
203 /* If set, automatically update nBufferCountActual to nBufferCountMin before
204 * allocating buffers. This can be used on OMX implementation decreasing
205 * nBufferCountMin depending of the format and so can reduce the number
206 * of allocated buffers.
208 #define GST_OMX_HACK_ENSURE_BUFFER_COUNT_ACTUAL G_GUINT64_CONSTANT (0x0000000000002000)
210 typedef struct _GstOMXCore GstOMXCore;
211 typedef struct _GstOMXPort GstOMXPort;
212 typedef enum _GstOMXPortDirection GstOMXPortDirection;
213 typedef struct _GstOMXComponent GstOMXComponent;
214 typedef struct _GstOMXBuffer GstOMXBuffer;
215 typedef struct _GstOMXClassData GstOMXClassData;
216 typedef struct _GstOMXMessage GstOMXMessage;
219 /* Everything good and the buffer is valid */
220 GST_OMX_ACQUIRE_BUFFER_OK = 0,
221 /* The port is flushing, exit ASAP */
222 GST_OMX_ACQUIRE_BUFFER_FLUSHING,
223 /* The port must be reconfigured */
224 GST_OMX_ACQUIRE_BUFFER_RECONFIGURE,
225 /* The port is EOS */
226 GST_OMX_ACQUIRE_BUFFER_EOS,
227 /* A fatal error happened */
228 GST_OMX_ACQUIRE_BUFFER_ERROR,
229 /* No buffer is currently available (used when calling gst_omx_port_acquire_buffer() in not waiting mode) */
230 GST_OMX_ACQUIRE_BUFFER_NO_AVAILABLE,
231 } GstOMXAcquireBufferReturn;
234 /* Handle to the OpenMAX IL core shared library */
237 /* Current number of users, transitions from/to 0
238 * call init/deinit */
240 gint user_count; /* LOCK */
242 /* OpenMAX core library functions, protected with LOCK */
243 OMX_ERRORTYPE (*init) (void);
244 OMX_ERRORTYPE (*deinit) (void);
245 OMX_ERRORTYPE (*get_handle) (OMX_HANDLETYPE * handle,
246 OMX_STRING name, OMX_PTR data, OMX_CALLBACKTYPE * callbacks);
247 OMX_ERRORTYPE (*free_handle) (OMX_HANDLETYPE handle);
248 OMX_ERRORTYPE (*setup_tunnel) (OMX_HANDLETYPE output, OMX_U32 outport, OMX_HANDLETYPE input, OMX_U32 inport);
252 GST_OMX_MESSAGE_STATE_SET,
253 GST_OMX_MESSAGE_FLUSH,
254 GST_OMX_MESSAGE_ERROR,
255 GST_OMX_MESSAGE_PORT_ENABLE,
256 GST_OMX_MESSAGE_PORT_SETTINGS_CHANGED,
257 GST_OMX_MESSAGE_BUFFER_FLAG,
258 GST_OMX_MESSAGE_BUFFER_DONE,
262 GST_OMX_COMPONENT_TYPE_SINK,
263 GST_OMX_COMPONENT_TYPE_SOURCE,
264 GST_OMX_COMPONENT_TYPE_FILTER
265 } GstOmxComponentType;
267 /* How the port's buffers are allocated */
269 GST_OMX_BUFFER_ALLOCATION_ALLOCATE_BUFFER,
270 GST_OMX_BUFFER_ALLOCATION_USE_BUFFER,
271 GST_OMX_BUFFER_ALLOCATION_USE_BUFFER_DYNAMIC, /* Only supported by OMX 1.2.0 */
272 } GstOMXBufferAllocation;
279 struct _GstOMXMessage {
280 GstOMXMessageType type;
298 } port_settings_changed;
304 OMX_HANDLETYPE component;
306 OMX_BUFFERHEADERTYPE *buffer;
313 GstOMXComponent *comp;
318 OMX_PARAM_PORTDEFINITIONTYPE port_def;
319 GPtrArray *buffers; /* Contains GstOMXBuffer* */
320 GQueue pending_buffers; /* Contains GstOMXBuffer* */
322 gboolean flushed; /* TRUE after OMX_CommandFlush was done */
323 gboolean enabled_pending; /* TRUE after OMX_Command{En,Dis}able */
324 gboolean disabled_pending; /* was done until it took effect */
325 gboolean eos; /* TRUE after a buffer with EOS flag was received */
326 GstOMXBufferAllocation allocation;
327 gboolean using_pool; /* TRUE if the buffers of this port are managed by a pool */
329 /* Increased whenever the settings of these port change.
330 * If settings_cookie != configured_settings_cookie
331 * the port has to be reconfigured.
333 gint settings_cookie;
334 gint configured_settings_cookie;
337 struct _GstOMXComponent {
338 GstMiniObject mini_object;
342 gchar *name; /* for debugging mostly */
344 OMX_HANDLETYPE handle;
347 guint64 hacks; /* Flags, GST_OMX_HACK_* */
349 /* Added once, never changed. No locks necessary */
350 GPtrArray *ports; /* Contains GstOMXPort* */
351 gint n_in_ports, n_out_ports;
353 /* Locking order: lock -> messages_lock
355 * Never hold lock while waiting for messages_cond
356 * Always check that messages is empty before waiting */
359 GQueue messages; /* Queue of GstOMXMessages */
360 GMutex messages_lock;
364 /* OMX_StateInvalid if no pending state */
365 OMX_STATETYPE pending_state;
366 /* OMX_ErrorNone usually, if different nothing will work */
367 OMX_ERRORTYPE last_error;
369 GList *pending_reconfigure_outports;
372 struct _GstOMXBuffer {
374 OMX_BUFFERHEADERTYPE *omx_buf;
376 /* TRUE if the buffer is used by the port, i.e.
377 * between {Empty,Fill}ThisBuffer and the callback
381 /* Cookie of the settings when this buffer was allocated */
382 gint settings_cookie;
384 /* TRUE if this is an EGLImage */
387 /* Used in dynamic buffer mode to keep track of the mapped content while it's
388 * being processed by the OMX component. */
389 GstVideoFrame input_frame;
390 gboolean input_frame_mapped; /* TRUE if input_frame is valid */
391 GstMemory *input_mem;
392 GstBuffer *input_buffer;
393 gboolean input_buffer_mapped;
397 struct _GstOMXClassData {
398 const gchar *core_name;
399 const gchar *component_name;
400 const gchar *component_role;
402 const gchar *default_src_template_caps;
403 const gchar *default_sink_template_caps;
405 guint32 in_port_index, out_port_index;
409 GstOmxComponentType type;
412 GKeyFile * gst_omx_get_configuration (void);
414 const gchar * gst_omx_error_to_string (OMX_ERRORTYPE err);
415 const gchar * gst_omx_state_to_string (OMX_STATETYPE state);
416 const gchar * gst_omx_command_to_string (OMX_COMMANDTYPE cmd);
417 const gchar * gst_omx_buffer_flags_to_string (guint32 flags);
419 guint64 gst_omx_parse_hacks (gchar ** hacks);
421 GstOMXCore * gst_omx_core_acquire (const gchar * filename);
422 void gst_omx_core_release (GstOMXCore * core);
424 GType gst_omx_component_get_type (void);
426 GstOMXComponent * gst_omx_component_new (GstObject * parent, const gchar *core_name, const gchar *component_name, const gchar * component_role, guint64 hacks);
427 GstOMXComponent * gst_omx_component_ref (GstOMXComponent * comp);
428 void gst_omx_component_unref (GstOMXComponent * comp);
430 OMX_ERRORTYPE gst_omx_component_set_state (GstOMXComponent * comp, OMX_STATETYPE state);
431 OMX_STATETYPE gst_omx_component_get_state (GstOMXComponent * comp, GstClockTime timeout);
433 OMX_ERRORTYPE gst_omx_component_get_last_error (GstOMXComponent * comp);
434 const gchar * gst_omx_component_get_last_error_string (GstOMXComponent * comp);
436 GstOMXPort * gst_omx_component_add_port (GstOMXComponent * comp, guint32 index);
437 GstOMXPort * gst_omx_component_get_port (GstOMXComponent * comp, guint32 index);
439 OMX_ERRORTYPE gst_omx_component_get_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
440 OMX_ERRORTYPE gst_omx_component_set_parameter (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer param);
442 OMX_ERRORTYPE gst_omx_component_get_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config);
443 OMX_ERRORTYPE gst_omx_component_set_config (GstOMXComponent * comp, OMX_INDEXTYPE index, gpointer config);
445 OMX_ERRORTYPE gst_omx_setup_tunnel (GstOMXPort * port1, GstOMXPort * port2);
446 OMX_ERRORTYPE gst_omx_close_tunnel (GstOMXPort * port1, GstOMXPort * port2);
449 OMX_ERRORTYPE gst_omx_port_get_port_definition (GstOMXPort * port, OMX_PARAM_PORTDEFINITIONTYPE * port_def);
450 OMX_ERRORTYPE gst_omx_port_update_port_definition (GstOMXPort *port, OMX_PARAM_PORTDEFINITIONTYPE *port_definition);
452 GstOMXAcquireBufferReturn gst_omx_port_acquire_buffer (GstOMXPort *port, GstOMXBuffer **buf, GstOMXWait wait);
453 OMX_ERRORTYPE gst_omx_port_release_buffer (GstOMXPort *port, GstOMXBuffer *buf);
455 OMX_ERRORTYPE gst_omx_port_set_flushing (GstOMXPort *port, GstClockTime timeout, gboolean flush);
456 gboolean gst_omx_port_is_flushing (GstOMXPort *port);
458 OMX_ERRORTYPE gst_omx_port_allocate_buffers (GstOMXPort *port);
459 OMX_ERRORTYPE gst_omx_port_use_buffers (GstOMXPort *port, const GList *buffers);
460 OMX_ERRORTYPE gst_omx_port_use_eglimages (GstOMXPort *port, const GList *images);
461 OMX_ERRORTYPE gst_omx_port_deallocate_buffers (GstOMXPort *port);
462 OMX_ERRORTYPE gst_omx_port_populate (GstOMXPort *port);
463 OMX_ERRORTYPE gst_omx_port_wait_buffers_released (GstOMXPort * port, GstClockTime timeout);
464 void gst_omx_port_requeue_buffer (GstOMXPort * port, GstOMXBuffer * buf);
466 OMX_ERRORTYPE gst_omx_port_mark_reconfigured (GstOMXPort * port);
468 OMX_ERRORTYPE gst_omx_port_set_enabled (GstOMXPort * port, gboolean enabled);
469 OMX_ERRORTYPE gst_omx_port_wait_enabled (GstOMXPort * port, GstClockTime timeout);
470 gboolean gst_omx_port_is_enabled (GstOMXPort * port);
471 gboolean gst_omx_port_ensure_buffer_count_actual (GstOMXPort * port, guint extra);
472 gboolean gst_omx_port_update_buffer_count_actual (GstOMXPort * port, guint nb);
474 gboolean gst_omx_port_set_dmabuf (GstOMXPort * port, gboolean dmabuf);
476 /* OMX 1.2.0 dynamic allocation mode */
477 gboolean gst_omx_is_dynamic_allocation_supported (void);
478 OMX_ERRORTYPE gst_omx_port_use_dynamic_buffers (GstOMXPort * port);
479 gboolean gst_omx_buffer_map_frame (GstOMXBuffer * buffer, GstBuffer * input, GstVideoInfo * info);
480 gboolean gst_omx_buffer_map_memory (GstOMXBuffer * buffer, GstMemory * mem);
481 gboolean gst_omx_buffer_map_buffer (GstOMXBuffer * buffer, GstBuffer * input);
482 gboolean gst_omx_buffer_import_fd (GstOMXBuffer * buffer, GstBuffer * input);
484 void gst_omx_set_default_role (GstOMXClassData *class_data, const gchar *default_role);
486 /* refered by plugin_init */
487 GST_DEBUG_CATEGORY_EXTERN (gst_omx_video_debug_category);
491 #endif /* __GST_OMX_H__ */