playback: Support runtime change connection-speed of adaptivedemux(2)

Update connection-speed at runtime in playbin, uridecodebin and decodebin
also do the same thing in urisourcebin.

With contributions from Philippe Normand <philn@igalia.com> (build fixes and
rebase on mono-repo).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4713>
This commit is contained in:
Haihua Hu 2020-12-17 12:11:45 +08:00 committed by GStreamer Marge Bot
parent 7b491f382c
commit 4e381b8901
4 changed files with 140 additions and 38 deletions

View file

@ -1281,6 +1281,73 @@ gst_decode_bin_get_subs_encoding (GstDecodeBin * dbin)
return encoding;
}
static void
gst_decode_bin_set_demux_connection_speed (GstDecodeBin * dbin,
GstElement * element)
{
guint64 speed = 0;
gboolean wrong_type = FALSE;
GParamSpec *pspec;
GST_OBJECT_LOCK (dbin);
speed = dbin->connection_speed / 1000;
GST_OBJECT_UNLOCK (dbin);
if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
"connection-speed"))) {
if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);
speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);
speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);
speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);
speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
} else {
GST_WARNING_OBJECT (dbin,
"The connection speed property %" G_GUINT64_FORMAT " of type %s"
" is not useful not setting it", speed,
g_type_name (G_PARAM_SPEC_TYPE (pspec)));
wrong_type = TRUE;
}
if (!wrong_type) {
GST_DEBUG_OBJECT (dbin, "setting connection-speed=%" G_GUINT64_FORMAT
" to demuxer element", speed);
g_object_set (element, "connection-speed", speed, NULL);
}
}
}
static void
gst_decode_bin_update_connection_speed (GstDecodeBin * dbin)
{
GstElement *demuxer = NULL;
if (!dbin->decode_chain)
return;
CHAIN_MUTEX_LOCK (dbin->decode_chain);
if (dbin->decode_chain->adaptive_demuxer) {
GstDecodeElement *delem = dbin->decode_chain->elements->data;
demuxer = gst_object_ref (delem->element);
}
CHAIN_MUTEX_UNLOCK (dbin->decode_chain);
if (demuxer) {
gst_decode_bin_set_demux_connection_speed (dbin, demuxer);
gst_object_unref (demuxer);
}
}
static void
gst_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@ -1330,6 +1397,7 @@ gst_decode_bin_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (dbin);
dbin->connection_speed = g_value_get_uint64 (value) * 1000;
GST_OBJECT_UNLOCK (dbin);
gst_decode_bin_update_connection_speed (dbin);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -2451,44 +2519,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
/* Set connection-speed property if needed */
if (chain->demuxer) {
GParamSpec *pspec;
if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
"connection-speed"))) {
guint64 speed = dbin->connection_speed / 1000;
gboolean wrong_type = FALSE;
if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);
speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);
speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);
speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
} else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);
speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
} else {
GST_WARNING_OBJECT (dbin,
"The connection speed property %" G_GUINT64_FORMAT " of type %s"
" is not useful not setting it", speed,
g_type_name (G_PARAM_SPEC_TYPE (pspec)));
wrong_type = TRUE;
}
if (!wrong_type) {
GST_DEBUG_OBJECT (dbin, "setting connection-speed=%" G_GUINT64_FORMAT
" to demuxer element", speed);
g_object_set (element, "connection-speed", speed, NULL);
}
}
gst_decode_bin_set_demux_connection_speed (dbin, element);
}
/* try to configure the subtitle encoding property when we can */

View file

@ -2469,10 +2469,30 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
g_value_get_string (value));
break;
case PROP_CONNECTION_SPEED:
{
guint64 connection_speed = 0;
GST_PLAY_BIN_LOCK (playbin);
playbin->connection_speed = g_value_get_uint64 (value) * 1000;
connection_speed = playbin->connection_speed;
if (playbin->curr_group) {
GST_SOURCE_GROUP_LOCK (playbin->curr_group);
if (playbin->curr_group->uridecodebin) {
g_object_set (playbin->curr_group->uridecodebin,
"connection-speed", connection_speed / 1000, NULL);
}
GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
}
if (playbin->next_group) {
GST_SOURCE_GROUP_LOCK (playbin->next_group);
if (playbin->next_group->uridecodebin) {
g_object_set (playbin->next_group->uridecodebin,
"connection-speed", connection_speed / 1000, NULL);
}
GST_SOURCE_GROUP_UNLOCK (playbin->next_group);
}
GST_PLAY_BIN_UNLOCK (playbin);
break;
}
case PROP_BUFFER_SIZE:
playbin->buffer_size = g_value_get_int (value);
break;

View file

@ -817,6 +817,26 @@ gst_uri_decode_bin_set_encoding (GstURIDecodeBin * dec, const gchar * encoding)
GST_URI_DECODE_BIN_UNLOCK (dec);
}
static void
gst_uri_decode_bin_set_connection_speed (GstURIDecodeBin * dec)
{
GSList *walk;
guint64 connection_speed;
GST_OBJECT_LOCK (dec);
connection_speed = dec->connection_speed;
GST_OBJECT_UNLOCK (dec);
/* set the property on all decodebins now */
GST_URI_DECODE_BIN_LOCK (dec);
for (walk = dec->decodebins; walk; walk = g_slist_next (walk)) {
GObject *decodebin = G_OBJECT (walk->data);
g_object_set (decodebin, "connection-speed", connection_speed / 1000, NULL);
}
GST_URI_DECODE_BIN_UNLOCK (dec);
}
static void
gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@ -834,6 +854,7 @@ gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (dec);
dec->connection_speed = g_value_get_uint64 (value) * 1000;
GST_OBJECT_UNLOCK (dec);
gst_uri_decode_bin_set_connection_speed (dec);
break;
case PROP_CAPS:
GST_OBJECT_LOCK (dec);

View file

@ -564,6 +564,35 @@ gst_uri_source_bin_finalize (GObject * obj)
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
static void
gst_uri_source_bin_update_connection_speed (GstURISourceBin * urisrc)
{
guint64 speed = 0;
GList *iter;
if (!urisrc->is_adaptive) {
return;
}
GST_OBJECT_LOCK (urisrc);
speed = urisrc->connection_speed / 1000;
GST_OBJECT_UNLOCK (urisrc);
GST_URI_SOURCE_BIN_LOCK (urisrc);
for (iter = urisrc->src_infos; iter; iter = iter->next) {
ChildSrcPadInfo *info = iter->data;
GParamSpec *pspec = NULL;
if (!info->demuxer)
continue;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info->demuxer),
"connection-speed");
if (pspec != NULL)
g_object_set (info->demuxer, "connection-speed", speed, NULL);
}
GST_URI_SOURCE_BIN_UNLOCK (urisrc);
}
static void
gst_uri_source_bin_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
@ -581,6 +610,7 @@ gst_uri_source_bin_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (urisrc);
urisrc->connection_speed = g_value_get_uint64 (value) * 1000;
GST_OBJECT_UNLOCK (urisrc);
gst_uri_source_bin_update_connection_speed (urisrc);
break;
case PROP_BUFFER_SIZE:
urisrc->buffer_size = g_value_get_int (value);