From 133c4b2ff96bbe2e86844dcfc4f00445e333c225 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Wed, 22 Mar 2023 10:58:59 +0100 Subject: [PATCH] uridecodebin3: Handle redirection errors This is done by doing an immediate switch to the redirection URI if compatible. Fixes #1562 Part-of: --- .../gst/playback/gstplaybin3.c | 3 + .../gst/playback/gsturidecodebin3.c | 57 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c b/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c index 0c70dd9c40..3b543963b3 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gstplaybin3.c @@ -187,6 +187,9 @@ * type. The new location may be a relative or an absolute URI. Examples * for such redirects can be found in many quicktime movie trailers. * + * NOTE: playbin3 (via uridecodebin3) will handle the redirect messages if + * possible. The message will only be forwarded if it can't handle it. + * * ## Examples * |[ * gst-launch-1.0 -v playbin3 uri=file:///path/to/somefile.mp4 diff --git a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c index 13cc7e44dc..d3a661d684 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c @@ -2040,6 +2040,53 @@ find_source_handler_for_element (GstURIDecodeBin3 * uridecodebin, return NULL; } +static GstMessage * +gst_uri_decode_bin3_handle_redirection (GstURIDecodeBin3 * uridecodebin, + GstMessage * message, const GstStructure * details) +{ + gchar *uri = NULL; + GstSourceHandler *handler; + const gchar *location; + gchar *current_uri; + + PLAY_ITEMS_LOCK (uridecodebin); + /* Find the matching handler (if any) */ + handler = find_source_handler_for_element (uridecodebin, message->src); + if (!handler || !handler->play_item || !handler->play_item->main_item) + goto beach; + + current_uri = handler->play_item->main_item->uri; + + location = gst_structure_get_string ((GstStructure *) details, + "redirect-location"); + GST_DEBUG_OBJECT (uridecodebin, "Handle redirection message from '%s' to '%s", + current_uri, location); + + if (gst_uri_is_valid (location)) { + uri = g_strdup (location); + } else if (current_uri) { + uri = gst_uri_join_strings (current_uri, location); + } + if (!uri) + goto beach; + + if (g_strcmp0 (current_uri, uri)) { + gboolean was_instant = uridecodebin->instant_uri; + GST_DEBUG_OBJECT (uridecodebin, "Doing instant switch to '%s'", uri); + uridecodebin->instant_uri = TRUE; + /* Force instant switch */ + gst_uri_decode_bin3_set_uri (uridecodebin, uri); + uridecodebin->instant_uri = was_instant; + gst_message_unref (message); + message = NULL; + } + g_free (uri); + +beach: + PLAY_ITEMS_UNLOCK (uridecodebin); + return message; +} + static void gst_uri_decode_bin3_handle_message (GstBin * bin, GstMessage * msg) { @@ -2090,6 +2137,16 @@ gst_uri_decode_bin3_handle_message (GstBin * bin, GstMessage * msg) break; } + case GST_MESSAGE_ERROR: + { + const GstStructure *details = NULL; + + gst_message_parse_error_details (msg, &details); + if (details && gst_structure_has_field (details, "redirect-location")) + msg = + gst_uri_decode_bin3_handle_redirection (uridecodebin, msg, details); + break; + } default: break; }