diff options
author | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2011-02-10 18:11:46 +0100 |
---|---|---|
committer | Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk> | 2011-02-10 18:17:56 +0100 |
commit | 686189f3f0cb7c26836ea2a5b6f294faddcf9971 (patch) | |
tree | cb66720795629179c4955e42f69ddadfe9647db6 | |
parent | 3dc42d370437e4fc1362e861f9c44d685b262aa3 (diff) |
qtdemux: propagate error during expose_streams
... as it may occur during initial parsing of fragmented file.
-rw-r--r-- | gst/qtdemux/qtdemux.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 7be9986f0..96e320d77 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -422,13 +422,13 @@ static GstCaps *qtdemux_audio_caps (GstQTDemux * qtdemux, gchar ** codec_name); static GstCaps *qtdemux_sub_caps (GstQTDemux * qtdemux, QtDemuxStream * stream, guint32 fourcc, const guint8 * data, gchar ** codec_name); static gboolean qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream, guint32 n); -static void qtdemux_expose_streams (GstQTDemux * qtdemux); +static GstFlowReturn qtdemux_expose_streams (GstQTDemux * qtdemux); static void gst_qtdemux_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); @@ -2762,21 +2762,21 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux) } } beach: if (ret == GST_FLOW_UNEXPECTED && qtdemux->got_moov) { /* digested all data, show what we have */ - qtdemux_expose_streams (qtdemux); + ret = qtdemux_expose_streams (qtdemux); /* Only post, event on pads is done after newsegment */ qtdemux_post_global_tags (qtdemux); qtdemux->state = QTDEMUX_STATE_MOVIE; GST_DEBUG_OBJECT (qtdemux, "switching state to STATE_MOVIE (%d)", qtdemux->state); - return GST_FLOW_OK; + return ret; } return ret; } /* Seeks to the previous keyframe of the indexed stream and * aligns other streams with respect to the keyframe timestamp @@ -5113,26 +5113,26 @@ locate_failed: return ret; } } /* should only do something in pull mode */ /* call with OBJECT lock */ -static gboolean +static GstFlowReturn qtdemux_add_fragmented_samples (GstQTDemux * qtdemux) { guint64 length, offset; GstBuffer *buf = NULL; GstFlowReturn ret = GST_FLOW_OK; - gboolean res = TRUE; + GstFlowReturn res = TRUE; offset = qtdemux->moof_offset; GST_DEBUG_OBJECT (qtdemux, "next moof at offset %" G_GUINT64_FORMAT, offset); if (!offset) { GST_DEBUG_OBJECT (qtdemux, "no next moof"); - return FALSE; + return GST_FLOW_UNEXPECTED; } /* best not do pull etc with lock held */ GST_OBJECT_UNLOCK (qtdemux); ret = qtdemux_find_atom (qtdemux, &offset, &length, FOURCC_moof); @@ -5166,26 +5166,26 @@ exit: return res; parse_failed: { GST_DEBUG_OBJECT (qtdemux, "failed to parse moof"); offset = 0; - res = FALSE; + res = GST_FLOW_ERROR; goto exit; } flow_failed: { /* maybe upstream temporarily flushing */ if (ret != GST_FLOW_WRONG_STATE) { GST_DEBUG_OBJECT (qtdemux, "no next moof"); offset = 0; } else { GST_DEBUG_OBJECT (qtdemux, "upstream WRONG_STATE"); /* resume at current position next time */ } - res = FALSE; + res = ret; goto exit; } } /* initialise bytereaders for stbl sub-atoms */ static gboolean @@ -5769,13 +5769,13 @@ done: /* if index has been completely parsed, free data that is no-longer needed */ if (n + 1 == stream->n_samples) { gst_qtdemux_stbl_free (stream); GST_DEBUG_OBJECT (qtdemux, "parsed all available samples; checking for more"); while (n + 1 == stream->n_samples) - if (!qtdemux_add_fragmented_samples (qtdemux)) + if (qtdemux_add_fragmented_samples (qtdemux) != GST_FLOW_OK) break; } GST_OBJECT_UNLOCK (qtdemux); return TRUE; @@ -7320,20 +7320,21 @@ too_many_streams: (_("This file contains too many streams. Only playing first %d"), GST_QTDEMUX_MAX_STREAMS), (NULL)); return TRUE; } } -static void +static GstFlowReturn qtdemux_expose_streams (GstQTDemux * qtdemux) { gint i; + GstFlowReturn ret = GST_FLOW_OK; GST_DEBUG_OBJECT (qtdemux, "exposing streams"); - for (i = 0; i < qtdemux->n_streams; i++) { + for (i = 0; ret == GST_FLOW_OK && i < qtdemux->n_streams; i++) { QtDemuxStream *stream = qtdemux->streams[i]; guint32 sample_num = 0; guint samples = 20; GArray *durations; GstTagList *list; @@ -7341,20 +7342,24 @@ qtdemux_expose_streams (GstQTDemux * qtdemux) i, stream->track_id, GST_FOURCC_ARGS (stream->fourcc)); if (qtdemux->fragmented) { /* need all moov samples first */ GST_OBJECT_LOCK (qtdemux); while (stream->n_samples == 0) - if (!qtdemux_add_fragmented_samples (qtdemux)) + if ((ret = qtdemux_add_fragmented_samples (qtdemux)) != GST_FLOW_OK) break; GST_OBJECT_UNLOCK (qtdemux); } else { /* discard any stray moof */ qtdemux->moof_offset = 0; } + /* prepare braking */ + if (ret != GST_FLOW_ERROR) + ret = GST_FLOW_OK; + /* in pull mode, we should have parsed some sample info by now; * and quite some code will not handle no samples. * in push mode, we'll just have to deal with it */ if (G_UNLIKELY (qtdemux->pullbased && !stream->n_samples)) { GST_DEBUG_OBJECT (qtdemux, "no samples for stream; discarding"); gst_qtdemux_stream_free (qtdemux, stream); @@ -7408,12 +7413,14 @@ qtdemux_expose_streams (GstQTDemux * qtdemux) gst_structure_new ("redirect", "new-location", G_TYPE_STRING, qtdemux->streams[0]->redirect_uri, NULL)); gst_element_post_message (GST_ELEMENT_CAST (qtdemux), m); qtdemux->posted_redirect = TRUE; } + + return ret; } /* check if major or compatible brand is 3GP */ static inline gboolean qtdemux_is_brand_3gp (GstQTDemux * qtdemux, gboolean major) { |