good:adaptivedemux: Add max video width/height limit property 55/295355/11 accepted/tizen/unified/20230726.020643
authorGilbok Lee <gilbok.lee@samsung.com>
Thu, 6 Jul 2023 01:24:22 +0000 (10:24 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Fri, 7 Jul 2023 08:44:27 +0000 (17:44 +0900)
[Version] 1.22.0-33
[Issue Type] New feature

Change-Id: I3a067c94f9bea023e6c3b0cd7d55258c79dd3b23

packaging/gstreamer.spec
subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.c
subprojects/gst-plugins-good/ext/adaptivedemux2/gstadaptivedemux.h
subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c
subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c
subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h
subprojects/gst-plugins-good/meson.build

index d0c4937..d4c258f 100644 (file)
@@ -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
index 0107286..165e22d 100644 (file)
@@ -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;
index 10ad04f..a89ee0c 100644 (file)
@@ -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 */
 
index c30eac6..8c5ff92 100644 (file)
@@ -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;
index ca5b3d7..500268b 100644 (file)
@@ -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)
index 3c24a46..072aeb1 100644 (file)
@@ -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);
index fb31a89..f17df1e 100644 (file)
@@ -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')