summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafał Dzięgiel <rafostar.github@gmail.com>2022-11-13 18:12:51 +0100
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2023-02-18 21:05:25 +0000
commit9d720554a06488ee18a582761d56cef7b96439e9 (patch)
tree3d6053d716237243dc01ad4b259db45043d5bf99
parent38028c987345dd6e7f2c383e6d74566f07bceacf (diff)
downloadgstreamer-9d720554a06488ee18a582761d56cef7b96439e9.tar.gz
dashdemux2: Improve initial representation selection
Do not always start with lowest quality possible. Use properties set by user to select best allowed initial representation at startup too. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3894>
-rw-r--r--subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstdashdemux.c10
-rw-r--r--subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.c31
-rw-r--r--subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.h2
-rw-r--r--subprojects/gst-plugins-good/tests/check/elements/dash_mpd.c48
4 files changed, 53 insertions, 38 deletions
diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstdashdemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstdashdemux.c
index 14b6f0ae4b..0b88997743 100644
--- a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstdashdemux.c
+++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstdashdemux.c
@@ -738,13 +738,19 @@ gst_dash_demux_setup_mpdparser_streams (GstDashDemux2 * demux,
{
gboolean has_streams = FALSE;
GList *adapt_sets, *iter;
+ guint connection_bitrate;
+
+ /* Using g_object_get so it goes through mutex locking in adaptivedemux2 */
+ g_object_get (demux, "connection-bitrate", &connection_bitrate, NULL);
adapt_sets = gst_mpd_client2_get_adaptation_sets (client);
for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
GstMPDAdaptationSetNode *adapt_set_node = iter->data;
- if (gst_mpd_client2_setup_streaming (client, adapt_set_node))
- has_streams = TRUE;
+ has_streams |= gst_mpd_client2_setup_streaming (client, adapt_set_node,
+ connection_bitrate, demux->max_video_width,
+ demux->max_video_height, demux->max_video_framerate_n,
+ demux->max_video_framerate_d);
}
if (!has_streams) {
diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.c
index 75de86f680..3067cfe019 100644
--- a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.c
+++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.c
@@ -1612,11 +1612,14 @@ gst_mpd_client2_get_adaptation_sets (GstMPDClient2 * client)
gboolean
gst_mpd_client2_setup_streaming (GstMPDClient2 * client,
- GstMPDAdaptationSetNode * adapt_set)
+ GstMPDAdaptationSetNode * adapt_set, gint64 max_bandwidth,
+ gint max_video_width, gint max_video_height,
+ gint max_video_framerate_n, gint max_video_framerate_d)
{
- GstMPDRepresentationNode *representation;
+ GstMPDRepresentationNode *representation = NULL;
GList *rep_list = NULL;
GstActiveStream *stream;
+ gint rep_id;
rep_list = adapt_set->Representations;
if (!rep_list) {
@@ -1632,21 +1635,23 @@ gst_mpd_client2_setup_streaming (GstMPDClient2 * client,
GST_DEBUG ("0. Current stream %p", stream);
-#if 0
- /* fast start */
- representation =
- gst_mpdparser_get_representation_with_max_bandwidth (rep_list,
- stream->max_bandwidth);
+ rep_id = gst_mpd_client2_get_rep_idx_with_max_bandwidth (rep_list,
+ max_bandwidth, max_video_width, max_video_height,
+ max_video_framerate_n, max_video_framerate_d);
+
+ if (rep_id >= 0) {
+ GList *best_rep;
+
+ best_rep = g_list_nth (rep_list, rep_id);
+ if (best_rep)
+ representation = (GstMPDRepresentationNode *) best_rep->data;
+ }
if (!representation) {
- GST_WARNING
- ("Can not retrieve a representation with the requested bandwidth");
+ GST_WARNING ("No representation with the requested bandwidth or video "
+ "resolution/framerate restriction");
representation = gst_mpd_client2_get_lowest_representation (rep_list);
}
-#else
- /* slow start */
- representation = gst_mpd_client2_get_lowest_representation (rep_list);
-#endif
if (!representation) {
GST_WARNING ("No valid representation in the MPD file, aborting...");
diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.h
index 72746e52cf..8074ebea7b 100644
--- a/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.h
+++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/dash/gstmpdclient.h
@@ -70,7 +70,7 @@ void gst_mpd_client2_fetch_on_load_external_resources (GstMPDClient2 * client);
/* Streaming management */
gboolean gst_mpd_client2_setup_media_presentation (GstMPDClient2 *client, GstClockTime time, gint period_index, const gchar *period_id);
-gboolean gst_mpd_client2_setup_streaming (GstMPDClient2 * client, GstMPDAdaptationSetNode * adapt_set);
+gboolean gst_mpd_client2_setup_streaming (GstMPDClient2 * client, GstMPDAdaptationSetNode * adapt_set, gint64 max_bandwidth, gint max_video_width, gint max_video_height, gint max_video_framerate_n, gint max_video_framerate_d);
gboolean gst_mpd_client2_setup_representation (GstMPDClient2 *client, GstActiveStream *stream, GstMPDRepresentationNode *representation);
GstClockTime gst_mpd_client2_get_next_fragment_duration (GstMPDClient2 * client, GstActiveStream * stream);
diff --git a/subprojects/gst-plugins-good/tests/check/elements/dash_mpd.c b/subprojects/gst-plugins-good/tests/check/elements/dash_mpd.c
index bda2787df9..562765f4b8 100644
--- a/subprojects/gst-plugins-good/tests/check/elements/dash_mpd.c
+++ b/subprojects/gst-plugins-good/tests/check/elements/dash_mpd.c
@@ -106,6 +106,10 @@ duration_to_clocktime (guint year, guint month, guint day, guint hour,
millisecond));
}
+/* Setup streaming with default properties values */
+#define setup_streaming_simple(cl, node) \
+ gst_mpd_client2_setup_streaming(cl, node, 0, 0, 0, 0, 1);
+
/*
* Test to ensure a simple mpd file successfully parses.
*
@@ -955,7 +959,7 @@ GST_START_TEST (dash_mpdparser_period_segmentTemplateWithPresentationTimeOffset)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
fail_if (activeStream == NULL);
@@ -2989,13 +2993,13 @@ GST_START_TEST (dash_mpdparser_bitstreamSwitching_inheritance)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* setup streaming from the second adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* 2 active streams */
@@ -3203,7 +3207,7 @@ GST_START_TEST (dash_mpdparser_setup_streaming)
fail_if (adapt_set == NULL);
/* setup streaming from the adaptation set */
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
gst_mpd_client2_free (mpdclient);
@@ -3536,7 +3540,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* 1 active streams */
@@ -3546,7 +3550,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the second adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* 2 active streams */
@@ -3556,7 +3560,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the third adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 2);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* 3 active streams */
@@ -3635,7 +3639,7 @@ GST_START_TEST (dash_mpdparser_activeStream_parameters)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* 1 active streams */
@@ -3727,7 +3731,7 @@ GST_START_TEST (dash_mpdparser_get_audio_languages)
for (i = 0; i < adaptationSetsCount; i++) {
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
}
activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
@@ -3779,7 +3783,7 @@ setup_mpd_client (const gchar * xml)
for (i = 0; i < adaptationSetsCount; i++) {
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
}
activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
@@ -4228,7 +4232,7 @@ GST_START_TEST (dash_mpdparser_get_streamPresentationOffset)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* test the stream presentation time offset */
@@ -4299,7 +4303,7 @@ GST_START_TEST (dash_mpdparser_segments)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -4434,7 +4438,7 @@ GST_START_TEST (dash_mpdparser_headers)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
/* get segment url and range from segment Initialization */
@@ -4510,7 +4514,7 @@ GST_START_TEST (dash_mpdparser_fragments)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
fail_if (activeStream == NULL);
@@ -4663,7 +4667,7 @@ GST_START_TEST (dash_mpdparser_inherited_segmentURL)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -4750,7 +4754,7 @@ GST_START_TEST (dash_mpdparser_segment_list)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -4835,7 +4839,7 @@ GST_START_TEST (dash_mpdparser_segment_template)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -4956,7 +4960,7 @@ GST_START_TEST (dash_mpdparser_segment_timeline)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -5146,7 +5150,7 @@ GST_START_TEST (dash_mpdparser_multiple_inherited_segmentURL)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -5265,7 +5269,7 @@ GST_START_TEST (dash_mpdparser_multipleSegmentURL)
/* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL);
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
@@ -5725,7 +5729,7 @@ GST_START_TEST (dash_mpdparser_unmatched_segmentTimeline_segmentURL)
* Should fail because the second S node does not have a matching
* SegmentURL node
*/
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
+ ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, FALSE);
gst_mpd_client2_free (mpdclient);
@@ -5892,7 +5896,7 @@ GST_START_TEST (dash_mpdparser_maximum_segment_duration)
for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
GstMPDAdaptationSetNode *adapt_set_node = iter->data;
- ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set_node);
+ ret = setup_streaming_simple (mpdclient, adapt_set_node);
assert_equals_int (ret, TRUE);
}
dur = gst_mpd_client2_get_maximum_segment_duration (mpdclient);