diff options
Diffstat (limited to 'meta-steppeeagle/recipes-multimedia')
14 files changed, 1171 insertions, 0 deletions
diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch new file mode 100644 index 00000000..28078995 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch @@ -0,0 +1,36 @@ +From c223d8863624a93cd969b421b302df5d74f7fbaf Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Thu, 7 Nov 2013 13:13:19 -0500 +Subject: [PATCH 01/11] gstomxvideodec: fix multithreads negotiation problem + v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +v2: update comment text + +Signed-off-by: Leo Liu <leo.liu@amd.com> +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index bf44b3d..0d8801e 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -2675,6 +2675,11 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, + if (!gst_omx_video_dec_negotiate (self)) + GST_LOG_OBJECT (self, "Negotiation failed, will get output format later"); + ++ /* Make sure other threads are done enabling it */ ++ if (gst_omx_port_wait_enabled (self->dec_out_port, ++ 1 * GST_SECOND) != OMX_ErrorNone) ++ return FALSE; ++ + /* Disable output port */ + if (gst_omx_port_set_enabled (self->dec_out_port, FALSE) != OMX_ErrorNone) + return FALSE; +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch new file mode 100644 index 00000000..305e8b20 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0002-gstomxvideodec-remove-dead-code.patch @@ -0,0 +1,99 @@ +From 45a91c687ea3a2ce80fcffcdea413b9dcac55242 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 02:05:52 -0600 +Subject: [PATCH 02/11] gstomxvideodec: remove dead code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This code doesn't seems to be used for quite a while, +remove it before it starts to rot. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 48 +----------------------------------------------- + 1 file changed, 1 insertion(+), 47 deletions(-) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 0d8801e..6b5cbe3 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -1008,19 +1008,13 @@ gst_omx_video_dec_change_state (GstElement * element, GstStateChange transition) + return ret; + } + +-#define MAX_FRAME_DIST_TICKS (5 * OMX_TICKS_PER_SECOND) +-#define MAX_FRAME_DIST_FRAMES (100) +- + static GstVideoCodecFrame * + _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + { +- GList *l, *best_l = NULL; +- GList *finish_frames = NULL; + GstVideoCodecFrame *best = NULL; +- guint64 best_timestamp = 0; + guint64 best_diff = G_MAXUINT64; +- BufferIdentification *best_id = NULL; + GList *frames; ++ GList *l; + + frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)); + +@@ -1045,10 +1039,7 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + + if (best == NULL || diff < best_diff) { + best = tmp; +- best_timestamp = timestamp; + best_diff = diff; +- best_l = l; +- best_id = id; + + /* For frames without timestamp we simply take the first frame */ + if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) +@@ -1056,43 +1047,6 @@ _find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + } + } + +- if (FALSE && best_id) { +- for (l = frames; l && l != best_l; l = l->next) { +- GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 diff_ticks, diff_frames; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- if (id->timestamp > best_timestamp) +- break; +- +- if (id->timestamp == 0 || best_timestamp == 0) +- diff_ticks = 0; +- else +- diff_ticks = best_timestamp - id->timestamp; +- diff_frames = best->system_frame_number - tmp->system_frame_number; +- +- if (diff_ticks > MAX_FRAME_DIST_TICKS +- || diff_frames > MAX_FRAME_DIST_FRAMES) { +- finish_frames = +- g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); +- } +- } +- } +- +- if (FALSE && finish_frames) { +- g_warning ("Too old frames, bug in decoder -- please file a bug"); +- for (l = finish_frames; l; l = l->next) { +- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), l->data); +- } +- } +- + if (best) + gst_video_codec_frame_ref (best); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch new file mode 100644 index 00000000..f2c9a912 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0003-gstomxvideodec-simplify-_find_nearest_frame.patch @@ -0,0 +1,125 @@ +From 75402afb7acd7bee4fe02ca2c2e524d3d7426d19 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 02:23:39 -0600 +Subject: [PATCH 03/11] gstomxvideodec: simplify _find_nearest_frame +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +No need to make it more complicated and error prone than +necessary. Also give the function a gst_omx_video_dec prefix +to distinct it from the encoder function. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 60 ++++++++++++++------------------------------------ + 1 file changed, 16 insertions(+), 44 deletions(-) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 6b5cbe3..020b7d3 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -646,18 +646,6 @@ gst_omx_buffer_pool_new (GstElement * element, GstOMXComponent * component, + return GST_BUFFER_POOL (pool); + } + +-typedef struct _BufferIdentification BufferIdentification; +-struct _BufferIdentification +-{ +- guint64 timestamp; +-}; +- +-static void +-buffer_identification_free (BufferIdentification * id) +-{ +- g_slice_free (BufferIdentification, id); +-} +- + /* prototypes */ + static void gst_omx_video_dec_finalize (GObject * object); + +@@ -1009,40 +997,32 @@ gst_omx_video_dec_change_state (GstElement * element, GstStateChange transition) + } + + static GstVideoCodecFrame * +-_find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) ++gst_omx_video_dec_find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf) + { + GstVideoCodecFrame *best = NULL; +- guint64 best_diff = G_MAXUINT64; ++ GstClockTimeDiff best_diff = G_MAXINT64; ++ GstClockTime timestamp; + GList *frames; + GList *l; + ++ if (buf->omx_buf->nTimeStamp) ++ timestamp = ++ gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, ++ OMX_TICKS_PER_SECOND); ++ else ++ timestamp = GST_CLOCK_TIME_NONE; ++ + frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)); + + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 timestamp, diff; ++ GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts)); + +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- timestamp = id->timestamp; +- +- if (timestamp > buf->omx_buf->nTimeStamp) +- diff = timestamp - buf->omx_buf->nTimeStamp; +- else +- diff = buf->omx_buf->nTimeStamp - timestamp; +- +- if (best == NULL || diff < best_diff) { ++ if (diff < best_diff) { + best = tmp; + best_diff = diff; + +- /* For frames without timestamp we simply take the first frame */ +- if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) ++ if (diff == 0) + break; + } + } +@@ -1947,7 +1927,7 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) + (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); + + GST_VIDEO_DECODER_STREAM_LOCK (self); +- frame = _find_nearest_frame (self, buf); ++ frame = gst_omx_video_dec_find_nearest_frame (self, buf); + + if (frame + && (deadline = gst_video_decoder_get_max_decode_time +@@ -2926,16 +2906,8 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, + buf->omx_buf->nTickCount = 0; + } + +- if (offset == 0) { +- BufferIdentification *id = g_slice_new0 (BufferIdentification); +- +- if (GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) +- buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; +- +- id->timestamp = buf->omx_buf->nTimeStamp; +- gst_video_codec_frame_set_user_data (frame, id, +- (GDestroyNotify) buffer_identification_free); +- } ++ if (offset == 0 && GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) ++ buf->omx_buf->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + + /* TODO: Set flags + * - OMX_BUFFERFLAG_DECODEONLY for buffers that are outside +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch new file mode 100644 index 00000000..b12bac17 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0004-gstomxvideoenc-simplify-_find_nearest_frame.patch @@ -0,0 +1,175 @@ +From 91123307c8f934a867cf70b9ae6b27373311b8fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 03:41:10 -0600 +Subject: [PATCH 04/11] gstomxvideoenc: simplify _find_nearest_frame +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Just the same as we did with the decoder. Also give the +function a gst_omx_video_enc prefix to distinct it from +the decoder function. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideoenc.c | 102 ++++++++------------------------------------------ + 1 file changed, 15 insertions(+), 87 deletions(-) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index a85e815..3a139bb 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -55,18 +55,6 @@ gst_omx_video_enc_control_rate_get_type (void) + return qtype; + } + +-typedef struct _BufferIdentification BufferIdentification; +-struct _BufferIdentification +-{ +- guint64 timestamp; +-}; +- +-static void +-buffer_identification_free (BufferIdentification * id) +-{ +- g_slice_free (BufferIdentification, id); +-} +- + /* prototypes */ + static void gst_omx_video_enc_finalize (GObject * object); + static void gst_omx_video_enc_set_property (GObject * object, guint prop_id, +@@ -551,88 +539,34 @@ gst_omx_video_enc_change_state (GstElement * element, GstStateChange transition) + return ret; + } + +-#define MAX_FRAME_DIST_TICKS (5 * OMX_TICKS_PER_SECOND) +-#define MAX_FRAME_DIST_FRAMES (100) +- + static GstVideoCodecFrame * +-_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) ++gst_omx_video_enc_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf) + { +- GList *l, *best_l = NULL; +- GList *finish_frames = NULL; + GstVideoCodecFrame *best = NULL; +- guint64 best_timestamp = 0; +- guint64 best_diff = G_MAXUINT64; +- BufferIdentification *best_id = NULL; ++ GstClockTimeDiff best_diff = G_MAXINT64; ++ GstClockTime timestamp; + GList *frames; ++ GList *l; ++ ++ if (buf->omx_buf->nTimeStamp) ++ timestamp = ++ gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND, ++ OMX_TICKS_PER_SECOND); ++ else ++ timestamp = GST_CLOCK_TIME_NONE; + + frames = gst_video_encoder_get_frames (GST_VIDEO_ENCODER (self)); + + for (l = frames; l; l = l->next) { + GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 timestamp, diff; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; +- +- timestamp = id->timestamp; ++ GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts)); + +- if (timestamp > buf->omx_buf->nTimeStamp) +- diff = timestamp - buf->omx_buf->nTimeStamp; +- else +- diff = buf->omx_buf->nTimeStamp - timestamp; +- +- if (best == NULL || diff < best_diff) { ++ if (diff < best_diff) { + best = tmp; +- best_timestamp = timestamp; + best_diff = diff; +- best_l = l; +- best_id = id; +- +- /* For frames without timestamp we simply take the first frame */ +- if ((buf->omx_buf->nTimeStamp == 0 && timestamp == 0) || diff == 0) +- break; +- } +- } +- +- if (best_id) { +- for (l = frames; l && l != best_l; l = l->next) { +- GstVideoCodecFrame *tmp = l->data; +- BufferIdentification *id = gst_video_codec_frame_get_user_data (tmp); +- guint64 diff_ticks, diff_frames; +- +- /* This happens for frames that were just added but +- * which were not passed to the component yet. Ignore +- * them here! +- */ +- if (!id) +- continue; + +- if (id->timestamp > best_timestamp) ++ if (diff == 0) + break; +- +- if (id->timestamp == 0 || best_timestamp == 0) +- diff_ticks = 0; +- else +- diff_ticks = best_timestamp - id->timestamp; +- diff_frames = best->system_frame_number - tmp->system_frame_number; +- +- if (diff_ticks > MAX_FRAME_DIST_TICKS +- || diff_frames > MAX_FRAME_DIST_FRAMES) { +- finish_frames = +- g_list_prepend (finish_frames, gst_video_codec_frame_ref (tmp)); +- } +- } +- } +- +- if (finish_frames) { +- g_warning ("Too old frames, bug in encoder -- please file a bug"); +- for (l = finish_frames; l; l = l->next) { +- gst_video_encoder_finish_frame (GST_VIDEO_ENCODER (self), l->data); + } + } + +@@ -851,7 +785,7 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self) + (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp); + + GST_VIDEO_ENCODER_STREAM_LOCK (self); +- frame = _find_nearest_frame (self, buf); ++ frame = gst_omx_video_enc_find_nearest_frame (self, buf); + + g_assert (klass->handle_output_frame); + flow_ret = klass->handle_output_frame (self, self->enc_out_port, buf, frame); +@@ -1559,7 +1493,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + port = self->enc_in_port; + + while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { +- BufferIdentification *id; + GstClockTime timestamp, duration; + + /* Make sure to release the base class stream lock, otherwise +@@ -1683,11 +1616,6 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + self->last_upstream_ts += duration; + } + +- id = g_slice_new0 (BufferIdentification); +- id->timestamp = buf->omx_buf->nTimeStamp; +- gst_video_codec_frame_set_user_data (frame, id, +- (GDestroyNotify) buffer_identification_free); +- + self->started = TRUE; + err = gst_omx_port_release_buffer (port, buf); + if (err != OMX_ErrorNone) +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch new file mode 100644 index 00000000..686e0693 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0005-omx-improve-tunneling-support.patch @@ -0,0 +1,77 @@ +From 1975efe159dc52a8030602736c5319785fb62329 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Thu, 5 Sep 2013 04:15:26 -0600 +Subject: [PATCH 05/11] omx: improve tunneling support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Keep track where the tunnel leads us instead of just if it's tunneled or not. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomx.c | 13 +++++++------ + omx/gstomx.h | 2 +- + 2 files changed, 8 insertions(+), 7 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index 4e94712..c8a8927 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -920,7 +920,7 @@ gst_omx_component_add_port (GstOMXComponent * comp, guint32 index) + port->comp = comp; + port->index = index; + +- port->tunneled = FALSE; ++ port->tunneled = NULL; + + port->port_def = port_def; + +@@ -1085,8 +1085,8 @@ gst_omx_component_setup_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + port2->index); + + if (err == OMX_ErrorNone) { +- port1->tunneled = TRUE; +- port2->tunneled = TRUE; ++ port1->tunneled = port2; ++ port2->tunneled = port1; + } + + GST_DEBUG_OBJECT (comp1->parent, +@@ -1115,7 +1115,8 @@ gst_omx_component_close_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + g_return_val_if_fail (port2->port_def.eDir == OMX_DirInput, + OMX_ErrorUndefined); + g_return_val_if_fail (comp1->core == comp2->core, OMX_ErrorUndefined); +- g_return_val_if_fail (port1->tunneled && port2->tunneled, OMX_ErrorUndefined); ++ g_return_val_if_fail (port1->tunneled == port2, OMX_ErrorUndefined); ++ g_return_val_if_fail (port2->tunneled == port1, OMX_ErrorUndefined); + + g_mutex_lock (&comp1->lock); + g_mutex_lock (&comp2->lock); +@@ -1136,8 +1137,8 @@ gst_omx_component_close_tunnel (GstOMXComponent * comp1, GstOMXPort * port1, + gst_omx_error_to_string (err), err); + } + +- port1->tunneled = FALSE; +- port2->tunneled = FALSE; ++ port1->tunneled = NULL; ++ port2->tunneled = NULL; + + GST_DEBUG_OBJECT (comp1->parent, + "Closed tunnel between %s port %u and %s port %u", +diff --git a/omx/gstomx.h b/omx/gstomx.h +index 8af81b8..3645b63 100644 +--- a/omx/gstomx.h ++++ b/omx/gstomx.h +@@ -199,7 +199,7 @@ struct _GstOMXPort { + GstOMXComponent *comp; + guint32 index; + +- gboolean tunneled; ++ GstOMXPort *tunneled; + + OMX_PARAM_PORTDEFINITIONTYPE port_def; + GPtrArray *buffers; /* Contains GstOMXBuffer* */ +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch new file mode 100644 index 00000000..aa3e403f --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0006-omx-add-tunneling-support-between-decoder-and-encode.patch @@ -0,0 +1,328 @@ +From 17e9d641799a075a085a64d0543c5a51b11fd73d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Fri, 13 Sep 2013 03:33:19 -0600 +Subject: [PATCH 06/11] omx: add tunneling support between decoder and + encoders v2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Forward the frames through both the OMX tunnel as well as the gst pad, this +way we can map OMX buffers to their frame counterpart when they left the +tunnel on the other side. + +v2: fix tunnel close and buffer dealloc order + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomx.c | 6 +++- + omx/gstomx.h | 2 ++ + omx/gstomxvideodec.c | 90 ++++++++++++++++++++++++++++++++++++++++++++------ + omx/gstomxvideoenc.c | 29 +++++++++++++--- + 4 files changed, 110 insertions(+), 17 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index c8a8927..df3a8ff 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -1204,7 +1204,6 @@ gst_omx_port_acquire_buffer (GstOMXPort * port, GstOMXBuffer ** buf) + GstOMXBuffer *_buf = NULL; + + g_return_val_if_fail (port != NULL, GST_OMX_ACQUIRE_BUFFER_ERROR); +- g_return_val_if_fail (!port->tunneled, GST_OMX_ACQUIRE_BUFFER_ERROR); + g_return_val_if_fail (buf != NULL, GST_OMX_ACQUIRE_BUFFER_ERROR); + + *buf = NULL; +@@ -1298,6 +1297,11 @@ retry: + goto done; + } + ++ if (port->tunneled) { ++ ret = GST_OMX_ACQUIRE_BUFFER_TUNNELED; ++ goto done; ++ } ++ + /* + * At this point we have no error or flushing/eos port + * and a properly configured port. +diff --git a/omx/gstomx.h b/omx/gstomx.h +index 3645b63..9b534bd 100644 +--- a/omx/gstomx.h ++++ b/omx/gstomx.h +@@ -124,6 +124,8 @@ typedef enum { + GST_OMX_ACQUIRE_BUFFER_RECONFIGURE, + /* The port is EOS */ + GST_OMX_ACQUIRE_BUFFER_EOS, ++ /* The port is tunneled */ ++ GST_OMX_ACQUIRE_BUFFER_TUNNELED, + /* A fatal error happened */ + GST_OMX_ACQUIRE_BUFFER_ERROR + } GstOMXAcquireBufferReturn; +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index 020b7d3..e8813fb 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -50,6 +50,7 @@ + #include <string.h> + + #include "gstomxvideodec.h" ++#include "gstomxvideoenc.h" + + GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category); + #define GST_CAT_DEFAULT gst_omx_video_dec_debug_category +@@ -881,6 +882,11 @@ gst_omx_video_dec_shutdown (GstOMXVideoDec * self) + gst_omx_component_get_state (self->dec, 5 * GST_SECOND); + } + ++ if (self->dec_out_port->tunneled) { ++ gst_omx_component_close_tunnel (self->dec, self->dec_out_port, ++ self->dec_out_port->tunneled->comp, self->dec_out_port->tunneled); ++ } ++ + return TRUE; + } + +@@ -1527,7 +1533,7 @@ done: + static OMX_ERRORTYPE + gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) + { +- OMX_ERRORTYPE err; ++ OMX_ERRORTYPE err = OMX_ErrorNone; + + if (self->out_port_pool) { + gst_buffer_pool_set_active (self->out_port_pool, FALSE); +@@ -1543,7 +1549,10 @@ gst_omx_video_dec_deallocate_output_buffers (GstOMXVideoDec * self) + gst_omx_port_deallocate_buffers (self-> + eglimage ? self->egl_out_port : self->dec_out_port); + #else +- err = gst_omx_port_deallocate_buffers (self->dec_out_port); ++ if (!self->dec_out_port->tunneled) ++ err = gst_omx_port_deallocate_buffers (self->dec_out_port); ++ else ++ err = gst_omx_port_set_enabled (self->dec_out_port, FALSE); + #endif + + return err; +@@ -1772,12 +1781,28 @@ gst_omx_video_dec_reconfigure_output_port (GstOMXVideoDec * self) + + GST_VIDEO_DECODER_STREAM_UNLOCK (self); + ++ { ++ GstPad *peer = gst_pad_get_peer (GST_VIDEO_DECODER_SRC_PAD (self)); ++ GstElement *element = peer ? gst_pad_get_parent_element (peer) : NULL; ++ ++ if (element && GST_IS_OMX_VIDEO_ENC (element)) { ++ GstOMXVideoEnc *enc = GST_OMX_VIDEO_ENC (element); ++ ++ gst_omx_component_setup_tunnel (self->dec, self->dec_out_port, ++ enc->enc, enc->enc_in_port); ++ ++ } ++ } ++ + #if defined (USE_OMX_TARGET_RPI) && defined (HAVE_GST_EGL) + enable_port: + #endif +- err = gst_omx_video_dec_allocate_output_buffers (self); +- if (err != OMX_ErrorNone) +- goto done; ++ ++ if (!self->dec_out_port->tunneled) { ++ err = gst_omx_video_dec_allocate_output_buffers (self); ++ if (err != OMX_ErrorNone) ++ goto done; ++ } + + err = gst_omx_port_populate (port); + if (err != OMX_ErrorNone) +@@ -1816,6 +1841,9 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self) + goto flushing; + } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_EOS) { + goto eos; ++ } else if (acq_return == GST_OMX_ACQUIRE_BUFFER_TUNNELED) { ++ gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self)); ++ return; + } + + if (!gst_pad_has_current_caps (GST_VIDEO_DECODER_SRC_PAD (self)) || +@@ -2657,6 +2685,7 @@ gst_omx_video_dec_set_format (GstVideoDecoder * decoder, + GST_DEBUG_OBJECT (self, "Starting task again"); + + self->downstream_flow_ret = GST_FLOW_OK; ++ + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL); + +@@ -2703,6 +2732,7 @@ gst_omx_video_dec_reset (GstVideoDecoder * decoder, gboolean hard) + self->last_upstream_ts = 0; + self->eos = FALSE; + self->downstream_flow_ret = GST_FLOW_OK; ++ + gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self), + (GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL); + +@@ -2925,7 +2955,11 @@ gst_omx_video_dec_handle_frame (GstVideoDecoder * decoder, + goto release_error; + } + +- gst_video_codec_frame_unref (frame); ++ if (self->dec_out_port->tunneled) { ++ frame->output_buffer = gst_buffer_new (); ++ gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame); ++ } else ++ gst_video_codec_frame_unref (frame); + + GST_DEBUG_OBJECT (self, "Passed frame to component"); + +@@ -3003,6 +3037,7 @@ gst_omx_video_dec_finish (GstVideoDecoder * decoder) + static GstFlowReturn + gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + { ++ GstOMXVideoEnc *enc = NULL; + GstOMXVideoDecClass *klass; + GstOMXBuffer *buf; + GstOMXAcquireBufferReturn acq_ret; +@@ -3031,6 +3066,14 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + return GST_FLOW_OK; + } + ++ if (self->dec_out_port->tunneled) { ++ GstPad *peer = gst_pad_get_peer (GST_VIDEO_DECODER_SRC_PAD (self)); ++ GstElement *element = peer ? gst_pad_get_parent_element (peer) : NULL; ++ ++ if (element && GST_IS_OMX_VIDEO_ENC (element)) ++ enc = GST_OMX_VIDEO_ENC (element); ++ } ++ + /* Make sure to release the base class stream lock, otherwise + * _loop() can't call _finish_frame() and we might block forever + * because no input buffers are released */ +@@ -3047,8 +3090,14 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + return GST_FLOW_ERROR; + } + +- g_mutex_lock (&self->drain_lock); +- self->draining = TRUE; ++ if (enc) { ++ g_mutex_lock (&enc->drain_lock); ++ enc->draining = TRUE; ++ } else { ++ g_mutex_lock (&self->drain_lock); ++ self->draining = TRUE; ++ } ++ + buf->omx_buf->nFilledLen = 0; + buf->omx_buf->nTimeStamp = + gst_util_uint64_scale (self->last_upstream_ts, OMX_TICKS_PER_SECOND, +@@ -3059,6 +3108,10 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, "Failed to drain component: %s (0x%08x)", + gst_omx_error_to_string (err), err); ++ if (enc) ++ g_mutex_unlock (&enc->drain_lock); ++ else ++ g_mutex_unlock (&self->drain_lock); + GST_VIDEO_DECODER_STREAM_LOCK (self); + return GST_FLOW_ERROR; + } +@@ -3067,18 +3120,33 @@ gst_omx_video_dec_drain (GstOMXVideoDec * self, gboolean is_eos) + + if (G_UNLIKELY (self->dec->hacks & GST_OMX_HACK_DRAIN_MAY_NOT_RETURN)) { + gint64 wait_until = g_get_monotonic_time () + G_TIME_SPAN_SECOND / 2; ++ gboolean result; ++ ++ if (enc) ++ result = ++ g_cond_wait_until (&enc->drain_cond, &enc->drain_lock, wait_until); ++ else ++ result = ++ g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until); + +- if (!g_cond_wait_until (&self->drain_cond, &self->drain_lock, wait_until)) ++ if (!result) + GST_WARNING_OBJECT (self, "Drain timed out"); + else + GST_DEBUG_OBJECT (self, "Drained component"); + + } else { +- g_cond_wait (&self->drain_cond, &self->drain_lock); ++ if (enc) ++ g_cond_wait (&enc->drain_cond, &enc->drain_lock); ++ else ++ g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained component"); + } + +- g_mutex_unlock (&self->drain_lock); ++ if (enc) ++ g_mutex_unlock (&enc->drain_lock); ++ else ++ g_mutex_unlock (&self->drain_lock); ++ + GST_VIDEO_DECODER_STREAM_LOCK (self); + + self->started = FALSE; +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index 3a139bb..8f6cab3 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -364,7 +364,10 @@ gst_omx_video_enc_shutdown (GstOMXVideoEnc * self) + gst_omx_component_get_state (self->enc, 5 * GST_SECOND); + } + gst_omx_component_set_state (self->enc, OMX_StateLoaded); +- gst_omx_port_deallocate_buffers (self->enc_in_port); ++ if (!self->enc_in_port->tunneled) ++ gst_omx_port_deallocate_buffers (self->enc_in_port); ++ else ++ gst_omx_port_set_enabled (self->enc_in_port, FALSE); + gst_omx_port_deallocate_buffers (self->enc_out_port); + if (state > OMX_StateLoaded) + gst_omx_component_get_state (self->enc, 5 * GST_SECOND); +@@ -1086,8 +1089,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, + if (gst_omx_port_wait_buffers_released (self->enc_out_port, + 1 * GST_SECOND) != OMX_ErrorNone) + return FALSE; +- if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone) +- return FALSE; ++ if (!self->enc_in_port->tunneled) ++ if (gst_omx_port_deallocate_buffers (self->enc_in_port) != OMX_ErrorNone) ++ return FALSE; + if (gst_omx_port_deallocate_buffers (self->enc_out_port) != OMX_ErrorNone) + return FALSE; + if (gst_omx_port_wait_enabled (self->enc_in_port, +@@ -1225,8 +1229,18 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder, + return FALSE; + + /* Need to allocate buffers to reach Idle state */ +- if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone) +- return FALSE; ++ if (self->enc_in_port->tunneled) { ++ if (gst_omx_port_set_enabled (self->enc_in_port->tunneled, ++ TRUE) != OMX_ErrorNone) ++ return FALSE; ++ ++ if (gst_omx_port_wait_enabled (self->enc_in_port->tunneled, ++ 1 * GST_SECOND) != OMX_ErrorNone) ++ return FALSE; ++ } else { ++ if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone) ++ return FALSE; ++ } + + if (gst_omx_component_get_state (self->enc, + GST_CLOCK_TIME_NONE) != OMX_StateIdle) +@@ -1492,6 +1506,11 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder, + + port = self->enc_in_port; + ++ if (port->tunneled) { ++ gst_video_codec_frame_unref (frame); ++ return self->downstream_flow_ret; ++ } ++ + while (acq_ret != GST_OMX_ACQUIRE_BUFFER_OK) { + GstClockTime timestamp, duration; + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch new file mode 100644 index 00000000..6db5e742 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch @@ -0,0 +1,155 @@ +From 9d1fc5ceb72222037b959c1a2c3fe05c50de676a Mon Sep 17 00:00:00 2001 +From: Leo Liu <leo.liu@amd.com> +Date: Thu, 14 Nov 2013 18:47:24 -0500 +Subject: [PATCH 07/11] gstomxvideoenc: implement scaling configuration + support + +Signed-off-by: Leo Liu <leo.liu@amd.com> +--- + omx/gstomxvideoenc.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++- + omx/gstomxvideoenc.h | 3 +++ + 2 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index 8f6cab3..ee41fa0 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -96,7 +96,9 @@ enum + PROP_TARGET_BITRATE, + PROP_QUANT_I_FRAMES, + PROP_QUANT_P_FRAMES, +- PROP_QUANT_B_FRAMES ++ PROP_QUANT_B_FRAMES, ++ PROP_SCALING_WIDTH, ++ PROP_SCALING_HEIGHT + }; + + /* FIXME: Better defaults */ +@@ -105,6 +107,8 @@ enum + #define GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT (0xffffffff) + #define GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT (0xffffffff) + #define GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT (0xffffffff) ++#define GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT (0xffffffff) ++#define GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT (0xffffffff) + + /* class initialization */ + +@@ -163,6 +167,20 @@ gst_omx_video_enc_class_init (GstOMXVideoEncClass * klass) + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + GST_PARAM_MUTABLE_READY)); + ++ g_object_class_install_property (gobject_class, PROP_SCALING_WIDTH, ++ g_param_spec_uint ("scaling-width", "Scaling Width", ++ "Scaling Width parameter (0xffffffff=component default)", ++ 0, G_MAXUINT, GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | ++ GST_PARAM_MUTABLE_READY)); ++ ++ g_object_class_install_property (gobject_class, PROP_SCALING_HEIGHT, ++ g_param_spec_uint ("scaling-height", "Scaling Height", ++ "Scaling Height parameter (0xffffffff=component default)", ++ 0, G_MAXUINT, GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | ++ GST_PARAM_MUTABLE_READY)); ++ + element_class->change_state = + GST_DEBUG_FUNCPTR (gst_omx_video_enc_change_state); + +@@ -197,6 +215,8 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self) + self->quant_i_frames = GST_OMX_VIDEO_ENC_QUANT_I_FRAMES_DEFAULT; + self->quant_p_frames = GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT; + self->quant_b_frames = GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT; ++ self->scaling_width = GST_OMX_VIDEO_ENC_SCALING_WIDTH_DEFAULT; ++ self->scaling_height = GST_OMX_VIDEO_ENC_SCALING_HEIGHT_DEFAULT; + + g_mutex_init (&self->drain_lock); + g_cond_init (&self->drain_cond); +@@ -345,6 +365,45 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder) + + } + } ++ ++ if (self->scaling_width != 0xffffffff || ++ self->scaling_height != 0xffffffff) { ++ OMX_CONFIG_SCALEFACTORTYPE scale_factor; ++ GST_OMX_INIT_STRUCT (&scale_factor); ++ scale_factor.nPortIndex = self->enc_out_port->index; ++ ++ err = gst_omx_component_get_config (self->enc, ++ OMX_IndexConfigCommonScale, &scale_factor); ++ ++ if (err == OMX_ErrorNone) { ++ ++ if (self->scaling_width != 0xffffffff) ++ scale_factor.xWidth = self->scaling_width; ++ if (self->scaling_height != 0xffffffff) ++ scale_factor.xHeight = self->scaling_height; ++ ++ err = ++ gst_omx_component_set_config (self->enc, ++ OMX_IndexConfigCommonScale, &scale_factor); ++ if (err == OMX_ErrorUnsupportedIndex) { ++ GST_WARNING_OBJECT (self, ++ "Setting scale configuration not supported by the component"); ++ } else if (err == OMX_ErrorUnsupportedSetting) { ++ GST_WARNING_OBJECT (self, ++ "Setting scale configuration %u %u not supported by the component", ++ self->scaling_width, self->scaling_height); ++ } else if (err != OMX_ErrorNone) { ++ GST_ERROR_OBJECT (self, ++ "Failed to set scale configuration: %s (0x%08x)", ++ gst_omx_error_to_string (err), err); ++ return FALSE; ++ } ++ } else { ++ GST_ERROR_OBJECT (self, ++ "Failed to set scale configuration: %s (0x%08x)", ++ gst_omx_error_to_string (err), err); ++ } ++ } + } + + return TRUE; +@@ -443,6 +502,12 @@ gst_omx_video_enc_set_property (GObject * object, guint prop_id, + case PROP_QUANT_B_FRAMES: + self->quant_b_frames = g_value_get_uint (value); + break; ++ case PROP_SCALING_WIDTH: ++ self->scaling_width = g_value_get_uint (value); ++ break; ++ case PROP_SCALING_HEIGHT: ++ self->scaling_height = g_value_get_uint (value); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -471,6 +536,12 @@ gst_omx_video_enc_get_property (GObject * object, guint prop_id, GValue * value, + case PROP_QUANT_B_FRAMES: + g_value_set_uint (value, self->quant_b_frames); + break; ++ case PROP_SCALING_WIDTH: ++ g_value_set_uint (value, self->scaling_width); ++ break; ++ case PROP_SCALING_HEIGHT: ++ g_value_set_uint (value, self->scaling_height); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +diff --git a/omx/gstomxvideoenc.h b/omx/gstomxvideoenc.h +index e266537..86e9c8f 100644 +--- a/omx/gstomxvideoenc.h ++++ b/omx/gstomxvideoenc.h +@@ -77,6 +77,9 @@ struct _GstOMXVideoEnc + guint32 quant_p_frames; + guint32 quant_b_frames; + ++ guint32 scaling_width; ++ guint32 scaling_height; ++ + GstFlowReturn downstream_flow_ret; + }; + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch new file mode 100644 index 00000000..8478cc3a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0008-configure-fix-first-run-of-autogen-automake.patch @@ -0,0 +1,29 @@ +From 8e089ae8249899b8e47cbe7abfe3dd8814458c89 Mon Sep 17 00:00:00 2001 +From: Tim Writer <Tim.Writer@amd.com> +Date: Mon, 25 Nov 2013 15:51:21 -0500 +Subject: [PATCH 08/11] configure: fix first run of autogen/automake + +Without AC_CONFIG_AUX_DIR, libtoolize fails to copy ltmain.sh, +causing the first run of automake to fail. +--- + configure.ac | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/configure.ac b/configure.ac +index fcf4d9d..6dcca1c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -9,6 +9,10 @@ AC_INIT(GStreamer OpenMAX Plug-ins, 1.0.0.1, + http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer, + gst-omx) + ++dnl Forces libtoolize to copy ltmain.sh. Without it, automake fails on ++dnl the first run. ++AC_CONFIG_AUX_DIR([.]) ++ + AG_GST_INIT + + dnl initialize automake +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch new file mode 100644 index 00000000..df070f44 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0009-omxvideodec-fix-startup-race-condition.patch @@ -0,0 +1,33 @@ +From c79c13c43e4d535fdb0c7fc508a7d5219eebe940 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 18:48:17 +0100 +Subject: [PATCH 09/11] omxvideodec: fix startup race condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The reset function shouldn't start the src pad +loop if it wasn't started before. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideodec.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/omx/gstomxvideodec.c b/omx/gstomxvideodec.c +index e8813fb..00f3951 100644 +--- a/omx/gstomxvideodec.c ++++ b/omx/gstomxvideodec.c +@@ -2703,6 +2703,9 @@ gst_omx_video_dec_reset (GstVideoDecoder * decoder, gboolean hard) + + GST_DEBUG_OBJECT (self, "Resetting decoder"); + ++ if (gst_omx_component_get_state (self->dec, 0) == OMX_StateLoaded) ++ return TRUE; ++ + gst_omx_port_set_flushing (self->dec_in_port, 5 * GST_SECOND, TRUE); + gst_omx_port_set_flushing (self->dec_out_port, 5 * GST_SECOND, TRUE); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch new file mode 100644 index 00000000..68b89b8a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0010-omxvideoenc-fix-startup-race-condition.patch @@ -0,0 +1,33 @@ +From ba51373c66f4c9c3349eb083c5218b31e4162a6e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 18:49:41 +0100 +Subject: [PATCH 10/11] omxvideoenc: fix startup race condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The reset function shouldn't start the src pad +loop if it wasn't started before. + +Signed-off-by: Christian König <christian.koenig@amd.com> +--- + omx/gstomxvideoenc.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/omx/gstomxvideoenc.c b/omx/gstomxvideoenc.c +index ee41fa0..e65a9e0 100644 +--- a/omx/gstomxvideoenc.c ++++ b/omx/gstomxvideoenc.c +@@ -1359,6 +1359,9 @@ gst_omx_video_enc_reset (GstVideoEncoder * encoder, gboolean hard) + + GST_DEBUG_OBJECT (self, "Resetting encoder"); + ++ if (gst_omx_component_get_state (self->enc, 0) == OMX_StateLoaded) ++ return TRUE; ++ + gst_omx_port_set_flushing (self->enc_in_port, 5 * GST_SECOND, TRUE); + gst_omx_port_set_flushing (self->enc_out_port, 5 * GST_SECOND, TRUE); + +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch new file mode 100644 index 00000000..6de3b84a --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx/0011-omx-fix-two-serious-message-handling-bugs.patch @@ -0,0 +1,40 @@ +From 6d0b6813745b54eb5dd249ba4446118b21383059 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Sat, 1 Mar 2014 22:28:24 +0100 +Subject: [PATCH 11/11] omx: fix two serious message handling bugs + +Waiting for the next message if we already got one +is nonsense and can lead to lockups. + +https://bugzilla.gnome.org/show_bug.cgi?id=725468 +--- + omx/gstomx.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/omx/gstomx.c b/omx/gstomx.c +index df3a8ff..b77c904 100644 +--- a/omx/gstomx.c ++++ b/omx/gstomx.c +@@ -842,8 +842,7 @@ gst_omx_component_get_state (GstOMXComponent * comp, GstClockTime timeout) + g_mutex_unlock (&comp->lock); + if (!g_queue_is_empty (&comp->messages)) { + signalled = TRUE; +- } +- if (timeout == GST_CLOCK_TIME_NONE) { ++ } else if (timeout == GST_CLOCK_TIME_NONE) { + g_cond_wait (&comp->messages_cond, &comp->messages_lock); + signalled = TRUE; + } else { +@@ -1519,8 +1518,7 @@ gst_omx_port_set_flushing (GstOMXPort * port, GstClockTime timeout, + + if (!g_queue_is_empty (&comp->messages)) { + signalled = TRUE; +- } +- if (timeout == GST_CLOCK_TIME_NONE) { ++ } else if (timeout == GST_CLOCK_TIME_NONE) { + g_cond_wait (&comp->messages_cond, &comp->messages_lock); + signalled = TRUE; + } else { +-- +1.7.9.5 + diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend new file mode 100644 index 00000000..7464a6da --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-omx_git.bbappend @@ -0,0 +1,32 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +# +# Remove the patch as it is not needed with the new SRCREV we are using +# +SRC_URI := "${@oe_filter_out('file://0001-omx-fixed-type-error-in-printf-call.patch', '${SRC_URI}', d)}" + +SRC_URI += "file://0001-gstomxvideodec-fix-multithreads-negotiation-problem-.patch \ + file://0002-gstomxvideodec-remove-dead-code.patch \ + file://0003-gstomxvideodec-simplify-_find_nearest_frame.patch \ + file://0004-gstomxvideoenc-simplify-_find_nearest_frame.patch \ + file://0005-omx-improve-tunneling-support.patch \ + file://0006-omx-add-tunneling-support-between-decoder-and-encode.patch \ + file://0007-gstomxvideoenc-implement-scaling-configuration-suppo.patch \ + file://0008-configure-fix-first-run-of-autogen-automake.patch \ + file://0009-omxvideodec-fix-startup-race-condition.patch \ + file://0010-omxvideoenc-fix-startup-race-condition.patch \ + file://0011-omx-fix-two-serious-message-handling-bugs.patch \ + " + +SRCREV = "c44cd849400b90f5f4b1f4f429278d9685b1daca" + +PV .= "+git${SRCPV}" + +EXTRA_OECONF += "--with-omx-target=bellagio" + +# +# This package should not have commercial license flags. +# There is discussion in the OE community about fixing this +# but in the meantime we'll explicitly remove it here. +# +LICENSE_FLAGS := "${@oe_filter_out('commercial', '${LICENSE_FLAGS}', d)}" diff --git a/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend new file mode 100644 index 00000000..ee510f63 --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend @@ -0,0 +1 @@ +PACKAGECONFIG[bluez] = "--enable-bluez,--disable-bluez,bluez5" diff --git a/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend b/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend new file mode 100644 index 00000000..068e3f2c --- /dev/null +++ b/meta-steppeeagle/recipes-multimedia/libomxil/libomxil_0.9.3.bbappend @@ -0,0 +1,8 @@ +RDEPENDS_${PN} += "libomx-mesa" + +# +# This package should not have commercial license flags. +# There is discussion in the OE community about fixing this +# but in the meantime we'll explicitly remove it here. +# +LICENSE_FLAGS := "${@oe_filter_out('commercial', '${LICENSE_FLAGS}', d)}" |