Opened 3 years ago

Last modified 2 years ago

#9269 new defect

ffmpeg produces broken files when cutting mp4s

Reported by: Artem S. Tashkinov Owned by:
Priority: normal Component: undetermined
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by Artem S. Tashkinov)

Summary of the bug: when fast seeking along with specifying the length, ffmpeg produces files with broken PTS timestamps.

How to reproduce:

/tmp/ffmpeg/ffmpeg -ss 00:01:00 -i "source.mp4" -t 10 -c copy /tmp/100-10.mp4
ffmpeg version N-102619-gebedd26eef Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10 (GCC)
  configuration: --disable-static --enable-nonfree --enable-avfilter --disable-shared --enable-static --enable-gpl --enable-postproc --enable-pthreads --enable-libspeex --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-libopus --enable-libopenjpeg --disable-debug --disable-doc --enable-libpulse --extra-cflags='-mtune=generic' --enable-version3 --enable-libvorbis --enable-libfdk-aac --enable-gnutls --enable-libfreetype --enable-libx265 --enable-libdav1d --libdir=/usr/local/lib64 --enable-lto --enable-pic --prefix=/tmp/ffmpeg
  libavutil      57.  0.100 / 57.  0.100
  libavcodec     59.  1.100 / 59.  1.100
  libavformat    59.  2.101 / 59.  2.101
  libavdevice    59.  0.100 / 59.  0.100
  libavfilter     8.  0.101 /  8.  0.101
  libswscale      6.  0.100 /  6.  0.100
  libswresample   4.  0.100 /  4.  0.100
  libpostproc    56.  0.100 / 56.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'source.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
  Duration: 00:02:30.14, start: 0.000000, bitrate: 17106 kb/s
  Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1920x1080, 16995 kb/s, SAR 1:1 DAR 16:9, 29.85 fps, 29.85 tbr, 90k tbn (default)
    Metadata:
      handler_name    : VideoHandle
      vendor_id       : [0][0][0][0]
  Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 96 kb/s (default)
    Metadata:
      handler_name    : SoundHandle
      vendor_id       : [0][0][0][0]
Output #0, mp4, to '/tmp/100-10.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf59.2.101
  Stream #0:0(eng): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 16995 kb/s, 29.85 fps, 29.85 tbr, 90k tbn (default)
    Metadata:
      handler_name    : VideoHandle
      vendor_id       : [0][0][0][0]
  Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, mono, fltp, 96 kb/s (default)
    Metadata:
      handler_name    : SoundHandle
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=  323 fps=0.0 q=-1.0 Lsize=   22611kB time=00:00:10.01 bitrate=18499.6kbits/s speed=1.12e+03x    
video:22473kB audio:127kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.046347%

Tested with ffmpeg-4.4 and the current ffmpeg snapshot.

Also discussed here: https://github.com/mpv-player/mpv/issues/8876

The resulting files produced by ffmpeg:

4.4 https://drive.google.com/file/d/1hdK51zO0ANLjIX9bC_OVd-jBv7_ReLbH/view?usp=sharing

GIT: https://drive.google.com/file/d/1AWnpx3xgf7g-oiYLE3HGzlRouXe6Ea4T/view?usp=sharing

Using slow seeking (-ss timestamp after the source file) fixes the issue.

Change History (2)

comment:1 by Artem S. Tashkinov, 3 years ago

Description: modified (diff)

comment:2 by Bugmenot, 2 years ago

I can confirm similar behaviour using ffmpeg 4.4.1.

However, see this extract from https://trac.ffmpeg.org/wiki/Seeking :

Using -ss as input option together with -c:v copy might not be accurate since ffmpeg is forced to only use/split on i-frames. Though it will—if possible—adjust the start time of the stream to a negative value to compensate for that. Basically, if you specify "second 157" and there is no key frame until second 159, it will include two seconds of audio (with no video) at the start, then will start from the first key frame. So be careful when splitting and doing codec copy.

So, I suggest we use a different cutting strategy : cut audio & video at the same (innacurate) point, instead of including some seconds of audio with no video, because that confuses some players (and people ;)). IMHO, this I-frame cut is a limitation which shouldn't lead to a different length in audio and video streams, but the same lenght, to keep the audio & video coherent (even though the seeking point won't be exactly respected). What do you think?

Would you (ffmpeg developers) agree to modify this strategy?

Note: See TracTickets for help on using tickets.