summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-08-25 20:50:11 +0300
committerSebastian Dröge <sebastian@centricular.com>2016-08-26 18:12:23 +0300
commit4734b10c6f7ed83cbd6be5f3b3c16aab8ca2b49b (patch)
treee07822b054d64c21c9841c1c4109fafb416020e1 /ext
parent1da1a3afc9f17e0e621b872fa472f7b8f7d0d97b (diff)
dashdemux: Add properties to select maximum allowed width/height and framerate
https://bugzilla.gnome.org/show_bug.cgi?id=770408
Diffstat (limited to 'ext')
-rw-r--r--ext/dash/gstdashdemux.c68
-rw-r--r--ext/dash/gstdashdemux.h2
-rw-r--r--ext/dash/gstmpdparser.c29
-rw-r--r--ext/dash/gstmpdparser.h2
4 files changed, 93 insertions, 8 deletions
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 2b29a1de8..6e24747a9 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -189,6 +189,9 @@ enum
PROP_MAX_BUFFERING_TIME,
PROP_BANDWIDTH_USAGE,
PROP_MAX_BITRATE,
+ PROP_MAX_VIDEO_WIDTH,
+ PROP_MAX_VIDEO_HEIGHT,
+ PROP_MAX_VIDEO_FRAMERATE,
PROP_PRESENTATION_DELAY,
PROP_LAST
};
@@ -196,7 +199,11 @@ enum
/* Default values for properties */
#define DEFAULT_MAX_BUFFERING_TIME 30 /* in seconds */
#define DEFAULT_BANDWIDTH_USAGE 0.8 /* 0 to 1 */
-#define DEFAULT_MAX_BITRATE 24000000 /* in bit/s */
+#define DEFAULT_MAX_BITRATE 0 /* in bit/s */
+#define DEFAULT_MAX_VIDEO_WIDTH 0
+#define DEFAULT_MAX_VIDEO_HEIGHT 0
+#define DEFAULT_MAX_VIDEO_FRAMERATE_N 0
+#define DEFAULT_MAX_VIDEO_FRAMERATE_D 1
#define DEFAULT_PRESENTATION_DELAY NULL /* zero */
/* Clock drift compensation for live streams */
@@ -418,8 +425,27 @@ gst_dash_demux_class_init (GstDashDemuxClass * klass)
g_object_class_install_property (gobject_class, PROP_MAX_BITRATE,
g_param_spec_uint ("max-bitrate", "Max bitrate",
- "Max of bitrate supported by target decoder",
- 1000, G_MAXUINT, DEFAULT_MAX_BITRATE,
+ "Max of bitrate supported by target video decoder (0 = no maximum)",
+ 0, G_MAXUINT, DEFAULT_MAX_BITRATE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_WIDTH,
+ g_param_spec_uint ("max-video-width", "Max video width",
+ "Max video width to select (0 = no maximum)",
+ 0, G_MAXUINT, DEFAULT_MAX_VIDEO_WIDTH,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_HEIGHT,
+ g_param_spec_uint ("max-video-height", "Max video height",
+ "Max video height to select (0 = no maximum)",
+ 0, G_MAXUINT, DEFAULT_MAX_VIDEO_HEIGHT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_MAX_VIDEO_FRAMERATE,
+ gst_param_spec_fraction ("max-video-framerate", "Max video framerate",
+ "Max video framerate to select (0/1 = no maximum)",
+ 0, 1, G_MAXINT, 1, DEFAULT_MAX_VIDEO_FRAMERATE_N,
+ DEFAULT_MAX_VIDEO_FRAMERATE_D,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_PRESENTATION_DELAY,
@@ -492,6 +518,10 @@ gst_dash_demux_init (GstDashDemux * demux)
/* Properties */
demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME * GST_SECOND;
demux->max_bitrate = DEFAULT_MAX_BITRATE;
+ demux->max_video_width = DEFAULT_MAX_VIDEO_WIDTH;
+ demux->max_video_height = DEFAULT_MAX_VIDEO_HEIGHT;
+ demux->max_video_framerate_n = DEFAULT_MAX_VIDEO_FRAMERATE_N;
+ demux->max_video_framerate_d = DEFAULT_MAX_VIDEO_FRAMERATE_D;
demux->default_presentation_delay = DEFAULT_PRESENTATION_DELAY;
g_mutex_init (&demux->client_lock);
@@ -517,6 +547,16 @@ gst_dash_demux_set_property (GObject * object, guint prop_id,
case PROP_MAX_BITRATE:
demux->max_bitrate = g_value_get_uint (value);
break;
+ case PROP_MAX_VIDEO_WIDTH:
+ demux->max_video_width = g_value_get_uint (value);
+ break;
+ case PROP_MAX_VIDEO_HEIGHT:
+ demux->max_video_height = g_value_get_uint (value);
+ break;
+ case PROP_MAX_VIDEO_FRAMERATE:
+ demux->max_video_framerate_n = gst_value_get_fraction_numerator (value);
+ demux->max_video_framerate_d = gst_value_get_fraction_denominator (value);
+ break;
case PROP_PRESENTATION_DELAY:
g_free (demux->default_presentation_delay);
demux->default_presentation_delay = g_value_dup_string (value);
@@ -544,6 +584,16 @@ gst_dash_demux_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_MAX_BITRATE:
g_value_set_uint (value, demux->max_bitrate);
break;
+ case PROP_MAX_VIDEO_WIDTH:
+ g_value_set_uint (value, demux->max_video_width);
+ break;
+ case PROP_MAX_VIDEO_HEIGHT:
+ g_value_set_uint (value, demux->max_video_height);
+ break;
+ case PROP_MAX_VIDEO_FRAMERATE:
+ gst_value_set_fraction (value, demux->max_video_framerate_n,
+ demux->max_video_framerate_d);
+ break;
case PROP_PRESENTATION_DELAY:
if (demux->default_presentation_delay == NULL)
g_value_set_static_string (value, "");
@@ -1457,15 +1507,23 @@ gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
GST_DEBUG_OBJECT (stream->pad,
"Trying to change to bitrate: %" G_GUINT64_FORMAT, bitrate);
+ if (active_stream->mimeType == GST_STREAM_VIDEO && demux->max_bitrate) {
+ bitrate = MIN (demux->max_bitrate, bitrate);
+ }
+
/* get representation index with current max_bandwidth */
if ((base_demux->segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) ||
ABS (base_demux->segment.rate) <= 1.0) {
new_index =
- gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate);
+ gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list, bitrate,
+ demux->max_video_width, demux->max_video_height,
+ demux->max_video_framerate_n, demux->max_video_framerate_d);
} else {
new_index =
gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list,
- bitrate / ABS (base_demux->segment.rate));
+ bitrate / ABS (base_demux->segment.rate), demux->max_video_width,
+ demux->max_video_height, demux->max_video_framerate_n,
+ demux->max_video_framerate_d);
}
/* if no representation has the required bandwidth, take the lowest one */
diff --git a/ext/dash/gstdashdemux.h b/ext/dash/gstdashdemux.h
index e32b7b4a8..0757d76b1 100644
--- a/ext/dash/gstdashdemux.h
+++ b/ext/dash/gstdashdemux.h
@@ -120,6 +120,8 @@ struct _GstDashDemux
/* Properties */
GstClockTime max_buffering_time; /* Maximum buffering time accumulated during playback */
guint64 max_bitrate; /* max of bitrate supported by target decoder */
+ gint max_video_width, max_video_height;
+ gint max_video_framerate_n, max_video_framerate_d;
gchar* default_presentation_delay; /* presentation time delay if MPD@suggestedPresentationDelay is not present */
gint n_audio_streams;
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index 7166ecbf4..10f0149a9 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -2453,7 +2453,8 @@ gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations)
gint
gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations,
- gint max_bandwidth)
+ gint max_bandwidth, gint max_video_width, gint max_video_height, gint
+ max_video_framerate_n, gint max_video_framerate_d)
{
GList *list = NULL, *best = NULL;
GstRepresentationNode *representation;
@@ -2468,8 +2469,32 @@ gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations,
return gst_mpdparser_get_rep_idx_with_min_bandwidth (Representations);
for (list = g_list_first (Representations); list; list = g_list_next (list)) {
+ GstFrameRate *framerate = NULL;
+
representation = (GstRepresentationNode *) list->data;
- if (representation && representation->bandwidth <= max_bandwidth &&
+
+ /* FIXME: Really? */
+ if (!representation)
+ continue;
+
+ framerate = representation->RepresentationBase->frameRate;
+ if (!framerate)
+ framerate = representation->RepresentationBase->maxFrameRate;
+
+ if (framerate && max_video_framerate_n > 0) {
+ if (gst_util_fraction_compare (framerate->num, framerate->den,
+ max_video_framerate_n, max_video_framerate_d) > 0)
+ continue;
+ }
+
+ if (max_video_width > 0
+ && representation->RepresentationBase->width > max_video_width)
+ continue;
+ if (max_video_height > 0
+ && representation->RepresentationBase->height > max_video_height)
+ continue;
+
+ if (representation->bandwidth <= max_bandwidth &&
representation->bandwidth > best_bandwidth) {
best = list;
best_bandwidth = representation->bandwidth;
diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h
index bc3f1ef2f..85b97ea2a 100644
--- a/ext/dash/gstmpdparser.h
+++ b/ext/dash/gstmpdparser.h
@@ -561,7 +561,7 @@ gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
/* Representation selection */
-gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint max_bandwidth);
+gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint max_bandwidth, gint max_video_width, gint max_video_height, gint max_video_framerate_n, gint max_video_framerate_d);
gint gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations);
/* URL management */