From 9d720554a06488ee18a582761d56cef7b96439e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Sun, 13 Nov 2022 18:12:51 +0100 Subject: [PATCH] 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: --- .../ext/adaptivedemux2/dash/gstdashdemux.c | 10 +++- .../ext/adaptivedemux2/dash/gstmpdclient.c | 31 +++++++----- .../ext/adaptivedemux2/dash/gstmpdclient.h | 2 +- .../tests/check/elements/dash_mpd.c | 48 ++++++++++--------- 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);