From accdba009fa89f2bdbb9e7fe482a1e081a3c4899 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 6 Jul 2023 10:24:22 +0900 Subject: [PATCH] good:adaptivedemux: Add max video width/height limit property [Version] 1.22.0-33 [Issue Type] New feature Change-Id: I3a067c94f9bea023e6c3b0cd7d55258c79dd3b23 --- packaging/gstreamer.spec | 2 +- .../ext/adaptivedemux2/gstadaptivedemux.c | 43 +++++++++++ .../ext/adaptivedemux2/gstadaptivedemux.h | 4 + .../ext/adaptivedemux2/hls/gsthlsdemux.c | 18 +++++ .../gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c | 90 +++++++++++++++++++++- .../gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h | 7 ++ subprojects/gst-plugins-good/meson.build | 1 + 7 files changed, 161 insertions(+), 4 deletions(-) diff --git a/packaging/gstreamer.spec b/packaging/gstreamer.spec index d0c4937..d4c258f 100644 --- a/packaging/gstreamer.spec +++ b/packaging/gstreamer.spec @@ -62,7 +62,7 @@ Name: %{_name} Version: 1.22.0 -Release: 32 +Release: 33 Summary: Streaming-Media Framework Runtime License: LGPL-2.0+ Group: Multimedia/Framework diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c index 0107286..165e22d 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c @@ -118,6 +118,9 @@ GST_DEBUG_CATEGORY_EXTERN (adaptivedemux2_debug); #define DEFAULT_MIN_BITRATE 0 #define DEFAULT_MAX_BITRATE 0 +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT +#define DEFAULT_MAX_RESOLUTION 0 +#endif #define DEFAULT_MAX_BUFFERING_TIME (30 * GST_SECOND) @@ -149,6 +152,10 @@ enum PROP_BUFFERING_LOW_WATERMARK_FRAGMENTS, PROP_CURRENT_LEVEL_TIME_VIDEO, PROP_CURRENT_LEVEL_TIME_AUDIO, +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + PROP_MAX_WIDTH, + PROP_MAX_HEIGHT, +#endif PROP_LAST }; @@ -326,6 +333,14 @@ gst_adaptive_demux_set_property (GObject * object, guint prop_id, case PROP_BUFFERING_LOW_WATERMARK_FRAGMENTS: demux->buffering_low_watermark_fragments = g_value_get_double (value); break; +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + case PROP_MAX_WIDTH: + demux->max_width = g_value_get_uint (value); + break; + case PROP_MAX_HEIGHT: + demux->max_height = g_value_get_uint (value); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -382,6 +397,14 @@ gst_adaptive_demux_get_property (GObject * object, guint prop_id, case PROP_CURRENT_LEVEL_TIME_AUDIO: g_value_set_uint64 (value, demux->current_level_time_audio); break; +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + case PROP_MAX_WIDTH: + g_value_set_uint (value, demux->max_width); + break; + case PROP_MAX_HEIGHT: + g_value_set_uint (value, demux->max_height); + break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -444,6 +467,22 @@ gst_adaptive_demux_class_init (GstAdaptiveDemuxClass * klass) 0, G_MAXUINT, DEFAULT_MAX_BITRATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + g_object_class_install_property (gobject_class, PROP_MAX_WIDTH, + g_param_spec_uint ("max-video-width", + "Max video width limit", + "Maximum limit of the available video width to use when switching to alternates. (0 = no limit)", + 0, G_MAXUINT, DEFAULT_MAX_RESOLUTION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, PROP_MAX_HEIGHT, + g_param_spec_uint ("max-video-height", + "Max video height limit", + "Maximum limit of the available video height to use when switching to alternates. (0 = no limit)", + 0, G_MAXUINT, DEFAULT_MAX_RESOLUTION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif + g_object_class_install_property (gobject_class, PROP_CURRENT_BANDWIDTH, g_param_spec_uint ("current-bandwidth", "Current download bandwidth (bits/s)", @@ -582,6 +621,10 @@ gst_adaptive_demux_init (GstAdaptiveDemux * demux, demux->connection_speed = DEFAULT_CONNECTION_BITRATE; demux->min_bitrate = DEFAULT_MIN_BITRATE; demux->max_bitrate = DEFAULT_MAX_BITRATE; +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + demux->max_width = DEFAULT_MAX_RESOLUTION; + demux->max_height = DEFAULT_MAX_RESOLUTION; +#endif demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME; demux->buffering_high_watermark_time = DEFAULT_BUFFERING_HIGH_WATERMARK_TIME; diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.h index 10ad04f..a89ee0c 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.h @@ -272,6 +272,10 @@ struct _GstAdaptiveDemux guint connection_speed; /* Available / bandwidth to use set by the application */ guint min_bitrate; /* Minimum bitrate to choose */ guint max_bitrate; /* Maximum bitrate to choose */ +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + guint max_width; + guint max_height; +#endif guint current_download_rate; /* Current estimate of download bitrate */ diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c index c30eac6..8c5ff92 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c @@ -922,12 +922,24 @@ gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf) variant = hlsdemux->master->default_variant; } else if (hlsdemux->start_bitrate > 0) { variant = +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + gst_hls_master_playlist_get_variant_for_bitrate_and_resolution ( + hlsdemux->master, NULL, hlsdemux->start_bitrate, demux->min_bitrate, + demux->max_width, demux->max_height); +#else gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master, NULL, hlsdemux->start_bitrate, demux->min_bitrate); +#endif } else { variant = +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + gst_hls_master_playlist_get_variant_for_bitrate_and_resolution ( + hlsdemux->master, NULL, demux->connection_speed, demux->min_bitrate, + demux->max_width, demux->max_height); +#else gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master, NULL, demux->connection_speed, demux->min_bitrate); +#endif } if (variant) { @@ -2695,8 +2707,14 @@ gst_hls_demux_change_playlist (GstHLSDemux * demux, guint max_bitrate, /* Make sure we keep a reference in case we need to switch back */ previous_variant = gst_hls_variant_stream_ref (demux->current_variant); new_variant = +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT + gst_hls_master_playlist_get_variant_for_bitrate_and_resolution (demux->master, + demux->current_variant, max_bitrate, adaptive_demux->min_bitrate, + adaptive_demux->max_width, adaptive_demux->max_height); +#else gst_hls_master_playlist_get_variant_for_bitrate (demux->master, demux->current_variant, max_bitrate, adaptive_demux->min_bitrate); +#endif retry_failover_protection: old_bandwidth = previous_variant->bandwidth; diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c index ca5b3d7..500268b 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c @@ -2262,10 +2262,8 @@ hls_master_playlist_new_from_data (gchar * data, const gchar * base_uri) g_list_length (playlist->renditions)); #ifdef TIZEN_FEATURE_POST_VARIANT_INFO - GList *v = (playlist->iframe_variants)?(playlist->iframe_variants):(playlist->variants); - /* update variant stream info */ - for (; v != NULL; v = v->next) { + for (GList *v = playlist->variants; v != NULL; v = v->next) { GstHLSVariantStream *data = v->data; GstM3U8VideoVariantInfo *var_info = g_new0 (GstM3U8VideoVariantInfo, 1); @@ -2282,6 +2280,91 @@ hls_master_playlist_new_from_data (gchar * data, const gchar * base_uri) return playlist; } +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT +static guint +get_num_of_codec(GstHLSVariantStream * variant) +{ +#define MAX_NUM_OF_CODEC 10 + guint cnt = 0; + gchar** codec_list = NULL; + + if (!variant || !variant->codecs) + return 0; + + codec_list = g_strsplit (variant->codecs, ",", MAX_NUM_OF_CODEC); + if (!codec_list) + return 0; + + cnt = g_strv_length (codec_list); + g_strfreev (codec_list); + + return cnt; +} + +static gboolean +is_codec_change_available(GstHLSVariantStream * variant, guint req_num) +{ + if (!variant) + return FALSE; + + if (req_num == 0) + return TRUE; + + if (get_num_of_codec (variant) == req_num) + return TRUE; + + GST_WARNING ("can not support to change codec"); + return FALSE; +} + +GstHLSVariantStream * +hls_master_playlist_get_variant_for_bitrate_and_resolution (GstHLSMasterPlaylist * + playlist, GstHLSVariantStream * current_variant, guint bitrate, + guint min_bitrate, guint max_width, guint max_height) +{ + GstHLSVariantStream *variant = current_variant; + GstHLSVariantStream *variant_by_min = NULL; // lowest + GList *l = NULL; + guint num_of_codec = 0; + + GST_DEBUG ("bitrate: %u, min_bitrate: %u, max resolution: %u X %u", + bitrate, min_bitrate, max_width, max_height); + + /* get variant list */ + if (current_variant == NULL || !current_variant->iframe) + l = g_list_last (playlist->variants); + else + l = g_list_last (playlist->iframe_variants); + + num_of_codec = get_num_of_codec (current_variant); + + for (; l; l = g_list_previous(l)) { + variant = l->data; + if (!is_codec_change_available ((GstHLSVariantStream *)variant, num_of_codec)) + continue; + + GST_DEBUG ("stream info: %d, %d x %d", variant->bandwidth, variant->width, variant->height); + + if (variant->bandwidth >= min_bitrate) + variant_by_min = variant; + + if (variant->bandwidth <= bitrate) { + if (max_width == 0 || max_height == 0 || variant->width == 0 || variant->height == 0) + break; + + if (variant->width > max_width || variant->height > max_height) + continue; + + break; + } + } + + if (variant && variant->bandwidth >= min_bitrate) + return variant; + + return variant_by_min; +} +#else GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist, GstHLSVariantStream * current_variant, guint bitrate, @@ -2315,6 +2398,7 @@ hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * * was higher than the min_bitrate */ return variant_by_min; } +#endif static gboolean remove_uncommon (GQuark field_id, GValue * value, GstStructure * st2) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h index 3c24a46..072aeb1 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h @@ -381,11 +381,18 @@ struct _GstHLSMasterPlaylist GstHLSMasterPlaylist * hls_master_playlist_new_from_data (gchar * data, const gchar * base_uri); +#ifdef TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT +#define gst_hls_master_playlist_get_variant_for_bitrate_and_resolution hls_master_playlist_get_variant_for_bitrate_and_resolution +GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate_and_resolution (GstHLSMasterPlaylist * + playlist, GstHLSVariantStream * current_variant, guint bitrate, + guint min_bitrate, guint max_width, guint max_height); +#else #define gst_hls_master_playlist_get_variant_for_bitrate hls_master_playlist_get_variant_for_bitrate GstHLSVariantStream * hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist, GstHLSVariantStream * current_variant, guint bitrate, guint min_bitrate); +#endif #define gst_hls_master_playlist_get_common_caps hls_master_playlist_get_common_caps GstCaps * hls_master_playlist_get_common_caps (GstHLSMasterPlaylist *playlist); diff --git a/subprojects/gst-plugins-good/meson.build b/subprojects/gst-plugins-good/meson.build index fb31a89..f17df1e 100644 --- a/subprojects/gst-plugins-good/meson.build +++ b/subprojects/gst-plugins-good/meson.build @@ -469,6 +469,7 @@ cdata.set('TIZEN_FEATURE_V4L2_SKIP_ADD_COLORSPACE', true) cdata.set('TIZEN_FEATURE_GST_MUX_ENHANCEMENT', true) cdata.set('TIZEN_FEATURE_V4L2_DISABLE_COLORIMETRY', true) cdata.set('TIZEN_FEATURE_POST_VARIANT_INFO', true) +cdata.set('TIZEN_FEATURE_ADAPTIVE_VARIANT_LIMIT', true) cdata.set('TIZEN_FEATURE_BUG_FIX', true) if get_option('tv-profile') -- 2.7.4