[Ffmpeg-devel] Intra-frame rate control
RLopez
rlopez
Thu Apr 12 22:12:33 CEST 2007
>On Thur, 12 Apr 2007, Baptiste Coudurier wrote:
>> On Wed, 11 Apr 2007, RLopez wrote:
>>
>>>> libavcodec supports adapting QP based on spatial and or temporal
>>>> complexity
>>>> of macroblocks, if you want to find out how then do as i said and
>>>> Read The Fine Manual
>>>
>>> Can you point me to where the manual discusses this? I looked through
>>> all
>>> the manuals on the ffmpeg website and didn't see any mention of adaptive
>>> spatial QP for MPEG2. Are there other manuals elsewhere that I don't
>>> know
>>> about?
>>
>> See all the options whose names end in _mask
>
>See also -mbd rd -flags +qprd
Do these switches work for MPEG2? Do they slow down the encoding when you
use them? I'm trying to replace the MPEG2 encoder we use with avcodec.lib
but I'm having problems getting bitrates that stay within an acceptable
range. I thought the problem was because avcodec.lib was only adjusting the
QP at frame boundaries. See the test I ran below. Would using some of the
switches mentioned give me better results?
I did a test where I encoded 10 flat gray frames(1920x1080) followed by 10
frames of random data using avcodec.lib and again using Pexeltool MPEG2
encoder at 20 Mbs. Here are the results:
avcodec Pixeltools
Frame # Frames size QP values Frames size QP values
======= ======================= ======================
1 30987 Fixed at 2 83245 1 - 3
2 30987 Fixed at 2 83242 1 - 3
3 30987 Fixed at 2 83239 Fixed at 1
4 30987 Fixed at 2 83239 Fixed at 1
5 30987 Fixed at 2 83239 Fixed at 1
6 30987 Fixed at 2 83239 Fixed at 1
7 30987 Fixed at 2 83239 Fixed at 1
8 30987 Fixed at 2 83239 Fixed at 1
9 30987 Fixed at 2 83239 Fixed at 1
10 30987 Fixed at 2 83239 Fixed at 1
11 3102876 Fixed at 2 86344 1 - 27
12 3103653 Fixed at 2 85680 12 - 31
13 1846080 Fixed at 5 83110 18 - 31
14 1498372 Fixed at 7 83141 27 - 31
15 1178371 Fixed at 10 83210 25 - 30
16 972263 Fixed at 13 83174 24 - 30
17 819350 Fixed at 16 83189 25 - 29
18 701635 Fixed at 19 83210 26 - 29
19 611076 Fixed at 22 83135 28 - 31
20 535178 Fixed at 25 83227 27 - 31
The average frame size should be 83416. Avcodec only changes the QP at
picture boundaries and when it hits frame 11 (the first random frame) the
bitrate skyrockets and it only adjusts the Q value by about 3 for each
subsequent frame. The Pixeltools encoder varies the Q throughout the frame
to keep the bitrate around 20 Mbs. I attached the code I used for the
avcodec test.
#include "avformat.h"
int picturebuf[1920*1080/2];
unsigned char outbuf[4*1024*1024];
AVCodecContext ffenc;
AVFrame picture;
int main(int argc, char* argv[])
{
int i,j,k,random,size1,size2;
FILE *fid;
AVCodec *codec;
int bitrate = 20000000;
int width = 1920;
int height = 1080;
int gopsize = 1;
int bframes = 0;
int ratenum = 1001;
int rateden = 30000;
av_register_all();
av_log_set_level(-1);
avcodec_get_frame_defaults(&picture);
avpicture_fill((AVPicture *)&picture, 0, PIX_FMT_YUV420P, width,
height);
size1 = picture.data[1] - picture.data[0];
size2 = picture.data[2] - picture.data[1];
avcodec_get_context_defaults(&ffenc);
ffenc.codec_id = CODEC_ID_MPEG2VIDEO;
ffenc.codec_type = CODEC_TYPE_VIDEO;
ffenc.sample_aspect_ratio.num = 1;
ffenc.sample_aspect_ratio.den = 1;
ffenc.bit_rate = bitrate;
ffenc.width = width;
ffenc.height = height;
ffenc.profile = 4;
ffenc.level = 4;
ffenc.time_base.num = ratenum;
ffenc.time_base.den = rateden;
ffenc.gop_size = gopsize;
ffenc.max_b_frames = bframes;
ffenc.scenechange_threshold = 1000000000;
ffenc.bit_rate_tolerance = 4000*1000;
ffenc.qblur = 0.5;
ffenc.rc_buffer_aggressivity = 1.0;
ffenc.pix_fmt = PIX_FMT_YUV420P;
codec = avcodec_find_encoder(ffenc.codec_id);
avcodec_open(&ffenc, codec);
fid = fopen("c:\\test.mpg","wb");
for (random=0;random<2;random++) {
if (!random) for (j=0;j<(1920*1080/2);j++) picturebuf[j] =
0x80808080;
for (i=0;i<10;i++) {
if (random) for (j=0;j<(1920*1080/2);j++) picturebuf[j] =
rand();
picture.data[0] = (unsigned char*) picturebuf;
picture.data[1] = picture.data[0] + size1;
picture.data[2] = picture.data[1] + size2;
k = avcodec_encode_video(&ffenc, outbuf, 16*1024*1024,
&picture);
fwrite(outbuf,1,k,fid);
}
}
fclose(fid);
avcodec_close(&ffenc);
return 0;
}
More information about the ffmpeg-devel
mailing list