Skip to content
Snippets Groups Projects
Commit 205b8fd0 authored by Tobias Rapp's avatar Tobias Rapp
Browse files

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: default avatarTobias Rapp <t.rapp@noa-archive.com>
Reviewed-by: default avatarMichael Niedermayer <michael@niedermayer.cc>
parent 8db301de
No related branches found
No related tags found
No related merge requests found
Showing
with 67 additions and 11 deletions
...@@ -363,4 +363,10 @@ int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, i ...@@ -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, int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
void **data, size_t *sei_size); 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 */ #endif /* AVCODEC_INTERNAL_H */
...@@ -24,6 +24,18 @@ ...@@ -24,6 +24,18 @@
#include "internal.h" #include "internal.h"
#include "bytestream.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, static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *pic, int *got_packet) const AVFrame *pic, int *got_packet)
{ {
...@@ -73,6 +85,7 @@ AVCodec ff_r210_encoder = { ...@@ -73,6 +85,7 @@ AVCodec ff_r210_encoder = {
.long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_R210, .id = AV_CODEC_ID_R210,
.init = encode_init,
.encode2 = encode_frame, .encode2 = encode_frame,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
.capabilities = AV_CODEC_CAP_INTRA_ONLY, .capabilities = AV_CODEC_CAP_INTRA_ONLY,
...@@ -84,6 +97,7 @@ AVCodec ff_r10k_encoder = { ...@@ -84,6 +97,7 @@ AVCodec ff_r10k_encoder = {
.long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_R10K, .id = AV_CODEC_ID_R10K,
.init = encode_init,
.encode2 = encode_frame, .encode2 = encode_frame,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
.capabilities = AV_CODEC_CAP_INTRA_ONLY, .capabilities = AV_CODEC_CAP_INTRA_ONLY,
...@@ -95,6 +109,7 @@ AVCodec ff_avrp_encoder = { ...@@ -95,6 +109,7 @@ AVCodec ff_avrp_encoder = {
.long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_AVRP, .id = AV_CODEC_ID_AVRP,
.init = encode_init,
.encode2 = encode_frame, .encode2 = encode_frame,
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE }, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
.capabilities = AV_CODEC_CAP_INTRA_ONLY, .capabilities = AV_CODEC_CAP_INTRA_ONLY,
......
...@@ -44,6 +44,8 @@ FF_ENABLE_DEPRECATION_WARNINGS ...@@ -44,6 +44,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc); avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc);
if(!avctx->codec_tag) if(!avctx->codec_tag)
avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);
avctx->bit_rate = ff_guess_coded_bitrate(avctx);
return 0; return 0;
} }
......
...@@ -4343,3 +4343,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, ...@@ -4343,3 +4343,24 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len,
return 0; 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;
}
...@@ -110,6 +110,9 @@ FF_ENABLE_DEPRECATION_WARNINGS ...@@ -110,6 +110,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
ff_v210enc_init(s); ff_v210enc_init(s);
avctx->bits_per_coded_sample = 20;
avctx->bit_rate = ff_guess_coded_bitrate(avctx) * 16 / 15;
return 0; return 0;
} }
......
...@@ -31,6 +31,9 @@ static av_cold int v308_encode_init(AVCodecContext *avctx) ...@@ -31,6 +31,9 @@ static av_cold int v308_encode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
avctx->bits_per_coded_sample = 24;
avctx->bit_rate = ff_guess_coded_bitrate(avctx);
return 0; return 0;
} }
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
static av_cold int v408_encode_init(AVCodecContext *avctx) 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; return 0;
} }
......
...@@ -32,6 +32,9 @@ static av_cold int v410_encode_init(AVCodecContext *avctx) ...@@ -32,6 +32,9 @@ static av_cold int v410_encode_init(AVCodecContext *avctx)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
avctx->bits_per_coded_sample = 32;
avctx->bit_rate = ff_guess_coded_bitrate(avctx);
return 0; return 0;
} }
......
...@@ -31,6 +31,7 @@ static av_cold int y41p_encode_init(AVCodecContext *avctx) ...@@ -31,6 +31,7 @@ static av_cold int y41p_encode_init(AVCodecContext *avctx)
} }
avctx->bits_per_coded_sample = 12; avctx->bits_per_coded_sample = 12;
avctx->bit_rate = ff_guess_coded_bitrate(avctx);
return 0; return 0;
} }
......
f7cf1b743c18f74d047ce8d6ea05d3d9 5fd2d9a7b3311f5c19dbdd647bb9eae6
a0b35707a9aa7144e3e1c70c1d01f4ce *tests/data/fate/vsynth1-bpp1.avi 1c78e77c971b1ce31f229c6fc23d0902 *tests/data/fate/vsynth1-bpp1.avi
640460 tests/data/fate/vsynth1-bpp1.avi 640460 tests/data/fate/vsynth1-bpp1.avi
cd1e1448d9895561347ceb66d0add34d *tests/data/fate/vsynth1-bpp1.out.rawvideo cd1e1448d9895561347ceb66d0add34d *tests/data/fate/vsynth1-bpp1.out.rawvideo
stddev: 84.48 PSNR: 9.60 MAXDIFF: 218 bytes: 7603200/ 7603200 stddev: 84.48 PSNR: 9.60 MAXDIFF: 218 bytes: 7603200/ 7603200
dc37d1db0429f44000a03a60862751cd *tests/data/fate/vsynth1-bpp15.avi 6147f5f235657fa9ced6ec6146be6ff0 *tests/data/fate/vsynth1-bpp15.avi
10144452 tests/data/fate/vsynth1-bpp15.avi 10144452 tests/data/fate/vsynth1-bpp15.avi
3aee2d6e82a9507d7f01844c04d2b57b *tests/data/fate/vsynth1-bpp15.out.rawvideo 3aee2d6e82a9507d7f01844c04d2b57b *tests/data/fate/vsynth1-bpp15.out.rawvideo
stddev: 38.44 PSNR: 16.43 MAXDIFF: 159 bytes: 7603200/ 7603200 stddev: 38.44 PSNR: 16.43 MAXDIFF: 159 bytes: 7603200/ 7603200
fd2bb8b3d3e47f5ea7769443324ee0ae *tests/data/fate/vsynth1-r210.avi 1ea72f280b110ed65fc535c3438d27f9 *tests/data/fate/vsynth1-r210.avi
22125252 tests/data/fate/vsynth1-r210.avi 22125252 tests/data/fate/vsynth1-r210.avi
ecaafa9eec11b5e1453a63ed6d194eed *tests/data/fate/vsynth1-r210.out.rawvideo ecaafa9eec11b5e1453a63ed6d194eed *tests/data/fate/vsynth1-r210.out.rawvideo
stddev: 3.23 PSNR: 37.94 MAXDIFF: 48 bytes: 7603200/ 7603200 stddev: 3.23 PSNR: 37.94 MAXDIFF: 48 bytes: 7603200/ 7603200
c8a4b8648436e73ced7fe32f6f65a1b3 *tests/data/fate/vsynth1-rgb.avi 9d2bd1fa569a803c41b5dc5dd03f088e *tests/data/fate/vsynth1-rgb.avi
15213252 tests/data/fate/vsynth1-rgb.avi 15213252 tests/data/fate/vsynth1-rgb.avi
93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-rgb.out.rawvideo 93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-rgb.out.rawvideo
stddev: 3.42 PSNR: 37.44 MAXDIFF: 48 bytes: 7603200/ 7603200 stddev: 3.42 PSNR: 37.44 MAXDIFF: 48 bytes: 7603200/ 7603200
0712d60b3a00cf2d5a7e39aa21e2547a *tests/data/fate/vsynth1-v210.avi 767471c71d60daf46ca3a758771c4f8e *tests/data/fate/vsynth1-v210.avi
14752452 tests/data/fate/vsynth1-v210.avi 14752452 tests/data/fate/vsynth1-v210.avi
2ba7f4ca302f3c4147860b9dfb12b6e4 *tests/data/fate/vsynth1-v210.out.rawvideo 2ba7f4ca302f3c4147860b9dfb12b6e4 *tests/data/fate/vsynth1-v210.out.rawvideo
stddev: 1.84 PSNR: 42.81 MAXDIFF: 29 bytes: 7603200/ 7603200 stddev: 1.84 PSNR: 42.81 MAXDIFF: 29 bytes: 7603200/ 7603200
230bbd31c82d4fbb92d5ea2ac591ded5 *tests/data/fate/vsynth1-v210-10.avi 9269ce2a5294a4c9a8346328d06b23af *tests/data/fate/vsynth1-v210-10.avi
14752452 tests/data/fate/vsynth1-v210-10.avi 14752452 tests/data/fate/vsynth1-v210-10.avi
50973792d3f1abe04a51ee0121f077f2 *tests/data/fate/vsynth1-v210-10.out.rawvideo 50973792d3f1abe04a51ee0121f077f2 *tests/data/fate/vsynth1-v210-10.out.rawvideo
stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200 stddev: 1.85 PSNR: 42.78 MAXDIFF: 29 bytes: 7603200/ 7603200
58ea26d3060f9d47cf95056ed9361c90 *tests/data/fate/vsynth1-v308.avi 5d868b73c554a9a2422d6c8a18ce9c02 *tests/data/fate/vsynth1-v308.avi
15213252 tests/data/fate/vsynth1-v308.avi 15213252 tests/data/fate/vsynth1-v308.avi
10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo 10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo
stddev: 2.67 PSNR: 39.60 MAXDIFF: 43 bytes: 7603200/ 7603200 stddev: 2.67 PSNR: 39.60 MAXDIFF: 43 bytes: 7603200/ 7603200
4ac68e91ac25bc422abb3febe86a4acd *tests/data/fate/vsynth1-v408.avi 4e977bec707cda2b09edb717805cb960 *tests/data/fate/vsynth1-v408.avi
20282052 tests/data/fate/vsynth1-v408.avi 20282052 tests/data/fate/vsynth1-v408.avi
c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-v408.out.rawvideo c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-v408.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
862ffddd90c82163d2505031e5bbcd9a *tests/data/fate/vsynth1-y41p.avi 7355fc7614e1ba50d364fc13af5fc3e1 *tests/data/fate/vsynth1-y41p.avi
7610052 tests/data/fate/vsynth1-y41p.avi 7610052 tests/data/fate/vsynth1-y41p.avi
3aef1d83732a3f9835ee2523a11c95c1 *tests/data/fate/vsynth1-y41p.out.rawvideo 3aef1d83732a3f9835ee2523a11c95c1 *tests/data/fate/vsynth1-y41p.out.rawvideo
stddev: 5.98 PSNR: 32.59 MAXDIFF: 87 bytes: 7603200/ 7603200 stddev: 5.98 PSNR: 32.59 MAXDIFF: 87 bytes: 7603200/ 7603200
2b930d809c19e8d50eb4c92474085c27 *tests/data/fate/vsynth1-yuv.avi 795ce63f1fe371b98822b1cb385b062f *tests/data/fate/vsynth1-yuv.avi
7610052 tests/data/fate/vsynth1-yuv.avi 7610052 tests/data/fate/vsynth1-yuv.avi
c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv.out.rawvideo c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv.out.rawvideo
stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200 stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment