From c3e6e23b854222e1d9ed0dd254511db9dc5e051d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 20 Dec 2011 21:48:29 +0000 Subject: [PATCH 01/19] audio, rtsp: remove private/protected gtk-doc markup for enums This confuses glib-mkenums, and is not really useful anyway. https://bugzilla.gnome.org/show_bug.cgi?id=666618 --- gst-libs/gst/audio/multichannel.h | 3 +-- gst-libs/gst/rtsp/gstrtspdefs.h | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/gst-libs/gst/audio/multichannel.h b/gst-libs/gst/audio/multichannel.h index 8bf92d7d40..df2aa968d9 100644 --- a/gst-libs/gst/audio/multichannel.h +++ b/gst-libs/gst/audio/multichannel.h @@ -77,8 +77,7 @@ typedef enum { * are defined or all positions are undefined, but can't mix'n'match */ GST_AUDIO_CHANNEL_POSITION_NONE, - /*< private >*/ - /* don't use - counter */ + /* don't use - counter (private) */ GST_AUDIO_CHANNEL_POSITION_NUM } GstAudioChannelPosition; diff --git a/gst-libs/gst/rtsp/gstrtspdefs.h b/gst-libs/gst/rtsp/gstrtspdefs.h index 3727bf29a6..aab8d3eb67 100644 --- a/gst-libs/gst/rtsp/gstrtspdefs.h +++ b/gst-libs/gst/rtsp/gstrtspdefs.h @@ -228,10 +228,9 @@ typedef enum { /** * GstRTSPHeaderField: * - * Enumeration of rtsp header fields. + * Enumeration of rtsp header fields */ typedef enum { - /*< protected >*/ GST_RTSP_HDR_INVALID, /* @@ -342,10 +341,9 @@ typedef enum { /** * GstRTSPStatusCode: * - * Enumeration of rtsp status codes. + * Enumeration of rtsp status codes */ typedef enum { - /*< protected >*/ GST_RTSP_STS_INVALID = 0, GST_RTSP_STS_CONTINUE = 100, GST_RTSP_STS_OK = 200, From 76cc8b8f2a157a100da8ca7787a52cb01e021ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 2 Jan 2012 00:59:39 +0000 Subject: [PATCH 02/19] tag: add function to check whether a string is a valid language code API: gst_tag_check_language_code() --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/tag/lang.c | 28 +++++++++++++++++--- gst-libs/gst/tag/tag.h | 2 ++ tests/check/libs/tag.c | 10 +++++++ win32/common/libgsttag.def | 1 + 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 3f60d565e4..5640d21733 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -1971,6 +1971,7 @@ gst_tag_get_language_code gst_tag_get_language_code_iso_639_1 gst_tag_get_language_code_iso_639_2B gst_tag_get_language_code_iso_639_2T +gst_tag_check_language_code
diff --git a/gst-libs/gst/tag/lang.c b/gst-libs/gst/tag/lang.c index a0838fe1ef..c37366e089 100644 --- a/gst-libs/gst/tag/lang.c +++ b/gst-libs/gst/tag/lang.c @@ -30,8 +30,6 @@ * */ -/* FIXME 0.11: maybe switch to ISO-639-2 everywhere incl. GST_TAG_LANGUAGE? */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -311,8 +309,8 @@ gst_tag_get_language_codes (void) * gst_tag_get_language_name: * @language_code: two or three-letter ISO-639 language code * - * Returns the name of the language given an ISO-639 language code, such - * as often found in a GST_TAG_LANGUAGE tag. The name will be translated + * Returns the name of the language given an ISO-639 language code as + * found in a GST_TAG_LANGUAGE_CODE tag. The name will be translated * according to the current locale (if the library was built against the * iso-codes package, otherwise the English name will be returned). * @@ -492,3 +490,25 @@ gst_tag_get_language_code_iso_639_2B (const gchar * lang_code) return c; } + +/** + * gst_tag_check_language_code: + * @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de") + * + * Check if a given string contains a known ISO 639 language code. + * + * This is useful in situations where it's not clear whether a given + * string is a language code (which should be put into a #GST_TAG_LANGUAGE_CODE + * tag) or a free-form language name descriptor (which should be put into a + * #GST_TAG_LANGUAGE_NAME tag instead). + * + * Returns: TRUE if the two- or three-letter language code in @lang_code + * is a valid ISO-639 language code. + * + * Since: 0.10.37 + */ +gboolean +gst_tag_check_language_code (const gchar * lang_code) +{ + return (gst_tag_get_language_code_iso_639_1 (lang_code) != NULL); +} diff --git a/gst-libs/gst/tag/tag.h b/gst-libs/gst/tag/tag.h index 057378c2e6..074f81e3bf 100644 --- a/gst-libs/gst/tag/tag.h +++ b/gst-libs/gst/tag/tag.h @@ -551,6 +551,8 @@ const gchar * gst_tag_get_language_code_iso_639_2B (const gchar * lang_code); const gchar * gst_tag_get_language_code_iso_639_2T (const gchar * lang_code); +gboolean gst_tag_check_language_code (const gchar * lang_code); + /** * gst_tag_get_language_code: * @lang_code: ISO-639 language code (e.g. "deu" or "ger" or "de") diff --git a/tests/check/libs/tag.c b/tests/check/libs/tag.c index 634cc3fe43..58748e007a 100644 --- a/tests/check/libs/tag.c +++ b/tests/check/libs/tag.c @@ -748,6 +748,16 @@ GST_START_TEST (test_language_utils) ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("de"), "ger"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("deu"), "ger"); ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("ger"), "ger"); + + fail_unless (gst_tag_check_language_code ("de")); + fail_unless (gst_tag_check_language_code ("deu")); + fail_unless (gst_tag_check_language_code ("ger")); + fail_if (gst_tag_check_language_code ("xxx")); + fail_if (gst_tag_check_language_code ("und")); + fail_if (gst_tag_check_language_code ("un")); + fail_if (gst_tag_check_language_code ("")); + fail_if (gst_tag_check_language_code ("\377")); + fail_if (gst_tag_check_language_code ("deutsch")); } GST_END_TEST; diff --git a/win32/common/libgsttag.def b/win32/common/libgsttag.def index 8fa522c525..4af90e3eec 100644 --- a/win32/common/libgsttag.def +++ b/win32/common/libgsttag.def @@ -1,4 +1,5 @@ EXPORTS + gst_tag_check_language_code gst_tag_demux_get_type gst_tag_demux_result_get_type gst_tag_freeform_string_to_utf8 From af28016d0acd2141a23de8dee62b697c987a025f Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 11:02:17 +0100 Subject: [PATCH 03/19] streamsynchronizer: avoid crashing when operating on released pad --- gst/playback/gststreamsynchronizer.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/playback/gststreamsynchronizer.c b/gst/playback/gststreamsynchronizer.c index 45f8db47af..3f2b8a8dfe 100644 --- a/gst/playback/gststreamsynchronizer.c +++ b/gst/playback/gststreamsynchronizer.c @@ -94,11 +94,16 @@ gst_stream_get_other_pad (GstStream * stream, GstPad * pad) static GstPad * gst_stream_get_other_pad_from_pad (GstPad * pad) { - GstStreamSynchronizer *self = - GST_STREAM_SYNCHRONIZER (gst_pad_get_parent (pad)); + GstObject *parent = gst_pad_get_parent (pad); + GstStreamSynchronizer *self; GstStream *stream; GstPad *opad = NULL; + /* released pad does not have parent anymore */ + if (!G_LIKELY (parent)) + goto exit; + + self = GST_STREAM_SYNCHRONIZER (parent); GST_STREAM_SYNCHRONIZER_LOCK (self); stream = gst_pad_get_element_private (pad); if (!stream) @@ -110,6 +115,7 @@ out: GST_STREAM_SYNCHRONIZER_UNLOCK (self); gst_object_unref (self); +exit: if (!opad) GST_WARNING_OBJECT (pad, "Trying to get other pad after releasing"); From 3e0d35aec41ad63b978a8c7be62dfb37fdd93650 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 11:04:23 +0100 Subject: [PATCH 04/19] streamsynchronizer: force fallback buffer_alloc when other pad not available ... to avoid unnecessary spurious errors (upon e.g. shutdown). If a real error is applicable in this unusual circumstance (missing other pad), other (STREAM_LOCK protected) call paths can take care of that. --- gst/playback/gststreamsynchronizer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst/playback/gststreamsynchronizer.c b/gst/playback/gststreamsynchronizer.c index 3f2b8a8dfe..b71dcb305b 100644 --- a/gst/playback/gststreamsynchronizer.c +++ b/gst/playback/gststreamsynchronizer.c @@ -565,7 +565,7 @@ gst_stream_synchronizer_sink_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf) { GstPad *opad; - GstFlowReturn ret = GST_FLOW_ERROR; + GstFlowReturn ret = GST_FLOW_OK; GST_LOG_OBJECT (pad, "Allocating buffer: size=%u", size); @@ -573,6 +573,10 @@ gst_stream_synchronizer_sink_bufferalloc (GstPad * pad, guint64 offset, if (opad) { ret = gst_pad_alloc_buffer (opad, offset, size, caps, buf); gst_object_unref (opad); + } else { + /* may have been released during shutdown; + * silently trigger fallback */ + *buf = NULL; } GST_LOG_OBJECT (pad, "Allocation: %s", gst_flow_get_name (ret)); From b15b03ee6f117a5f511ab6f58f2babd486bd3a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 3 Jan 2012 21:20:04 +0000 Subject: [PATCH 05/19] videotestsrc: don't build generate_sine_table utility by default --- gst/videotestsrc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/videotestsrc/Makefile.am b/gst/videotestsrc/Makefile.am index 91b6f6376e..de4ce26bd3 100644 --- a/gst/videotestsrc/Makefile.am +++ b/gst/videotestsrc/Makefile.am @@ -15,7 +15,7 @@ libgstvideotestsrc_la_LIBTOOLFLAGS = --tag=disable-static noinst_HEADERS = gstvideotestsrc.h videotestsrc.h -noinst_PROGRAMS = generate_sine_table +EXTRA_PROGRAMS = generate_sine_table generate_sine_table_SOURCES = generate_sine_table.c generate_sine_table_CFLAGS = $(GST_CFLAGS) From 08af765ea2778ea48c3c56af3f567d2fc003fb80 Mon Sep 17 00:00:00 2001 From: Philip Flarsheim Date: Thu, 5 Jan 2012 01:51:35 +0000 Subject: [PATCH 06/19] docs: add win32 code snippets to GstXOverlay Gtk+ example --- gst-libs/gst/interfaces/xoverlay.c | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/interfaces/xoverlay.c b/gst-libs/gst/interfaces/xoverlay.c index 77c9e75c41..a5d9d60023 100644 --- a/gst-libs/gst/interfaces/xoverlay.c +++ b/gst-libs/gst/interfaces/xoverlay.c @@ -148,8 +148,11 @@ * #ifdef GDK_WINDOWING_X11 * #include <gdk/gdkx.h> // for GDK_WINDOW_XID * #endif + * #ifdef GDK_WINDOWING_WIN32 + * #include <gdk/gdkwin32.h> // for GDK_WINDOW_HWND + * #endif * ... - * static gulong video_window_xid = 0; + * static guintptr video_window_handle = 0; * ... * static GstBusSyncReply * bus_sync_handler (GstBus * bus, GstMessage * message, gpointer user_data) @@ -160,14 +163,14 @@ * if (!gst_structure_has_name (message->structure, "prepare-xwindow-id")) * return GST_BUS_PASS; * - * if (video_window_xid != 0) { + * if (video_window_handle != 0) { * GstXOverlay *xoverlay; * * // GST_MESSAGE_SRC (message) will be the video sink element * xoverlay = GST_X_OVERLAY (GST_MESSAGE_SRC (message)); - * gst_x_overlay_set_window_handle (xoverlay, video_window_xid); + * gst_x_overlay_set_window_handle (xoverlay, video_window_handle); * } else { - * g_warning ("Should have obtained video_window_xid by now!"); + * g_warning ("Should have obtained video_window_handle by now!"); * } * * gst_message_unref (message); @@ -178,6 +181,8 @@ * video_widget_realize_cb (GtkWidget * widget, gpointer data) * { * #if GTK_CHECK_VERSION(2,18,0) + * // Tell Gtk+/Gdk to create a native window for this widget instead of + * // drawing onto the parent widget. * // This is here just for pedagogical purposes, GDK_WINDOW_XID will call * // it as well in newer Gtk versions * if (!gdk_window_ensure_native (widget->window)) @@ -185,7 +190,16 @@ * #endif * * #ifdef GDK_WINDOWING_X11 - * video_window_xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window)); + * { + * gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window)); + * video_window_handle = xid; + * } + * #endif + * #ifdef GDK_WINDOWING_WIN32 + * { + * HWND wnd = GDK_WINDOW_HWND (gtk_widget_get_window (video_window)); + * video_window_handle = (guintptr) wnd; + * } * #endif * } * ... @@ -211,12 +225,12 @@ * gtk_widget_show_all (app_window); * * // realize window now so that the video window gets created and we can - * // obtain its XID before the pipeline is started up and the videosink - * // asks for the XID of the window to render onto + * // obtain its XID/HWND before the pipeline is started up and the videosink + * // asks for the XID/HWND of the window to render onto * gtk_widget_realize (video_window); * - * // we should have the XID now - * g_assert (video_window_xid != 0); + * // we should have the XID/HWND now + * g_assert (video_window_handle != 0); * ... * // set up sync handler for setting the xid once the pipeline is started * bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); From 580b6b2b69f6c4c90962edceee19b7284999f36b Mon Sep 17 00:00:00 2001 From: Idar Tollefsen Date: Thu, 4 Aug 2011 11:30:05 +0200 Subject: [PATCH 07/19] pango: changes includes from brackets to quotes for local files https://bugzilla.gnome.org/show_bug.cgi?id=667316 --- ext/pango/gstclockoverlay.c | 2 +- ext/pango/gsttimeoverlay.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pango/gstclockoverlay.c b/ext/pango/gstclockoverlay.c index d90cff1c31..24a8238087 100644 --- a/ext/pango/gstclockoverlay.c +++ b/ext/pango/gstclockoverlay.c @@ -46,7 +46,7 @@ #include "config.h" #endif -#include +#include "gstclockoverlay.h" #include #include diff --git a/ext/pango/gsttimeoverlay.c b/ext/pango/gsttimeoverlay.c index 27fab92057..fc663040ad 100644 --- a/ext/pango/gsttimeoverlay.c +++ b/ext/pango/gsttimeoverlay.c @@ -48,7 +48,7 @@ #include -#include +#include "gsttimeoverlay.h" GST_BOILERPLATE (GstTimeOverlay, gst_time_overlay, GstTextOverlay, GST_TYPE_TEXT_OVERLAY); From cfdb48ba8f46128baeb8ce249bcf9013d5fe0b3e Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Sat, 24 Sep 2011 14:05:42 +0200 Subject: [PATCH 08/19] videotestsrc: keep the calculation fixed-point https://bugzilla.gnome.org/show_bug.cgi?id=667315 --- gst/videotestsrc/videotestsrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/videotestsrc/videotestsrc.c b/gst/videotestsrc/videotestsrc.c index 8f7ddaff21..d7c3f87fe6 100644 --- a/gst/videotestsrc/videotestsrc.c +++ b/gst/videotestsrc/videotestsrc.c @@ -740,7 +740,7 @@ gst_video_test_src_smpte (GstVideoTestSrc * v, unsigned char *dest, int w, fourcc->paint_setup (p, dest); y1 = 2 * h / 3; - y2 = h * 0.75; + y2 = 3 * h / 4; /* color bars */ for (j = 0; j < y1; j++) { From 0febae7443b165ceaa69641e95d7069f26719e59 Mon Sep 17 00:00:00 2001 From: Pascal Buhler Date: Wed, 12 Oct 2011 11:28:10 +0200 Subject: [PATCH 09/19] rtcpbuffer: prevent overflow of 16bit header length. RTCP header can be (2^16 + 1) * 4 bytes long, so when validating a bogus packet it was possible to get a 16bit overflow resulting in a length of 0. This would put the gst_rtcp_buffer_validate_data function in a endless loop. https://bugzilla.gnome.org/show_bug.cgi?id=667313 --- gst-libs/gst/rtp/gstrtcpbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/rtp/gstrtcpbuffer.c b/gst-libs/gst/rtp/gstrtcpbuffer.c index fbd928c922..539f763875 100644 --- a/gst-libs/gst/rtp/gstrtcpbuffer.c +++ b/gst-libs/gst/rtp/gstrtcpbuffer.c @@ -111,7 +111,7 @@ gboolean gst_rtcp_buffer_validate_data (guint8 * data, guint len) { guint16 header_mask; - guint16 header_len; + guint header_len; guint8 version; guint data_len; gboolean padding; From 88ad3e65a1600c51a38f2340595ded6bc53d7f1d Mon Sep 17 00:00:00 2001 From: Idar Tollefsen Date: Sun, 1 Jan 2012 20:44:08 +0100 Subject: [PATCH 10/19] build: Run platform check for platform specific configuration. --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 698451ca9b..13647a48aa 100644 --- a/configure.ac +++ b/configure.ac @@ -119,6 +119,7 @@ AG_GST_ARG_ENABLE_EXTERNAL AG_GST_ARG_ENABLE_EXPERIMENTAL dnl *** checks for platform *** +AG_GST_PLATFORM dnl * hardware/architecture * From 19d17b8f248f00967d1f96a4d9d7cf0df1742492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Thu, 5 Jan 2012 12:23:08 +0000 Subject: [PATCH 11/19] tools: avoid unportable vararg macro construct in gst-discoverer https://bugzilla.gnome.org/show_bug.cgi?id=667306 --- tools/gst-discoverer.c | 101 +++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index a3cd4f9df4..5a168d636e 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -37,8 +37,19 @@ typedef struct char **argv; } PrivStruct; -#define my_g_string_append_printf(str, format, ...) \ - g_string_append_printf (str, "%*s" format, 2*depth, " ", ##__VA_ARGS__) +static void +my_g_string_append_printf (GString * str, int depth, const gchar * format, ...) +{ + va_list args; + + while (depth-- > 0) { + g_string_append (str, " "); + } + + va_start (args, format); + g_string_append_vprintf (str, format, args); + va_end (args); +} static gchar * gst_stream_audio_information_to_string (GstDiscovererStreamInfo * info, @@ -56,48 +67,49 @@ gst_stream_audio_information_to_string (GstDiscovererStreamInfo * info, s = g_string_sized_new (len); - my_g_string_append_printf (s, "Codec:\n"); + my_g_string_append_printf (s, depth, "Codec:\n"); caps = gst_discoverer_stream_info_get_caps (info); tmp = gst_caps_to_string (caps); gst_caps_unref (caps); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); - my_g_string_append_printf (s, "Additional info:\n"); + my_g_string_append_printf (s, depth, "Additional info:\n"); if (gst_discoverer_stream_info_get_misc (info)) { tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info)); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } audio_info = (GstDiscovererAudioInfo *) info; ctmp = gst_discoverer_audio_info_get_language (audio_info); - my_g_string_append_printf (s, "Language: %s\n", ctmp ? ctmp : ""); - my_g_string_append_printf (s, "Channels: %u\n", + my_g_string_append_printf (s, depth, "Language: %s\n", + ctmp ? ctmp : ""); + my_g_string_append_printf (s, depth, "Channels: %u\n", gst_discoverer_audio_info_get_channels (audio_info)); - my_g_string_append_printf (s, "Sample rate: %u\n", + my_g_string_append_printf (s, depth, "Sample rate: %u\n", gst_discoverer_audio_info_get_sample_rate (audio_info)); - my_g_string_append_printf (s, "Depth: %u\n", + my_g_string_append_printf (s, depth, "Depth: %u\n", gst_discoverer_audio_info_get_depth (audio_info)); - my_g_string_append_printf (s, "Bitrate: %u\n", + my_g_string_append_printf (s, depth, "Bitrate: %u\n", gst_discoverer_audio_info_get_bitrate (audio_info)); - my_g_string_append_printf (s, "Max bitrate: %u\n", + my_g_string_append_printf (s, depth, "Max bitrate: %u\n", gst_discoverer_audio_info_get_max_bitrate (audio_info)); - my_g_string_append_printf (s, "Tags:\n"); + my_g_string_append_printf (s, depth, "Tags:\n"); tags = gst_discoverer_stream_info_get_tags (info); if (tags) { tmp = gst_structure_to_string ((GstStructure *) tags); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } if (verbose) - my_g_string_append_printf (s, "\n"); + my_g_string_append_printf (s, depth, "\n"); return g_string_free (s, FALSE); } @@ -118,58 +130,58 @@ gst_stream_video_information_to_string (GstDiscovererStreamInfo * info, s = g_string_sized_new (len); - my_g_string_append_printf (s, "Codec:\n"); + my_g_string_append_printf (s, depth, "Codec:\n"); caps = gst_discoverer_stream_info_get_caps (info); tmp = gst_caps_to_string (caps); gst_caps_unref (caps); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); - my_g_string_append_printf (s, "Additional info:\n"); + my_g_string_append_printf (s, depth, "Additional info:\n"); misc = gst_discoverer_stream_info_get_misc (info); if (misc) { tmp = gst_structure_to_string (misc); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } video_info = (GstDiscovererVideoInfo *) info; - my_g_string_append_printf (s, "Width: %u\n", + my_g_string_append_printf (s, depth, "Width: %u\n", gst_discoverer_video_info_get_width (video_info)); - my_g_string_append_printf (s, "Height: %u\n", + my_g_string_append_printf (s, depth, "Height: %u\n", gst_discoverer_video_info_get_height (video_info)); - my_g_string_append_printf (s, "Depth: %u\n", + my_g_string_append_printf (s, depth, "Depth: %u\n", gst_discoverer_video_info_get_depth (video_info)); - my_g_string_append_printf (s, "Frame rate: %u/%u\n", + my_g_string_append_printf (s, depth, "Frame rate: %u/%u\n", gst_discoverer_video_info_get_framerate_num (video_info), gst_discoverer_video_info_get_framerate_denom (video_info)); - my_g_string_append_printf (s, "Pixel aspect ratio: %u/%u\n", + my_g_string_append_printf (s, depth, "Pixel aspect ratio: %u/%u\n", gst_discoverer_video_info_get_par_num (video_info), gst_discoverer_video_info_get_par_denom (video_info)); - my_g_string_append_printf (s, "Interlaced: %s\n", + my_g_string_append_printf (s, depth, "Interlaced: %s\n", gst_discoverer_video_info_is_interlaced (video_info) ? "true" : "false"); - my_g_string_append_printf (s, "Bitrate: %u\n", + my_g_string_append_printf (s, depth, "Bitrate: %u\n", gst_discoverer_video_info_get_bitrate (video_info)); - my_g_string_append_printf (s, "Max bitrate: %u\n", + my_g_string_append_printf (s, depth, "Max bitrate: %u\n", gst_discoverer_video_info_get_max_bitrate (video_info)); - my_g_string_append_printf (s, "Tags:\n"); + my_g_string_append_printf (s, depth, "Tags:\n"); tags = gst_discoverer_stream_info_get_tags (info); if (tags) { tmp = gst_structure_to_string ((GstStructure *) tags); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } if (verbose) - my_g_string_append_printf (s, "\n"); + my_g_string_append_printf (s, depth, "\n"); return g_string_free (s, FALSE); } @@ -190,37 +202,38 @@ gst_stream_subtitle_information_to_string (GstDiscovererStreamInfo * info, s = g_string_sized_new (len); - my_g_string_append_printf (s, "Codec:\n"); + my_g_string_append_printf (s, depth, "Codec:\n"); caps = gst_discoverer_stream_info_get_caps (info); tmp = gst_caps_to_string (caps); gst_caps_unref (caps); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); - my_g_string_append_printf (s, "Additional info:\n"); + my_g_string_append_printf (s, depth, "Additional info:\n"); if (gst_discoverer_stream_info_get_misc (info)) { tmp = gst_structure_to_string (gst_discoverer_stream_info_get_misc (info)); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } subtitle_info = (GstDiscovererSubtitleInfo *) info; ctmp = gst_discoverer_subtitle_info_get_language (subtitle_info); - my_g_string_append_printf (s, "Language: %s\n", ctmp ? ctmp : ""); + my_g_string_append_printf (s, depth, "Language: %s\n", + ctmp ? ctmp : ""); - my_g_string_append_printf (s, "Tags:\n"); + my_g_string_append_printf (s, depth, "Tags:\n"); tags = gst_discoverer_stream_info_get_tags (info); if (tags) { tmp = gst_structure_to_string ((GstStructure *) tags); - my_g_string_append_printf (s, " %s\n", tmp); + my_g_string_append_printf (s, depth, " %s\n", tmp); g_free (tmp); } else { - my_g_string_append_printf (s, " None\n"); + my_g_string_append_printf (s, depth, " None\n"); } if (verbose) - my_g_string_append_printf (s, "\n"); + my_g_string_append_printf (s, depth, "\n"); return g_string_free (s, FALSE); } From b11d516c46beaac194785b36ae0245c10f00c620 Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Sat, 22 Oct 2011 16:41:23 +0200 Subject: [PATCH 12/19] appsrc: implement get_caps vfunc This allows downstream elements to query what caps are available. https://bugzilla.gnome.org/show_bug.cgi?id=667312 --- gst-libs/gst/app/gstappsrc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c index 543a2ad043..24686b9531 100644 --- a/gst-libs/gst/app/gstappsrc.c +++ b/gst-libs/gst/app/gstappsrc.c @@ -219,6 +219,7 @@ static void gst_app_src_get_property (GObject * object, guint prop_id, static void gst_app_src_set_latencies (GstAppSrc * appsrc, gboolean do_min, guint64 min, gboolean do_max, guint64 max); +static GstCaps *gst_app_src_internal_get_caps (GstBaseSrc * bsrc); static GstFlowReturn gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size, GstBuffer ** buf); static gboolean gst_app_src_start (GstBaseSrc * bsrc); @@ -485,6 +486,7 @@ gst_app_src_class_init (GstAppSrcClass * klass) end_of_stream), NULL, NULL, __gst_app_marshal_ENUM__VOID, GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE); + basesrc_class->get_caps = gst_app_src_internal_get_caps; basesrc_class->create = gst_app_src_create; basesrc_class->start = gst_app_src_start; basesrc_class->stop = gst_app_src_stop; @@ -567,6 +569,12 @@ gst_app_src_finalize (GObject * obj) G_OBJECT_CLASS (parent_class)->finalize (obj); } +static GstCaps * +gst_app_src_internal_get_caps (GstBaseSrc * bsrc) +{ + return gst_app_src_get_caps (GST_APP_SRC_CAST (bsrc)); +} + static void gst_app_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) From 95be60de15801c8fec702672f9c1437298138e2f Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Tue, 1 Nov 2011 17:57:59 +0100 Subject: [PATCH 13/19] Fix various unlikely, but still potential memoryleaks in error code paths https://bugzilla.gnome.org/show_bug.cgi?id=667311 --- gst-libs/gst/pbutils/gstdiscoverer-types.c | 4 +++- gst-libs/gst/tag/tags.c | 1 + gst/audiotestsrc/gstaudiotestsrc.c | 2 ++ gst/encoding/gstsmartencoder.c | 5 +++-- gst/playback/gstplaysink.c | 1 + tools/gst-discoverer.c | 2 ++ 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c index 0d48a3d413..1f658c97db 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer-types.c +++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c @@ -372,11 +372,13 @@ GstDiscovererInfo * gst_discoverer_info_copy (GstDiscovererInfo * ptr) { GstDiscovererInfo *ret; - GHashTable *stream_map = g_hash_table_new (g_direct_hash, NULL); + GHashTable *stream_map; GList *tmp; g_return_val_if_fail (ptr != NULL, NULL); + stream_map = g_hash_table_new (g_direct_hash, NULL); + ret = gst_discoverer_info_new (); ret->uri = g_strdup (ptr->uri); diff --git a/gst-libs/gst/tag/tags.c b/gst-libs/gst/tag/tags.c index f89b348c7e..80285ae137 100644 --- a/gst-libs/gst/tag/tags.c +++ b/gst-libs/gst/tag/tags.c @@ -501,6 +501,7 @@ gst_tag_freeform_string_to_utf8 (const gchar * data, gint size, /* fallback in case iconv implementation doesn't support windows-1252 * for some reason */ if (err->code == G_CONVERT_ERROR_NO_CONVERSION) { + g_free (utf8); utf8 = g_convert (data, size, "UTF-8", "ISO-8859-1", &bytes_read, NULL, NULL); } diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c index 4428ccefc1..f0808c6095 100644 --- a/gst/audiotestsrc/gstaudiotestsrc.c +++ b/gst/audiotestsrc/gstaudiotestsrc.c @@ -1166,6 +1166,8 @@ gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset, if (eclass->send_event) eclass->send_event (GST_ELEMENT_CAST (basesrc), gst_event_new_tag (taglist)); + else + gst_tag_list_free (taglist); src->tags_pushed = TRUE; } diff --git a/gst/encoding/gstsmartencoder.c b/gst/encoding/gstsmartencoder.c index 97a5635578..6d2e7781ff 100644 --- a/gst/encoding/gstsmartencoder.c +++ b/gst/encoding/gstsmartencoder.c @@ -644,9 +644,10 @@ gst_smart_encoder_find_elements (GstSmartEncoder * smart_encoder) gst_caps_unref (tmpl); - if (gst_caps_is_empty (res)) + if (gst_caps_is_empty (res)) { + gst_caps_unref (res); ret = GST_STATE_CHANGE_FAILURE; - else + } else smart_encoder->available_caps = res; GST_DEBUG_OBJECT (smart_encoder, "Done, available_caps:%" GST_PTR_FORMAT, diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 81729e6dc2..57d194f51f 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -2867,6 +2867,7 @@ gst_play_sink_convert_frame (GstPlaySink * playsink, GstCaps * caps) * on the bus or not. It's not like it's a critical issue regarding * playsink behaviour. */ GST_ERROR ("Error converting frame: %s", err->message); + g_error_free (err); } result = temp; } diff --git a/tools/gst-discoverer.c b/tools/gst-discoverer.c index 5a168d636e..c6d609277f 100644 --- a/tools/gst-discoverer.c +++ b/tools/gst-discoverer.c @@ -456,6 +456,8 @@ process_file (GstDiscoverer * dc, const gchar * filename) g_print ("Analyzing %s\n", uri); info = gst_discoverer_discover_uri (dc, uri, &err); print_info (info, err); + if (err) + g_error_free (err); gst_discoverer_info_unref (info); if (st) gst_structure_free (st); From 5cf87eedc44d9dd252aba4156b2eaf235370f9bf Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 14 Dec 2011 14:14:47 +0000 Subject: [PATCH 14/19] video: overlays may now have premultiplied alpha https://bugzilla.gnome.org/show_bug.cgi?id=666177 --- docs/libs/gst-plugins-base-libs-sections.txt | 1 + gst-libs/gst/video/video-blend.c | 102 ++++++++-- gst-libs/gst/video/video-blend.h | 5 +- .../gst/video/video-overlay-composition.c | 187 ++++++++++++++---- .../gst/video/video-overlay-composition.h | 6 +- win32/common/libgstvideo.def | 1 + 6 files changed, 242 insertions(+), 60 deletions(-) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index 5640d21733..123b0a93d6 100644 --- a/docs/libs/gst-plugins-base-libs-sections.txt +++ b/docs/libs/gst-plugins-base-libs-sections.txt @@ -2345,6 +2345,7 @@ gst_video_overlay_rectangle_get_render_rectangle gst_video_overlay_rectangle_get_seqnum gst_video_overlay_rectangle_set_render_rectangle gst_video_overlay_rectangle_copy +gst_video_overlay_rectangle_get_flags GST_TYPE_VIDEO_OVERLAY_COMPOSITION GST_VIDEO_OVERLAY_COMPOSITION diff --git a/gst-libs/gst/video/video-blend.c b/gst-libs/gst/video/video-blend.c index 8dc21c3d5f..9231464bcd 100644 --- a/gst-libs/gst/video/video-blend.c +++ b/gst-libs/gst/video/video-blend.c @@ -1155,6 +1155,34 @@ matrix_identity (guint8 * tmpline, guint width) { } +static void +matrix_prea_rgb_to_yuv (guint8 * tmpline, guint width) +{ + int i; + int a, r, g, b; + int y, u, v; + + for (i = 0; i < width; i++) { + a = tmpline[i * 4 + 0]; + r = tmpline[i * 4 + 1]; + g = tmpline[i * 4 + 2]; + b = tmpline[i * 4 + 3]; + if (a) { + r = (r * 255 + a / 2) / a; + g = (g * 255 + a / 2) / a; + b = (b * 255 + a / 2) / a; + } + + y = (47 * r + 157 * g + 16 * b + 4096) >> 8; + u = (-26 * r - 87 * g + 112 * b + 32768) >> 8; + v = (112 * r - 102 * g - 10 * b + 32768) >> 8; + + tmpline[i * 4 + 1] = CLAMP (y, 0, 255); + tmpline[i * 4 + 2] = CLAMP (u, 0, 255); + tmpline[i * 4 + 3] = CLAMP (v, 0, 255); + } +} + static void matrix_rgb_to_yuv (guint8 * tmpline, guint width) { @@ -1221,10 +1249,15 @@ lookup_getput (GetPutLine * getput, GstVideoFormat fmt) return FALSE; } -#define BLEND(ret, alpha, v0, v1) \ -{ \ +#define BLEND00(ret, alpha, v0, v1) \ +G_STMT_START { \ ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \ -} +} G_STMT_END + +#define BLEND10(ret, alpha, v0, v1) \ +G_STMT_START { \ + ret = v0 + (v1 * (255 - alpha)) / 255; \ +} G_STMT_END void video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src, @@ -1289,7 +1322,7 @@ video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src, /* Update src, our reference to the old src->pixels is lost */ video_blend_format_info_init (src, dest_pixels, dest_height, dest_width, - src->fmt); + src->fmt, src->premultiplied_alpha); g_free (tmpbuf); } @@ -1310,10 +1343,21 @@ video_blend (GstBlendVideoFormatInfo * dest, guint i, j; guint8 alpha; GetPutLine getputdest, getputsrc; + gint src_stride; + guint8 *tmpdestline = NULL, *tmpsrcline = NULL; + gboolean src_premultiplied_alpha; - gint src_stride = src->width * 4; - guint8 *tmpdestline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); - guint8 *tmpsrcline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); + g_return_val_if_fail (dest, FALSE); + g_return_val_if_fail (src, FALSE); + + /* we do no support writing to premultiplied alpha, though that should + just be a matter of adding blenders below (BLEND01 and BLEND11) */ + g_return_val_if_fail (!dest->premultiplied_alpha, FALSE); + src_premultiplied_alpha = src->premultiplied_alpha; + + src_stride = src->width * 4; + tmpdestline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); + tmpsrcline = g_malloc (sizeof (guint8) * (dest->width + 8) * 4); ensure_debug_category (); @@ -1324,9 +1368,18 @@ video_blend (GstBlendVideoFormatInfo * dest, if (!lookup_getput (&getputsrc, src->fmt)) goto failed; - if (gst_video_format_is_rgb (src->fmt) != gst_video_format_is_rgb (dest->fmt)) - getputsrc.matrix = gst_video_format_is_rgb (src->fmt) ? - matrix_rgb_to_yuv : matrix_yuv_to_rgb; + if (gst_video_format_is_rgb (src->fmt) != gst_video_format_is_rgb (dest->fmt)) { + if (gst_video_format_is_rgb (src->fmt)) { + if (src_premultiplied_alpha) { + getputsrc.matrix = matrix_prea_rgb_to_yuv; + src_premultiplied_alpha = FALSE; + } else { + getputsrc.matrix = matrix_rgb_to_yuv; + } + } else { + getputsrc.matrix = matrix_yuv_to_rgb; + } + } /* adjust src pointers for negative sizes */ if (x < 0) { @@ -1358,14 +1411,29 @@ video_blend (GstBlendVideoFormatInfo * dest, /* Here dest and src are both either in AYUV or ARGB * TODO: Make the orc version working properly*/ - for (j = 0; j < src->width * 4; j += 4) { - alpha = tmpsrcline[j]; +#define BLENDLOOP(blender) \ + do { \ + for (j = 0; j < src->width * 4; j += 4) { \ + alpha = tmpsrcline[j]; \ + \ + blender (tmpdestline[j + 1], alpha, tmpsrcline[j + 1], tmpdestline[j + 1]); \ + blender (tmpdestline[j + 2], alpha, tmpsrcline[j + 2], tmpdestline[j + 2]); \ + blender (tmpdestline[j + 3], alpha, tmpsrcline[j + 3], tmpdestline[j + 3]); \ + } \ + } while(0) - BLEND (tmpdestline[j + 1], alpha, tmpsrcline[j + 1], tmpdestline[j + 1]); - BLEND (tmpdestline[j + 2], alpha, tmpsrcline[j + 2], tmpdestline[j + 2]); - BLEND (tmpdestline[j + 3], alpha, tmpsrcline[j + 3], tmpdestline[j + 3]); + if (src_premultiplied_alpha && dest->premultiplied_alpha) { + /* BLENDLOOP (BLEND11); */ + } else if (!src_premultiplied_alpha && dest->premultiplied_alpha) { + /* BLENDLOOP (BLEND01); */ + } else if (src_premultiplied_alpha && !dest->premultiplied_alpha) { + BLENDLOOP (BLEND10); + } else { + BLENDLOOP (BLEND00); } +#undef BLENDLOOP + /* FIXME * #if G_BYTE_ORDER == LITTLE_ENDIAN * orc_blend_little (tmpdestline, tmpsrcline, dest->width); @@ -1403,7 +1471,8 @@ failed: */ void video_blend_format_info_init (GstBlendVideoFormatInfo * info, - guint8 * pixels, guint height, guint width, GstVideoFormat fmt) + guint8 * pixels, guint height, guint width, GstVideoFormat fmt, + gboolean premultiplied_alpha) { guint nb_component = gst_video_format_has_alpha (fmt) ? 4 : 3; @@ -1417,6 +1486,7 @@ video_blend_format_info_init (GstBlendVideoFormatInfo * info, info->height = height; info->pixels = pixels; info->fmt = fmt; + info->premultiplied_alpha = premultiplied_alpha; info->size = gst_video_format_get_size (fmt, height, width); fill_planes (info); diff --git a/gst-libs/gst/video/video-blend.h b/gst-libs/gst/video/video-blend.h index 3f5e0cd69b..f3673a6fe4 100644 --- a/gst-libs/gst/video/video-blend.h +++ b/gst-libs/gst/video/video-blend.h @@ -53,6 +53,8 @@ struct _GstBlendVideoFormatInfo guint8 * pixels; gsize size; + gboolean premultiplied_alpha; + /* YUV components: Y=0, U=1, V=2, A=3 * RGB components: R=0, G=1, B=2, A=3 */ gint offset[MAX_VIDEO_PLANES]; @@ -61,7 +63,8 @@ struct _GstBlendVideoFormatInfo void video_blend_format_info_init (GstBlendVideoFormatInfo * info, guint8 *pixels, guint height, - guint width, GstVideoFormat fmt); + guint width, GstVideoFormat fmt, + gboolean premultiplied_alpha); void video_blend_scale_linear_RGBA (GstBlendVideoFormatInfo * src, gint dest_height, gint dest_width); diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index 3bfbad1bbe..4633b6b489 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -108,6 +108,9 @@ struct _GstVideoOverlayRectangle /* The format of the data in pixels */ GstVideoFormat format; + /* The flags associated to this rectangle */ + GstVideoOverlayFormatFlags flags; + /* Refcounted blob of memory, no caps or timestamps */ GstBuffer *pixels; @@ -501,7 +504,7 @@ gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, } video_blend_format_info_init (&video_info, GST_BUFFER_DATA (video_buf), - h, w, fmt); + h, w, fmt, FALSE); num = comp->num_rectangles; GST_LOG ("Blending composition %p with %u rectangles onto video buffer %p " @@ -518,7 +521,8 @@ gst_video_overlay_composition_blend (GstVideoOverlayComposition * comp, video_blend_format_info_init (&rectangle_info, GST_BUFFER_DATA (rect->pixels), rect->height, rect->width, - rect->format); + rect->format, + !!(rect->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)); needs_scaling = gst_video_overlay_rectangle_needs_scaling (rect); if (needs_scaling) { @@ -706,6 +710,22 @@ gst_video_overlay_rectangle_instance_init (GstMiniObject * mini_obj) #endif } +static inline gboolean +gst_video_overlay_rectangle_check_flags (GstVideoOverlayFormatFlags flags) +{ + /* Check flags only contains flags we know about */ + return (flags & ~(GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)) == 0; +} + +static gboolean +gst_video_overlay_rectangle_is_same_alpha_type (GstVideoOverlayFormatFlags + flags1, GstVideoOverlayFormatFlags flags2) +{ + return ((flags1 ^ flags2) & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) + == 0; +} + + /** * gst_video_overlay_rectangle_new_argb: * @pixels: (transfer none): a #GstBuffer pointing to the pixel memory @@ -718,7 +738,7 @@ gst_video_overlay_rectangle_instance_init (GstMiniObject * mini_obj) * overlay rectangle should be rendered to * @render_width: the render width of this rectangle on the video * @render_height: the render height of this rectangle on the video - * @flags: flags (currently unused) + * @flags: flags * * Creates a new video overlay rectangle with ARGB pixel data. The layout * of the components in memory is B-G-R-A on little-endian platforms @@ -726,9 +746,9 @@ gst_video_overlay_rectangle_instance_init (GstMiniObject * mini_obj) * platforms (corresponding to #GST_VIDEO_FORMAT_ARGB). In other words, * pixels are treated as 32-bit words and the lowest 8 bits then contain * the blue component value and the highest 8 bits contain the alpha - * component value. The RGB values are non-premultiplied. This is the - * format that is used by most hardware, and also many rendering libraries - * such as Cairo, for example. + * component value. Unless specified in the flags, the RGB values are + * non-premultiplied. This is the format that is used by most hardware, + * and also many rendering libraries such as Cairo, for example. * * Returns: (transfer full): a new #GstVideoOverlayRectangle. Unref with * gst_video_overlay_rectangle_unref() when no longer needed. @@ -748,7 +768,7 @@ gst_video_overlay_rectangle_new_argb (GstBuffer * pixels, g_return_val_if_fail (stride >= (4 * width), NULL); g_return_val_if_fail (height > 0 && width > 0, NULL); g_return_val_if_fail (render_height > 0 && render_width > 0, NULL); - g_return_val_if_fail (flags == 0, NULL); + g_return_val_if_fail (gst_video_overlay_rectangle_check_flags (flags), NULL); rect = (GstVideoOverlayRectangle *) gst_mini_object_new (GST_TYPE_VIDEO_OVERLAY_RECTANGLE); @@ -758,6 +778,7 @@ gst_video_overlay_rectangle_new_argb (GstBuffer * pixels, #else rect->format = GST_VIDEO_FORMAT_ARGB; #endif + rect->pixels = gst_buffer_ref (pixels); rect->width = width; @@ -769,11 +790,13 @@ gst_video_overlay_rectangle_new_argb (GstBuffer * pixels, rect->render_width = render_width; rect->render_height = render_height; + rect->flags = flags; + rect->seq_num = gst_video_overlay_get_seqnum (); GST_LOG ("new rectangle %p: %ux%u => %ux%u @ %u,%u, seq_num %u, format %u, " - "pixels %p", rect, width, height, render_width, render_height, render_x, - render_y, rect->seq_num, rect->format, pixels); + "flags %x, pixels %p", rect, width, height, render_width, render_height, + render_x, render_y, rect->seq_num, rect->format, rect->flags, pixels); return rect; } @@ -846,37 +869,61 @@ gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle * rectangle->render_height = render_height; } -/** - * gst_video_overlay_rectangle_get_pixels_argb: - * @rectangle: a #GstVideoOverlayRectangle - * @stride: (out) (allow-none): address of guint variable where to store the - * row stride of the ARGB pixel data in the buffer - * @flags: flags (unused) - * - * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with - * row stride @stride and width and height of the render dimensions as per - * gst_video_overlay_rectangle_get_render_rectangle(). This function does - * not return a reference, the caller should obtain a reference of her own - * with gst_buffer_ref() if needed. - * - * Since: 0.10.36 - */ -GstBuffer * -gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * - rectangle, guint * stride, GstVideoOverlayFormatFlags flags) +static void +gst_video_overlay_rectangle_premultiply (GstBlendVideoFormatInfo * info) +{ + int i, j; + for (j = 0; j < info->height; ++j) { + guint8 *line = info->pixels + info->stride[0] * j; + for (i = 0; i < info->width; ++i) { + int a = line[0]; + line[1] = line[1] * a / 255; + line[2] = line[2] * a / 255; + line[3] = line[3] * a / 255; + line += 4; + } + } +} + +static void +gst_video_overlay_rectangle_unpremultiply (GstBlendVideoFormatInfo * info) +{ + int i, j; + for (j = 0; j < info->height; ++j) { + guint8 *line = info->pixels + info->stride[0] * j; + for (i = 0; i < info->width; ++i) { + int a = line[0]; + if (a) { + line[1] = MIN ((line[1] * 255 + a / 2) / a, 255); + line[2] = MIN ((line[2] * 255 + a / 2) / a, 255); + line[3] = MIN ((line[3] * 255 + a / 2) / a, 255); + } + line += 4; + } + } +} + +static GstBuffer * +gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * + rectangle, guint * stride, GstVideoOverlayFormatFlags flags, + gboolean unscaled) { GstVideoOverlayRectangle *scaled_rect = NULL; GstBlendVideoFormatInfo info; GstBuffer *buf; GList *l; + guint wanted_width = unscaled ? rectangle->width : rectangle->render_width; + guint wanted_height = unscaled ? rectangle->height : rectangle->render_height; g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), NULL); - g_return_val_if_fail (flags == 0, NULL); g_return_val_if_fail (stride != NULL, NULL); + g_return_val_if_fail (gst_video_overlay_rectangle_check_flags (flags), NULL); /* This assumes we don't need to adjust the format */ - if (rectangle->render_width == rectangle->width && - rectangle->render_height == rectangle->height) { + if (wanted_width == rectangle->width && + wanted_height == rectangle->height && + gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, + flags)) { *stride = rectangle->stride; return rectangle->pixels; } @@ -886,8 +933,10 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * for (l = rectangle->scaled_rectangles; l != NULL; l = l->next) { GstVideoOverlayRectangle *r = l->data; - if (r->width == rectangle->render_width && - r->height == rectangle->render_height) { + if (r->width == wanted_width && + r->height == wanted_height && + gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, + flags)) { /* we'll keep these rectangles around until finalize, so it's ok not * to take our own ref here */ scaled_rect = r; @@ -901,10 +950,20 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * /* not cached yet, do the scaling and put the result into our cache */ video_blend_format_info_init (&info, GST_BUFFER_DATA (rectangle->pixels), - rectangle->height, rectangle->width, rectangle->format); + rectangle->height, rectangle->width, rectangle->format, + !!(rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA)); - video_blend_scale_linear_RGBA (&info, rectangle->render_height, - rectangle->render_width); + if (wanted_width != rectangle->width || wanted_height != rectangle->height) { + video_blend_scale_linear_RGBA (&info, wanted_height, wanted_width); + } + + if (!gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, flags)) { + if (rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) { + gst_video_overlay_rectangle_unpremultiply (&info); + } else { + gst_video_overlay_rectangle_premultiply (&info); + } + } buf = gst_buffer_new (); GST_BUFFER_DATA (buf) = info.pixels; @@ -912,8 +971,8 @@ gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * GST_BUFFER_SIZE (buf) = info.size; scaled_rect = gst_video_overlay_rectangle_new_argb (buf, - rectangle->render_width, rectangle->render_height, info.stride[0], - 0, 0, rectangle->render_width, rectangle->render_height, 0); + wanted_width, wanted_height, info.stride[0], + 0, 0, wanted_width, wanted_height, rectangle->flags); gst_buffer_unref (buf); @@ -928,6 +987,29 @@ done: return scaled_rect->pixels; } +/** + * gst_video_overlay_rectangle_get_pixels_argb: + * @rectangle: a #GstVideoOverlayRectangle + * @stride: (out) (allow-none): address of guint variable where to store the + * row stride of the ARGB pixel data in the buffer + * @flags: flags + * + * Returns: (transfer none): a #GstBuffer holding the ARGB pixel data with + * row stride @stride and width and height of the render dimensions as per + * gst_video_overlay_rectangle_get_render_rectangle(). This function does + * not return a reference, the caller should obtain a reference of her own + * with gst_buffer_ref() if needed. + * + * Since: 0.10.36 + */ +GstBuffer * +gst_video_overlay_rectangle_get_pixels_argb (GstVideoOverlayRectangle * + rectangle, guint * stride, GstVideoOverlayFormatFlags flags) +{ + return gst_video_overlay_rectangle_get_pixels_argb_internal (rectangle, + stride, flags, FALSE); +} + /** * gst_video_overlay_rectangle_get_pixels_unscaled_argb: * @rectangle: a #GstVideoOverlayRectangle @@ -937,7 +1019,7 @@ done: * rectangle in pixels * @stride: (out): address of guint variable where to store the row * stride of the ARGB pixel data in the buffer - * @flags: flags for future use (unused) + * @flags: flags * * Retrieves the pixel data as it is. This is useful if the caller can * do the scaling itself when handling the overlaying. The rectangle will @@ -959,13 +1041,34 @@ gst_video_overlay_rectangle_get_pixels_unscaled_argb (GstVideoOverlayRectangle * g_return_val_if_fail (width != NULL, NULL); g_return_val_if_fail (height != NULL, NULL); g_return_val_if_fail (stride != NULL, NULL); - g_return_val_if_fail (flags == 0, NULL); *width = rectangle->width; *height = rectangle->height; - *stride = rectangle->stride; + return gst_video_overlay_rectangle_get_pixels_argb_internal (rectangle, + stride, flags, TRUE); +} - return rectangle->pixels; +/** + * gst_video_overlay_rectangle_get_flags: + * @rectangle: a #GstVideoOverlayRectangle + * + * Retrieves the flags associated with a #GstVideoOverlayRectangle. + * This is useful if the caller can handle both premultiplied alpha and + * non premultiplied alpha, for example. By knowing whether the rectangle + * uses premultiplied or not, it can request the pixel data in the format + * it is stored in, to avoid unnecessary conversion. + * + * Returns: the #GstVideoOverlayFormatFlags associated with the rectangle. + * + * Since: 0.10.37 + */ +GstVideoOverlayFormatFlags +gst_video_overlay_rectangle_get_flags (GstVideoOverlayRectangle * rectangle) +{ + g_return_val_if_fail (GST_IS_VIDEO_OVERLAY_RECTANGLE (rectangle), + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + return rectangle->flags; } /** @@ -992,7 +1095,7 @@ gst_video_overlay_rectangle_copy (GstVideoOverlayRectangle * rectangle) copy = gst_video_overlay_rectangle_new_argb (rectangle->pixels, rectangle->width, rectangle->height, rectangle->stride, rectangle->x, rectangle->y, - rectangle->render_width, rectangle->render_height, 0); + rectangle->render_width, rectangle->render_height, rectangle->flags); return copy; } diff --git a/gst-libs/gst/video/video-overlay-composition.h b/gst-libs/gst/video/video-overlay-composition.h index 5ff7ce36c6..b91404ba91 100644 --- a/gst-libs/gst/video/video-overlay-composition.h +++ b/gst-libs/gst/video/video-overlay-composition.h @@ -95,13 +95,15 @@ gst_video_overlay_rectangle_unref (GstVideoOverlayRectangle * comp) /** * GstVideoOverlayFormatFlags: * @GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE: no flags + * @GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA: RGB are premultiplied by A/255. Since: 0.10.37 * * Overlay format flags. * * Since: 0.10.36 */ typedef enum { - GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE = 0 + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE = 0, + GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA = 1 } GstVideoOverlayFormatFlags; GType gst_video_overlay_rectangle_get_type (void); @@ -138,6 +140,8 @@ GstBuffer * gst_video_overlay_rectangle_get_pixels_unscaled_arg guint * stride, GstVideoOverlayFormatFlags flags); +GstVideoOverlayFormatFlags gst_video_overlay_rectangle_get_flags (GstVideoOverlayRectangle * rectangle); + /** * GstVideoOverlayComposition: * diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index dd6e2b0157..54a2186abb 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -52,6 +52,7 @@ EXPORTS gst_video_overlay_rectangle_get_type gst_video_overlay_rectangle_new_argb gst_video_overlay_rectangle_set_render_rectangle + gst_video_overlay_rectangle_get_flags gst_video_parse_caps_chroma_site gst_video_parse_caps_color_matrix gst_video_parse_caps_framerate From 4471ee65d8d4a1ab58d743a07372b43375eb6859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 7 Jan 2012 14:44:51 +0000 Subject: [PATCH 15/19] win32: .def file should be sorted for make check-exports --- win32/common/libgstvideo.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def index 54a2186abb..879b942cef 100644 --- a/win32/common/libgstvideo.def +++ b/win32/common/libgstvideo.def @@ -45,6 +45,7 @@ EXPORTS gst_video_overlay_composition_n_rectangles gst_video_overlay_composition_new gst_video_overlay_rectangle_copy + gst_video_overlay_rectangle_get_flags gst_video_overlay_rectangle_get_pixels_argb gst_video_overlay_rectangle_get_pixels_unscaled_argb gst_video_overlay_rectangle_get_render_rectangle @@ -52,7 +53,6 @@ EXPORTS gst_video_overlay_rectangle_get_type gst_video_overlay_rectangle_new_argb gst_video_overlay_rectangle_set_render_rectangle - gst_video_overlay_rectangle_get_flags gst_video_parse_caps_chroma_site gst_video_parse_caps_color_matrix gst_video_parse_caps_framerate From aa16155172c2c73b05bd6509010f1a52b5b81022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 7 Jan 2012 16:43:26 +0000 Subject: [PATCH 16/19] tests: add ogg test file and some proper unit tests for discoverer Leaks when re-used, so blacklisted for valgrind for now. --- tests/check/Makefile.am | 1 + tests/check/libs/discoverer.c | 68 +++++++++++++++++++++++++++++++++- tests/files/Makefile.am | 3 +- tests/files/theora-vorbis.ogg | Bin 0 -> 20070 bytes 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/files/theora-vorbis.ogg diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 3280ba3018..ad9cafac44 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -167,6 +167,7 @@ check_PROGRAMS = \ # ffmpegcolorspace takes too long, so disabled for now VALGRIND_TO_FIX = \ elements/ffmpegcolorspace \ + libs/discoverer \ libs/video # these tests don't even pass diff --git a/tests/check/libs/discoverer.c b/tests/check/libs/discoverer.c index 2d20576bbe..a8de512e1d 100644 --- a/tests/check/libs/discoverer.c +++ b/tests/check/libs/discoverer.c @@ -52,7 +52,8 @@ GST_START_TEST (test_disco_sync) GstDiscovererResult result; gchar *uri; - dc = gst_discoverer_new (GST_SECOND, &err); + /* high timeout, in case we're running under valgrind */ + dc = gst_discoverer_new (5 * GST_SECOND, &err); fail_unless (dc != NULL); fail_unless (err == NULL); @@ -78,6 +79,68 @@ GST_START_TEST (test_disco_sync) GST_END_TEST; +static void +test_disco_sync_reuse (const gchar * test_fn, guint num, GstClockTime timeout) +{ + GError *err = NULL; + GstDiscoverer *dc; + GstDiscovererInfo *info; + GstDiscovererResult result; + gchar *uri, *path; + int i; + + dc = gst_discoverer_new (timeout, &err); + fail_unless (dc != NULL); + fail_unless (err == NULL); + + /* GST_TEST_FILE comes from makefile CFLAGS */ + path = g_build_filename (GST_TEST_FILES_PATH, test_fn, NULL); + uri = gst_filename_to_uri (path, &err); + g_free (path); + fail_unless (err == NULL); + + for (i = 0; i < num; ++i) { + GST_INFO ("[%02d] discovering uri '%s'", i, uri); + info = gst_discoverer_discover_uri (dc, uri, &err); + if (info) { + result = gst_discoverer_info_get_result (info); + GST_INFO ("result: %d", result); + gst_discoverer_info_unref (info); + } + /* in case we don't have some of the elements needed */ + if (err) { + g_error_free (err); + err = NULL; + } + } + g_free (uri); + + g_object_unref (dc); +} + +GST_START_TEST (test_disco_sync_reuse_ogg) +{ + test_disco_sync_reuse ("theora-vorbis.ogg", 2, 10 * GST_SECOND); +} + +GST_END_TEST; + +GST_START_TEST (test_disco_sync_reuse_mp3) +{ + /* this will cause errors because -base doesn't do mp3 parsing or decoding */ + test_disco_sync_reuse ("test.mp3", 3, 10 * GST_SECOND); +} + +GST_END_TEST; + +GST_START_TEST (test_disco_sync_reuse_timeout) +{ + /* set minimum timeout to test that, esp. leakage under valgrind */ + /* FIXME: should really be even shorter */ + test_disco_sync_reuse ("theora-vorbis.ogg", 2, GST_SECOND); +} + +GST_END_TEST; static Suite * discoverer_suite (void) @@ -88,6 +151,9 @@ discoverer_suite (void) suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_disco_init); tcase_add_test (tc_chain, test_disco_sync); + tcase_add_test (tc_chain, test_disco_sync_reuse_ogg); + tcase_add_test (tc_chain, test_disco_sync_reuse_mp3); + tcase_add_test (tc_chain, test_disco_sync_reuse_timeout); return s; } diff --git a/tests/files/Makefile.am b/tests/files/Makefile.am index 9556f5efb9..99b043f5d8 100644 --- a/tests/files/Makefile.am +++ b/tests/files/Makefile.am @@ -3,4 +3,5 @@ EXTRA_DIST = \ hls.m3u8 \ license-uris \ partialframe.mjpeg \ - test.mp3 + test.mp3 \ + theora-vorbis.ogg diff --git a/tests/files/theora-vorbis.ogg b/tests/files/theora-vorbis.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ab635cc58915cc100669adbea826a032cd7f4e46 GIT binary patch literal 20070 zcma*P1zc54^EiI#?i5k!?gr^j$xBMNNVf_pyjA@Sgy(q_nSjivQ0uxk!Yf9_K?hIO6`Oh8<7IFS}YSpngSciKel?yM4B8($Zqa3Vj@5Z@FV+T#fE>8LNt*8*1*Rd8IFxnQO3gP?~4dmP>@GOMegeA z3=R$sl9ra1LI46>+f``wyAChKu7W5z=xsKPpFihNbMq2=Zf={y;xOh`nrueR=)zzj?u5CHlj|!vJ}}3m)eBg$R4~g@}CfLWW!Z@qP${ z6R%M`a&bHKW1R)XoXp)t5vNcJgT<+C?8!E{gNWI-E6tmzJs6ogQnkz5A}SF^lFl z?C%F2ba)t`c+UL7iyFnUIxeCxg>kjvq%Y)NKu?Uxy%7C~>M^yhADiV)CzLx-r&RM{ ziqS7Y8r~51MMusAKhiA4z5eo3?5fBhlb)fwuc@8ryxynFJu8+E@JyqXpLj}iw*&c2 z^N8r`p~PJM!DXeX=Tm(D&x^XQ>79g(?7_|EGL+Ie)@IX}+iJ7BQB1;E@qWOUAmNug z-(1ibVVT)id!ShX6VV24a8D>MU+z9{447?o^JadlS&OGYQ*YvXOzU2pCyHzHZQtNE zolmoN;AriHxJXl|Aav<

j^Ca(B#8#Z*@stZQhu3R_zUQ(V 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 ZdLDgnC{*w>peXYTN+#Pk=#_P<{||3XH(CGy literal 0 HcmV?d00001 From 1031fedaf01097b32ea8945c5476a850e3e8d028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 7 Jan 2012 19:39:42 +0000 Subject: [PATCH 17/19] discoverer: make is_subtitle_caps thread-safe --- gst-libs/gst/pbutils/gstdiscoverer.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c index 6af71dca4a..581739e9a6 100644 --- a/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/gst-libs/gst/pbutils/gstdiscoverer.c @@ -438,19 +438,22 @@ _event_probe (GstPad * pad, GstEvent * event, PrivateStream * ps) return TRUE; } +static GstStaticCaps subtitle_caps = GST_STATIC_CAPS ("text/plain; " + "text/x-pango-markup; subpicture/x-pgs; subpicture/x-dvb; " + "application/x-subtitle-unknown; application/x-ssa; application/x-ass; " + "subtitle/x-kate; application/x-kate; video/x-dvd-subpicture"); + static gboolean is_subtitle_caps (const GstCaps * caps) { - static GstCaps *subs_caps = NULL; + GstCaps *subs_caps; + gboolean ret; - if (!subs_caps) { - subs_caps = gst_caps_from_string ("text/plain; text/x-pango-markup; " - "subpicture/x-pgs; subpicture/x-dvb; application/x-subtitle-unknown; " - "application/x-ssa; application/x-ass; subtitle/x-kate; " - "application/x-kate; video/x-dvd-subpicture; "); - } + subs_caps = gst_static_caps_get (&subtitle_caps); + ret = gst_caps_can_intersect (caps, subs_caps); + gst_caps_unref (subs_caps); - return gst_caps_can_intersect (caps, subs_caps); + return ret; } static void From 9f042ae224b3d84643bf4ad977080987fe80d36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 7 Jan 2012 20:12:17 +0000 Subject: [PATCH 18/19] rtspconnection: make hostname lookup more thread-safe Don't write IP number string to return into a static array which is shared amongst all threads (note: of course a copy is returned). https://bugzilla.gnome.org/show_bug.cgi?id=666711 --- gst-libs/gst/rtsp/gstrtspconnection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c index 5fcfa252d3..c7b0f3284b 100644 --- a/gst-libs/gst/rtsp/gstrtspconnection.c +++ b/gst-libs/gst/rtsp/gstrtspconnection.c @@ -458,7 +458,7 @@ wrong_family: static gchar * do_resolve (const gchar * host) { - static gchar ip[INET6_ADDRSTRLEN]; + gchar ip[INET6_ADDRSTRLEN]; struct addrinfo *aires, hints; struct addrinfo *ai; gint aierr; From e8fd3056233d28d4301fc2b92882fed31ae0e68a Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 9 Jan 2012 12:31:02 +0100 Subject: [PATCH 19/19] playback: document DEINTERLACE flag --- gst/playback/gstplay-enum.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/playback/gstplay-enum.h b/gst/playback/gstplay-enum.h index 1e33f0609e..77a34cfeaf 100644 --- a/gst/playback/gstplay-enum.h +++ b/gst/playback/gstplay-enum.h @@ -56,6 +56,7 @@ GType gst_autoplug_select_result_get_type (void); * @GST_PLAY_FLAG_DOWNLOAD: enable progressice download buffering for selected * formats. * @GST_PLAY_FLAG_BUFFERING: enable buffering of the demuxed or parsed data. + * @GST_PLAY_FLAG_DEINTERLACE: deinterlace raw video (if native not forced). * * Extra flags to configure the behaviour of the sinks. */