avidemux works fine but trying the same with ffmpeg don't

Started by manbau00, September 21, 2018, 08:20:47 AM

Previous topic - Next topic

eumagga0x2a

The search for the actual bug in Avidemux is ongoing, but the nature of the problem becomes apparent: when indexing TS files, Avidemux gets the size of each keyframe slightly wrong (in the samples I tried +6 bytes), which means that following PES packets are shifted 6 bytes relative to respective frame boundaries. This confuses ffmpeg which sees the beginning of a second frame in the first packet but doesn't have DTS/PTS for it yet. When the second packet arrives from the demuxer, it pushes it with timestamps unset to the muxer so that saving fails.

If you edit the .idx2 file to subtract 6 from the first field following each IF or DF marker, reload the TS file in Avidemux and save a portion of it in copy mode using the MpegTS muxer, ffmpeg is able to remux resulting video to mkv without problems.

manbau00

Fine, hopefully you find it.

At the moment I use ffmpeg to cut the ts files.

eumagga0x2a

Quote from: eumagga0x2a on October 09, 2018, 07:00:44 PM
the nature of the problem becomes apparent: when indexing TS files, Avidemux gets the size of each keyframe slightly wrong (in the samples I tried +6 bytes)

It turned out to be that it is the internal FFmpeg that adds these 6 bytes to each packet with H.264 video, my first analysis was plain wrong.

eumagga0x2a

Please try the latest nightly, it contains a fix by Mean for mpegts with H.264 video (not yet for HEVC).

The problem is that during indexing of H.264 streams Avidemux sets the frame boundary to the first NAL unit after the access unit delimiter (AUD), it should be at AUD. The internal libavformat notices that the packet doesn't start with AUD and generates an AUD itself (this increases the length of each packet by 6 bytes for H.264 and by 7 bytes for HEVC). Now we get two consecutive delimiters – the one which came with the original stream and actually belongs to the following frame, but now is at the end of the current frame, and another one that libavformat added for us.

When ffmpeg parses such a stream, it interprets the second AUD as an empty packet with unknown timestamp – at this point remuxing fails. The fix removes trailing AUDs before the frame is passed to the muxer.

Things are a little bit more complex for HEVC (Avidemux sets frame boundary to a different type of NALU) , but the general outlines of the problem are the same.

manbau00

Test with H264 looks good.

First I cut the file with avidemux and remuxed it to MPEG-TS. Afterwards I remuxed it to mkv with ffmpeg.

ffmpeg -hide_banner -i Test.ts -map 0 -c copy -ignore_unknown -sn -f matroska -y Test.mkv

Input #0, mpegts, from 'Test.ts':
  Duration: 01:30:21.34, start: 0.025122, bitrate: 11977 kb/s
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn, 100 tbc
    Stream #0:1[0x101](deu): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 192 kb/s
    Stream #0:2[0x102](mis): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 192 kb/s
    Stream #0:3[0x103](deu): Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, stereo, fltp, 448 kb/s
Output #0, matroska, to 'Test.mkv':
  Metadata:
    encoder         : Lavf57.83.100
    Stream #0:0: Video: h264 (High) (H264 / 0x34363248), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 50 fps, 50 tbr, 1k tbn, 90k tbc
    Stream #0:1(deu): Audio: mp2 (P[0][0][0] / 0x0050), 48000 Hz, stereo, s16p, 192 kb/s
    Stream #0:2(mis): Audio: mp2 (P[0][0][0] / 0x0050), 48000 Hz, stereo, s16p, 192 kb/s
    Stream #0:3(deu): Audio: ac3 ([0]
  • / 0x2000), 48000 Hz, stereo, fltp, 448 kb/s
    Stream mapping:
      Stream #0:0 -> #0:0 (copy)
      Stream #0:1 -> #0:1 (copy)
      Stream #0:2 -> #0:2 (copy)
      Stream #0:3 -> #0:3 (copy)
    Press [q] to stop, [?] for help
    frame=271066 fps=8174 q=-1.0 Lsize= 7250751kB time=01:30:21.29 bitrate=10956.4kbits/s speed= 163x
    video:6693272kB audio:550600kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.094967%

    Is there a way to reconstruct the damaged MPEG-TS Files? Or is the information lost forever?

eumagga0x2a

#20
Quote from: manbau00 on October 26, 2018, 08:16:22 AM
Is there a way to reconstruct the damaged MPEG-TS Files? Or is the information lost forever?

In case of H.264, no information is lost at all. In case of HEVC, it looks like dropping SEI_PREFIX NALUs mostly doesn't cause any trouble. As of now, the new AUD remover doesn't handle HEVC correctly as it removes AUD but not the following SEI_PREFIX NALUs which actually belong to the following frame. In any case, no picture data is lost.

To fix mpegts files containing a H.264 video track with multiple consecutive AUDs, save them in copy mode using Avidemux (using a nightly build containing the fix mentioned above).