[libav-api] Best way to discard bad frames in a video file?
Phillip LeBlanc
Phillip.LeBlanc at nrlssc.navy.mil
Fri Jun 24 18:38:42 CEST 2011
Hi all,
I am trying to take a video and output each individual frame to disk as an image. This is a relatively simple process using the ffmpeg command line, but I want to be able to drop bad frames. The video that I have is pretty messed up and I would like to be able to drop any frame that has any kind of error that libav can detect, such as these:
[mpeg2video @ 0x97d1580] ac-tex damaged at 4 23
[mpeg2video @ 0x97d1580] Warning MVs not available
[mpeg2video @ 0x97d1580] concealing 280 DC, 280 AC, 280 MV errors
[mpeg2video @ 0x97d1580] ac-tex damaged at 17 15
[mpeg2video @ 0x97d1580] Warning MVs not available
[mpeg2video @ 0x97d1580] concealing 600 DC, 600 AC, 600 MV errors
[mpeg2video @ 0x97d1580] skipped MB in I frame at 19 15
[mpeg2video @ 0x97d1580] ac-tex damaged at 5 27
[mpeg2video @ 0x97d1580] concealing 240 DC, 240 AC, 240 MV errors
My initial approach involved following the tutorial at http://dranger.com/ffmpeg/ (which conveniently saved frames to images) and I added a log callback to parse for the error messages. Right before I call the function to save the frame, I check to see if error_happened is equal to 1 (see below code snippets).
void log_callback(void* ptr, int level, const char* fmt, va_list vl) {
AVClass* avc= ptr ? *(AVClass**)ptr : NULL;
if (level > av_log_get_level())
return;
if (avc && !strcmp(avc->item_name(ptr), "mpeg2video")){
error_happened = 1;
// Notify main function
}
}
... and later on
if (error_happened)
{
error_happened=0;
fprintf(stderr, "Skipping frame #%d\n", i);
continue;
}
My question is, is this the best way to go about this? Is there a simpler way to tell libav to drop any bad frames instead of trying to correct them? I poked around libavcodec/mpeg12.c and libavcodec/error_resilience.c and I didn't really see anything too useful (of course I am relatively new to this, so I don't exactly know what to look for). Any help would be greatly appreciated.
Here is the output from ffprobe on the video file I'm using, if it will help. I know that all of the frames in the video are I-frames, not P or B frames. Also, the unknown stream is called KLV Metadata (http://www.gwg.nga.mil/misb/faq.html#section3.2) and for the purposes of my project, I'm not interested in it.
ffprobe version v0.7-57-gadbfc60, Copyright (c) 2007-2011 the Libav developers
built on Jun 24 2011 09:03:04 with gcc 4.5.2
configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-x11grab --enable-shared
libavutil 51. 8. 0 / 51. 8. 0
libavcodec 53. 5. 0 / 53. 5. 0
libavformat 53. 2. 0 / 53. 2. 0
libavdevice 53. 0. 0 / 53. 0. 0
libavfilter 2. 4. 0 / 2. 4. 0
libswscale 2. 0. 0 / 2. 0. 0
libpostproc 52. 0. 0 / 52. 0. 0
[mpegts @ 0x8abe520] max_analyze_duration reached
Input #0, mpegts, from 'Host/PumaAE_2011-05-12_16-13-18.00Z.mpg':
Duration: 00:27:54.81, start: 6966.903333, bitrate: 6255 kb/s
Program 1
Stream #0.0[0x80]: Video: mpeg2video (Main), yuv420p, 640x480 [PAR 1:1 DAR 4:3], 6000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0.1[0x90]: Data: [6][0][0][0] / 0x0006
Unsupported codec with id 102400 for input stream 1
--
Phillip LeBlanc
Naval Research Laboratory, Code 7442
1005 Balch Blvd, Room D-9F
Stennis Space Center, MS 39529
More information about the libav-api
mailing list