dashdemux: Add properties to select maximum allowed width/height and framerate

https://bugzilla.gnome.org/show_bug.cgi?id=770408
This commit is contained in:
Sebastian Dröge 2016-08-25 20:50:11 +03:00
parent 1da1a3afc9
commit 4734b10c6f
4 changed files with 93 additions and 8 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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 */