Предупреждение ffmpeg (libavcodec): слишком большой закодированный кадр

Я пытаюсь использовать libavcodec (ffmpeg) для кодирования необработанных данных пикселей в формат mp4. Все идет хорошо, и я получаю файл .avi с приличным качеством, но иногда кодек выдает предупреждение «слишком большой кодированный кадр». И когда это происходит, часть некоторых кадров (обычно нижняя часть кадра) выглядит искаженной или все смешанной. Кто-нибудь может сказать мне, когда дается это предупреждение. Ниже приведены настройки, которые я использую для кодировщика:

qmax = 6;
qmin = 2;
bit_rate = 200000; // if I increase this, I get more warnings. 
width = 1360;
height = 768;
time_base.den = 15; // frames per second
time_base.num = 1;
gop_size = 48;
pix_fmt = PIX_FMT_YUV420P;

С уважением,


person ivymike    schedule 05.10.2010    source источник
comment
Какой кодек вы используете? Быстрый поиск с помощью команды grep в источнике ffmpeg показывает, что эта ошибка генерируется кодеками (исходными файлами в libavcodec), а не мультиплексорами (исходными файлами в libavformat).   -  person stribika    schedule 05.10.2010
comment
Другое дело: вы хотите avi или mp4 файл?   -  person stribika    schedule 05.10.2010
comment
Я использую CODEC_ID_MPEG4 (используя av_guess_format (mp4, NULL, NULL);). Обычно формат mp4 хранится в контейнерах avi (поэтому конечным результатом всегда является файл avi).   -  person ivymike    schedule 05.10.2010


Ответы (3)


Из того, что я могу понять, ffmpeg выделяет постоянный размер буфера 2 МБ для хранения сжатого кадра. Например, 1080p - это 3 МБ без сжатия, а кодек не всегда может сжать большой кадр до размера менее 2 МБ.

Вы можете исправить это, увеличив размер буфера и / или сделав его динамическим.

person Jeff B    schedule 14.12.2010
comment
Спасибо, у меня была большая проблема с повреждением фильмов, связанная с этим. А пока поправил, уменьшив размер фильма. Известно ли вам, какие еще есть способы уменьшить размер закодированного кадра помимо разрешения? Такие вещи, как, скажем, изменить уровень сжатия jpeg внутри фреймов или что-то в этом роде? - person kriss; 15.12.2010
comment
Я поискал в исходном коде libavcodec и не нашел буфера размером 2 МБ. Более того, сообщение слишком большого закодированного кадра, похоже, связано с маленькими буферами (более крупный, который я обнаружил, проверенный в mpegvideo_enc.c, составляет около 3000 байт). - person kriss; 16.12.2010

Очень вероятно, что буфер кодека недостаточно велик. Попробуйте изменить rc_buffer_size. В качестве альтернативы вы можете попробовать следующие настройки:

ctx->bit_rate = 500000;
ctx->bit_rate_tolerance = 0;
ctx->rc_max_rate = 0;
ctx->rc_buffer_size = 0;
ctx->gop_size = 40;
ctx->max_b_frames = 3;
ctx->b_frame_strategy = 1;
ctx->coder_type = 1;
ctx->me_cmp = 1;
ctx->me_range = 16;
ctx->qmin = 10;
ctx->qmax = 51;
ctx->scenechange_threshold = 40;
ctx->flags |= CODEC_FLAG_LOOP_FILTER;
ctx->me_method = ME_HEX;
ctx->me_subpel_quality = 5;
ctx->i_quant_factor = 0.71;
ctx->qcompress = 0.6;
ctx->max_qdiff = 4;
ctx->directpred = 1;
ctx->flags2 |= CODEC_FLAG2_FASTPSKIP;
person psihodelia    schedule 16.12.2010
comment
Придется изучить настройки, но спасибо. Это что-то действительно новое для изучения. - person kriss; 18.12.2010

В примере кода я нашел что-то вроде:

outbuf_size = 100000;
outbuf = malloc(outbuf_size);

[...]

out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);

Нажатие outbuf_size на увеличение разрешило проблему.

person Anon    schedule 23.12.2011