summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2019-09-03 16:46:30 -0400
committerTim-Philipp Müller <tim@centricular.com>2019-12-06 11:30:09 +0000
commita0c6156a81d56c472a9eccd9797a0e77628067df (patch)
tree4bda427545f3c2fd7d5628f801cf2736a9449310
parentce0723527aa37d5f4d19ef8021c0b2eb8f83b08d (diff)
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
-rw-r--r--gst/isomp4/qtdemux.c32
-rw-r--r--gst/isomp4/qtdemux.h2
2 files changed, 26 insertions, 8 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index ad07c1e36..61fec02cb 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -523,6 +523,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,
@@ -625,6 +626,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
@@ -681,6 +683,16 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
}
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)
{
GstQTDemux *qtdemux = GST_QTDEMUX (object);
@@ -708,10 +720,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.")),
@@ -2112,7 +2125,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;
@@ -6038,11 +6051,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");
@@ -12912,7 +12926,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,
@@ -13965,9 +13981,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
diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
index 83a050a43..05ea7c78f 100644
--- a/gst/isomp4/qtdemux.h
+++ b/gst/isomp4/qtdemux.h
@@ -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;