mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-07 15:02:40 +00:00
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:
parent
1da1a3afc9
commit
4734b10c6f
4 changed files with 93 additions and 8 deletions
|
@ -189,6 +189,9 @@ enum
|
||||||
PROP_MAX_BUFFERING_TIME,
|
PROP_MAX_BUFFERING_TIME,
|
||||||
PROP_BANDWIDTH_USAGE,
|
PROP_BANDWIDTH_USAGE,
|
||||||
PROP_MAX_BITRATE,
|
PROP_MAX_BITRATE,
|
||||||
|
PROP_MAX_VIDEO_WIDTH,
|
||||||
|
PROP_MAX_VIDEO_HEIGHT,
|
||||||
|
PROP_MAX_VIDEO_FRAMERATE,
|
||||||
PROP_PRESENTATION_DELAY,
|
PROP_PRESENTATION_DELAY,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
@ -196,7 +199,11 @@ enum
|
||||||
/* Default values for properties */
|
/* Default values for properties */
|
||||||
#define DEFAULT_MAX_BUFFERING_TIME 30 /* in seconds */
|
#define DEFAULT_MAX_BUFFERING_TIME 30 /* in seconds */
|
||||||
#define DEFAULT_BANDWIDTH_USAGE 0.8 /* 0 to 1 */
|
#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 */
|
#define DEFAULT_PRESENTATION_DELAY NULL /* zero */
|
||||||
|
|
||||||
/* Clock drift compensation for live streams */
|
/* 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_object_class_install_property (gobject_class, PROP_MAX_BITRATE,
|
||||||
g_param_spec_uint ("max-bitrate", "Max bitrate",
|
g_param_spec_uint ("max-bitrate", "Max bitrate",
|
||||||
"Max of bitrate supported by target decoder",
|
"Max of bitrate supported by target video decoder (0 = no maximum)",
|
||||||
1000, G_MAXUINT, DEFAULT_MAX_BITRATE,
|
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_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_PRESENTATION_DELAY,
|
g_object_class_install_property (gobject_class, PROP_PRESENTATION_DELAY,
|
||||||
|
@ -492,6 +518,10 @@ gst_dash_demux_init (GstDashDemux * demux)
|
||||||
/* Properties */
|
/* Properties */
|
||||||
demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME * GST_SECOND;
|
demux->max_buffering_time = DEFAULT_MAX_BUFFERING_TIME * GST_SECOND;
|
||||||
demux->max_bitrate = DEFAULT_MAX_BITRATE;
|
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;
|
demux->default_presentation_delay = DEFAULT_PRESENTATION_DELAY;
|
||||||
|
|
||||||
g_mutex_init (&demux->client_lock);
|
g_mutex_init (&demux->client_lock);
|
||||||
|
@ -517,6 +547,16 @@ gst_dash_demux_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_MAX_BITRATE:
|
case PROP_MAX_BITRATE:
|
||||||
demux->max_bitrate = g_value_get_uint (value);
|
demux->max_bitrate = g_value_get_uint (value);
|
||||||
break;
|
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:
|
case PROP_PRESENTATION_DELAY:
|
||||||
g_free (demux->default_presentation_delay);
|
g_free (demux->default_presentation_delay);
|
||||||
demux->default_presentation_delay = g_value_dup_string (value);
|
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:
|
case PROP_MAX_BITRATE:
|
||||||
g_value_set_uint (value, demux->max_bitrate);
|
g_value_set_uint (value, demux->max_bitrate);
|
||||||
break;
|
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:
|
case PROP_PRESENTATION_DELAY:
|
||||||
if (demux->default_presentation_delay == NULL)
|
if (demux->default_presentation_delay == NULL)
|
||||||
g_value_set_static_string (value, "");
|
g_value_set_static_string (value, "");
|
||||||
|
@ -1457,15 +1507,23 @@ gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
|
||||||
GST_DEBUG_OBJECT (stream->pad,
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
"Trying to change to bitrate: %" G_GUINT64_FORMAT, bitrate);
|
"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 */
|
/* get representation index with current max_bandwidth */
|
||||||
if ((base_demux->segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) ||
|
if ((base_demux->segment.flags & GST_SEGMENT_FLAG_TRICKMODE_KEY_UNITS) ||
|
||||||
ABS (base_demux->segment.rate) <= 1.0) {
|
ABS (base_demux->segment.rate) <= 1.0) {
|
||||||
new_index =
|
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 {
|
} else {
|
||||||
new_index =
|
new_index =
|
||||||
gst_mpdparser_get_rep_idx_with_max_bandwidth (rep_list,
|
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 */
|
/* if no representation has the required bandwidth, take the lowest one */
|
||||||
|
|
|
@ -120,6 +120,8 @@ struct _GstDashDemux
|
||||||
/* Properties */
|
/* Properties */
|
||||||
GstClockTime max_buffering_time; /* Maximum buffering time accumulated during playback */
|
GstClockTime max_buffering_time; /* Maximum buffering time accumulated during playback */
|
||||||
guint64 max_bitrate; /* max of bitrate supported by target decoder */
|
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 */
|
gchar* default_presentation_delay; /* presentation time delay if MPD@suggestedPresentationDelay is not present */
|
||||||
|
|
||||||
gint n_audio_streams;
|
gint n_audio_streams;
|
||||||
|
|
|
@ -2453,7 +2453,8 @@ gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations)
|
||||||
|
|
||||||
gint
|
gint
|
||||||
gst_mpdparser_get_rep_idx_with_max_bandwidth (GList * Representations,
|
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;
|
GList *list = NULL, *best = NULL;
|
||||||
GstRepresentationNode *representation;
|
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);
|
return gst_mpdparser_get_rep_idx_with_min_bandwidth (Representations);
|
||||||
|
|
||||||
for (list = g_list_first (Representations); list; list = g_list_next (list)) {
|
for (list = g_list_first (Representations); list; list = g_list_next (list)) {
|
||||||
|
GstFrameRate *framerate = NULL;
|
||||||
|
|
||||||
representation = (GstRepresentationNode *) list->data;
|
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) {
|
representation->bandwidth > best_bandwidth) {
|
||||||
best = list;
|
best = list;
|
||||||
best_bandwidth = representation->bandwidth;
|
best_bandwidth = representation->bandwidth;
|
||||||
|
|
|
@ -561,7 +561,7 @@ gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
|
||||||
gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
|
gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
|
||||||
|
|
||||||
/* Representation selection */
|
/* 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);
|
gint gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations);
|
||||||
|
|
||||||
/* URL management */
|
/* URL management */
|
||||||
|
|
Loading…
Reference in a new issue