From f3e65f1c9374df13e4fa082bc750ce94e38c58de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20J=C3=A4genstedt?= Date: Wed, 15 Jun 2011 13:51:31 +0200 Subject: [PATCH 1/5] typefind: NULL check in degas_type_find The length check isn't sufficient, an source might report the correct length, but then still fail to read the requested number of bytes for some reason. https://bugzilla.gnome.org/show_bug.cgi?id=652642 --- gst/typefind/gsttypefindfunctions.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 55152e8e3e..ed393d87b2 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -4078,6 +4078,8 @@ degas_type_find (GstTypeFind * tf, gpointer private) if (len < 34) /* smallest header of the lot */ return; data = gst_type_find_peek (tf, 0, 4); + if (G_UNLIKELY (data == NULL)) + return; resolution = GST_READ_UINT16_BE (data); if (len == 32034) { /* could be DEGAS */ @@ -4088,6 +4090,8 @@ degas_type_find (GstTypeFind * tf, gpointer private) /* could be DEGAS Elite */ if (resolution <= 2) { data = gst_type_find_peek (tf, len - 16, 8); + if (G_UNLIKELY (data == NULL)) + return; for (n = 0; n < 4; n++) { if (GST_READ_UINT16_BE (data + n * 2) > 2) return; @@ -4100,6 +4104,8 @@ degas_type_find (GstTypeFind * tf, gpointer private) it does have 4 16 bytes values near the end that are 0-2 though. */ if ((resolution & 0x8000) && (resolution & 0x7fff) <= 2) { data = gst_type_find_peek (tf, len - 16, 8); + if (G_UNLIKELY (data == NULL)) + return; for (n = 0; n < 4; n++) { if (GST_READ_UINT16_BE (data + n * 2) > 2) return; From dc79c424849133d4ee1687beff40e33d472f8919 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Wed, 29 Jun 2011 11:30:51 +0200 Subject: [PATCH 2/5] streamsplitter: Fix getcaps src pad caps merge Caps returned from gst_pad_peer_get_caps_reffed () may not be writable. If they are not is should cause an assertion in gst_caps_merge (), however, sometimes assertions are disabled in binary builds of -base and it's safer to just be sure the caps are writable. Also, check that the reffed caps pointer is not NULL. --- gst/encoding/gststreamsplitter.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gst/encoding/gststreamsplitter.c b/gst/encoding/gststreamsplitter.c index c473386e56..c531b4c6c0 100644 --- a/gst/encoding/gststreamsplitter.c +++ b/gst/encoding/gststreamsplitter.c @@ -268,10 +268,13 @@ resync: GstPad *srcpad = (GstPad *) tmp->data; STREAMS_UNLOCK (stream_splitter); - if (res) - gst_caps_merge (res, gst_pad_peer_get_caps_reffed (srcpad)); - else + if (res) { + GstCaps *peercaps = gst_pad_peer_get_caps_reffed (srcpad); + if (peercaps) + gst_caps_merge (res, gst_caps_make_writable (peercaps)); + } else { res = gst_pad_peer_get_caps (srcpad); + } STREAMS_LOCK (stream_splitter); if (G_UNLIKELY (cookie != stream_splitter->cookie)) { From 96d2120c2bb0b29e1849098198f5fbef81939cdd Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Wed, 29 Jun 2011 09:59:05 -0300 Subject: [PATCH 3/5] tag: xmp: Remove extra chars from end of xmp packet Windows picture viewer is unhappy with extra trailing chars at the end of the xmppacket footer. So remove them as they aren't needed. --- gst-libs/gst/tag/gstxmptag.c | 6 +++--- tests/check/libs/tag.c | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/tag/gstxmptag.c b/gst-libs/gst/tag/gstxmptag.c index dd20fd3b51..6ae5d995be 100644 --- a/gst-libs/gst/tag/gstxmptag.c +++ b/gst-libs/gst/tag/gstxmptag.c @@ -1317,7 +1317,7 @@ gst_tag_list_from_xmp_buffer (const GstBuffer * buffer) if (*xp1 != '>') goto missing_header; - max_ft_len = 1 + strlen ("\n"); + max_ft_len = 1 + strlen (""); if (len < max_ft_len) goto missing_footer; @@ -1848,11 +1848,11 @@ gst_tag_list_to_xmp_buffer_full (const GstTagList * list, gboolean read_only, " " " " "\n"); } } - g_string_append_printf (data, "\n", + g_string_append_printf (data, "", (read_only ? 'r' : 'w')); buffer = gst_buffer_new (); - GST_BUFFER_SIZE (buffer) = data->len + 1; + GST_BUFFER_SIZE (buffer) = data->len; GST_BUFFER_DATA (buffer) = (guint8 *) g_string_free (data, FALSE); GST_BUFFER_MALLOCDATA (buffer) = GST_BUFFER_DATA (buffer); diff --git a/tests/check/libs/tag.c b/tests/check/libs/tag.c index 555cdb8df3..a65cdf1616 100644 --- a/tests/check/libs/tag.c +++ b/tests/check/libs/tag.c @@ -793,8 +793,7 @@ GST_START_TEST (test_xmp_parsing) "" "" ""; - const gchar *xmp_footer = - "" "" "\n"; + const gchar *xmp_footer = "" "" ""; struct { const gchar *xmp_data; From 7ad1ba6fbad5af1c0b873f49e28dde03201b0712 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Wed, 29 Jun 2011 13:12:49 +0200 Subject: [PATCH 4/5] encodebin: Add flags to disable conversion elements Add a flags property and two flags to allow one to disable the conversion elements within encodebin. Doing so insists that the uncompressed input to encodebin for the appropriate stream type is sufficient to meet the caps requirements of the encoders, muxers and encodebin target. This is mostly beneficial to bypass slow caps negotiations in the conversion elements. --- gst/encoding/gstencodebin.c | 130 +++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 32 deletions(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index d90e74597d..446f93b3c0 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -118,6 +118,15 @@ #define fast_pad_link(a,b) gst_pad_link_full((a),(b),GST_PAD_LINK_CHECK_NOTHING) #define fast_element_link(a,b) gst_element_link_pads_full((a),"src",(b),"sink",GST_PAD_LINK_CHECK_NOTHING) +typedef enum +{ + GST_ENC_FLAG_NATIVE_AUDIO = (1 << 0), + GST_ENC_FLAG_NATIVE_VIDEO = (1 << 1) +} GstEncFlags; + +#define GST_TYPE_ENC_FLAGS (gst_enc_flags_get_type()) +GType gst_enc_flags_get_type (void); + /* generic templates */ static GstStaticPadTemplate muxer_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, @@ -180,6 +189,8 @@ struct _GstEncodeBin guint64 tolerance; gboolean avoid_reencoding; + + GstEncFlags flags; }; struct _GstEncodeBinClass @@ -216,6 +227,7 @@ struct _StreamGroup #define DEFAULT_QUEUE_TIME_MAX GST_SECOND #define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND #define DEFAULT_AVOID_REENCODING FALSE +#define DEFAULT_FLAGS 0 #define DEFAULT_RAW_CAPS \ "video/x-raw-yuv; " \ @@ -238,6 +250,7 @@ enum PROP_QUEUE_TIME_MAX, PROP_AUDIO_JITTER_TOLERANCE, PROP_AVOID_REENCODING, + PROP_FLAGS, PROP_LAST }; @@ -248,6 +261,31 @@ enum LAST_SIGNAL }; +#define C_FLAGS(v) ((guint) v) + +GType +gst_enc_flags_get_type (void) +{ + static const GFlagsValue values[] = { + {C_FLAGS (GST_ENC_FLAG_NATIVE_AUDIO), "Only use native audio formats", + "native-audio"}, + {C_FLAGS (GST_ENC_FLAG_NATIVE_VIDEO), "Only use native video formats", + "native-video"}, + {0, NULL, NULL} + }; + static volatile GType id = 0; + + if (g_once_init_enter ((gsize *) & id)) { + GType _id; + + _id = g_flags_register_static ("GstEncFlags", values); + + g_once_init_leave ((gsize *) & id, _id); + } + + return id; +} + static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 }; static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS); @@ -339,6 +377,16 @@ gst_encode_bin_class_init (GstEncodeBinClass * klass) DEFAULT_AVOID_REENCODING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * GstEncodeBin:flags + * + * Control the behaviour of encodebin. + */ + g_object_class_install_property (gobject_klass, PROP_FLAGS, + g_param_spec_flags ("flags", "Flags", "Flags to control behaviour", + GST_TYPE_ENC_FLAGS, DEFAULT_FLAGS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* Signals */ /** * GstEncodeBin::request-pad @@ -447,6 +495,7 @@ gst_encode_bin_init (GstEncodeBin * encode_bin) encode_bin->queue_time_max = DEFAULT_QUEUE_TIME_MAX; encode_bin->tolerance = DEFAULT_AUDIO_JITTER_TOLERANCE; encode_bin->avoid_reencoding = DEFAULT_AVOID_REENCODING; + encode_bin->flags = DEFAULT_FLAGS; tmpl = gst_static_pad_template_get (&muxer_src_template); encode_bin->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl); @@ -480,6 +529,9 @@ gst_encode_bin_set_property (GObject * object, guint prop_id, case PROP_AVOID_REENCODING: ebin->avoid_reencoding = g_value_get_boolean (value); break; + case PROP_FLAGS: + ebin->flags = g_value_get_flags (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -511,6 +563,9 @@ gst_encode_bin_get_property (GObject * object, guint prop_id, case PROP_AVOID_REENCODING: g_value_set_boolean (value, ebin->avoid_reencoding); break; + case PROP_FLAGS: + g_value_set_flags (value, ebin->flags); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1206,37 +1261,40 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, /* 3.2. restriction elements */ /* FIXME : Once we have properties for specific converters, use those */ if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { + const gboolean native_video = ! !(ebin->flags & GST_ENC_FLAG_NATIVE_VIDEO); GstElement *cspace, *scale, *vrate, *cspace2; GST_LOG ("Adding conversion elements for video stream"); - cspace = gst_element_factory_make ("ffmpegcolorspace", NULL); - scale = gst_element_factory_make ("videoscale", NULL); - if (!scale) { - missing_element_name = "videoscale"; - goto missing_element; + if (!native_video) { + cspace = gst_element_factory_make ("ffmpegcolorspace", NULL); + scale = gst_element_factory_make ("videoscale", NULL); + if (!scale) { + missing_element_name = "videoscale"; + goto missing_element; + } + /* 4-tap scaling and black borders */ + g_object_set (scale, "method", 2, "add-borders", TRUE, NULL); + cspace2 = gst_element_factory_make ("ffmpegcolorspace", NULL); + + if (!cspace || !cspace2) { + missing_element_name = "ffmpegcolorspace"; + goto missing_element; + } + + gst_bin_add_many ((GstBin *) ebin, cspace, scale, cspace2, NULL); + tosync = g_list_append (tosync, cspace); + tosync = g_list_append (tosync, scale); + tosync = g_list_append (tosync, cspace2); + + sgroup->converters = g_list_prepend (sgroup->converters, cspace); + sgroup->converters = g_list_prepend (sgroup->converters, scale); + sgroup->converters = g_list_prepend (sgroup->converters, cspace2); + + if (!fast_element_link (cspace, scale) || + !fast_element_link (scale, cspace2)) + goto converter_link_failure; } - /* 4-tap scaling and black borders */ - g_object_set (scale, "method", 2, "add-borders", TRUE, NULL); - cspace2 = gst_element_factory_make ("ffmpegcolorspace", NULL); - - if (!cspace || !cspace2) { - missing_element_name = "ffmpegcolorspace"; - goto missing_element; - } - - gst_bin_add_many ((GstBin *) ebin, cspace, scale, cspace2, NULL); - tosync = g_list_append (tosync, cspace); - tosync = g_list_append (tosync, scale); - tosync = g_list_append (tosync, cspace2); - - sgroup->converters = g_list_prepend (sgroup->converters, cspace); - sgroup->converters = g_list_prepend (sgroup->converters, scale); - sgroup->converters = g_list_prepend (sgroup->converters, cspace2); - - if (!fast_element_link (cspace, scale) || - !fast_element_link (scale, cspace2)) - goto converter_link_failure; if (!gst_encoding_video_profile_get_variableframerate (GST_ENCODING_VIDEO_PROFILE (sprof))) { @@ -1249,15 +1307,23 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, gst_bin_add ((GstBin *) ebin, vrate); tosync = g_list_prepend (tosync, vrate); sgroup->converters = g_list_prepend (sgroup->converters, vrate); - if (!fast_element_link (cspace2, vrate) || - !fast_element_link (vrate, last)) + + if ((!native_video && !fast_element_link (cspace2, vrate)) + || !fast_element_link (vrate, last)) goto converter_link_failure; - } else if (!fast_element_link (cspace2, last)) - goto converter_link_failure; - last = cspace; + if (!native_video) + last = cspace; + else + last = vrate; + } else if (!native_video) { + if (!fast_element_link (cspace2, last)) + goto converter_link_failure; + last = cspace; + } - } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)) { + } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof) + && !(ebin->flags & GST_ENC_FLAG_NATIVE_AUDIO)) { GstElement *aconv, *ares, *arate, *aconv2; GST_LOG ("Adding conversion elements for audio stream"); From bf816fe81624d31a68d48bba1c48a969cee399f4 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Thu, 30 Jun 2011 20:33:36 +0200 Subject: [PATCH 5/5] encodebin: fix compiler warning cspace and cspace2 may run uninitialized. --- gst/encoding/gstencodebin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c index 446f93b3c0..dd50ac165e 100644 --- a/gst/encoding/gstencodebin.c +++ b/gst/encoding/gstencodebin.c @@ -1262,7 +1262,7 @@ _create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof, /* FIXME : Once we have properties for specific converters, use those */ if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) { const gboolean native_video = ! !(ebin->flags & GST_ENC_FLAG_NATIVE_VIDEO); - GstElement *cspace, *scale, *vrate, *cspace2; + GstElement *cspace = NULL, *scale, *vrate, *cspace2 = NULL; GST_LOG ("Adding conversion elements for video stream");