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>
This commit is contained in:
Rafał Dzięgiel 2022-11-13 18:12:51 +01:00 committed by GStreamer Marge Bot
parent 38028c9873
commit 9d720554a0
4 changed files with 53 additions and 38 deletions

View file

@ -738,13 +738,19 @@ gst_dash_demux_setup_mpdparser_streams (GstDashDemux2 * demux,
{ {
gboolean has_streams = FALSE; gboolean has_streams = FALSE;
GList *adapt_sets, *iter; 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); adapt_sets = gst_mpd_client2_get_adaptation_sets (client);
for (iter = adapt_sets; iter; iter = g_list_next (iter)) { for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
GstMPDAdaptationSetNode *adapt_set_node = iter->data; GstMPDAdaptationSetNode *adapt_set_node = iter->data;
if (gst_mpd_client2_setup_streaming (client, adapt_set_node)) has_streams |= gst_mpd_client2_setup_streaming (client, adapt_set_node,
has_streams = TRUE; connection_bitrate, demux->max_video_width,
demux->max_video_height, demux->max_video_framerate_n,
demux->max_video_framerate_d);
} }
if (!has_streams) { if (!has_streams) {

View file

@ -1612,11 +1612,14 @@ gst_mpd_client2_get_adaptation_sets (GstMPDClient2 * client)
gboolean gboolean
gst_mpd_client2_setup_streaming (GstMPDClient2 * client, 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; GList *rep_list = NULL;
GstActiveStream *stream; GstActiveStream *stream;
gint rep_id;
rep_list = adapt_set->Representations; rep_list = adapt_set->Representations;
if (!rep_list) { if (!rep_list) {
@ -1632,21 +1635,23 @@ gst_mpd_client2_setup_streaming (GstMPDClient2 * client,
GST_DEBUG ("0. Current stream %p", stream); GST_DEBUG ("0. Current stream %p", stream);
#if 0 rep_id = gst_mpd_client2_get_rep_idx_with_max_bandwidth (rep_list,
/* fast start */ max_bandwidth, max_video_width, max_video_height,
representation = max_video_framerate_n, max_video_framerate_d);
gst_mpdparser_get_representation_with_max_bandwidth (rep_list,
stream->max_bandwidth); 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) { if (!representation) {
GST_WARNING GST_WARNING ("No representation with the requested bandwidth or video "
("Can not retrieve a representation with the requested bandwidth"); "resolution/framerate restriction");
representation = gst_mpd_client2_get_lowest_representation (rep_list); representation = gst_mpd_client2_get_lowest_representation (rep_list);
} }
#else
/* slow start */
representation = gst_mpd_client2_get_lowest_representation (rep_list);
#endif
if (!representation) { if (!representation) {
GST_WARNING ("No valid representation in the MPD file, aborting..."); GST_WARNING ("No valid representation in the MPD file, aborting...");

View file

@ -70,7 +70,7 @@ void gst_mpd_client2_fetch_on_load_external_resources (GstMPDClient2 * client);
/* Streaming management */ /* 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_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); gboolean gst_mpd_client2_setup_representation (GstMPDClient2 *client, GstActiveStream *stream, GstMPDRepresentationNode *representation);
GstClockTime gst_mpd_client2_get_next_fragment_duration (GstMPDClient2 * client, GstActiveStream * stream); GstClockTime gst_mpd_client2_get_next_fragment_duration (GstMPDClient2 * client, GstActiveStream * stream);

View file

@ -106,6 +106,10 @@ duration_to_clocktime (guint year, guint month, guint day, guint hour,
millisecond)); 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. * 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
fail_if (activeStream == NULL); fail_if (activeStream == NULL);
@ -2989,13 +2993,13 @@ GST_START_TEST (dash_mpdparser_bitstreamSwitching_inheritance)
/* setup streaming from the first adaptation set */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* setup streaming from the second adaptation set */ /* setup streaming from the second adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* 2 active streams */ /* 2 active streams */
@ -3203,7 +3207,7 @@ GST_START_TEST (dash_mpdparser_setup_streaming)
fail_if (adapt_set == NULL); fail_if (adapt_set == NULL);
/* setup streaming from the adaptation set */ /* 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); assert_equals_int (ret, TRUE);
gst_mpd_client2_free (mpdclient); gst_mpd_client2_free (mpdclient);
@ -3536,7 +3540,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the first adaptation set */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* 1 active streams */ /* 1 active streams */
@ -3546,7 +3550,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the second adaptation set */ /* setup streaming from the second adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* 2 active streams */ /* 2 active streams */
@ -3556,7 +3560,7 @@ GST_START_TEST (dash_mpdparser_activeStream_selection)
/* setup streaming from the third adaptation set */ /* setup streaming from the third adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 2); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 2);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* 3 active streams */ /* 3 active streams */
@ -3635,7 +3639,7 @@ GST_START_TEST (dash_mpdparser_activeStream_parameters)
/* setup streaming from the first adaptation set */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* 1 active streams */ /* 1 active streams */
@ -3727,7 +3731,7 @@ GST_START_TEST (dash_mpdparser_get_audio_languages)
for (i = 0; i < adaptationSetsCount; i++) { for (i = 0; i < adaptationSetsCount; i++) {
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
} }
activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient); 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++) { for (i = 0; i < adaptationSetsCount; i++) {
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
} }
activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* test the stream presentation time offset */ /* test the stream presentation time offset */
@ -4299,7 +4303,7 @@ GST_START_TEST (dash_mpdparser_segments)
/* setup streaming from the first adaptation set */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
/* get segment url and range from segment Initialization */ /* 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
fail_if (activeStream == NULL); fail_if (activeStream == NULL);
@ -4663,7 +4667,7 @@ GST_START_TEST (dash_mpdparser_inherited_segmentURL)
/* setup streaming from the first adaptation set */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 */ /* setup streaming from the first adaptation set */
adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
fail_if (adapt_set == NULL); 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); assert_equals_int (ret, TRUE);
activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0); 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 * Should fail because the second S node does not have a matching
* SegmentURL node * SegmentURL node
*/ */
ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set); ret = setup_streaming_simple (mpdclient, adapt_set);
assert_equals_int (ret, FALSE); assert_equals_int (ret, FALSE);
gst_mpd_client2_free (mpdclient); 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)) { for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
GstMPDAdaptationSetNode *adapt_set_node = iter->data; 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); assert_equals_int (ret, TRUE);
} }
dur = gst_mpd_client2_get_maximum_segment_duration (mpdclient); dur = gst_mpd_client2_get_maximum_segment_duration (mpdclient);