From 94daabf71fc1e439a1ef49c607383a1d349e5277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:43:14 +0100 Subject: [PATCH 01/26] aacparse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstaacparse.c | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index 51410704e8..bc1c60be55 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -74,6 +74,7 @@ gboolean gst_aac_parse_stop (GstBaseParse * parse); static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); +static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse); gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * size, gint * skipsize); @@ -144,6 +145,7 @@ gst_aac_parse_class_init (GstAacParseClass * klass) parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start); parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop); parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_parse_frame); parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_check_valid_frame); @@ -723,3 +725,36 @@ gst_aac_parse_stop (GstBaseParse * parse) GST_DEBUG ("stop"); return TRUE; } + +static GstCaps * +gst_aac_parse_sink_getcaps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Remove the framed field */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + gst_structure_remove_field (s, "framed"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From 48b07ae434d4d6ca5284f92ba9f68deffa505ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:44:58 +0100 Subject: [PATCH 02/26] aacparse: Mark some functions as static and remove unused function declarations --- gst/audioparsers/gstaacparse.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index bc1c60be55..4f6bdd694f 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -69,28 +69,19 @@ GST_DEBUG_CATEGORY_STATIC (aacparse_debug); #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec) -gboolean gst_aac_parse_start (GstBaseParse * parse); -gboolean gst_aac_parse_stop (GstBaseParse * parse); +static gboolean gst_aac_parse_start (GstBaseParse * parse); +static gboolean gst_aac_parse_stop (GstBaseParse * parse); static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse); -gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse, +static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * size, gint * skipsize); -GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse, +static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); -gboolean gst_aac_parse_convert (GstBaseParse * parse, - GstFormat src_format, - gint64 src_value, GstFormat dest_format, gint64 * dest_value); - -gint gst_aac_parse_get_frame_overhead (GstBaseParse * parse, - GstBuffer * buffer); - -gboolean gst_aac_parse_event (GstBaseParse * parse, GstEvent * event); - #define _do_init(bla) \ GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0, \ "AAC audio stream parser"); @@ -577,7 +568,7 @@ gst_aac_parse_detect_stream (GstAacParse * aacparse, * * Returns: TRUE if buffer contains a valid frame. */ -gboolean +static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { @@ -650,7 +641,7 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse, * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed * forward. Otherwise appropriate error is returned. */ -GstFlowReturn +static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { GstAacParse *aacparse; @@ -698,7 +689,7 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) * * Returns: TRUE if startup succeeded. */ -gboolean +static gboolean gst_aac_parse_start (GstBaseParse * parse) { GstAacParse *aacparse; @@ -719,7 +710,7 @@ gst_aac_parse_start (GstBaseParse * parse) * * Returns: TRUE is stopping succeeded. */ -gboolean +static gboolean gst_aac_parse_stop (GstBaseParse * parse) { GST_DEBUG ("stop"); From fabc5c969be34e496662a810ba1b3f0b2721163d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:48:33 +0100 Subject: [PATCH 03/26] ac3parse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstac3parse.c | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/gst/audioparsers/gstac3parse.c b/gst/audioparsers/gstac3parse.c index f907249076..d7354eb1df 100644 --- a/gst/audioparsers/gstac3parse.c +++ b/gst/audioparsers/gstac3parse.c @@ -165,6 +165,7 @@ static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); static gboolean gst_ac3_parse_src_event (GstBaseParse * parse, GstEvent * event); +static GstCaps *gst_ac3_parse_get_sink_caps (GstBaseParse * parse); GST_BOILERPLATE (GstAc3Parse, gst_ac3_parse, GstBaseParse, GST_TYPE_BASE_PARSE); @@ -199,8 +200,8 @@ gst_ac3_parse_class_init (GstAc3ParseClass * klass) parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_check_valid_frame); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_ac3_parse_parse_frame); - parse_class->src_event = GST_DEBUG_FUNCPTR (gst_ac3_parse_src_event); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_ac3_parse_get_sink_caps); } static void @@ -662,3 +663,38 @@ gst_ac3_parse_src_event (GstBaseParse * parse, GstEvent * event) return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event); } + +static GstCaps * +gst_ac3_parse_get_sink_caps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Remove the framed and alignment field. We can convert + * between different alignments. */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + gst_structure_remove_field (s, "framed"); + gst_structure_remove_field (s, "alignment"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From 5203b0884abc1deeec5943557dd4c7b49bb91579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:49:27 +0100 Subject: [PATCH 04/26] amrparse: Mark some more functions as static --- gst/audioparsers/gstamrparse.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index bdb860434b..3dbd3e0bc7 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -71,16 +71,16 @@ static const gint block_size_wb[16] = #define AMR_FRAME_DURATION (GST_SECOND/AMR_FRAMES_PER_SECOND) #define AMR_MIME_HEADER_SIZE 9 -gboolean gst_amr_parse_start (GstBaseParse * parse); -gboolean gst_amr_parse_stop (GstBaseParse * parse); +static gboolean gst_amr_parse_start (GstBaseParse * parse); +static gboolean gst_amr_parse_stop (GstBaseParse * parse); static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); -gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, +static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize); -GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, +static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); #define _do_init(bla) \ @@ -90,7 +90,6 @@ GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GST_BOILERPLATE_FULL (GstAmrParse, gst_amr_parse, GstBaseParse, GST_TYPE_BASE_PARSE, _do_init); - /** * gst_amr_parse_base_init: * @klass: #GstElementClass. @@ -265,7 +264,7 @@ gst_amr_parse_parse_header (GstAmrParse * amrparse, * * Returns: TRUE if the given data contains valid frame. */ -gboolean +static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { @@ -346,7 +345,7 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse, * * Returns: #GstFlowReturn defining the parsing status. */ -GstFlowReturn +static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { return GST_FLOW_OK; @@ -361,7 +360,7 @@ gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_start (GstBaseParse * parse) { GstAmrParse *amrparse; @@ -382,7 +381,7 @@ gst_amr_parse_start (GstBaseParse * parse) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_stop (GstBaseParse * parse) { GstAmrParse *amrparse; From c5b770df0937ada20df065d3a9a3397b644bb1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:53:18 +0100 Subject: [PATCH 05/26] amrparse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstamrparse.c | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index 3dbd3e0bc7..90a65c4687 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -76,6 +76,7 @@ static gboolean gst_amr_parse_stop (GstBaseParse * parse); static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); +static GstCaps *gst_amr_parse_sink_getcaps (GstBaseParse * parse); static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize); @@ -125,6 +126,7 @@ gst_amr_parse_class_init (GstAmrParseClass * klass) parse_class->start = GST_DEBUG_FUNCPTR (gst_amr_parse_start); parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop); parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_setcaps); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_getcaps); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_parse_frame); parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_check_valid_frame); @@ -392,3 +394,39 @@ gst_amr_parse_stop (GstBaseParse * parse) amrparse->header = 0; return TRUE; } + +static GstCaps * +gst_amr_parse_sink_getcaps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Rename structure names */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + if (gst_structure_has_name (s, "audio/AMR")) + gst_structure_set_name (s, "audio/x-amr-nb-sh"); + else + gst_structure_set_name (s, "audio/x-amr-wb-sh"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From e6a21299778538f7ec5d63a1ba6dd1ce248e233c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:55:47 +0100 Subject: [PATCH 06/26] dcaparse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstdcaparse.c | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/gst/audioparsers/gstdcaparse.c b/gst/audioparsers/gstdcaparse.c index 2c020e7144..14d313d534 100644 --- a/gst/audioparsers/gstdcaparse.c +++ b/gst/audioparsers/gstdcaparse.c @@ -78,6 +78,7 @@ static gboolean gst_dca_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * size, gint * skipsize); static GstFlowReturn gst_dca_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); +static GstCaps *gst_dca_parse_get_sink_caps (GstBaseParse * parse); GST_BOILERPLATE (GstDcaParse, gst_dca_parse, GstBaseParse, GST_TYPE_BASE_PARSE); @@ -112,6 +113,7 @@ gst_dca_parse_class_init (GstDcaParseClass * klass) parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_check_valid_frame); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_parse_frame); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_dca_parse_get_sink_caps); } static void @@ -450,3 +452,36 @@ broken_header: return GST_FLOW_ERROR; } } + +static GstCaps * +gst_dca_parse_get_sink_caps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Remove the framed field */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + gst_structure_remove_field (s, "framed"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From 996b4eb4ccf90ce94604fe5dc034a4dfd23d9489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:57:57 +0100 Subject: [PATCH 07/26] flacparse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstflacparse.c | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c index 637319f621..36db7c1700 100644 --- a/gst/audioparsers/gstflacparse.c +++ b/gst/audioparsers/gstflacparse.c @@ -201,6 +201,7 @@ static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse, static gboolean gst_flac_parse_convert (GstBaseParse * parse, GstFormat src_format, gint64 src_value, GstFormat dest_format, gint64 * dest_value); +static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse); GST_BOILERPLATE (GstFlacParse, gst_flac_parse, GstBaseParse, GST_TYPE_BASE_PARSE); @@ -248,6 +249,8 @@ gst_flac_parse_class_init (GstFlacParseClass * klass) baseparse_class->pre_push_frame = GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame); baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert); + baseparse_class->get_sink_caps = + GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps); } static void @@ -1425,3 +1428,36 @@ gst_flac_parse_convert (GstBaseParse * parse, return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format, src_value, dest_format, dest_value); } + +static GstCaps * +gst_flac_parse_get_sink_caps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Remove the framed field */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + gst_structure_remove_field (s, "framed"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From c114e7c073c5da7c46f06c6c908383f3b0f0d3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 09:59:40 +0100 Subject: [PATCH 08/26] mpegaudioparse: Implement ::get_sink_caps vfunc to propagate downstream caps constraints upstream --- gst/audioparsers/gstmpegaudioparse.c | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gst/audioparsers/gstmpegaudioparse.c b/gst/audioparsers/gstmpegaudioparse.c index d816fff438..25e373ccbc 100644 --- a/gst/audioparsers/gstmpegaudioparse.c +++ b/gst/audioparsers/gstmpegaudioparse.c @@ -100,6 +100,7 @@ static GstFlowReturn gst_mpeg_audio_parse_pre_push_frame (GstBaseParse * parse, static gboolean gst_mpeg_audio_parse_convert (GstBaseParse * parse, GstFormat src_format, gint64 src_value, GstFormat dest_format, gint64 * dest_value); +static GstCaps *gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse); GST_BOILERPLATE (GstMpegAudioParse, gst_mpeg_audio_parse, GstBaseParse, GST_TYPE_BASE_PARSE); @@ -177,6 +178,8 @@ gst_mpeg_audio_parse_class_init (GstMpegAudioParseClass * klass) parse_class->pre_push_frame = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_pre_push_frame); parse_class->convert = GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_convert); + parse_class->get_sink_caps = + GST_DEBUG_FUNCPTR (gst_mpeg_audio_parse_get_sink_caps); /* register tags */ #define GST_TAG_CRC "has-crc" @@ -1269,3 +1272,36 @@ gst_mpeg_audio_parse_pre_push_frame (GstBaseParse * parse, return GST_FLOW_OK; } + +static GstCaps * +gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Remove the parsed field */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + gst_structure_remove_field (s, "parsed"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + (parse))); + } + + return res; +} From 6204464735c32821fb47019a03fbf5280eb7751d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 24 Nov 2011 10:25:02 +0100 Subject: [PATCH 09/26] audioparse: Use the sinkpad template caps as fallback, not the srcpad ones --- gst/audioparsers/gstaacparse.c | 2 +- gst/audioparsers/gstac3parse.c | 2 +- gst/audioparsers/gstamrparse.c | 2 +- gst/audioparsers/gstdcaparse.c | 2 +- gst/audioparsers/gstflacparse.c | 2 +- gst/audioparsers/gstmpegaudioparse.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index 4f6bdd694f..0c62aa4b7d 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -743,7 +743,7 @@ gst_aac_parse_sink_getcaps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } diff --git a/gst/audioparsers/gstac3parse.c b/gst/audioparsers/gstac3parse.c index d7354eb1df..b9335f0899 100644 --- a/gst/audioparsers/gstac3parse.c +++ b/gst/audioparsers/gstac3parse.c @@ -692,7 +692,7 @@ gst_ac3_parse_get_sink_caps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index 90a65c4687..ddeac18007 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -424,7 +424,7 @@ gst_amr_parse_sink_getcaps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } diff --git a/gst/audioparsers/gstdcaparse.c b/gst/audioparsers/gstdcaparse.c index 14d313d534..64aef4ca6e 100644 --- a/gst/audioparsers/gstdcaparse.c +++ b/gst/audioparsers/gstdcaparse.c @@ -479,7 +479,7 @@ gst_dca_parse_get_sink_caps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c index 36db7c1700..dcfa3e89fe 100644 --- a/gst/audioparsers/gstflacparse.c +++ b/gst/audioparsers/gstflacparse.c @@ -1455,7 +1455,7 @@ gst_flac_parse_get_sink_caps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } diff --git a/gst/audioparsers/gstmpegaudioparse.c b/gst/audioparsers/gstmpegaudioparse.c index 25e373ccbc..f910c96b81 100644 --- a/gst/audioparsers/gstmpegaudioparse.c +++ b/gst/audioparsers/gstmpegaudioparse.c @@ -1299,7 +1299,7 @@ gst_mpeg_audio_parse_get_sink_caps (GstBaseParse * parse) gst_caps_unref (peercaps); } else { res = - gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse))); } From 852104b4eee0609ad62abc87ca6f014d1a4a63cd Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 31 Oct 2011 17:04:23 +0000 Subject: [PATCH 10/26] edgetv: don't leave bits of the output buffer uninitialized Let's initialize them to zero. It looks alright, but then it also looks alright with v3, or with the corresponding pixels from the source. I don't know what the original intent would be, and the original effectv source also has this bug/feature. https://bugzilla.gnome.org/show_bug.cgi?id=661841 --- gst/effectv/gstedge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst/effectv/gstedge.c b/gst/effectv/gstedge.c index f4b7762975..6b6b092075 100644 --- a/gst/effectv/gstedge.c +++ b/gst/effectv/gstedge.c @@ -189,8 +189,12 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) dest[width + 3] = v3; dest[width * 2] = v2; dest[width * 2 + 1] = v2; + dest[width * 2 + 2] = 0; + dest[width * 2 + 3] = 0; dest[width * 3] = v2; dest[width * 3 + 1] = v2; + dest[width * 3 + 2] = 0; + dest[width * 3 + 3] = 0; src += 4; dest += 4; From cbbabd6ccca6bdada309f42f1f8998dc1db94962 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 31 Oct 2011 17:06:18 +0000 Subject: [PATCH 11/26] edgetv: trivial comment fix for clarity https://bugzilla.gnome.org/show_bug.cgi?id=661841 --- gst/effectv/gstedge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/effectv/gstedge.c b/gst/effectv/gstedge.c index 6b6b092075..44f286784b 100644 --- a/gst/effectv/gstedge.c +++ b/gst/effectv/gstedge.c @@ -130,7 +130,7 @@ gst_edgetv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) p = *src; q = *(src - 4); - /* difference between the current pixel and right neighbor. */ + /* difference between the current pixel and left neighbor. */ r = ((p & 0xff0000) - (q & 0xff0000)) >> 16; g = ((p & 0xff00) - (q & 0xff00)) >> 8; b = (p & 0xff) - (q & 0xff); From b33da78f72ba610350582be852be417898cc9dd4 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 27 Sep 2011 16:49:45 +0100 Subject: [PATCH 12/26] wavparse: skip id32 tags This allows decoding at least one sample where something has stuffed some ID3 tag before the (supposedly initial) FMT\ . https://bugzilla.gnome.org/show_bug.cgi?id=660249 --- gst/wavparse/gstwavparse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index 5f8a789c4e..32ee58c5ae 100644 --- a/gst/wavparse/gstwavparse.c +++ b/gst/wavparse/gstwavparse.c @@ -1200,7 +1200,8 @@ gst_wavparse_stream_headers (GstWavParse * wav) if (tag == GST_RIFF_TAG_JUNK || tag == GST_RIFF_TAG_JUNQ || tag == GST_RIFF_TAG_bext || tag == GST_RIFF_TAG_BEXT || - tag == GST_RIFF_TAG_LIST) { + tag == GST_RIFF_TAG_LIST || tag == GST_RIFF_TAG_ID32 || + tag == GST_RIFF_TAG_IDVX) { GST_DEBUG_OBJECT (wav, "skipping %" GST_FOURCC_FORMAT " chunk", GST_FOURCC_ARGS (tag)); gst_buffer_unref (buf); From 3dc5a09a5cedfb1d323fc3c5359ea09046c5122c Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 24 Nov 2011 14:11:33 -0300 Subject: [PATCH 13/26] multifile: fix build of tests Tests fail to build because g_mkdtemp is available from glib since 2.26. This patch adds a condition around the redefinition of g_mkdtemp on the tests to only build it if glib is older than 2.26. --- tests/check/elements/multifile.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/check/elements/multifile.c b/tests/check/elements/multifile.c index 479e028b66..52ce2ceb87 100644 --- a/tests/check/elements/multifile.c +++ b/tests/check/elements/multifile.c @@ -40,19 +40,19 @@ run_pipeline (GstElement * pipeline) gst_element_set_state (pipeline, GST_STATE_NULL); } +#if !GLIB_CHECK_VERSION(2,26,0) static gchar * -g_mkdtemp (const gchar * template) +g_mkdtemp (gchar * template) { - gchar *s; gchar *tmpdir; - s = g_strdup (template); - tmpdir = mkdtemp (s); + tmpdir = mkdtemp (template); if (tmpdir == NULL) { - g_free (s); + g_free (template); } return tmpdir; } +#endif GST_START_TEST (test_multifilesink_key_frame) { @@ -93,7 +93,6 @@ GST_START_TEST (test_multifilesink_key_frame) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; @@ -144,7 +143,6 @@ GST_START_TEST (test_multifilesink_max_files) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; @@ -202,7 +200,6 @@ GST_START_TEST (test_multifilesrc) g_free (mfs_pattern); g_free (my_tmpdir); - g_free (template); } GST_END_TEST; From 230ce4367f5f1ca7b4d3449a8d641c92d4a824c3 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 24 Nov 2011 14:14:53 -0300 Subject: [PATCH 14/26] multifilesink: Fix leak of filename strings Do not forget to free the filename strings when deleting the list of files. --- gst/multifile/gstmultifilesink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gst/multifile/gstmultifilesink.c b/gst/multifile/gstmultifilesink.c index 4d454e6209..2a1e57961f 100644 --- a/gst/multifile/gstmultifilesink.c +++ b/gst/multifile/gstmultifilesink.c @@ -594,6 +594,7 @@ gst_multi_file_sink_ensure_max_files (GstMultiFileSink * multifilesink) multifilesink->n_files >= multifilesink->max_files) { filename = multifilesink->files->data; g_remove (filename); + g_free (filename); multifilesink->files = g_slist_delete_link (multifilesink->files, multifilesink->files); multifilesink->n_files -= 1; From b6de7baeb66adff655d04a66d81ab93166735f2f Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 24 Nov 2011 20:42:49 +0100 Subject: [PATCH 15/26] effecttv: fix reverse negotiation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugins were using _fixed_caps_ and thus not adjusting to new upstream sizes. Spotted by Tim Müller. --- gst/effectv/gstquark.c | 3 --- gst/effectv/gststreak.c | 3 --- gst/effectv/gstvertigo.c | 3 --- gst/effectv/gstwarp.c | 3 +-- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/gst/effectv/gstquark.c b/gst/effectv/gstquark.c index 3b307f22bf..fc31e95eb7 100644 --- a/gst/effectv/gstquark.c +++ b/gst/effectv/gstquark.c @@ -306,7 +306,4 @@ gst_quarktv_init (GstQuarkTV * filter, GstQuarkTVClass * klass) { filter->planes = PLANES; filter->current_plane = filter->planes - 1; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gststreak.c b/gst/effectv/gststreak.c index bdda54df7f..9816a50f32 100644 --- a/gst/effectv/gststreak.c +++ b/gst/effectv/gststreak.c @@ -276,7 +276,4 @@ static void gst_streaktv_init (GstStreakTV * filter, GstStreakTVClass * klass) { filter->feedback = DEFAULT_FEEDBACK; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstvertigo.c b/gst/effectv/gstvertigo.c index 2f7ac7c911..d38aab338f 100644 --- a/gst/effectv/gstvertigo.c +++ b/gst/effectv/gstvertigo.c @@ -325,7 +325,4 @@ gst_vertigotv_init (GstVertigoTV * filter, GstVertigoTVClass * klass) filter->phase = 0.0; filter->phase_increment = 0.02; filter->zoomrate = 1.01; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstwarp.c b/gst/effectv/gstwarp.c index e5eb7580af..068301c24c 100644 --- a/gst/effectv/gstwarp.c +++ b/gst/effectv/gstwarp.c @@ -288,6 +288,5 @@ gst_warptv_class_init (GstWarpTVClass * klass) static void gst_warptv_init (GstWarpTV * warptv, GstWarpTVClass * klass) { - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (warptv)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (warptv)); + /* nothing to do */ } From f0fe717cd9e31d15e0c9862870730181cc8e91ad Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 25 Nov 2011 10:15:35 +0100 Subject: [PATCH 16/26] rippletv: clean up the rendering code a bit This is corrrupts the memoy when resizing. Add a FIXME to make it resizeable once that is solved. --- gst/effectv/gstripple.c | 93 +++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/gst/effectv/gstripple.c b/gst/effectv/gstripple.c index e002ad1bd6..ce95e54ca9 100644 --- a/gst/effectv/gstripple.c +++ b/gst/effectv/gstripple.c @@ -312,9 +312,9 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, guint32 *src, *dest; GstFlowReturn ret = GST_FLOW_OK; gint x, y, i; - gint dx, dy; + gint dx, dy, o_dx; gint h, v; - gint width, height; + gint m_w, m_h, v_w, v_h; gint *p, *q, *r; gint8 *vp; GstClockTime timestamp, stream_time; @@ -339,22 +339,24 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, else motiondetect (filter, src); + m_w = filter->map_w; + m_h = filter->map_h; + v_w = filter->width; + v_h = filter->height; + /* simulate surface wave */ - width = filter->map_w; - height = filter->map_h; /* This function is called only 30 times per second. To increase a speed * of wave, iterates this loop several times. */ for (i = loopnum; i > 0; i--) { /* wave simulation */ - p = filter->map1 + width + 1; - q = filter->map2 + width + 1; - r = filter->map3 + width + 1; - for (y = height - 2; y > 0; y--) { - for (x = width - 2; x > 0; x--) { - h = *(p - width - 1) + *(p - width + 1) + *(p + width - 1) + *(p + - width + 1) - + *(p - width) + *(p - 1) + *(p + 1) + *(p + width) - (*p) * 9; + p = filter->map1 + m_w + 1; + q = filter->map2 + m_w + 1; + r = filter->map3 + m_w + 1; + for (y = m_h - 2; y > 0; y--) { + for (x = m_w - 2; x > 0; x--) { + h = *(p - m_w - 1) + *(p - m_w + 1) + *(p + m_w - 1) + *(p + m_w + 1) + + *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) - (*p) * 9; h = h >> 3; v = *p - *q; v += h - (v >> decay); @@ -369,11 +371,11 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, } /* low pass filter */ - p = filter->map3 + width + 1; - q = filter->map2 + width + 1; - for (y = height - 2; y > 0; y--) { - for (x = width - 2; x > 0; x--) { - h = *(p - width) + *(p - 1) + *(p + 1) + *(p + width) + (*p) * 60; + p = filter->map3 + m_w + 1; + q = filter->map2 + m_w + 1; + for (y = m_h - 2; y > 0; y--) { + for (x = m_w - 2; x > 0; x--) { + h = *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) + (*p) * 60; *q = h >> 6; p++; q++; @@ -389,12 +391,12 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, vp = filter->vtable; p = filter->map1; - for (y = height - 1; y > 0; y--) { - for (x = width - 1; x > 0; x--) { + for (y = m_h - 1; y > 0; y--) { + for (x = m_w - 1; x > 0; x--) { /* difference of the height between two voxel. They are twiced to * emphasise the wave. */ vp[0] = sqrtable[((p[0] - p[1]) >> (point - 1)) & 0xff]; - vp[1] = sqrtable[((p[0] - p[width]) >> (point - 1)) & 0xff]; + vp[1] = sqrtable[((p[0] - p[m_w]) >> (point - 1)) & 0xff]; p++; vp += 2; } @@ -402,48 +404,34 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in, vp += 2; } - height = filter->height; - width = filter->width; vp = filter->vtable; /* draw refracted image. The vector table is stretched. */ - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { + for (y = 0; y < v_h; y += 2) { + for (x = 0; x < v_w; x += 2) { h = (gint) vp[0]; v = (gint) vp[1]; dx = x + h; dy = y + v; - if (dx < 0) - dx = 0; - if (dy < 0) - dy = 0; - if (dx >= width) - dx = width - 1; - if (dy >= height) - dy = height - 1; - dest[0] = src[dy * width + dx]; + dx = CLAMP (dx, 0, (v_w - 1)); + dy = CLAMP (dy, 0, (v_h - 1)); + dest[0] = src[dy * v_w + dx]; - i = dx; + o_dx = dx; dx = x + 1 + (h + (gint) vp[2]) / 2; - if (dx < 0) - dx = 0; - if (dx >= width) - dx = width - 1; - dest[1] = src[dy * width + dx]; + dx = CLAMP (dx, 0, (v_w - 1)); + dest[1] = src[dy * v_w + dx]; - dy = y + 1 + (v + (gint) vp[filter->map_w * 2 + 1]) / 2; - if (dy < 0) - dy = 0; - if (dy >= height) - dy = height - 1; - dest[width] = src[dy * width + i]; + dy = y + 1 + (v + (gint) vp[m_w * 2 + 1]) / 2; + dy = CLAMP (dy, 0, (v_h - 1)); + dest[v_w] = src[dy * v_w + o_dx]; - dest[width + 1] = src[dy * width + dx]; + dest[v_w + 1] = src[dy * v_w + dx]; dest += 2; vp += 2; } - dest += filter->width; + dest += v_w; vp += 2; } GST_OBJECT_UNLOCK (filter); @@ -468,9 +456,11 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, filter->map_h = filter->height / 2 + 1; filter->map_w = filter->width / 2 + 1; + /* we over allocate the buffers, as the render code does not handle clipping + * very well */ if (filter->map) g_free (filter->map); - filter->map = g_new0 (gint, filter->map_h * filter->map_w * 3); + filter->map = g_new0 (gint, (1 + filter->map_h) * filter->map_w * 3); filter->map1 = filter->map; filter->map2 = filter->map + filter->map_w * filter->map_h; @@ -478,15 +468,15 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, if (filter->vtable) g_free (filter->vtable); - filter->vtable = g_new0 (gint8, filter->map_h * filter->map_w * 2); + filter->vtable = g_new0 (gint8, (1 + filter->map_h) * filter->map_w * 2); if (filter->background) g_free (filter->background); - filter->background = g_new0 (gint16, filter->width * filter->height); + filter->background = g_new0 (gint16, filter->width * (filter->height + 1)); if (filter->diff) g_free (filter->diff); - filter->diff = g_new0 (guint8, filter->width * filter->height); + filter->diff = g_new0 (guint8, filter->width * (filter->height + 1)); ret = TRUE; } @@ -626,6 +616,7 @@ gst_rippletv_init (GstRippleTV * filter, GstRippleTVClass * klass) { filter->mode = DEFAULT_MODE; + /* FIXME: remove this when memory corruption after resizes are fixed */ gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } From 5d03d653495b137d59b5de8930ef8dfd6f2de307 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 25 Nov 2011 11:43:16 +0100 Subject: [PATCH 17/26] warptv: remove not needed ifdef --- gst/effectv/gstwarp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gst/effectv/gstwarp.c b/gst/effectv/gstwarp.c index 068301c24c..d10cca7720 100644 --- a/gst/effectv/gstwarp.c +++ b/gst/effectv/gstwarp.c @@ -144,11 +144,7 @@ initDistTable (GstWarpTV * filter) { gint32 halfw, halfh, *distptr; gint x, y; -#ifdef PS2 float m; -#else - float m; -#endif halfw = filter->width >> 1; halfh = filter->height >> 1; From 3295482afd6eca49b20d321db2ad98aab6f40185 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 25 Nov 2011 11:44:18 +0100 Subject: [PATCH 18/26] effecttv: fix reverse negotiation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugins were using _fixed_caps_ and thus not adjusting to new upstream sizes. Spotted by Tim Müller. --- gst/effectv/gstradioac.c | 3 --- gst/effectv/gstshagadelic.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/gst/effectv/gstradioac.c b/gst/effectv/gstradioac.c index 58c1b7b9e8..3db06c5e5c 100644 --- a/gst/effectv/gstradioac.c +++ b/gst/effectv/gstradioac.c @@ -616,7 +616,4 @@ gst_radioactv_init (GstRadioacTV * filter, GstRadioacTVClass * klass) filter->color = DEFAULT_COLOR; filter->interval = DEFAULT_INTERVAL; filter->trigger = DEFAULT_TRIGGER; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } diff --git a/gst/effectv/gstshagadelic.c b/gst/effectv/gstshagadelic.c index 650a563d3e..5a07242366 100644 --- a/gst/effectv/gstshagadelic.c +++ b/gst/effectv/gstshagadelic.c @@ -267,7 +267,4 @@ gst_shagadelictv_init (GstShagadelicTV * filter, GstShagadelicTVClass * klass) { filter->ripple = NULL; filter->spiral = NULL; - - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter)); - gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); } From c1d38ea8d4b8bbd12b031f9a1d422788da79d93c Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 25 Nov 2011 11:44:49 +0100 Subject: [PATCH 19/26] radioactv: add one more set of caps It also work in this format. Avoids the need for conversion. --- gst/effectv/gstradioac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/effectv/gstradioac.c b/gst/effectv/gstradioac.c index 3db06c5e5c..fc3f9afc5e 100644 --- a/gst/effectv/gstradioac.c +++ b/gst/effectv/gstradioac.c @@ -139,9 +139,9 @@ GST_BOILERPLATE (GstRadioacTV, gst_radioactv, GstVideoFilter, GST_TYPE_VIDEO_FILTER); #if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define CAPS_STR GST_VIDEO_CAPS_RGBx +#define CAPS_STR GST_VIDEO_CAPS_RGBx "; " GST_VIDEO_CAPS_BGRx #else -#define CAPS_STR GST_VIDEO_CAPS_xBGR +#define CAPS_STR GST_VIDEO_CAPS_xBGR "; " GST_VIDEO_CAPS_xRGB #endif static GstStaticPadTemplate gst_radioactv_src_template = From ebefb140b99ac169babb3a3e18fe11f20524bec1 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Fri, 25 Nov 2011 13:13:47 +0100 Subject: [PATCH 20/26] effectv: repair color modes in radioactv by taking rgb,bgr into account --- gst/effectv/gstradioac.c | 27 ++++++++++++++++++++------- gst/effectv/gstradioac.h | 2 ++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/gst/effectv/gstradioac.c b/gst/effectv/gstradioac.c index fc3f9afc5e..9886d569f9 100644 --- a/gst/effectv/gstradioac.c +++ b/gst/effectv/gstradioac.c @@ -134,6 +134,7 @@ enum #define RATIO 0.95 static guint32 palettes[COLORS * PATTERN]; +static gint swap_tab[] = { 2, 1, 0, 3 }; GST_BOILERPLATE (GstRadioacTV, gst_radioactv, GstVideoFilter, GST_TYPE_VIDEO_FILTER); @@ -165,18 +166,20 @@ makePalette (void) #define DELTA (255/(COLORS/2-1)) + /* red, gree, blue */ for (i = 0; i < COLORS / 2; i++) { palettes[i] = i * DELTA; palettes[COLORS + i] = (i * DELTA) << 8; palettes[COLORS * 2 + i] = (i * DELTA) << 16; } for (i = 0; i < COLORS / 2; i++) { - palettes[+i + COLORS / 2] = 255 | (i * DELTA) << 16 | (i * DELTA) << 8; + palettes[i + COLORS / 2] = 255 | (i * DELTA) << 16 | (i * DELTA) << 8; palettes[COLORS + i + COLORS / 2] = (255 << 8) | (i * DELTA) << 16 | i * DELTA; palettes[COLORS * 2 + i + COLORS / 2] = (255 << 16) | (i * DELTA) << 8 | i * DELTA; } + /* white */ for (i = 0; i < COLORS; i++) { palettes[COLORS * 3 + i] = (255 * i / COLORS) * 0x10101; } @@ -341,7 +344,19 @@ gst_radioactv_transform (GstBaseTransform * trans, GstBuffer * in, dest = (guint32 *) GST_BUFFER_DATA (out); GST_OBJECT_LOCK (filter); - palette = &palettes[COLORS * filter->color]; +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + if (filter->format == GST_VIDEO_FORMAT_RGBx) { + palette = &palettes[COLORS * filter->color]; + } else { + palette = &palettes[COLORS * swap_tab[filter->color]]; + } +#else + if (filter->format == GST_VIDEO_FORMAT_xBGR) { + palette = &palettes[COLORS * filter->color]; + } else { + palette = &palettes[COLORS * swap_tab[filter->color]]; + } +#endif diff = filter->diff; if (filter->mode == 3 && filter->trigger) @@ -405,14 +420,12 @@ gst_radioactv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, GstCaps * outcaps) { GstRadioacTV *filter = GST_RADIOACTV (btrans); - GstStructure *structure; gboolean ret = FALSE; - structure = gst_caps_get_structure (incaps, 0); - GST_OBJECT_LOCK (filter); - if (gst_structure_get_int (structure, "width", &filter->width) && - gst_structure_get_int (structure, "height", &filter->height)) { + + if (gst_video_format_parse_caps (incaps, &filter->format, &filter->width, + &filter->height)) { filter->buf_width_blocks = filter->width / 32; if (filter->buf_width_blocks > 255) goto out; diff --git a/gst/effectv/gstradioac.h b/gst/effectv/gstradioac.h index 34ad8ed721..64a425d113 100644 --- a/gst/effectv/gstradioac.h +++ b/gst/effectv/gstradioac.h @@ -29,6 +29,7 @@ #include +#include #include G_BEGIN_DECLS @@ -53,6 +54,7 @@ struct _GstRadioacTV /* < private > */ gint width, height; + GstVideoFormat format; gint mode; gint color; From 21d3faa40070b2ddc10a1c572bd4d4a7dd28af39 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 24 Nov 2011 16:31:38 +0000 Subject: [PATCH 21/26] flvdemux: fix seeking Which I accidentally broke when fixing flv videos breaking on spurious timestamp discontinuities in broken files. https://bugzilla.gnome.org/show_bug.cgi?id=631430 --- gst/flv/gstflvdemux.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gst/flv/gstflvdemux.c b/gst/flv/gstflvdemux.c index 7d3c992fe1..6e95f95c57 100644 --- a/gst/flv/gstflvdemux.c +++ b/gst/flv/gstflvdemux.c @@ -763,10 +763,10 @@ gst_flv_demux_push_tags (GstFlvDemux * demux) } static void -gst_flv_demux_update_resync (GstFlvDemux * demux, guint32 pts, guint32 * last, - GstClockTime * offset) +gst_flv_demux_update_resync (GstFlvDemux * demux, guint32 pts, gboolean discont, + guint32 * last, GstClockTime * offset) { - if (ABS (pts - *last) >= RESYNC_THRESHOLD) { + if (!discont && ABS (pts - *last) >= RESYNC_THRESHOLD) { /* Theoretically, we should use substract the duration of the last buffer, but this demuxer sends no durations on buffers, not sure if it cannot know, or just does not care to calculate. */ @@ -966,8 +966,8 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer) } /* detect (and deem to be resyncs) large pts gaps */ - gst_flv_demux_update_resync (demux, pts, &demux->last_audio_pts, - &demux->audio_time_offset); + gst_flv_demux_update_resync (demux, pts, demux->audio_need_discont, + &demux->last_audio_pts, &demux->audio_time_offset); /* Fill buffer with data */ GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->audio_time_offset; @@ -1338,8 +1338,8 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer) } /* detect (and deem to be resyncs) large pts gaps */ - gst_flv_demux_update_resync (demux, pts, &demux->last_video_pts, - &demux->video_time_offset); + gst_flv_demux_update_resync (demux, pts, demux->video_need_discont, + &demux->last_video_pts, &demux->video_time_offset); /* Fill buffer with data */ GST_BUFFER_TIMESTAMP (outbuf) = pts * GST_MSECOND + demux->video_time_offset; From f6f16054681ccb52689f95712f32f974abe7164a Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 14 Nov 2011 12:41:41 +0530 Subject: [PATCH 22/26] pulseaudiosink: Clean up refcounting in event probe Makes sure we don't leak a refcount if the object is disposed before a NEWSEGMENT turns up. --- ext/pulse/pulseaudiosink.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/pulse/pulseaudiosink.c b/ext/pulse/pulseaudiosink.c index a16a6ad184..1aa806dfa6 100644 --- a/ext/pulse/pulseaudiosink.c +++ b/ext/pulse/pulseaudiosink.c @@ -537,7 +537,6 @@ dbin2_event_probe (GstPad * pad, GstMiniObject * obj, gpointer data) if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) { GST_DEBUG_OBJECT (pbin, "Got newsegment - dropping"); gst_pad_remove_event_probe (pad, pbin->event_probe_id); - gst_object_unref (pbin); return FALSE; } @@ -596,8 +595,9 @@ gst_pulse_audio_sink_add_dbin2 (GstPulseAudioSink * pbin) /* Trap the newsegment events that we feed the decodebin and discard them */ sinkpad = gst_element_get_static_pad (GST_ELEMENT (pbin->psink), "sink"); - pbin->event_probe_id = gst_pad_add_event_probe (sinkpad, - G_CALLBACK (dbin2_event_probe), gst_object_ref (pbin)); + pbin->event_probe_id = gst_pad_add_event_probe_full (sinkpad, + G_CALLBACK (dbin2_event_probe), gst_object_ref (pbin), + (GDestroyNotify) gst_object_unref); gst_object_unref (sinkpad); sinkpad = NULL; From bdf95eb39b45f377072a66fb883cb1593dee274e Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 14 Nov 2011 12:43:27 +0530 Subject: [PATCH 23/26] pulseaudiosink: Remove redundant code --- ext/pulse/pulseaudiosink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pulse/pulseaudiosink.c b/ext/pulse/pulseaudiosink.c index 1aa806dfa6..0b2e4b8492 100644 --- a/ext/pulse/pulseaudiosink.c +++ b/ext/pulse/pulseaudiosink.c @@ -546,7 +546,7 @@ dbin2_event_probe (GstPad * pad, GstMiniObject * obj, gpointer data) static void pad_added_cb (GstElement * dbin2, GstPad * pad, gpointer * data) { - GstPulseAudioSink *pbin = GST_PULSE_AUDIO_SINK (data); + GstPulseAudioSink *pbin; GstPad *sinkpad = NULL; pbin = GST_PULSE_AUDIO_SINK (data); From 8c6a5486987fd3bc03e13b5540a9e71ee7b89d0d Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Sat, 10 Sep 2011 21:21:38 -0700 Subject: [PATCH 24/26] pulsesrc: Trivial comment copy-paste-o fix --- ext/pulse/pulsesrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c index da3ae24771..d2d60a9c52 100644 --- a/ext/pulse/pulsesrc.c +++ b/ext/pulse/pulsesrc.c @@ -251,7 +251,7 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass) clientname = gst_pulse_client_name (); /** - * GstPulseSink:client + * GstPulseSrc:client * * The PulseAudio client name to use. * From 1f4bb687940f87a05a43cac1fcb074afac9cd7f8 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Thu, 24 Nov 2011 12:05:33 +0530 Subject: [PATCH 25/26] pulsesrc: Implement GstStreamVolume interface PulseAudio 1.0 supports per-source-output volumes, and this exposes the functionality via the GstStreamVolume interface. When compiled against pre-1.0 PulseAudio, the interface is not implemented, and the "volume" or "mute" properties are not available. This bit of ugliness will go away when we can depend on PulseAudio 1.0 or greater. https://bugzilla.gnome.org/show_bug.cgi?id=595055 --- ext/pulse/pulsesrc.c | 416 ++++++++++++++++++++++++++++++++++++++++++- ext/pulse/pulsesrc.h | 9 + 2 files changed, 422 insertions(+), 3 deletions(-) diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c index d2d60a9c52..b424a6a841 100644 --- a/ext/pulse/pulsesrc.c +++ b/ext/pulse/pulsesrc.c @@ -43,6 +43,9 @@ #include #include +#ifdef HAVE_PULSE_1_0 +#include +#endif #include "pulsesrc.h" #include "pulseutil.h" @@ -55,6 +58,12 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug); #define DEFAULT_DEVICE NULL #define DEFAULT_DEVICE_NAME NULL +#ifdef HAVE_PULSE_1_0 +#define DEFAULT_VOLUME 1.0 +#define DEFAULT_MUTE FALSE +#define MAX_VOLUME 10.0 +#endif + enum { PROP_0, @@ -64,6 +73,10 @@ enum PROP_CLIENT, PROP_STREAM_PROPERTIES, PROP_SOURCE_OUTPUT_INDEX, +#ifdef HAVE_PULSE_1_0 + PROP_VOLUME, + PROP_MUTE, +#endif PROP_LAST }; @@ -121,6 +134,11 @@ gst_pulsesrc_interface_supported (GstImplementsInterface * if (interface_type == GST_TYPE_PROPERTY_PROBE && this->probe) return TRUE; +#ifdef HAVE_PULSE_1_0 + if (interface_type == GST_TYPE_STREAM_VOLUME) + return TRUE; +#endif + return FALSE; } @@ -133,6 +151,11 @@ gst_pulsesrc_implements_interface_init (GstImplementsInterfaceClass * klass) static void gst_pulsesrc_init_interfaces (GType type) { +#ifdef HAVE_PULSE_1_0 + static const GInterfaceInfo svol_iface_info = { + NULL, NULL, NULL, + }; +#endif static const GInterfaceInfo implements_iface_info = { (GInterfaceInitFunc) gst_pulsesrc_implements_interface_init, NULL, @@ -149,6 +172,9 @@ gst_pulsesrc_init_interfaces (GType type) NULL, }; +#ifdef HAVE_PULSE_1_0 + g_type_add_interface_static (type, GST_TYPE_STREAM_VOLUME, &svol_iface_info); +#endif g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, &implements_iface_info); g_type_add_interface_static (type, GST_TYPE_MIXER, &mixer_iface_info); @@ -301,6 +327,35 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass) "The index of the PulseAudio source output corresponding to this " "record stream", 0, G_MAXUINT, PA_INVALID_INDEX, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + +#ifdef HAVE_PULSE_1_0 + /** + * GstPulseSrc:volume + * + * The volume of the record stream. Only works when using PulseAudio 1.0 or + * later. + * + * Since: 0.10.36 + */ + g_object_class_install_property (gobject_class, + PROP_VOLUME, g_param_spec_double ("volume", "Volume", + "Linear volume of this stream, 1.0=100%", + 0.0, MAX_VOLUME, DEFAULT_VOLUME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstPulseSrc:mute + * + * Whether the stream is muted or not. Only works when using PulseAudio 1.0 + * or later. + * + * Since: 0.10.36 + */ + g_object_class_install_property (gobject_class, + PROP_MUTE, g_param_spec_boolean ("mute", "Mute", + "Mute state of this stream", + DEFAULT_MUTE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif } static void @@ -324,6 +379,16 @@ gst_pulsesrc_init (GstPulseSrc * pulsesrc, GstPulseSrcClass * klass) pulsesrc->paused = FALSE; pulsesrc->in_read = FALSE; +#ifdef HAVE_PULSE_1_0 + pulsesrc->volume = DEFAULT_VOLUME; + pulsesrc->volume_set = FALSE; + + pulsesrc->mute = DEFAULT_MUTE; + pulsesrc->mute_set = FALSE; + + pulsesrc->notify = 0; +#endif + pulsesrc->mixer = NULL; pulsesrc->properties = NULL; @@ -359,7 +424,15 @@ gst_pulsesrc_destroy_context (GstPulseSrc * pulsesrc) if (pulsesrc->context) { pa_context_disconnect (pulsesrc->context); + + /* Make sure we don't get any further callbacks */ + pa_context_set_state_callback (pulsesrc->context, NULL, NULL); +#ifdef HAVE_PULSE_1_0 + pa_context_set_subscribe_callback (pulsesrc->context, NULL, NULL); +#endif + pa_context_unref (pulsesrc->context); + pulsesrc->context = NULL; } } @@ -477,6 +550,260 @@ no_mainloop: } } +#ifdef HAVE_PULSE_1_0 +static void +gst_pulsesrc_source_output_info_cb (pa_context * c, + const pa_source_output_info * i, int eol, void *userdata) +{ + GstPulseSrc *psrc; + + psrc = GST_PULSESRC_CAST (userdata); + + if (!i) + goto done; + + /* If the index doesn't match our current stream, + * it implies we just recreated the stream (caps change) + */ + if (i->index == psrc->source_output_idx) { + psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume)); + psrc->mute = i->mute; + } + +done: + pa_threaded_mainloop_signal (psrc->mainloop, 0); +} + +static gdouble +gst_pulsesrc_get_stream_volume (GstPulseSrc * pulsesrc) +{ + pa_operation *o = NULL; + gdouble v; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (pulsesrc->source_output_idx == PA_INVALID_INDEX) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + if (!(o = pa_context_get_source_output_info (pulsesrc->context, + pulsesrc->source_output_idx, gst_pulsesrc_source_output_info_cb, + pulsesrc))) + goto info_failed; + + while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait (pulsesrc->mainloop); + if (gst_pulsesrc_is_dead (pulsesrc, TRUE)) + goto unlock; + } + +unlock: + v = pulsesrc->volume; + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + if (v > MAX_VOLUME) { + GST_WARNING_OBJECT (pulsesrc, "Clipped volume from %f to %f", v, + MAX_VOLUME); + v = MAX_VOLUME; + } + + return v; + + /* ERRORS */ +no_mainloop: + { + v = pulsesrc->volume; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return v; + } +no_index: + { + v = pulsesrc->volume; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return v; + } +info_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_get_source_output_info() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static gboolean +gst_pulsesrc_get_stream_mute (GstPulseSrc * pulsesrc) +{ + pa_operation *o = NULL; + gboolean mute; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (pulsesrc->source_output_idx == PA_INVALID_INDEX) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + if (!(o = pa_context_get_source_output_info (pulsesrc->context, + pulsesrc->source_output_idx, gst_pulsesrc_source_output_info_cb, + pulsesrc))) + goto info_failed; + + while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { + pa_threaded_mainloop_wait (pulsesrc->mainloop); + if (gst_pulsesrc_is_dead (pulsesrc, TRUE)) + goto unlock; + } + +unlock: + mute = pulsesrc->mute; + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return mute; + + /* ERRORS */ +no_mainloop: + { + mute = pulsesrc->mute; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return mute; + } +no_index: + { + mute = pulsesrc->mute; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return mute; + } +info_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_get_source_output_info() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static void +gst_pulsesrc_set_stream_volume (GstPulseSrc * pulsesrc, gdouble volume) +{ + pa_cvolume v; + pa_operation *o = NULL; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (!pulsesrc->source_output_idx) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + GST_DEBUG_OBJECT (pulsesrc, "setting volume to %f", volume); + + gst_pulse_cvolume_from_linear (&v, pulsesrc->sample_spec.channels, volume); + + if (!(o = pa_context_set_source_output_volume (pulsesrc->context, + pulsesrc->source_output_idx, &v, NULL, NULL))) + goto volume_failed; + + /* We don't really care about the result of this call */ +unlock: + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return; + + /* ERRORS */ +no_mainloop: + { + pulsesrc->volume = volume; + pulsesrc->volume_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return; + } +no_index: + { + pulsesrc->volume = volume; + pulsesrc->volume_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return; + } +volume_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_stream_set_source_output_volume() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} + +static void +gst_pulsesrc_set_stream_mute (GstPulseSrc * pulsesrc, gboolean mute) +{ + pa_operation *o = NULL; + + if (!pulsesrc->mainloop) + goto no_mainloop; + + if (!pulsesrc->source_output_idx) + goto no_index; + + pa_threaded_mainloop_lock (pulsesrc->mainloop); + + GST_DEBUG_OBJECT (pulsesrc, "setting mute state to %d", mute); + + if (!(o = pa_context_set_source_output_mute (pulsesrc->context, + pulsesrc->source_output_idx, mute, NULL, NULL))) + goto mute_failed; + + /* We don't really care about the result of this call */ +unlock: + + if (o) + pa_operation_unref (o); + + pa_threaded_mainloop_unlock (pulsesrc->mainloop); + + return; + + /* ERRORS */ +no_mainloop: + { + pulsesrc->mute = mute; + pulsesrc->mute_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we have no mainloop"); + return; + } +no_index: + { + pulsesrc->mute = mute; + pulsesrc->mute_set = TRUE; + GST_DEBUG_OBJECT (pulsesrc, "we don't have a stream index"); + return; + } +mute_failed: + { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_stream_set_source_output_mute() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock; + } +} +#endif + static void gst_pulsesrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -513,6 +840,14 @@ gst_pulsesrc_set_property (GObject * object, pa_proplist_free (pulsesrc->proplist); pulsesrc->proplist = gst_pulse_make_proplist (pulsesrc->properties); break; +#ifdef HAVE_PULSE_1_0 + case PROP_VOLUME: + gst_pulsesrc_set_stream_volume (pulsesrc, g_value_get_double (value)); + break; + case PROP_MUTE: + gst_pulsesrc_set_stream_mute (pulsesrc, g_value_get_boolean (value)); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -545,6 +880,14 @@ gst_pulsesrc_get_property (GObject * object, case PROP_SOURCE_OUTPUT_INDEX: g_value_set_uint (value, pulsesrc->source_output_idx); break; +#ifdef HAVE_PULSE_1_0 + case PROP_VOLUME: + g_value_set_double (value, gst_pulsesrc_get_stream_volume (pulsesrc)); + break; + case PROP_MUTE: + g_value_set_boolean (value, gst_pulsesrc_get_stream_mute (pulsesrc)); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -638,6 +981,30 @@ gst_pulsesrc_stream_overflow_cb (pa_stream * s, void *userdata) GST_WARNING_OBJECT (GST_PULSESRC_CAST (userdata), "Got overflow"); } +#ifdef HAVE_PULSE_1_0 +static void +gst_pulsesrc_context_subscribe_cb (pa_context * c, + pa_subscription_event_type_t t, uint32_t idx, void *userdata) +{ + GstPulseSrc *psrc = GST_PULSESRC (userdata); + + if (t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_CHANGE) + && t != (PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT | PA_SUBSCRIPTION_EVENT_NEW)) + return; + + if (idx != psrc->source_output_idx) + return; + + /* Actually this event is also triggered when other properties of the stream + * change that are unrelated to the volume. However it is probably cheaper to + * signal the change here and check for the volume when the GObject property + * is read instead of querying it always. */ + + /* inform streaming thread to notify */ + g_atomic_int_compare_and_exchange (&psrc->notify, 0, 1); +} +#endif + static gboolean gst_pulsesrc_open (GstAudioSrc * asrc) { @@ -660,6 +1027,10 @@ gst_pulsesrc_open (GstAudioSrc * asrc) pa_context_set_state_callback (pulsesrc->context, gst_pulsesrc_context_state_cb, pulsesrc); +#ifdef HAVE_PULSE_1_0 + pa_context_set_subscribe_callback (pulsesrc->context, + gst_pulsesrc_context_subscribe_cb, pulsesrc); +#endif GST_DEBUG_OBJECT (pulsesrc, "connect to server %s", GST_STR_NULL (pulsesrc->server)); @@ -741,6 +1112,13 @@ gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length) pa_threaded_mainloop_lock (pulsesrc->mainloop); pulsesrc->in_read = TRUE; +#ifdef HAVE_PULSE_1_0 + if (g_atomic_int_compare_and_exchange (&pulsesrc->notify, 1, 0)) { + g_object_notify (G_OBJECT (pulsesrc), "volume"); + g_object_notify (G_OBJECT (pulsesrc), "mute"); + } +#endif + if (pulsesrc->paused) goto was_paused; @@ -1040,9 +1418,27 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) pa_buffer_attr wanted; const pa_buffer_attr *actual; GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc); + pa_stream_flags_t flags; +#ifdef HAVE_PULSE_1_0 + pa_operation *o; +#endif pa_threaded_mainloop_lock (pulsesrc->mainloop); +#ifdef HAVE_PULSE_1_0 + /* enable event notifications */ + GST_LOG_OBJECT (pulsesrc, "subscribing to context events"); + if (!(o = pa_context_subscribe (pulsesrc->context, + PA_SUBSCRIPTION_MASK_SINK_INPUT, NULL, NULL))) { + GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, + ("pa_context_subscribe() failed: %s", + pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); + goto unlock_and_fail; + } + + pa_operation_unref (o); +#endif + wanted.maxlength = -1; wanted.tlength = -1; wanted.prebuf = 0; @@ -1055,10 +1451,17 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) GST_INFO_OBJECT (pulsesrc, "minreq: %d", wanted.minreq); GST_INFO_OBJECT (pulsesrc, "fragsize: %d", wanted.fragsize); + flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | + PA_STREAM_NOT_MONOTONIC | PA_STREAM_ADJUST_LATENCY | + PA_STREAM_START_CORKED; + +#ifdef HAVE_PULSE_1_0 + if (pulsesrc->mute_set && pulsesrc->mute) + flags |= PA_STREAM_START_MUTED; +#endif + if (pa_stream_connect_record (pulsesrc->stream, pulsesrc->device, &wanted, - PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | - PA_STREAM_NOT_MONOTONIC | PA_STREAM_ADJUST_LATENCY | - PA_STREAM_START_CORKED) < 0) { + flags) < 0) { GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect stream: %s", pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); @@ -1090,6 +1493,13 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) pulsesrc->source_output_idx = pa_stream_get_index (pulsesrc->stream); g_object_notify (G_OBJECT (pulsesrc), "source-output-index"); +#ifdef HAVE_PULSE_1_0 + if (pulsesrc->volume_set) { + gst_pulsesrc_set_stream_volume (pulsesrc, pulsesrc->volume); + pulsesrc->volume_set = FALSE; + } +#endif + /* get the actual buffering properties now */ actual = pa_stream_get_buffer_attr (pulsesrc->stream); diff --git a/ext/pulse/pulsesrc.h b/ext/pulse/pulsesrc.h index a308afd334..655417f1dd 100644 --- a/ext/pulse/pulsesrc.h +++ b/ext/pulse/pulsesrc.h @@ -72,6 +72,15 @@ struct _GstPulseSrc GstPulseMixerCtrl *mixer; GstPulseProbe *probe; +#ifdef HAVE_PULSE_1_0 + gdouble volume; + gboolean volume_set:1; + gboolean mute:1; + gboolean mute_set:1; + + gint notify; /* atomic */ +#endif + gboolean corked:1; gboolean operation_success:1; gboolean paused:1; From a3bc43192477baf4a8a0510fd55a762a408955c0 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Fri, 25 Nov 2011 19:28:55 -0300 Subject: [PATCH 26/26] ismlmux: Use iso-fragmented as variant type Using 'iso' conflicts with mp4mux variant type, ismlmux now uses iso-fragmented Fixes #656823 --- gst/isomp4/gstqtmuxmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/isomp4/gstqtmuxmap.c b/gst/isomp4/gstqtmuxmap.c index 7872f0cb36..e0fb78bf18 100644 --- a/gst/isomp4/gstqtmuxmap.c +++ b/gst/isomp4/gstqtmuxmap.c @@ -201,7 +201,7 @@ GstQTMuxFormatProp gst_qt_mux_format_list[] = { "ismlmux", "ISML", "GstISMLMux", - GST_STATIC_CAPS ("video/quicktime, variant = (string) iso"), + GST_STATIC_CAPS ("video/quicktime, variant = (string) iso-fragmented"), GST_STATIC_CAPS (MPEG4V_CAPS "; " H264_CAPS), GST_STATIC_CAPS (MP3_CAPS "; " AAC_CAPS) }