Opened 9 years 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.
Sample file used as input for commands above