summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2011-02-10 18:11:46 +0100
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2011-02-10 18:17:56 +0100
commit686189f3f0cb7c26836ea2a5b6f294faddcf9971 (patch)
treecb66720795629179c4955e42f69ddadfe9647db6
parent3dc42d370437e4fc1362e861f9c44d685b262aa3 (diff)
qtdemux: propagate error during expose_streams
... as it may occur during initial parsing of fragmented file.
-rw-r--r--gst/qtdemux/qtdemux.c31
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)
{