Commit a55576d1 authored by Thibault Saunier's avatar Thibault Saunier

qtdemux: Specify REDIRECT information in error message

There are in the wild (mp4) streams that basically contain no tracks
but do have a redirect info[0], in which case, we won't be able
to expose any pad (there are no tracks) so we can't post anything but
an error on the bus, as:

- it can't send EOS downstream, it has no pad,
- posting an EOS message will be useless as PAUSED state can't be
  reached and there is no sink in the pipeline meaning GstBin will
  simply ignore it

The approach here is to to add details to the ERROR message with a
`redirect-location` field which elements like playbin handle and use right
away.

[0]: http://movietrailers.apple.com/movies/paramount/terminator-dark-fate/terminator-dark-fate-trailer-2_480p.mov
parent a2459642
Pipeline #67919 passed with stages
in 65 minutes and 52 seconds
......@@ -526,6 +526,7 @@ GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
G_DEFINE_TYPE (GstQTDemux, gst_qtdemux, GST_TYPE_ELEMENT);
static void gst_qtdemux_dispose (GObject * object);
static void gst_qtdemux_finalize (GObject * object);
static guint32
gst_qtdemux_find_index_linear (GstQTDemux * qtdemux, QtDemuxStream * str,
......@@ -628,6 +629,7 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
parent_class = g_type_class_peek_parent (klass);
gobject_class->dispose = gst_qtdemux_dispose;
gobject_class->finalize = gst_qtdemux_finalize;
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_qtdemux_change_state);
#if 0
......@@ -683,6 +685,16 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
gst_qtdemux_reset (qtdemux, TRUE);
}
static void
gst_qtdemux_finalize (GObject * object)
{
GstQTDemux *qtdemux = GST_QTDEMUX (object);
g_free (qtdemux->redirect_location);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_qtdemux_dispose (GObject * object)
{
......@@ -711,10 +723,11 @@ gst_qtdemux_dispose (GObject * object)
static void
gst_qtdemux_post_no_playable_stream_error (GstQTDemux * qtdemux)
{
if (qtdemux->posted_redirect) {
GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
if (qtdemux->redirect_location) {
GST_ELEMENT_ERROR_WITH_DETAILS (qtdemux, STREAM, DEMUX,
(_("This file contains no playable streams.")),
("no known streams found, a redirect message has been posted"));
("no known streams found, a redirect message has been posted"),
("redirect-location", G_TYPE_STRING, qtdemux->redirect_location, NULL));
} else {
GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
(_("This file contains no playable streams.")),
......@@ -2111,7 +2124,7 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
qtdemux->neededbytes = 16;
qtdemux->todrop = 0;
qtdemux->pullbased = FALSE;
qtdemux->posted_redirect = FALSE;
g_clear_pointer (&qtdemux->redirect_location, g_free);
qtdemux->first_mdat = -1;
qtdemux->header_size = 0;
qtdemux->mdatoffset = -1;
......@@ -6065,11 +6078,12 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
gst_buffer_unmap (buf, &map);
if (url != NULL && strlen (url) != 0) {
/* we have RTSP redirect now */
g_free (qtdemux->redirect_location);
qtdemux->redirect_location = g_strdup (url);
gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
gst_message_new_element (GST_OBJECT_CAST (qtdemux),
gst_structure_new ("redirect",
"new-location", G_TYPE_STRING, url, NULL)));
qtdemux->posted_redirect = TRUE;
} else {
GST_WARNING_OBJECT (qtdemux, "Redirect URI of stream is empty, not "
"posting");
......@@ -12915,7 +12929,9 @@ qtdemux_expose_streams (GstQTDemux * qtdemux)
"new-location", G_TYPE_STRING,
QTDEMUX_NTH_STREAM (qtdemux, 0)->redirect_uri, NULL));
gst_element_post_message (GST_ELEMENT_CAST (qtdemux), m);
qtdemux->posted_redirect = TRUE;
g_free (qtdemux->redirect_location);
qtdemux->redirect_location =
g_strdup (QTDEMUX_NTH_STREAM (qtdemux, 0)->redirect_uri);
}
g_ptr_array_foreach (qtdemux->active_streams,
......@@ -13968,9 +13984,11 @@ qtdemux_process_redirects (GstQTDemux * qtdemux, GList * references)
g_list_free (references);
GST_INFO_OBJECT (qtdemux, "posting redirect message: %" GST_PTR_FORMAT, s);
g_free (qtdemux->redirect_location);
qtdemux->redirect_location =
g_strdup (gst_structure_get_string (s, "new-location"));
msg = gst_message_new_element (GST_OBJECT_CAST (qtdemux), s);
gst_element_post_message (GST_ELEMENT_CAST (qtdemux), msg);
qtdemux->posted_redirect = TRUE;
}
/* look for redirect nodes, collect all redirect information and
......
......@@ -69,7 +69,7 @@ struct _GstQTDemux {
/* TRUE if pull-based */
gboolean pullbased;
gboolean posted_redirect;
gchar *redirect_location;
/* Protect pad exposing from flush event */
GMutex expose_lock;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment