From 89c0fda5f43d8a3d3a1c538ff8d72e6737bc7d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Sobala?= Date: Fri, 3 Mar 2017 09:38:28 +0100 Subject: [PATCH] lavf/dashenc: update bitrates on dash_write_trailer Provides a way to change bandwidth parameter inside DASH manifest after a non-CBR H.264 encoding. Caller now is able to compute the bitrate by itself, after all packets have been written, and then set that value in AVFormatContext->streams->codecpar->bit_rate before calling av_write_trailer. As a result that value will be set in DASH manifest. Signed-off-by: Michael Niedermayer --- libavformat/dashenc.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index fa56505f8f..1f31968ab9 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -561,6 +561,30 @@ static int write_manifest(AVFormatContext *s, int final) return 0; } +static int set_bitrate(AVFormatContext *s) +{ + DASHContext *c = s->priv_data; + int i; + + for (i = 0; i < s->nb_streams; i++) { + OutputStream *os = &c->streams[i]; + + os->bit_rate = s->streams[i]->codecpar->bit_rate; + if (os->bit_rate) { + snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), + " bandwidth=\"%d\"", os->bit_rate); + } else { + int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? + AV_LOG_ERROR : AV_LOG_WARNING; + av_log(s, level, "No bit rate set for stream %d\n", i); + if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) + return AVERROR(EINVAL); + } + } + + return 0; +} + static int dash_init(AVFormatContext *s) { DASHContext *c = s->priv_data; @@ -597,6 +621,10 @@ static int dash_init(AVFormatContext *s) if (!c->streams) return AVERROR(ENOMEM); + ret = set_bitrate(s); + if (ret < 0) + return ret; + for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVFormatContext *ctx; @@ -604,18 +632,6 @@ static int dash_init(AVFormatContext *s) AVDictionary *opts = NULL; char filename[1024]; - os->bit_rate = s->streams[i]->codecpar->bit_rate; - if (os->bit_rate) { - snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); - } else { - int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? - AV_LOG_ERROR : AV_LOG_WARNING; - av_log(s, level, "No bit rate set for stream %d\n", i); - if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT) - return AVERROR(EINVAL); - } - ctx = avformat_alloc_context(); if (!ctx) return AVERROR(ENOMEM); @@ -981,6 +997,8 @@ static int dash_write_trailer(AVFormatContext *s) { DASHContext *c = s->priv_data; + set_bitrate(s); + if (s->nb_streams > 0) { OutputStream *os = &c->streams[0]; // If no segments have been written so far, try to do a crude