0

I discovered some damaged AVI files that VLC complains about broken index when I try to play them. I can play directly without ability to scroll the timeline or wait...wait... for the index to be built (but not saved) and play normally. Some other players can play them without complaining, others refuse to play.

I can solve the problem seamlessly in VirtualDub by opening the .avi with "extended options" in Open with "re-derive keyframe flags" and then saving a new .AVI file with direct-stream-copy for video and audio. The resulting file plays perfectly.

I can also solve the problem with ffmpeg but not without problems.

ffmpeg -i INFILE -vcodec copy -acodec copy OUTFILE

Important: only stream copy and same container are of interest.

The resulting file plays in VLC without complaints or the next problem, but in many other players when jumping on the timeline the video gets distorted immediately at the jump destination and stays heavily distorted until the next I frame in the stream. All this doesn't happen when it was processed with VirtualDub.

ffmpeg is faster but most importantly it is scriptable and one could make automation for many files. With VirtualDub one has to manually process each file and wait a looooooong time for the open process to re-derive keyframe flags first. Wouldn't mind if ffmpeg speed was lost because of the automation it can provide.

So far I only found a very old unanswered mailing list post here

Can ffmpeg fix such files, without the afore mentioned problem? If yes, how?

Thank you.

andrixnet
  • 41
  • 1
  • 8

1 Answers1

0

AVI file indexes contain all frames (key or not), but they have a flags field (which FFmpeg fills in) which should help players seek only to keyframes. I don't have access to your exact file (ffprobe information would be helpful), but we can assume the flags field is not written correctly, e.g. it might be set for every frame or for none at all.

VLC likely parses the codec packets to derive the keyframe flag if absent in the container, but other players might not. I think what you're looking for is to derive keyframe flags while stream-copying. The exact commandline depends a bit on the codec. For example, for H264 you'd want to dump to annex-B as intermediate file format, and then re-read that so the H264 parser is invoked, which sets the keyframe flag, and then re-mux that into AVI - but H264 in AVI is rare so that's probably not what's happening here.

So for a solution, I will need the output of ffprobe $file so I know what codec the AVI file contains.

Ronald S. Bultje
  • 10,828
  • 26
  • 47
  • Example 1: `Duration: 01:29:36.13, start: 0.000000, bitrate: 810 kb/s Stream #0:0: Video: msmpeg4v3 (DIV3 / 0x33564944), yuv420p, 352x224, 709 kb/ s, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc Metadata: title : Videostream Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 96 kb /s Metadata: title : Audiostream 1` according to ffprobe I see nothing particular. `ffmpeg -i X.avi -vcodec copy -acodec copy Y.avi` results in a good file (in all players) – andrixnet Feb 02 '22 at 10:49
  • But this was a quit test today with another file I just discovered, while not having access to one of those that prompted me to write the question in the first place. I'll have to see also about ffmpeg version differences. – andrixnet Feb 02 '22 at 12:27
  • In this particular codec, this will be difficult. There are no dedicated parsers for this codec, so you need a full decode (like what Vdub does) to re-derive frametype (like keyframe). You could alternatively write your own decoder that only parses keyframe flags, but that's probably not what you want. For scripting, you could write your own FFmpeg'ish application that decodes (to derive keyframe flag) and then uses that flag to re-mux the originally-encoded packet. But there is unfortunately no straightforward solution. – Ronald S. Bultje Feb 02 '22 at 13:07
  • Another file out of the can: ` Duration: 01:22:40.12, start: 0.000000, bitrate: 1186 kb/s Stream #0:0: Video: mpeg4 (XVID / 0x44495658), yuv420p, 576x320 [SAR 1:1 DAR 9:5], 986 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc Stream #0:1: Audio: ac3 ([0] [0][0] / 0x2000), 48000 Hz, stereo, fltp, 192 k b/s` Different codec, ffprobe doesn't show anything IMO abnormal to indicate missing or damaged index. `ffmpeg -i X.avi -vcodec copy -acodec copy Y.avi` results again in a good file. (I mean in problematic players) Still searching. – andrixnet Feb 02 '22 at 16:47
  • Another file: `[avi @ 035c2060] Non-interleaved AVI without index, switching to interleaved Duration: 01:09:33.80, start: 0.000000, bitrate: 1131 kb/s Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 600x480 [SAR 1:1 DAR 5:4], 25 fps, 25 tbr, 25 tbn, 25 tbc Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 128 kb/s` This is the first time ffprobe mentiones anything about AVI index problems. VLC refuses to play, other players refuse to seek. – andrixnet Feb 02 '22 at 16:55
  • Am I just unlucky today? Have I just managed to correct all the badly damaged files with VirtualDub already? I mean ffmpeg now seems to repair files correctly... – andrixnet Feb 02 '22 at 16:57
  • Guess I'm just going to try them one by one, by hand, and depeding on the outcome rework with VirtualDub. – andrixnet Feb 02 '22 at 17:07
  • This file `Duration: 02:25:11.75, start: 0.000000, bitrate: 653 kb/s Stream #0:0: Video: msmpeg4v3 (DIV3 / 0x33564944), yuv420p, 640x272, 520 kb/ s, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc Metadata: title : Videostream Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 128 k b/s` doesn't seem much different then previous examples, but after ffmpeg and *codec copy both VLC and MPC play it with the problematic effect when seeking. VirtualDub method fixed it properly. I guess I'll stick to this manual method :-( – andrixnet Feb 02 '22 at 17:32