summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2019-09-03 16:03:49 -0400
committerTim-Philipp Müller <tim@centricular.com>2019-12-06 11:29:12 +0000
commit0375d3a393385f8098928c06520ce03f456f1b28 (patch)
treefe3ba528a85cd5499db148552bf496577a596245
parent9d3581b2e6f12f0b7e790d1ebb63b90cf5b1ef4e (diff)
downloadgstreamer-plugins-base-0375d3a393385f8098928c06520ce03f456f1b28.tar.gz
playbin: Handle error message with redirection indication
There are in the wild (mp4) streams that basically contain no tracks but do have a redirect info[0], in which case, qtdemux won't be able to expose any pad (there are no tracks) so 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 In that case, currently the application could try to handle that but it is pretty complex as it will get the REDIRECT message on the bus at which point it could set the URL but playbin will ignore it, as it will only be for the next EOS, it thus need to set the pipeline to NULL (READY won't do as it is already in READY at that point). And it needs to figure out the following ERROR message on the bus needs to be ignored, which is not really simple. The approach here is to allow element to add details to the ERROR message with a `redirect-location` field which elements like playbin handle and use right away. We could also use the element 'redirect' message in playbin, but the issue with that approach is that the element will still emit the ERROR message on the bus, leading to wrong behaviour. That can't be avoided since in the case the app/parent pipeline is not handling the redirect instruction, the ERROR message is necessary (and there is no way to detect that the message has been "handled" from the element emitting the redirect). [0]: http://movietrailers.apple.com/movies/paramount/terminator-dark-fate/terminator-dark-fate-trailer-2_480p.mov
-rw-r--r--gst/playback/gstplaybin2.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 1f3d9faf0..cec4b36b7 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -170,6 +170,10 @@
* 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: playbin will internally handle the redirect messages in the case
+ * that the redirecting stream doesn't contain any tracks and thus
+ * needs to report an error message on the bus.
+ *
* ## Examples
* |[
* gst-launch-1.0 -v playbin uri=file:///path/to/somefile.mp4
@@ -3027,6 +3031,42 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
no_more_pads_cb (NULL, group);
}
}
+ } else {
+ const GstStructure *details = NULL;
+
+ gst_message_parse_error_details (msg, &details);
+ if (details && gst_structure_has_field (details, "redirect-location")) {
+ gchar *uri = NULL;
+ const gchar *location =
+ gst_structure_get_string ((GstStructure *) details,
+ "redirect-location");
+
+ if (gst_uri_is_valid (location)) {
+ uri = g_strdup (location);
+ } else {
+ uri = gst_uri_join_strings (group->uri, location);
+ }
+
+ if (g_strcmp0 (uri, group->uri)) {
+ GST_PLAY_BIN_LOCK (playbin);
+ if (playbin->next_group && playbin->next_group->valid) {
+ GST_DEBUG_OBJECT (playbin,
+ "User already setup next uri %s, using it",
+ playbin->next_group->uri);
+ } else {
+ GST_DEBUG_OBJECT (playbin,
+ "Using newly configured redirect URI: %s", uri);
+ gst_play_bin_set_uri (playbin, uri);
+ }
+ GST_PLAY_BIN_UNLOCK (playbin);
+
+ setup_next_source (playbin, GST_STATE_PAUSED);
+ gst_message_unref (msg);
+ msg = NULL;
+ }
+
+ g_free (uri);
+ }
}
}