[FFmpeg-user] Prevent ffmpeg from completely skipping corrupt frames when transcoding MPEG-2 TS?

Dan Harkless 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 
stream.

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 
as-is.

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 
corruptions.

I can use different (free) software if someone has a suggestion, but it 
seems impossible that ffmpeg has no way to do this...?

--
Dan Harkless
http://harkless.org/dan/



More information about the ffmpeg-user mailing list