Opened 21 months ago

#5415 new defect

Incorrect timestamps when using seek OR segment muxer for mp4

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

Description

Hi,

According to https://trac.ffmpeg.org/wiki/Seeking#Cuttingsmallsections it should be possible to cut a part of an e.g. mp4 file and keep the original timestamps (using copyts).
Also, it should be possible to segment an e.g. mp4 and keep original timestamps using the segment muxer.

Both of these fail to keep original timestamp for me for the attached sample file.

The reason I created one ticket for both issues is that I get the exact same mismatch in the timestamps so it seems it the same issue causing both.

What I want to do is to cut from 9 seconds to ~18 seconds in the sample file, creating a new file and keeping the original timestamps.

Given the timestamps in the original file, that would mean keeping packets with PTS 432128 (9.00267 s) to PTS 863232 (17.984000 s) (Inspected using ffprobe -show_packets).

Both commands below achieves almost that, except that PTS is shifted by -32 in the given timescale. I get first PTS 432096 (9.002000 s) and last PTS 863200 (17.983333 s). Also I get a negative duration on the last packet -431072 (-8.980667 s) whereas all other packets seem to have correct duration.

Output with the seek approach:

root@bf6643488050:# ffmpeg -v debug -y -ss 9.002667 -i aac_lc.mp4 -to 18 -flags +global_header -codec copy -copyts seek.mp4
ffmpeg version N-79258-g3a9611d Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.2.1 (Ubuntu 5.2.1-22ubuntu2) 20151010
  configuration: --prefix=/tmp/tmp_build_dir --pkg-config-flags=--static --extra-cflags=-I/tmp/tmp_build_dir/include --extra-ldflags=-L/tmp/tmp_build_dir/lib --bindir=/root/bin --enable-gpl --enable-nonfree --enable-libx264 --enable-libsoxr --enable-libfdk-aac
  libavutil      55. 20.100 / 55. 20.100
  libavcodec     57. 34.100 / 57. 34.100
  libavformat    57. 31.100 / 57. 31.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 41.100 /  6. 41.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument 'debug'.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '-ss' ... matched as option 'ss' (set the start time offset) with argument '9.002667'.
Reading option '-i' ... matched as input file with argument 'aac_lc.mp4'.
Reading option '-to' ... matched as option 'to' (record or transcode stop time) with argument '18'.
Reading option '-flags' ... matched as AVOption 'flags' with argument '+global_header'.
Reading option '-codec' ... matched as option 'codec' (codec name) with argument 'copy'.
Reading option '-copyts' ... matched as option 'copyts' (copy timestamps) with argument '1'.
Reading option 'seek.mp4' ... matched as output file.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument debug.
Applying option y (overwrite output files) with argument 1.
Applying option copyts (copy timestamps) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input file aac_lc.mp4.
Applying option ss (set the start time offset) with argument 9.002667.
Successfully parsed a group of options.
Opening an input file: aac_lc.mp4.
[file @ 0x273ada0] Setting default whitelist 'file,crypto'
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] Format mov,mp4,m4a,3gp,3g2,mj2 probed with size=2048 and score=100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] ISO: File Type Major Brand: isom
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] Unknown dref type 0x08206c7275 size 12
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] Before avformat_find_stream_info() pos: 165951 bytes read:37234 seeks:1
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] All info found
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x273a520] After avformat_find_stream_info() pos: 214 bytes read:70002 seeks:2 frames:1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'aac_lc.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf56.36.100
  Duration: 00:00:20.10, start: 0.000000, bitrate: 66 kb/s
    Stream #0:0(eng), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Successfully opened the file.
Parsing a group of options: output file seek.mp4.
Applying option to (record or transcode stop time) with argument 18.
Applying option codec (codec name) with argument copy.
Successfully parsed a group of options.
Opening an output file: seek.mp4.
[file @ 0x274dc80] Setting default whitelist 'file,crypto'
Successfully opened the file.
Output #0, mp4, to 'seek.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf57.31.100
    Stream #0:0(eng), 0, 1/48000: Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
No more output streams to write to, finishing.
size=      73kB time=00:00:18.00 bitrate=  33.1kbits/s speed=7.26e+03x    
video:0kB audio:70kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 3.393788%
Input file #0 (aac_lc.mp4):
  Input stream #0:0 (audio): 423 packets read (72123 bytes); 
  Total: 423 packets (72123 bytes) demuxed
Output file #0 (seek.mp4):
  Output stream #0:0 (audio): 422 packets muxed (71955 bytes); 
  Total: 422 packets (71955 bytes) muxed
0 frames successfully decoded, 0 decoding errors
[AVIOContext @ 0x2755e60] Statistics: 30 seeks, 445 writeouts
[AVIOContext @ 0x2743040] Statistics: 162974 bytes read, 3 seeks

The incorrect timestamps can be seen by running ffprobe -show_packets on the resulting seek.mp4

Output with the segment approach (without debug since segment logs every packet..):

root@bf6643488050:# ffmpeg -y -i aac_lc.mp4 -flags +global_header -codec copy -f segment -segment_format mp4 -segment_time 9 seg%02d.mp4
ffmpeg version N-79258-g3a9611d Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.2.1 (Ubuntu 5.2.1-22ubuntu2) 20151010
  configuration: --prefix=/tmp/tmp_build_dir --pkg-config-flags=--static --extra-cflags=-I/tmp/tmp_build_dir/include --extra-ldflags=-L/tmp/tmp_build_dir/lib --bindir=/root/bin --enable-gpl --enable-nonfree --enable-libx264 --enable-libsoxr --enable-libfdk-aac
  libavutil      55. 20.100 / 55. 20.100
  libavcodec     57. 34.100 / 57. 34.100
  libavformat    57. 31.100 / 57. 31.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 41.100 /  6. 41.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'aac_lc.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf56.36.100
  Duration: 00:00:20.10, start: 0.000000, bitrate: 66 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Output #0, segment, to 'seg%02d.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf57.31.100
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, 64 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
size=N/A time=00:00:20.05 bitrate=N/A speed=2.57e+03x    
video:0kB audio:158kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

The incorrect timestamps can be seen by running ffprobe -show_packets on the resulting seg01.mp4

It is interesting to execute the segment command using -v debug. There we can see that the segment muxer outputs the correct, non-shifted, timestamps for each packet. So it seems there is something in the mov/mp4 muxer??

Tested with latest nightly, but the issue is there in 3.0.1 as well.

Attaching the file I used for testing.

Attachments (1)

aac_lc.mp4 (162.1 KB) - added by stefan.moro 21 months ago.
Sample file used as input for commands above

Download all attachments as: .zip

Change History (1)

Changed 21 months ago by stefan.moro

Sample file used as input for commands above

Note: See TracTickets for help on using tickets.