From 79d5a7d03c34c96b1d7bb971ac22948c25fe9365 Mon Sep 17 00:00:00 2001 From: Alexander Schrab Date: Mon, 8 Apr 2013 11:38:33 +0200 Subject: [PATCH] wavparse: error out if we receive eos before any valid data https://bugzilla.gnome.org/show_bug.cgi?id=696684 --- gst/wavparse/gstwavparse.c | 109 ++++++++++++++++---------------- tests/check/Makefile.am | 1 + tests/check/elements/wavparse.c | 72 +++++++++++++++++++++ 3 files changed, 129 insertions(+), 53 deletions(-) create mode 100644 tests/check/elements/wavparse.c diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index a6a6258b41..d5c954b463 100644 --- a/gst/wavparse/gstwavparse.c +++ b/gst/wavparse/gstwavparse.c @@ -160,7 +160,7 @@ gst_wavparse_class_init (GstWavParseClass * klass) /** * GstWavParse:ignore-length - * + * * This selects whether the length found in a data chunk * should be ignored. This may be useful for streamed audio * where the length is unknown until the end of streaming, @@ -2053,27 +2053,27 @@ gst_wavparse_add_src_pad (GstWavParse * wav, GstBuffer * buf) GST_DEBUG_OBJECT (wav, "adding src pad"); - if (wav->caps) { - s = gst_caps_get_structure (wav->caps, 0); - if (s && gst_structure_has_name (s, "audio/x-raw") && buf != NULL) { - GstTypeFindProbability prob; - GstCaps *tf_caps; + g_assert (wav->caps != NULL); - tf_caps = gst_type_find_helper_for_buffer (GST_OBJECT (wav), buf, &prob); - if (tf_caps != NULL) { - GST_LOG ("typefind caps = %" GST_PTR_FORMAT ", P=%d", tf_caps, prob); - if (gst_wavparse_have_dts_caps (tf_caps, prob)) { - GST_INFO_OBJECT (wav, "Found DTS marker in file marked as raw PCM"); - gst_caps_unref (wav->caps); - wav->caps = tf_caps; + s = gst_caps_get_structure (wav->caps, 0); + if (s && gst_structure_has_name (s, "audio/x-raw") && buf != NULL) { + GstTypeFindProbability prob; + GstCaps *tf_caps; - gst_tag_list_add (wav->tags, GST_TAG_MERGE_REPLACE, - GST_TAG_AUDIO_CODEC, "dts", NULL); - } else { - GST_DEBUG_OBJECT (wav, "found caps %" GST_PTR_FORMAT " for stream " - "marked as raw PCM audio, but ignoring for now", tf_caps); - gst_caps_unref (tf_caps); - } + tf_caps = gst_type_find_helper_for_buffer (GST_OBJECT (wav), buf, &prob); + if (tf_caps != NULL) { + GST_LOG ("typefind caps = %" GST_PTR_FORMAT ", P=%d", tf_caps, prob); + if (gst_wavparse_have_dts_caps (tf_caps, prob)) { + GST_INFO_OBJECT (wav, "Found DTS marker in file marked as raw PCM"); + gst_caps_unref (wav->caps); + wav->caps = tf_caps; + + gst_tag_list_add (wav->tags, GST_TAG_MERGE_REPLACE, + GST_TAG_AUDIO_CODEC, "dts", NULL); + } else { + GST_DEBUG_OBJECT (wav, "found caps %" GST_PTR_FORMAT " for stream " + "marked as raw PCM audio, but ignoring for now", tf_caps); + gst_caps_unref (tf_caps); } } } @@ -2353,30 +2353,32 @@ pause: else if (wav->segment.rate < 0.0) wav->segment.position = wav->segment.start; } - /* add pad before we perform EOS */ - if (G_UNLIKELY (wav->first)) { - wav->first = FALSE; - gst_wavparse_add_src_pad (wav, NULL); - } - - if (wav->state == GST_WAVPARSE_START) - GST_ELEMENT_ERROR (wav, STREAM, WRONG_TYPE, - ("No valid input found before end of stream"), (NULL)); - - /* perform EOS logic */ - if (wav->segment.flags & GST_SEEK_FLAG_SEGMENT) { - GstClockTime stop; - - if ((stop = wav->segment.stop) == -1) - stop = wav->segment.duration; - - gst_element_post_message (GST_ELEMENT_CAST (wav), - gst_message_new_segment_done (GST_OBJECT_CAST (wav), - wav->segment.format, stop)); - gst_pad_push_event (wav->srcpad, - gst_event_new_segment_done (wav->segment.format, stop)); - } else { + if (wav->state == GST_WAVPARSE_START) { + GST_ELEMENT_ERROR (wav, STREAM, WRONG_TYPE, (NULL), + ("No valid input found before end of stream")); gst_pad_push_event (wav->srcpad, gst_event_new_eos ()); + } else { + /* add pad before we perform EOS */ + if (G_UNLIKELY (wav->first)) { + wav->first = FALSE; + gst_wavparse_add_src_pad (wav, NULL); + } + + /* perform EOS logic */ + if (wav->segment.flags & GST_SEEK_FLAG_SEGMENT) { + GstClockTime stop; + + if ((stop = wav->segment.stop) == -1) + stop = wav->segment.duration; + + gst_element_post_message (GST_ELEMENT_CAST (wav), + gst_message_new_segment_done (GST_OBJECT_CAST (wav), + wav->segment.format, stop)); + gst_pad_push_event (wav->srcpad, + gst_event_new_segment_done (wav->segment.format, stop)); + } else { + gst_pad_push_event (wav->srcpad, gst_event_new_eos ()); + } } } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { /* for fatal errors we post an error message, post the error @@ -2561,19 +2563,20 @@ gst_wavparse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) break; } case GST_EVENT_EOS: - /* add pad if needed so EOS is seen downstream */ - if (G_UNLIKELY (wav->first)) { - wav->first = FALSE; - gst_wavparse_add_src_pad (wav, NULL); + if (wav->state == GST_WAVPARSE_START) { + GST_ELEMENT_ERROR (wav, STREAM, WRONG_TYPE, (NULL), + ("No valid input found before end of stream")); } else { - /* stream leftover data in current segment */ - gst_wavparse_flush_data (wav); + /* add pad if needed so EOS is seen downstream */ + if (G_UNLIKELY (wav->first)) { + wav->first = FALSE; + gst_wavparse_add_src_pad (wav, NULL); + } else { + /* stream leftover data in current segment */ + gst_wavparse_flush_data (wav); + } } - if (wav->state == GST_WAVPARSE_START) - GST_ELEMENT_ERROR (wav, STREAM, WRONG_TYPE, - ("No valid input found before end of stream"), (NULL)); - /* fall-through */ case GST_EVENT_FLUSH_STOP: { diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 96016348c2..3f4d6b5eff 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -151,6 +151,7 @@ check_PROGRAMS = \ elements/videocrop \ elements/videofilter \ elements/wavpackparse \ + elements/wavparse \ elements/y4menc \ pipelines/simple-launch-lines \ pipelines/effectv \ diff --git a/tests/check/elements/wavparse.c b/tests/check/elements/wavparse.c new file mode 100644 index 0000000000..65e03a2535 --- /dev/null +++ b/tests/check/elements/wavparse.c @@ -0,0 +1,72 @@ +/* GStreamer WavParse unit tests + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include + +GST_START_TEST (test_empty_file) +{ + GstElement *pipeline; + GstElement *filesrc; + GstElement *wavparse; + GstElement *fakesink; + + pipeline = gst_pipeline_new ("testpipe"); + filesrc = gst_element_factory_make ("filesrc", NULL); + fail_if (filesrc == NULL); + wavparse = gst_element_factory_make ("wavparse", NULL); + fail_if (wavparse == NULL); + fakesink = gst_element_factory_make ("fakesink", NULL); + fail_if (fakesink == NULL); + + gst_object_ref_sink (filesrc); + gst_object_ref_sink (wavparse); + gst_object_ref_sink (fakesink); + + gst_bin_add_many (GST_BIN (pipeline), filesrc, wavparse, fakesink, NULL); + g_object_set (filesrc, "location", "/dev/null", NULL); + + fail_unless (gst_element_link_many (filesrc, wavparse, fakesink, NULL)); + + gst_element_set_state (pipeline, GST_STATE_PLAYING); + + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + + gst_element_set_state (pipeline, GST_STATE_NULL); + + gst_object_unref (filesrc); + gst_object_unref (wavparse); + gst_object_unref (fakesink); + gst_object_unref (pipeline); +} + +GST_END_TEST; + +static Suite * +wavparse_suite (void) +{ + Suite *s = suite_create ("wavparse"); + TCase *tc_chain = tcase_create ("wavparse"); + + suite_add_tcase (s, tc_chain); + tcase_add_test (tc_chain, test_empty_file); + return s; +} + +GST_CHECK_MAIN (wavparse)