From 7ff608889afc46b326a8d1d4fea1813a6fafab0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 9 Mar 2012 10:54:48 +0100 Subject: [PATCH 01/20] audio{en,de}coder: Add optional open/close vfuncs This can be used to do something in NULL->READY, like checking if a hardware codec is actually available and to error out early. --- gst-libs/gst/audio/gstaudiodecoder.c | 20 +++++++++++ gst-libs/gst/audio/gstaudiodecoder.h | 12 ++++++- gst-libs/gst/audio/gstaudioencoder.c | 51 ++++++++++++++++++++++++++++ gst-libs/gst/audio/gstaudioencoder.h | 12 ++++++- 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c index 0198d849d8..5dfd278e1d 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.c +++ b/gst-libs/gst/audio/gstaudiodecoder.c @@ -2070,12 +2070,18 @@ static GstStateChangeReturn gst_audio_decoder_change_state (GstElement * element, GstStateChange transition) { GstAudioDecoder *codec; + GstAudioDecoderClass *klass; GstStateChangeReturn ret; codec = GST_AUDIO_DECODER (element); + klass = GST_AUDIO_DECODER_GET_CLASS (codec); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + if (klass->open) { + if (!klass->open (codec)) + goto open_failed; + } break; case GST_STATE_CHANGE_READY_TO_PAUSED: if (!gst_audio_decoder_start (codec)) { @@ -2099,6 +2105,10 @@ gst_audio_decoder_change_state (GstElement * element, GstStateChange transition) } break; case GST_STATE_CHANGE_READY_TO_NULL: + if (klass->close) { + if (!klass->close (codec)) + goto close_failed; + } break; default: break; @@ -2116,6 +2126,16 @@ stop_failed: GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to stop codec")); return GST_STATE_CHANGE_FAILURE; } +open_failed: + { + GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to open codec")); + return GST_STATE_CHANGE_FAILURE; + } +close_failed: + { + GST_ELEMENT_ERROR (codec, LIBRARY, INIT, (NULL), ("Failed to close codec")); + return GST_STATE_CHANGE_FAILURE; + } } GstFlowReturn diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h index bd6cb8988c..bf1c44e96e 100644 --- a/gst-libs/gst/audio/gstaudiodecoder.h +++ b/gst-libs/gst/audio/gstaudiodecoder.h @@ -201,6 +201,12 @@ struct _GstAudioDecoder * Called just prior to pushing (encoded data) buffer downstream. * Subclass has full discretionary access to buffer, * and a not OK flow return will abort downstream pushing. + * @open: Optional. + * Called when the element changes to GST_STATE_READY. + * Allows opening external resources. Since: 0.10.37. + * @close: Optional. + * Called when the element changes to GST_STATE_NULL. + * Allows closing external resources. Since: 0.10.37. * * Subclasses can override any of the available virtual methods or not, as * needed. At minimum @handle_frame (and likely @set_format) needs to be @@ -237,8 +243,12 @@ struct _GstAudioDecoderClass gboolean (*event) (GstAudioDecoder *dec, GstEvent *event); + gboolean (*open) (GstAudioDecoder *dec); + + gboolean (*close) (GstAudioDecoder *dec); + /*< private >*/ - gpointer _gst_reserved[GST_PADDING_LARGE]; + gpointer _gst_reserved[GST_PADDING_LARGE-2]; }; GType gst_audio_decoder_get_type (void); diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index b915ae7f0b..ea2595eefd 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -301,6 +301,9 @@ static void gst_audio_encoder_set_property (GObject * object, static void gst_audio_encoder_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static GstStateChangeReturn gst_audio_encoder_change_state (GstElement * + element, GstStateChange transition); + static gboolean gst_audio_encoder_sink_activate_push (GstPad * pad, gboolean active); @@ -317,8 +320,10 @@ static void gst_audio_encoder_class_init (GstAudioEncoderClass * klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; gobject_class = G_OBJECT_CLASS (klass); + gstelement_class = GST_ELEMENT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); GST_DEBUG_CATEGORY_INIT (gst_audio_encoder_debug, "audioencoder", 0, @@ -349,6 +354,9 @@ gst_audio_encoder_class_init (GstAudioEncoderClass * klass) "Consider discontinuity if timestamp jitter/imperfection exceeds tolerance (ns)", 0, G_MAXINT64, DEFAULT_TOLERANCE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + gstelement_class->change_state = + GST_DEBUG_FUNCPTR (gst_audio_encoder_change_state); } static void @@ -460,6 +468,49 @@ gst_audio_encoder_finalize (GObject * object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static GstStateChangeReturn +gst_audio_encoder_change_state (GstElement * element, GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstAudioEncoder *enc = GST_AUDIO_ENCODER (element); + GstAudioEncoderClass *klass = GST_AUDIO_ENCODER_GET_CLASS (enc); + + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: + if (klass->open) { + if (!klass->open (enc)) + goto open_failed; + } + default: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + switch (transition) { + case GST_STATE_CHANGE_READY_TO_NULL: + if (klass->close) { + if (!klass->close (enc)) + goto close_failed; + } + default: + break; + } + + return ret; + +open_failed: + { + GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to open codec")); + return GST_STATE_CHANGE_FAILURE; + } +close_failed: + { + GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL), ("Failed to close codec")); + return GST_STATE_CHANGE_FAILURE; + } +} + /** * gst_audio_encoder_finish_frame: * @enc: a #GstAudioEncoder diff --git a/gst-libs/gst/audio/gstaudioencoder.h b/gst-libs/gst/audio/gstaudioencoder.h index aa40677222..2db19ab197 100644 --- a/gst-libs/gst/audio/gstaudioencoder.h +++ b/gst-libs/gst/audio/gstaudioencoder.h @@ -151,6 +151,12 @@ struct _GstAudioEncoder { * for multichannel input specification). If not implemented, * default returns gst_audio_encoder_proxy_getcaps * applied to sink template caps. + * @open: Optional. + * Called when the element changes to GST_STATE_READY. + * Allows opening external resources. Since: 0.10.37. + * @close: Optional. + * Called when the element changes to GST_STATE_NULL. + * Allows closing external resources. Since: 0.10.37. * * Subclasses can override any of the available virtual methods or not, as * needed. At minimum @set_format and @handle_frame needs to be overridden. @@ -183,8 +189,12 @@ struct _GstAudioEncoderClass { GstCaps * (*getcaps) (GstAudioEncoder *enc); + gboolean (*open) (GstAudioEncoder *enc); + + gboolean (*close) (GstAudioEncoder *enc); + /*< private >*/ - gpointer _gst_reserved[GST_PADDING_LARGE]; + gpointer _gst_reserved[GST_PADDING_LARGE-2]; }; GType gst_audio_encoder_get_type (void); From 5fee17ac8f2cd951451ee08ad3f48470812d7393 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 9 Mar 2012 14:15:44 +0100 Subject: [PATCH 02/20] uridecodebin: restore FLOATING flag when reusing decodebin instance ... which avoids leaking these due to an extra ref later on. --- gst/playback/gsturidecodebin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 9fe1691639..30f80289a6 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -1513,6 +1513,8 @@ remove_decoders (GstURIDecodeBin * bin, gboolean force) caps = DEFAULT_CAPS; g_object_set (decoder, "caps", caps, NULL); gst_caps_unref (caps); + /* make it freshly floating again */ + GST_OBJECT_FLAG_SET (decoder, GST_OBJECT_FLOATING); bin->pending_decodebins = g_slist_prepend (bin->pending_decodebins, decoder); From 8c99412a0d3fbd147913229b74bb3beab18b1085 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 9 Mar 2012 14:16:03 +0100 Subject: [PATCH 03/20] playbin2: do not take a superfluous ref on uridecodebin instances ... which are no longer FLOATING. --- gst/playback/gstplaybin2.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 0ed8b3ac87..d5e7d36221 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -3541,7 +3541,10 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group, GstState target) GST_DEBUG_OBJECT (playbin, "reusing existing uridecodebin"); uridecodebin = group->uridecodebin; gst_element_set_state (uridecodebin, GST_STATE_READY); - gst_bin_add (GST_BIN_CAST (playbin), gst_object_ref (uridecodebin)); + /* no need to take extra ref, we already have one + * and the bin will add one since it is no longer floating, + * as it was at least added once before (below) */ + gst_bin_add (GST_BIN_CAST (playbin), uridecodebin); } else { GST_DEBUG_OBJECT (playbin, "making new uridecodebin"); uridecodebin = gst_element_factory_make ("uridecodebin", NULL); @@ -3604,7 +3607,10 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group, GstState target) GST_DEBUG_OBJECT (playbin, "reusing existing suburidecodebin"); suburidecodebin = group->suburidecodebin; gst_element_set_state (suburidecodebin, GST_STATE_READY); - gst_bin_add (GST_BIN_CAST (playbin), gst_object_ref (suburidecodebin)); + /* no need to take extra ref, we already have one + * and the bin will add one since it is no longer floating, + * as it was at least added once before (below) */ + gst_bin_add (GST_BIN_CAST (playbin), suburidecodebin); } else { GST_DEBUG_OBJECT (playbin, "making new suburidecodebin"); suburidecodebin = gst_element_factory_make ("uridecodebin", NULL); From 6589c561575426c2bf123f110e4ebe5fb569bd6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Mar 2012 15:41:30 +0000 Subject: [PATCH 04/20] .gitignore: add new playback-test binary --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 78f083eac8..31894404aa 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,8 @@ Makefile /gst-libs/gst/tag/mklangtables /gst-libs/gst/tag/mklicensestables +/tests/examples/playback/playback-test + tmp-orc.c gst*orc.h tests/check/orc From 30fe3b7bad08603c2d2c6e69da3d3298fcc920bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Mar 2012 16:56:00 +0000 Subject: [PATCH 05/20] configure: fix AC_LANG_SOURCE-related warnings when doing autogen.sh --- common | 2 +- configure.ac | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/common b/common index bb15f1a28b..4b51fb8ae1 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit bb15f1a28b56d86380ed113cab88ed596b1ad452 +Subproject commit 4b51fb8ae1a8e2019010305cc96c8397dc68000d diff --git a/configure.ac b/configure.ac index 13bfb8e4dc..3af1e6904a 100644 --- a/configure.ac +++ b/configure.ac @@ -180,14 +180,18 @@ AC_CHECK_HEADERS([malloc.h]) ac_cppflags_save="$CPPFLAGS" CPPFLAGS="`$PKG_CONFIG --cflags libxml-2.0`" -AC_COMPILE_IFELSE( - AC_LANG_PROGRAM([ +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ #include - ],[ +]],[[ #ifndef LIBXML_HTML_ENABLED #error libxml2 has no HTML support #endif /* LIBXML_HTML_ENABLED */ - ]), HAVE_LIBXML_HTML="yes", HAVE_LIBXML_HTML="no") +]])], [ + HAVE_LIBXML_HTML="yes" +], [ + HAVE_LIBXML_HTML="no" +]) CPPFLAGS="$ac_cppflags_save" AM_CONDITIONAL(HAVE_LIBXML_HTML, test "x$HAVE_LIBXML_HTML" = "xyes") @@ -812,14 +816,14 @@ AG_GST_CHECK_FEATURE(VORBIS, [Xiph Vorbis audio codec], vorbis, [ if test "x$HAVE_VORBIS" = "xyes"; then ac_cflags_save="$CFLAGS" - AC_COMPILE_IFELSE( - AC_LANG_PROGRAM([ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ #include - ],[ + ]],[[ vorbis_dsp_state *v; vorbis_synthesis_restart (v); - ]), HAVE_VSR=yes, HAVE_VSR=no) + ]])], HAVE_VSR=yes, HAVE_VSR=no) if test "x$HAVE_VSR" = "xyes"; then AC_DEFINE_UNQUOTED(HAVE_VORBIS_SYNTHESIS_RESTART, 1, [defined if vorbis_synthesis_restart is present]) From 5cb1cd2d540ef434c6916c917054b72f7ed5ae72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Mar 2012 20:53:27 +0000 Subject: [PATCH 06/20] riff: when reading tags from INFO chunk, accept lower-case IDs as well --- gst-libs/gst/riff/riff-read.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index 314c19fe66..d73832d545 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -632,6 +632,9 @@ gst_riff_parse_info (GstElement * element, tsize = size; } + /* make uppercase */ + tag = tag & 0xDFDFDFDF; + /* find out the type of metadata */ switch (tag) { case GST_RIFF_INFO_IARL: From b2d066f49cd07a590440d009b05a1b1bd6d703bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 9 Mar 2012 20:54:00 +0000 Subject: [PATCH 07/20] riff: extract track number and album artist tags from INFO chunks https://bugzilla.gnome.org/show_bug.cgi?id=670286 --- gst-libs/gst/riff/riff-ids.h | 3 +++ gst-libs/gst/riff/riff-read.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/riff/riff-ids.h b/gst-libs/gst/riff/riff-ids.h index 106f71aa7b..afe87704d2 100644 --- a/gst-libs/gst/riff/riff-ids.h +++ b/gst-libs/gst/riff/riff-ids.h @@ -104,6 +104,9 @@ G_BEGIN_DECLS #define GST_RIFF_INFO_ISRF GST_MAKE_FOURCC ('I','S','R','F') /* source form */ #define GST_RIFF_INFO_ITCH GST_MAKE_FOURCC ('I','T','C','H') /* technician(s) */ +#define GST_RIFF_INFO_IAAR GST_MAKE_FOURCC ('I','A','A','R') /* album artist */ +#define GST_RIFF_INFO_ITRK GST_MAKE_FOURCC ('I','T','R','K') /* track number */ + /*********Chunk Names***************/ #define GST_RIFF_FF00 GST_MAKE_FOURCC (0xFF,0xFF,0x00,0x00) #define GST_RIFF_00 GST_MAKE_FOURCC ('0', '0',0x00,0x00) diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index d73832d545..512f31a1fe 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -620,6 +620,9 @@ gst_riff_parse_info (GstElement * element, while (size > 8) { tag = GST_READ_UINT32_LE (data); tsize = GST_READ_UINT32_LE (data + 4); + + GST_MEMDUMP_OBJECT (element, "tag chunk", data, MIN (tsize + 8, size)); + size -= 8; data += 8; @@ -640,6 +643,9 @@ gst_riff_parse_info (GstElement * element, case GST_RIFF_INFO_IARL: type = GST_TAG_LOCATION; break; + case GST_RIFF_INFO_IAAR: + type = GST_TAG_ALBUM_ARTIST; + break; case GST_RIFF_INFO_IART: type = GST_TAG_ARTIST; break; @@ -706,6 +712,9 @@ gst_riff_parse_info (GstElement * element, case GST_RIFF_INFO_ITCH: type = NULL; /*"Technician"; */ break; + case GST_RIFF_INFO_ITRK: + type = GST_TAG_TRACK_NUMBER; + break; default: type = NULL; GST_WARNING_OBJECT (element, @@ -718,12 +727,31 @@ gst_riff_parse_info (GstElement * element, static const gchar *env_vars[] = { "GST_AVI_TAG_ENCODING", "GST_RIFF_TAG_ENCODING", "GST_TAG_ENCODING", NULL }; + GType tag_type; gchar *val; + GST_DEBUG_OBJECT (element, "mapped tag %" GST_FOURCC_FORMAT " to tag %s", + GST_FOURCC_ARGS (tag), type); + + tag_type = gst_tag_get_type (type); val = gst_tag_freeform_string_to_utf8 ((gchar *) data, tsize, env_vars); - if (val) { - gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL); + if (val != NULL) { + if (tag_type == G_TYPE_STRING) { + gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, type, val, NULL); + } else { + GValue tag_val = { 0, }; + + g_value_init (&tag_val, tag_type); + if (gst_value_deserialize (&tag_val, val)) { + gst_tag_list_add_value (taglist, GST_TAG_MERGE_APPEND, type, + &tag_val); + } else { + GST_WARNING_OBJECT (element, "could not deserialize '%s' into a " + "tag %s of type %s", val, type, g_type_name (tag_type)); + } + g_value_unset (&tag_val); + } g_free (val); } else { GST_WARNING_OBJECT (element, "could not extract %s tag", type); @@ -741,6 +769,7 @@ gst_riff_parse_info (GstElement * element, } if (!gst_tag_list_is_empty (taglist)) { + GST_INFO_OBJECT (element, "extracted tags: %" GST_PTR_FORMAT, taglist); *_taglist = taglist; } else { *_taglist = NULL; From b1938e9c0da898397bbf9db9a5aec12d75b7c698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 12 Mar 2012 23:28:12 +0000 Subject: [PATCH 08/20] configure: backport AS_LIBTOOL version from 0.10.36 release Should fix issues with missing symbols for people who install GStreamer from source and at some point jumped back and forth between git master and the 0.10.36 release (or 0.10. branch). --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3af1e6904a..747215e826 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,7 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 dnl sets GST_LT_LDFLAGS -AS_LIBTOOL(GST, 24, 0, 24) +AS_LIBTOOL(GST, 25, 0, 25) dnl FIXME: this macro doesn't actually work; dnl the generated libtool script has no support for the listed tags. From 3d8d31b29e201918e608d5eb0cf0527e7843170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 12 Mar 2012 23:29:26 +0000 Subject: [PATCH 09/20] configure: bump AS_LIBTOOL version API was added in libgsttag, libgstaudio and libgstvideo --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 747215e826..3b87f433b7 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,7 @@ dnl - interfaces added/removed/changed -> increment CURRENT, REVISION = 0 dnl - interfaces added -> increment AGE dnl - interfaces removed -> AGE = 0 dnl sets GST_LT_LDFLAGS -AS_LIBTOOL(GST, 25, 0, 25) +AS_LIBTOOL(GST, 26, 0, 26) dnl FIXME: this macro doesn't actually work; dnl the generated libtool script has no support for the listed tags. From d13e1b49f6b690f8476fdca12a115f571f180171 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 13 Mar 2012 15:24:38 +0100 Subject: [PATCH 10/20] playsink: provide fresh copy for gst_caps_merge ... since it is documented to modify provided caps. --- gst/playback/gstplaysinkconvertbin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index 977c6cede7..255c0efe0d 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -397,7 +397,7 @@ gst_play_sink_convert_bin_getcaps (GstPad * pad) gst_object_unref (peer); if (self->converter_caps && is_raw_caps (peer_caps, self->audio)) { peer_caps = gst_caps_make_writable (peer_caps); - gst_caps_merge (peer_caps, gst_caps_ref (self->converter_caps)); + gst_caps_merge (peer_caps, gst_caps_copy (self->converter_caps)); ret = peer_caps; } else { ret = peer_caps; From 787e896bdeb6c67d13a918ec55d3826fa010fb90 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 25 Jan 2012 23:53:04 +0100 Subject: [PATCH 11/20] vorbisdec: support modern Tremor versions Tremor changed to use standard libogg rather than its own incompatible copy back in Aug 2010 (r17375), causing gst-plugin-base build to fail. Tremolo so far unfortunately hasn't been updated. Restructure vorbisdeclib.h so the int/float logic is seperate from the ogg handling, and only use the legacy _ogg_packet_wrapper code for Tremolo. https://bugzilla.gnome.org/show_bug.cgi?id=668726 --- ext/vorbis/gstvorbisdeclib.h | 77 +++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/ext/vorbis/gstvorbisdeclib.h b/ext/vorbis/gstvorbisdeclib.h index ca00af9db8..e1475918a0 100644 --- a/ext/vorbis/gstvorbisdeclib.h +++ b/ext/vorbis/gstvorbisdeclib.h @@ -29,11 +29,6 @@ #ifndef TREMOR -#include - -typedef float vorbis_sample_t; -typedef ogg_packet ogg_packet_wrapper; - #define GST_VORBIS_DEC_DESCRIPTION "decode raw vorbis streams to float audio" #define GST_VORBIS_DEC_SRC_CAPS \ @@ -47,6 +42,42 @@ typedef ogg_packet ogg_packet_wrapper; #define GST_VORBIS_DEC_GLIB_TYPE_NAME GstVorbisDec +#else /* TREMOR */ + +#define GST_VORBIS_DEC_DESCRIPTION "decode raw vorbis streams to integer audio" + +#define GST_VORBIS_DEC_SRC_CAPS \ + GST_STATIC_CAPS ("audio/x-raw-int, " \ + "rate = (int) [ 1, MAX ], " \ + "channels = (int) [ 1, 6 ], " \ + "endianness = (int) BYTE_ORDER, " \ + "width = (int) { 16, 32 }, " \ + "depth = (int) 16, " \ + "signed = (boolean) true") + +#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16) + +/* we need a different type name here */ +#define GST_VORBIS_DEC_GLIB_TYPE_NAME GstIVorbisDec + +/* and still have it compile */ +typedef struct _GstVorbisDec GstIVorbisDec; +typedef struct _GstVorbisDecClass GstIVorbisDecClass; + +#endif /* TREMOR */ + +#ifndef USE_TREMOLO + +#ifdef TREMOR + #include + typedef ogg_int32_t vorbis_sample_t; +#else + #include + typedef float vorbis_sample_t; +#endif + +typedef ogg_packet ogg_packet_wrapper; + static inline guint8 * gst_ogg_packet_data (ogg_packet * p) { @@ -72,17 +103,11 @@ gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet) return packet; } -#else - -#ifdef USE_TREMOLO - #include - #include - typedef ogg_int16_t vorbis_sample_t; -#else - #include - typedef ogg_int32_t vorbis_sample_t; -#endif +#else /* USE_TREMOLO */ +#include +#include +typedef ogg_int16_t vorbis_sample_t; typedef struct _ogg_packet_wrapper ogg_packet_wrapper; struct _ogg_packet_wrapper { @@ -91,26 +116,6 @@ struct _ogg_packet_wrapper { ogg_buffer buf; }; -#define GST_VORBIS_DEC_DESCRIPTION "decode raw vorbis streams to integer audio" - -#define GST_VORBIS_DEC_SRC_CAPS \ - GST_STATIC_CAPS ("audio/x-raw-int, " \ - "rate = (int) [ 1, MAX ], " \ - "channels = (int) [ 1, 6 ], " \ - "endianness = (int) BYTE_ORDER, " \ - "width = (int) { 16, 32 }, " \ - "depth = (int) 16, " \ - "signed = (boolean) true") - -#define GST_VORBIS_DEC_DEFAULT_SAMPLE_WIDTH (16) - -/* we need a different type name here */ -#define GST_VORBIS_DEC_GLIB_TYPE_NAME GstIVorbisDec - -/* and still have it compile */ -typedef struct _GstVorbisDec GstIVorbisDec; -typedef struct _GstVorbisDecClass GstIVorbisDecClass; - /* compensate minor variation */ #define vorbis_synthesis(a, b) vorbis_synthesis (a, b, 1) @@ -154,7 +159,7 @@ gst_ogg_packet_from_wrapper (ogg_packet_wrapper * packet) return &(packet->packet); } -#endif +#endif /* USE_TREMOLO */ typedef void (*CopySampleFunc)(vorbis_sample_t *out, vorbis_sample_t **in, guint samples, gint channels, gint width); From 9fc640b9e0ba807b7f8ce6bdbd7c754bdbfdb761 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 14 Mar 2012 11:04:25 +0100 Subject: [PATCH 12/20] playsink: remove circular ref between bin and internal pad ... by not assigning an additional ref to an async blocked callback, which should not be called anyway by the time the object is gone. Fixes #672006. --- gst/playback/gstplaysink.c | 30 ++++++++++------------------ gst/playback/gstplaysinkconvertbin.c | 15 +++++--------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 8757e2b8e0..0bc70ac531 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -3382,8 +3382,7 @@ sinkpad_blocked_cb (GstPad * blockedpad, gboolean blocked, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } @@ -3391,8 +3390,7 @@ sinkpad_blocked_cb (GstPad * blockedpad, gboolean blocked, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } @@ -3400,8 +3398,7 @@ sinkpad_blocked_cb (GstPad * blockedpad, gboolean blocked, gpointer user_data) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } } @@ -3446,8 +3443,7 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); - gst_pad_set_blocked_async_full (opad, TRUE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, TRUE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } @@ -3455,8 +3451,7 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); - gst_pad_set_blocked_async_full (opad, TRUE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, TRUE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } @@ -3464,8 +3459,7 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) GstPad *opad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); - gst_pad_set_blocked_async_full (opad, TRUE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, TRUE, sinkpad_blocked_cb, playsink); gst_object_unref (opad); } GST_PLAY_SINK_UNLOCK (playsink); @@ -3579,8 +3573,7 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type) GstPad *blockpad = GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (res))); - gst_pad_set_blocked_async_full (blockpad, TRUE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (blockpad, TRUE, sinkpad_blocked_cb, playsink); PENDING_FLAG_SET (playsink, type); gst_object_unref (blockpad); } @@ -3865,8 +3858,7 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->video_pad))); if (gst_pad_is_blocked (opad)) { - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); } gst_object_unref (opad); playsink->video_pad_blocked = FALSE; @@ -3877,8 +3869,7 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->audio_pad))); if (gst_pad_is_blocked (opad)) { - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); } gst_object_unref (opad); playsink->audio_pad_blocked = FALSE; @@ -3889,8 +3880,7 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (playsink->text_pad))); if (gst_pad_is_blocked (opad)) { - gst_pad_set_blocked_async_full (opad, FALSE, sinkpad_blocked_cb, - gst_object_ref (playsink), (GDestroyNotify) gst_object_unref); + gst_pad_set_blocked_async (opad, FALSE, sinkpad_blocked_cb, playsink); } gst_object_unref (opad); playsink->text_pad_blocked = FALSE; diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c index 255c0efe0d..67a6d7409b 100644 --- a/gst/playback/gstplaysinkconvertbin.c +++ b/gst/playback/gstplaysinkconvertbin.c @@ -254,8 +254,7 @@ pad_blocked_cb (GstPad * pad, gboolean blocked, GstPlaySinkConvertBin * self) unblock: gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + (GstPadBlockCallback) pad_blocked_cb, self, NULL); done: GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); @@ -338,8 +337,7 @@ gst_play_sink_convert_bin_sink_setcaps (GstPad * pad, GstCaps * caps) reconfigure = TRUE; gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + (GstPadBlockCallback) pad_blocked_cb, self, NULL); } if (target) @@ -350,8 +348,7 @@ gst_play_sink_convert_bin_sink_setcaps (GstPad * pad, GstCaps * caps) GST_DEBUG_OBJECT (self, "Changing caps from raw to non-raw"); reconfigure = TRUE; gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + (GstPadBlockCallback) pad_blocked_cb, self, NULL); } } @@ -509,8 +506,7 @@ gst_play_sink_convert_bin_change_state (GstElement * element, GST_PLAY_SINK_CONVERT_BIN_LOCK (self); if (gst_pad_is_blocked (self->sink_proxypad)) gst_pad_set_blocked_async_full (self->sink_proxypad, FALSE, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + (GstPadBlockCallback) pad_blocked_cb, self, NULL); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -540,8 +536,7 @@ gst_play_sink_convert_bin_change_state (GstElement * element, GST_PLAY_SINK_CONVERT_BIN_LOCK (self); if (!gst_pad_is_blocked (self->sink_proxypad)) gst_pad_set_blocked_async_full (self->sink_proxypad, TRUE, - (GstPadBlockCallback) pad_blocked_cb, gst_object_ref (self), - (GDestroyNotify) gst_object_unref); + (GstPadBlockCallback) pad_blocked_cb, self, NULL); GST_PLAY_SINK_CONVERT_BIN_UNLOCK (self); break; default: From f234923c07afc6e0aa5d6ab819a9fca55c8124d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 14 Mar 2012 15:31:45 +0000 Subject: [PATCH 13/20] tests: remove ASSERT_CRITICAL disablement in overlay composition unit test No idea why that was there. --- tests/check/libs/video.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index ea32bd4f27..3e13341c43 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -781,9 +781,6 @@ GST_START_TEST (test_video_size_from_caps) GST_END_TEST; -#undef ASSERT_CRITICAL -#define ASSERT_CRITICAL(code) while(0){} /* nothing */ - GST_START_TEST (test_overlay_composition) { GstVideoOverlayComposition *comp1, *comp2; @@ -907,6 +904,7 @@ GST_START_TEST (test_overlay_composition) fail_unless (gst_video_buffer_get_overlay_composition (buf) == NULL); gst_buffer_ref (buf); + /* buffer now has refcount of 2, so its metadata is not writable */ ASSERT_CRITICAL (gst_video_buffer_set_overlay_composition (buf, comp1)); gst_buffer_unref (buf); gst_video_buffer_set_overlay_composition (buf, comp1); From 6b7f25a2f07082be5fb95d676bf90fda91511204 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Wed, 14 Mar 2012 16:42:24 +0000 Subject: [PATCH 14/20] video: overlay-composition: check the right flags when searching for a cached rectangle Compare the flags of the *cached* rectangle to the desired flags when checking for a suitable rectangle in the cache. https://bugzilla.gnome.org/show_bug.cgi?id=668483 --- gst-libs/gst/video/video-overlay-composition.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index 4633b6b489..e6e5d2a403 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -935,8 +935,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * if (r->width == wanted_width && r->height == wanted_height && - gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, - flags)) { + gst_video_overlay_rectangle_is_same_alpha_type (r->flags, flags)) { /* we'll keep these rectangles around until finalize, so it's ok not * to take our own ref here */ scaled_rect = r; From 7a21d1eb32a02139236378f66e8a245cba5d35e0 Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Wed, 14 Mar 2012 17:18:47 +0000 Subject: [PATCH 15/20] video: overlay-composition: fix crash when doing premultiplied<->unpremultiplied alpha conversion We need to copy the pixels before messing with them, not least because the buffer creation code below assumes it's ok to take ownership. Fixes crash caused by double-free. https://bugzilla.gnome.org/show_bug.cgi?id=668483 --- gst-libs/gst/video/video-overlay-composition.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index e6e5d2a403..8c6ebb20db 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -954,6 +954,10 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * if (wanted_width != rectangle->width || wanted_height != rectangle->height) { video_blend_scale_linear_RGBA (&info, wanted_height, wanted_width); + } else { + /* if we don't have to scale, we have to modify the alpha values, so we + * need to make a copy of the pixel memory (and we take ownership below) */ + info.pixels = g_memdup (info.pixels, info.size); } if (!gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, flags)) { From 027f5bb47182130ae1edb30de789e42f4305e2ca Mon Sep 17 00:00:00 2001 From: Holger Kaelberer Date: Wed, 14 Mar 2012 17:28:57 +0000 Subject: [PATCH 16/20] video: overlay-composition: fix rectangle caching after alpha (un)premultiplying If we are asked to (un)premultiply,we need to create the new rectangle with the right flags, so we can find it properly on subsequent cache lookups (also because it's wrong otherwise). https://bugzilla.gnome.org/show_bug.cgi?id=668483 --- gst-libs/gst/video/video-overlay-composition.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index 8c6ebb20db..73641ea076 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -908,6 +908,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * rectangle, guint * stride, GstVideoOverlayFormatFlags flags, gboolean unscaled) { + GstVideoOverlayFormatFlags new_flags; GstVideoOverlayRectangle *scaled_rect = NULL; GstBlendVideoFormatInfo info; GstBuffer *buf; @@ -960,11 +961,14 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * info.pixels = g_memdup (info.pixels, info.size); } + new_flags = rectangle->flags; 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); + new_flags &= ~GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; } else { gst_video_overlay_rectangle_premultiply (&info); + new_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA; } } @@ -975,7 +979,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle * scaled_rect = gst_video_overlay_rectangle_new_argb (buf, wanted_width, wanted_height, info.stride[0], - 0, 0, wanted_width, wanted_height, rectangle->flags); + 0, 0, wanted_width, wanted_height, new_flags); gst_buffer_unref (buf); From 2c4b379470963ea2baff1e85db4f4568e53e83d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 14 Mar 2012 17:46:23 +0000 Subject: [PATCH 17/20] video: overlay-composition: fix alpha premultiply and unpremultiply Fix component offsets for little endian systems. https://bugzilla.gnome.org/show_bug.cgi?id=668483 --- .../gst/video/video-overlay-composition.c | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c index 73641ea076..ad9788670f 100644 --- a/gst-libs/gst/video/video-overlay-composition.c +++ b/gst-libs/gst/video/video-overlay-composition.c @@ -869,6 +869,19 @@ gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle * rectangle->render_height = render_height; } +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define ARGB_A 3 +# define ARGB_R 2 +# define ARGB_G 1 +# define ARGB_B 0 +#else +# define ARGB_A 0 +# define ARGB_R 1 +# define ARGB_G 2 +# define ARGB_B 3 +#endif + +/* FIXME: orc-ify */ static void gst_video_overlay_rectangle_premultiply (GstBlendVideoFormatInfo * info) { @@ -876,15 +889,16 @@ gst_video_overlay_rectangle_premultiply (GstBlendVideoFormatInfo * info) 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; + int a = line[ARGB_A]; + line[ARGB_R] = line[ARGB_R] * a / 255; + line[ARGB_G] = line[ARGB_G] * a / 255; + line[ARGB_B] = line[ARGB_B] * a / 255; line += 4; } } } +/* FIXME: orc-ify */ static void gst_video_overlay_rectangle_unpremultiply (GstBlendVideoFormatInfo * info) { @@ -892,11 +906,11 @@ gst_video_overlay_rectangle_unpremultiply (GstBlendVideoFormatInfo * info) 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]; + int a = line[ARGB_A]; 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[ARGB_R] = MIN ((line[ARGB_R] * 255 + a / 2) / a, 255); + line[ARGB_G] = MIN ((line[ARGB_G] * 255 + a / 2) / a, 255); + line[ARGB_B] = MIN ((line[ARGB_B] * 255 + a / 2) / a, 255); } line += 4; } From 87a9e5634e3c44a02bb1dad9233a2cbd2c4f5311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 14 Mar 2012 17:59:31 +0000 Subject: [PATCH 18/20] tests: add unit test for premultiplied alpha handling of video overlay rectangles https://bugzilla.gnome.org/show_bug.cgi?id=668483 --- tests/check/libs/video.c | 114 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index 3e13341c43..bc2445110f 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -3,6 +3,7 @@ * Copyright (C) <2003> David A. Schleef * Copyright (C) <2006> Jan Schmidt * Copyright (C) <2008,2011> Tim-Philipp Müller + * Copyright (C) <2012> Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -924,6 +925,118 @@ GST_START_TEST (test_overlay_composition) GST_END_TEST; +GST_START_TEST (test_overlay_composition_premultiplied_alpha) +{ + GstVideoOverlayRectangle *rect1; + GstBuffer *pix1, *pix2, *pix3, *pix4, *pix5; + GstBuffer *pix6, *pix7, *pix8, *pix9, *pix10; + guint8 *data5, *data7; + guint w, h, stride, w2, h2, stride2; + + pix1 = gst_buffer_new_and_alloc (200 * sizeof (guint32) * 50); + memset (GST_BUFFER_DATA (pix1), 0x80, GST_BUFFER_SIZE (pix1)); + + rect1 = gst_video_overlay_rectangle_new_argb (pix1, 200, 50, 200 * 4, + 600, 50, 300, 50, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + gst_buffer_unref (pix1); + + /* same flags, unscaled, should be the same buffer */ + pix2 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w, &h, + &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless (pix1 == pix2); + + /* same flags, but scaled */ + pix3 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_if (pix3 == pix1 || pix3 == pix2); + + /* same again, should hopefully get the same (cached) buffer as before */ + pix4 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless (pix4 == pix3); + + /* just to update the vars */ + pix2 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w, &h, + &stride, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + + /* now, let's try to get premultiplied alpha from the unpremultiplied input */ + pix5 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w2, &h2, + &stride2, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); + fail_if (pix5 == pix1 || pix5 == pix2 || pix5 == pix3); + fail_unless_equals_int (stride, stride2); + fail_unless_equals_int (w, w2); + fail_unless_equals_int (h, h2); + fail_unless_equals_int (GST_BUFFER_SIZE (pix2), GST_BUFFER_SIZE (pix5)); + data5 = GST_BUFFER_DATA (pix5); + fail_if (memcmp (data5, GST_BUFFER_DATA (pix2), GST_BUFFER_SIZE (pix5)) == 0); + + /* make sure it actually did what we expected it to do (input=0x80808080) */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + /* B - G - R - A */ + fail_unless_equals_int (data5[0], 0x40); + fail_unless_equals_int (data5[1], 0x40); + fail_unless_equals_int (data5[2], 0x40); + fail_unless_equals_int (data5[3], 0x80); +#else + /* A - R - G - B */ + fail_unless_equals_int (data5[0], 0x40); + fail_unless_equals_int (data5[1], 0x40); + fail_unless_equals_int (data5[2], 0x40); + fail_unless_equals_int (data5[3], 0x80); +#endif + + /* same again, now we should be getting back the same buffer as before, + * as it should have been cached */ + pix6 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w2, &h2, + &stride2, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); + fail_unless (pix6 == pix5); + + /* just to update the stride var */ + pix3 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless (pix3 == pix4); + + /* now try to get scaled premultiplied alpha from unpremultiplied input */ + pix7 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride2, + GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); + fail_if (pix7 == pix1 || pix7 == pix2 || pix7 == pix3 || pix7 == pix5); + fail_unless_equals_int (stride, stride2); + + data7 = GST_BUFFER_DATA (pix7); + /* make sure it actually did what we expected it to do (input=0x80808080) + * hoping that the scaling didn't mess up our values */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + /* B - G - R - A */ + fail_unless_equals_int (data7[0], 0x40); + fail_unless_equals_int (data7[1], 0x40); + fail_unless_equals_int (data7[2], 0x40); + fail_unless_equals_int (data7[3], 0x80); +#else + /* A - R - G - B */ + fail_unless_equals_int (data7[0], 0x40); + fail_unless_equals_int (data7[1], 0x40); + fail_unless_equals_int (data7[2], 0x40); + fail_unless_equals_int (data7[3], 0x80); +#endif + + /* and the same again, it should be cached now */ + pix8 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride2, + GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); + fail_unless (pix8 == pix7); + + /* make sure other cached stuff is still there */ + pix9 = gst_video_overlay_rectangle_get_pixels_argb (rect1, &stride, + GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); + fail_unless (pix9 == pix3); + pix10 = gst_video_overlay_rectangle_get_pixels_unscaled_argb (rect1, &w2, &h2, + &stride2, GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA); + fail_unless (pix10 == pix5); + + gst_video_overlay_rectangle_unref (rect1); +} + +GST_END_TEST; + static Suite * video_suite (void) { @@ -941,6 +1054,7 @@ video_suite (void) tcase_add_test (tc_chain, test_convert_frame_async); tcase_add_test (tc_chain, test_video_size_from_caps); tcase_add_test (tc_chain, test_overlay_composition); + tcase_add_test (tc_chain, test_overlay_composition_premultiplied_alpha); return s; } From 73605cb33ddaaea6f6cec3afa224fe712374125e Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 15 Mar 2012 12:59:38 +0000 Subject: [PATCH 19/20] playsink: send navigation event to the sink as a fallback When the video sink is a fakesink, which does not implement the navigation interface, playsink will drop the navigation command. In this case, send to the video sink as a fallback. It breaks the interface abstraction, but is better than just dropping the navigation event. --- gst/playback/gstplaysink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 0bc70ac531..a68b6ae5dd 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -4295,6 +4295,10 @@ gst_play_sink_navigation_send_event (GstNavigation * navigation, gst_navigation_send_event (GST_NAVIGATION (nav), structure); structure = NULL; gst_object_unref (nav); + } else { + GstEvent *event = gst_event_new_navigation (structure); + structure = NULL; + gst_element_send_event (GST_ELEMENT (bin), event); } gst_object_unref (bin); From fe0e2d65e190b816959c624149a6dc48b7118796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 18 Mar 2012 22:56:58 +0000 Subject: [PATCH 20/20] riff: map IPRD ("product") tag to GST_TAG_ALBUM http://www.bass.radio42.com/help/html/7e1a8908-88bd-d54b-77d7-f0d08466284c.htm https://bugzilla.gnome.org/show_bug.cgi?id=670286 --- gst-libs/gst/riff/riff-ids.h | 2 +- gst-libs/gst/riff/riff-read.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/riff/riff-ids.h b/gst-libs/gst/riff/riff-ids.h index afe87704d2..9442018b51 100644 --- a/gst-libs/gst/riff/riff-ids.h +++ b/gst-libs/gst/riff/riff-ids.h @@ -96,7 +96,7 @@ G_BEGIN_DECLS #define GST_RIFF_INFO_IMED GST_MAKE_FOURCC ('I','M','E','D') /* medium */ #define GST_RIFF_INFO_INAM GST_MAKE_FOURCC ('I','N','A','M') /* name */ #define GST_RIFF_INFO_IPLT GST_MAKE_FOURCC ('I','P','L','T') /* palette setting */ -#define GST_RIFF_INFO_IPRD GST_MAKE_FOURCC ('I','P','R','D') /* product */ +#define GST_RIFF_INFO_IPRD GST_MAKE_FOURCC ('I','P','R','D') /* product (album) */ #define GST_RIFF_INFO_ISBJ GST_MAKE_FOURCC ('I','S','B','J') /* subject */ #define GST_RIFF_INFO_ISFT GST_MAKE_FOURCC ('I','S','F','T') /* software */ #define GST_RIFF_INFO_ISHP GST_MAKE_FOURCC ('I','S','H','P') /* sharpness */ diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index 512f31a1fe..c4ba3e823d 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -692,7 +692,7 @@ gst_riff_parse_info (GstElement * element, type = NULL; /*"Palette"; */ break; case GST_RIFF_INFO_IPRD: - type = NULL; /*"Product"; */ + type = GST_TAG_ALBUM; break; case GST_RIFF_INFO_ISBJ: type = NULL; /*"Subject"; */