From 205b8fd078e50aa3f7f401646dbb73de1bb35a10 Mon Sep 17 00:00:00 2001 From: Tobias Rapp Date: Mon, 6 Mar 2017 08:53:28 +0100 Subject: avcodec: estimate output bitrate for uncompressed video codecs Allows to get a more realistic total bitrate (and estimated file size) in avi_write_header. Previously a static default value of 200k was assumed. Adds an internal helper function for bitrate guessing. Signed-off-by: Tobias Rapp Reviewed-by: Michael Niedermayer --- libavcodec/internal.h | 6 ++++++ libavcodec/r210enc.c | 15 +++++++++++++++ libavcodec/rawenc.c | 2 ++ libavcodec/utils.c | 21 +++++++++++++++++++++ libavcodec/v210enc.c | 3 +++ libavcodec/v308enc.c | 3 +++ libavcodec/v408enc.c | 2 ++ libavcodec/v410enc.c | 3 +++ libavcodec/y41penc.c | 1 + 9 files changed, 56 insertions(+) (limited to 'libavcodec') diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 6e93eeb1a9..e5f132a673 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -363,4 +363,10 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); +/** + * Get an estimated video bitrate based on frame size, frame rate and coded + * bits per pixel. + */ +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c index 65b3c069fc..a55e5434f3 100644 --- a/libavcodec/r210enc.c +++ b/libavcodec/r210enc.c @@ -24,6 +24,18 @@ #include "internal.h" #include "bytestream.h" +static av_cold int encode_init(AVCodecContext *avctx) +{ + int aligned_width = FFALIGN(avctx->width, + avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64); + + avctx->bits_per_coded_sample = 32; + if (avctx->width > 0) + avctx->bit_rate = ff_guess_coded_bitrate(avctx) * aligned_width / avctx->width; + + return 0; +} + static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { @@ -73,6 +85,7 @@ AVCodec ff_r210_encoder = { .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R210, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, @@ -84,6 +97,7 @@ AVCodec ff_r10k_encoder = { .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_R10K, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, @@ -95,6 +109,7 @@ AVCodec ff_avrp_encoder = { .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AVRP, + .init = encode_init, .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .capabilities = AV_CODEC_CAP_INTRA_ONLY, diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index a2d5ccc0a6..d181b74570 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -44,6 +44,8 @@ FF_ENABLE_DEPRECATION_WARNINGS avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc); if(!avctx->codec_tag) avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 6f7b2e7af7..63a6349703 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -4343,3 +4343,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } + +int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) +{ + AVRational framerate = avctx->framerate; + int bits_per_coded_sample = avctx->bits_per_coded_sample; + int64_t bitrate; + + if (!(framerate.num && framerate.den)) + framerate = av_inv_q(avctx->time_base); + if (!(framerate.num && framerate.den)) + return 0; + + if (!bits_per_coded_sample) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + bits_per_coded_sample = av_get_bits_per_pixel(desc); + } + bitrate = (int64_t)bits_per_coded_sample * avctx->width * avctx->height * + framerate.num / framerate.den; + + return bitrate; +} diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c index d3a8e26bc1..a6afbbfc41 100644 --- a/libavcodec/v210enc.c +++ b/libavcodec/v210enc.c @@ -110,6 +110,9 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_v210enc_init(s); + avctx->bits_per_coded_sample = 20; + avctx->bit_rate = ff_guess_coded_bitrate(avctx) * 16 / 15; + return 0; } diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c index b60a72cee6..e88f1f4648 100644 --- a/libavcodec/v308enc.c +++ b/libavcodec/v308enc.c @@ -31,6 +31,9 @@ static av_cold int v308_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + avctx->bits_per_coded_sample = 24; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c index f37f360b73..e12965b7ad 100644 --- a/libavcodec/v408enc.c +++ b/libavcodec/v408enc.c @@ -26,6 +26,8 @@ static av_cold int v408_encode_init(AVCodecContext *avctx) { + avctx->bits_per_coded_sample = 32; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); return 0; } diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c index f35ff75963..5e2450279f 100644 --- a/libavcodec/v410enc.c +++ b/libavcodec/v410enc.c @@ -32,6 +32,9 @@ static av_cold int v410_encode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + avctx->bits_per_coded_sample = 32; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); + return 0; } diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c index 94acc343fb..ca94a3c171 100644 --- a/libavcodec/y41penc.c +++ b/libavcodec/y41penc.c @@ -31,6 +31,7 @@ static av_cold int y41p_encode_init(AVCodecContext *avctx) } avctx->bits_per_coded_sample = 12; + avctx->bit_rate = ff_guess_coded_bitrate(avctx); return 0; } -- cgit v1.2.3