FFmpeg av_read_frame not reading frames properly?

2019-07-29 12:18发布

Alright, so I've downloaded some raw UHD sequences in .yuv format and encoded them with ffmpeg in .mp4 container (h264 4:4:4, 100% quality, 25fps). When i use ffprobe to find out how many frames are encoded i get 600, so that's 24 secs of video.

BUT, when i run those encoded video sequences through av_read_frame i only get like 40-50% of frames processed before av_read_frame returns error code -12. So I'm wild guessing that there are some data packages in middle of the streams which get read by av_read_frame and forces a function to return -12.

What my questions are, how should i deal with this problem so i can encode full number of frames (600)? When av_read_frame returns value different from 0 should i av_free_packet and proceed to read next frame? Since av_read_frame returns values < 0 for error codes, which error code is used for EOF so i can insulate end of file code?

标签: video ffmpeg
2条回答
冷血范
2楼-- · 2019-07-29 12:54

for some versions of libav the utility av_err2str is not compiled, i use the following trick:

#undef  av_err2str
#define av_err2str(errnum) av_make_error_string((char*)__builtin_alloca(AV_ERROR_MAX_STRING_SIZE), AV_ERROR_MAX_STRING_SIZE, errnum)
查看更多
该账号已被封号
3楼-- · 2019-07-29 13:02

Though it's difficult to say what's wrong with your decoding, still -12 is not a magic number that can't be understood.

printf("%s\n", av_err2str(-12));

This will print Cannot allocate memory, which is the real problem here.

And when getting a positive return value from av_read_frame(), it's ok to go on.

av_free_packet() has been deprecated, using av_packet_unref() instead, at the end of each av_read_frame() loop.

while(av_read_frame(fmt_ctx, &pkt) >= 0) {
    // decode packet and other stuff
    av_packet_unref(&pkt); 
}

At last, usually there's no need to worry about EOF, since av_decode_video2() or other decode functions will set a int parameter to proper value indicating whether there is frame to be decompressed.

If you're using a rather new ffmpeg(>=3.1) decoding/encoding API or really need to deal with EOF, compare the return value with AVERROR_EOF.

查看更多
登录 后发表回答