[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