From 41af36aa2f7e59351c98cbd2de3526ca010779af Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 26 Sep 2005 13:06:27 +0000 Subject: [PATCH] gst/avi/gstavidemux.c: Don't crash when encountering a stream with an unknown fourcc or codec id. Instead, create a p... Original commit message from CVS: * gst/avi/gstavidemux.c: (gst_avi_demux_base_init), (gst_avi_demux_class_init), (gst_avi_demux_parse_stream), (gst_avi_demux_change_state): Don't crash when encountering a stream with an unknown fourcc or codec id. Instead, create a pad of type video/x-avi-unknown or audio/x-avi-unknown, which as a side-effect also results in less confusing error messages in players ('no decoder' vs. 'no streams'); minor fixes to state change function and class_init function. --- ChangeLog | 11 +++++++++ gst/avi/gstavidemux.c | 64 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5fcdc18..bd84d1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-09-26 Tim-Philipp Müller + + * gst/avi/gstavidemux.c: (gst_avi_demux_base_init), + (gst_avi_demux_class_init), (gst_avi_demux_parse_stream), + (gst_avi_demux_change_state): + Don't crash when encountering a stream with an unknown fourcc or + codec id. Instead, create a pad of type video/x-avi-unknown or + audio/x-avi-unknown, which as a side-effect also results in less + confusing error messages in players ('no decoder' vs. 'no streams'); + minor fixes to state change function and class_init function. + 2005-09-24 Wim Taymans * gst/autodetect/gstautoaudiosink.c: (gst_auto_audio_sink_init): diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index eb084bd..07bd4d5 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -110,11 +110,13 @@ gst_avi_demux_base_init (GstAviDemuxClass * klass) GstCaps *audcaps, *vidcaps; audcaps = gst_riff_create_audio_template_caps (); + gst_caps_append (audcaps, gst_caps_new_simple ("audio/x-avi-unknown", NULL)); audiosrctempl = gst_pad_template_new ("audio_%02d", GST_PAD_SRC, GST_PAD_SOMETIMES, audcaps); vidcaps = gst_riff_create_video_template_caps (); gst_caps_append (vidcaps, gst_riff_create_iavs_template_caps ()); + gst_caps_append (vidcaps, gst_caps_new_simple ("video/x-avi-unknown", NULL)); videosrctempl = gst_pad_template_new ("video_%02d", GST_PAD_SRC, GST_PAD_SOMETIMES, vidcaps); @@ -133,7 +135,7 @@ gst_avi_demux_class_init (GstAviDemuxClass * klass) GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux", 0, "Demuxer for AVI streams"); - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + parent_class = g_type_class_peek_parent (klass); gstelement_class->change_state = gst_avi_demux_change_state; } @@ -991,34 +993,52 @@ gst_avi_demux_parse_stream (GstElement * element, GstBuffer * buf) /* we now have all info, let´s set up a pad and a caps and be done */ /* create stream name + pad */ switch (stream->strh->type) { - case GST_RIFF_FCC_vids: + case GST_RIFF_FCC_vids:{ + guint32 fourcc; + + fourcc = (stream->strf.vids->compression) ? + stream->strf.vids->compression : stream->strh->fcc_handler; padname = g_strdup_printf ("video_%02d", avi->num_v_streams); templ = gst_element_class_get_pad_template (klass, "video_%02d"); - caps = gst_riff_create_video_caps (stream->strf.vids->compression ? - stream->strf.vids->compression : stream->strh->fcc_handler, - stream->strh, stream->strf.vids, - stream->extradata, stream->initdata, &codec_name); + caps = gst_riff_create_video_caps (fourcc, stream->strh, + stream->strf.vids, stream->extradata, stream->initdata, &codec_name); + if (!caps) { + caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc", + GST_TYPE_FOURCC, fourcc, NULL); + } tag_name = GST_TAG_VIDEO_CODEC; avi->num_v_streams++; break; - case GST_RIFF_FCC_auds: + } + case GST_RIFF_FCC_auds:{ padname = g_strdup_printf ("audio_%02d", avi->num_a_streams); templ = gst_element_class_get_pad_template (klass, "audio_%02d"); caps = gst_riff_create_audio_caps (stream->strf.auds->format, - stream->strh, stream->strf.auds, - stream->extradata, stream->initdata, &codec_name); + stream->strh, stream->strf.auds, stream->extradata, + stream->initdata, &codec_name); + if (!caps) { + caps = gst_caps_new_simple ("audio/x-avi-unknown", "codec_id", + G_TYPE_INT, stream->strf.auds->format, NULL); + } tag_name = GST_TAG_AUDIO_CODEC; avi->num_a_streams++; break; - case GST_RIFF_FCC_iavs: + } + case GST_RIFF_FCC_iavs:{ + guint32 fourcc = stream->strh->fcc_handler; + padname = g_strdup_printf ("video_%02d", avi->num_v_streams); templ = gst_element_class_get_pad_template (klass, "video_%02d"); - caps = gst_riff_create_iavs_caps (stream->strh->fcc_handler, - stream->strh, stream->strf.iavs, - stream->extradata, stream->initdata, &codec_name); + caps = gst_riff_create_iavs_caps (fourcc, stream->strh, + stream->strf.iavs, stream->extradata, stream->initdata, &codec_name); + if (!caps) { + caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc", + GST_TYPE_FOURCC, fourcc, NULL); + } tag_name = GST_TAG_VIDEO_CODEC; avi->num_v_streams++; break; + } default: g_assert_not_reached (); } @@ -2196,6 +2216,21 @@ gst_avi_demux_change_state (GstElement * element, GstStateChange transition) GstAviDemux *avi = GST_AVI_DEMUX (element); switch (transition) { + case GST_STATE_CHANGE_READY_TO_PAUSED: + break; + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) { + GstStateChangeReturn ret; + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + if (ret != GST_STATE_CHANGE_SUCCESS) + return ret; + } + + switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: gst_avi_demux_reset (avi); break; @@ -2203,8 +2238,5 @@ gst_avi_demux_change_state (GstElement * element, GstStateChange transition) break; } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - return GST_STATE_CHANGE_SUCCESS; } -- 2.7.4