HOWTO: Check avi file for errors

TOC

  1. Introduction
  2. Disclaimer
  3. Scanning avi file for errors
  4. Automation, or scanning multiple files
  5. Verifying result with VirtualDub
  6. Local downloads
  7. Links

Introduction

So... you've got an avi file (I don't want to know how) and you're having problems playing it, or converting it, or "put-the-word-here" you wish to do with it...? This small article will introduce (one-of) the ways of checking a movie file for errors, bad frames or whatever else could go wrong with it.

Disclaimer

This article is published here, because I think that someone else might find it useful. However, before go on reading you should accept that "All this comes with no warranty. You're using it at your own risk."

Please, note, that possession and distribution of pirated content is illegal.

Scanning avi file for errors

The best way to scan an .avi is to decompress each and every video- and audio-frame and to yell with fury in case something goes wrong. VirtualDubMod has an option scan an .avi file for errors, but in most cases errors are cleverly covered up by the wise decoders. AviFix could scan the movie but it will detect only some errors (since AFAIK avi container does not include even simple CRC check). DRF Analyzer scans .avi files and makes a text- and image-based report of image quality and sometimes it would crash during the scan phase when the movie file is seriously damaged.

So here comes my winner: ffmpeg. ffmpeg is really a "Swiss-Army Knife" for the video/audio conversions and much more, and is perfectly suitable for the scan task when invoked with a "null" output, as shown below:

$ ffmpeg -v 5 -i episode01.avi -f null -
Input #0, avi, from 'episode01.avi':
  Duration: 00:23:52.1, bitrate: 1188 kb/s
  Stream #0.0: Video: mpeg4, 640x480, 29.97 fps
  Stream #0.1: Audio: mp3, 48000 Hz, stereo, 128 kb/s
Output #0, null, to 'pipe:':
  Stream #0.0: Video: rawvideo, yuv420p, 640x480, 29.97 fps, q=2-31, 200 kb/s
  Stream #0.1: Audio: pcm_s16le, 48000 Hz, stereo, 1536 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame=   63 q=0.0 size=       0kB time=2.1 bitrate=   0.0kbits/s    

The last line will track current progress. It will take some time for ffmpeg to process your file, depending on your machine speed, resolution, compression type, etc. If everything is OK ffmpeg will output one more line, similar to this one:

video:0kB audio:268520kB global headers:0kB muxing overhead -100.000000%

Any other line (with a few exceptions) should be considered for an error. Here is a partial list of errors I've got so far:

[msmpeg4 @ 0x68a3c0]ac-tex damaged at 15 10
[msmpeg4 @ 0x68a3c0]
error while decoding block: 15 x 10 (3)
[msmpeg4 @ 0x68a3c0]Error at MB: 425
[msmpeg4 @ 0x68a3c0]concealing errors
[mpeg4 @ 0x6913c0]I cbpy damaged at 20 19
[mpeg4 @ 0x6913c0]Error at MB: 742
[mpeg4 @ 0x6913c0]concealing errors
[mpeg4 @ 0x6913c0]ac-tex damaged at 20 15
[mpeg4 @ 0x6913c0]Error at MB: 590
[mpeg4 @ 0x6913c0]concealing errors

There are two errors that I consider to be just warnings:

It seems that "header damaged" error is shown instead of "dropped frames" warning:

[mpeg4 @ 0x6913c0]header damaged
Error while decoding stream #0.0

Next warning is displayed on some DivX4-encoded movies:

[mpeg4 @ 0x6913c0]looks like this file was encoded with (divx4/(old)xvid/opendivx)
  -> forcing low_delay flag

Automation, or scanning multiple files

Redirecting output to a file

If you wish to save ffmpeg output use a command similar to this one:

$ ffmpeg -v 5 -i episode01.avi -f null - 2> episode01.txt

However, there will be no indication of current progress.

bash script to scan multiple files consecutively

The following script would scan all .avi files located in sub-directories of the current directory. When the script completes, next to every .avi file would stand .avi.txt.ok or .avi.txt file with the results. As you could guess if result file is .avi.txt.ok .avi file is all right (heuristics is pretty simple).

#!/bin/bash

FFMPEG="/bin/ffmpeg"
LIST=`find | grep \.avi$`

for i in $LIST; do
    OUTP="$i.txt"
    OUTP_OK="$i.txt.ok"
    TMP_OUTP="$i.tmp"
    if [ -f "$OUTP" -o -f "$OUTP_OK" ] ; then
	echo Skipping "$i"
    else
	echo Checking "$i"...
	RESULT="bad"
	"$FFMPEG" -v 5 -i "$i" -f null - 2> "$TMP_OUTP" && \
	    mv "$TMP_OUTP" "$OUTP" && \
	    RESULT=`grep -v "\(frame\)\|\(Press\)" "$OUTP" | grep "\["`
	if [ -z "$RESULT" ] ; then
	    mv "$OUTP" "$OUTP_OK"
	fi
    fi
done

If you're living in the Microsoft's world fetch CYGWIN.

Verifying result with VirtualDub

NOTE: This section assumes, that you're using Windows OS and you've stored the ffmpeg's output in a text file.

When you have errors reported open the text file and locate first error. Generally it would be between two frame= ... lines, for example:

frame= 2943 q=0.0 size=       0kB time=122.7 bitrate=   0.0kbits/s
[msmpeg4 @ 0x68a3c0]ac-tex damaged at 15 13
[msmpeg4 @ 0x68a3c0]
error while decoding block: 15 x 13 (0)
[msmpeg4 @ 0x68a3c0]Error at MB: 548
[msmpeg4 @ 0x68a3c0]concealing errors
frame= 2999 q=0.0 size=       0kB time=125.1 bitrate=   0.0kbits/s

Now open the .avi file with VirtualDub (or VirtualDubMod), jump to the first frame (Ctrl+G) and step towards the next frame. If there is a big damage, you'll see it. In case the number of errors is not too high you can check them all using the method provided.

Local downloads

Here is a precompiled binary of ffmpeg with included AC3-support (Win32, 1MB) and ffmpeg CVS snapshot (source code, 3,3MB) used to compile the binary.

To run executable you'll probably need cygwin1.dll (Win32, 512KB) and cygz.dll (Win32, 35KB)

NOTE: gz extension goes for Gzip Compressed Archive; both, WinZip and WinRar, can handle those.

Links

Links are in alphabetical order.