[FFmpeg-user] Prevent ffmpeg from completely skipping corrupt frames when transcoding MPEG-2 TS?
ffmpeg at harkless.org
Wed Nov 23 14:23:40 EET 2022
Hi. I have some old SD & HD recordings in MPEG-2 Transport Stream
format, mostly recorded off my U.S. cable-box 1394 port with CapDVHS.
My end-goal is to transcode these to interlaced AVC, while preserving
the optional embedded Closed Captions. Per MediaInfo, the CCs are in
EIA-608 and EIA-708 format, (DTVCC Transport) muxed into the main video
I've tried various software to do the transcoding, but the only one that
preserves the CCs is ffmpeg. It even lets me use the MP4 container
format (which my old versions of Sony Vegas read, unlike MKV), thanks to
the single muxed video stream. A command like this (using a recent
gyan.dev Windows build, run from Cygwin bash) works almost perfectly:
% ffmpeg -y -i tvshow.ts -map 0 -c:v libx264 -b:v 5500k -flags
+ildct+ilme -threads 0 -pass 1 -fps_mode cfr -f null /dev/null && ffmpeg
-i tvshow.ts -map 0 -c:v libx264 -b:v 5500k -flags +ildct+ilme -threads
0 -pass 2 -fps_mode cfr -c:a copy -c:s copy tvshow.mp4
(Not 100% sure the -c:s copy is necessary. Also, I had to avoid using
slow presets, as they cause originally good frames after dropouts to
contain new corruption artifacts, presumably due to more aggressive
reference framing into the corrupt areas.)
The one glaring problem is that the .MP4 is over 30 seconds shorter than
the .TS. The reason for this is occasional corrupt frame-sequences.
When watching the original TS with VLC, at these points, the video
freezes and the audio goes silent for the expected duration, then
resumes, which I want.
In the transcoded MP4, the munged parts are just skipped over, so
someone will be cut off mid-word, and then the next frame, it
immediately jumps to where the signal came back, continuing
mid-someone-else's-word. Very jarring, and hides how much time is
missing in each dropout.
The docs say that when using -vsync/-fps_mode cfr, "Frames will be
duplicated and dropped to achieve exactly the requested constant frame
rate." Does this only apply to VFR->CFR conversion, not to handling of
corrupt frames? Is there any way to get ffmpeg to preserve these
time-slices, either by repeating the last good frame, or showing a black
frame or color bars?
Using 'NVEncC64 --avsync forcecfr' properly includes these sequences,
and matches the source length, with correct sync. But it doesn't
preserve the CCs. Looks like I might be able to get it to work if I add
Caption2Ass to convert them to subtitles, but I'd prefer to leave them
Things I've tried that didn't work include doing a simple -c copy to
another .TS file before transcoding, adding an explicit -r framerate,
-fflags genpts/igndts/sortdts, and more. I didn't try messing with
-async and -adrift_threshold, since the audio also drops out during the
I can use different (free) software if someone has a suggestion, but it
seems impossible that ffmpeg has no way to do this...?
More information about the ffmpeg-user