uridecodebin3: Handle redirection errors

This is done by doing an immediate switch to the redirection URI if compatible.

Fixes #1562

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4242>
This commit is contained in:
Edward Hervey 2023-03-22 10:58:59 +01:00 committed by GStreamer Marge Bot
parent 1abc8aa733
commit 133c4b2ff9
2 changed files with 60 additions and 0 deletions

View file

@ -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

View file

@ -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;
}