diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2016-08-25 20:50:11 +0300 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-08-26 18:12:23 +0300 |
commit | 4734b10c6f7ed83cbd6be5f3b3c16aab8ca2b49b (patch) | |
tree | e07822b054d64c21c9841c1c4109fafb416020e1 /ext | |
parent | 1da1a3afc9f17e0e621b872fa472f7b8f7d0d97b (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.c | 68 | ||||
-rw-r--r-- | ext/dash/gstdashdemux.h | 2 | ||||
-rw-r--r-- | ext/dash/gstmpdparser.c | 29 | ||||
-rw-r--r-- | ext/dash/gstmpdparser.h | 2 |
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 */ |