| From a55576d1fd25c7d67661630fc94367908802a496 Mon Sep 17 00:00:00 2001 |
| From: Thibault Saunier <tsaunier@igalia.com> |
| Date: Tue, 3 Sep 2019 16:46:30 -0400 |
| Subject: [PATCH] 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 |
| --- |
| gst/isomp4/qtdemux.c | 32 +++++++++++++++++++++++++------- |
| gst/isomp4/qtdemux.h | 2 +- |
| 2 files changed, 26 insertions(+), 8 deletions(-) |
| |
| diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c |
| index ba4d43648..8a6bf08c7 100644 |
| --- a/gst/isomp4/qtdemux.c |
| +++ b/gst/isomp4/qtdemux.c |
| @@ -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 |
| diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h |
| index f9731b2b8..c5e85c721 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; |
| -- |
| 2.21.0 |
| |