3

I'm trying to use libavcodec (ffmpeg) to encode raw pixel data to mp4 format. Every thing goes well and I'm getting .avi file with decent quality but some times the codec gives "encoded frame too large" warning. And when ever it does that, a part of some frames (usually bottom portion of the frame) look garbled or all mixed up. Can any one tell me when this warning is given. Following are the settings I'm using for encoder:

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;

Regards,

ivymike
  • 1,511
  • 2
  • 20
  • 27
  • What codec are you using? A quick grep on the ffmpeg source shows that this error is generated by the codecs (source files in libavcodec) and not the muxers (source files in libavformat). – stribika Oct 05 '10 at 13:25
  • Another thing: do you want an avi or a mp4 file? – stribika Oct 05 '10 at 13:26
  • I'm using CODEC_ID_MPEG4 (using "av_guess_format("mp4", NULL, NULL);"). In general mp4 format is stored in avi containers (so the end result is always avi file). – ivymike Oct 05 '10 at 13:36

3 Answers3

4

From what I can gather ffmpeg allocates a constant buffer size of 2MB to hold a compressed frame. 1080p is 3MB uncompressed for example, and the codec can't always compress a large frame into less than 2MB.

You can possibly fix this by increasing the buffer size, and/or making it dynamic.

Jeff B
  • 29,943
  • 7
  • 61
  • 90
  • Thanks, I had a big problem of movie corruption related to that. For now I corrected it using a smaller movie size. Do you known what other possible ways there is to reduce encoded frame size beside resolution. Things like say change jpeg compression level inside frames, or such ? – kriss Dec 15 '10 at 13:57
  • I have searched in the source code of libavcodec and can't find any 2MB buffer. More so the "encoded frame too large" message seems to be related to small buffers (larger I found, tested in mpegvideo_enc.c, is about 3000 bytes). – kriss Dec 16 '10 at 10:34
2

Very probably that codec's buffer is not big enough. Try to change rc_buffer_size. Alternatively, you can try this settings:

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;
psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • I will have to explore the settings, but thanks. That's something really new to explore. – kriss Dec 18 '10 at 08:19
1

In the example code I found something like:

outbuf_size = 100000;
outbuf = malloc(outbuf_size);

[...]

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

Pushing outbuf_size to be larger resolved the issue.

Anon
  • 11
  • 1