Here is my current command based on this answer:
ffmpeg \
-hide_banner \
-r $FRAMERATE \
-s $(((WIDTH + 63) / 64 * 64))"x"$(((HEIGHT + 15) / 16 * 16)) \
-f rawvideo \
-pix_fmt yuv420p \
-i - \
-filter_complex "crop=$WIDTH:$CROPPED_HEIGHT:0:0,settb=1/1000,setpts=RTCTIME/1000-1500000000000,split[out][ts];[out]setpts=N/FRAME_RATE/TB[out]" \
-map [out] \
-c:v ffv1 \
-vsync passthrough \
-f matroska \
"$OUTPUT_PATH/${FILENAME}.mkv" \
-map [ts] \
-flush_packets 1 \
-f mkvtimestamp_v2 \
"$OUTPUT_PATH/${FILENAME}_ts2.txt"
$FRAMERATE
is set to 4. Here is the _ts2.txt
output:
# timecode format v2
181489707750
181489708750
181489708751
181489709000
181489709250
181489709251
181489709500
181489709501
181489709750
181489710000
181489710001
181489710250
181489710500
181489710750
181489711000
181489711250
...
As you can see, except for the hiccups at the beginning (no idea why), it only generates timestamps that are a multiple of 250ms, i.e. 1/$FRAMERATE
. How can I make these timestamps more precise, ideally on milliseconds level?
TL;DR: Remove the /1000-1500000000000
if possible.
I removed the -1500000000000
and compared the timestamps when using /1000 and without. I noticed, that in both cases, the numbers always end with 000, 250, ... as above. This is one output with raw RTCTIME as pts:
# timecode format v2
1681736801215250
1681736802129750
1681736802258750
1681736802392250
1681736802545500
1681736802683750
1681736802815250
1681736802965000
1681736803101000
...
1681736809206250
1681736809450500
1681736809707000
1681736809950500
1681736810207500
1681736810448500
1681736810705500
1681736810950750
1681736811205000
1681736811451250
These values are in microseconds precision. Note how in the first block the difference between 1st and 2nd frame is ~900ms, whereas for the remaining it is ~150ms. In the second block (end of file), the differences are ~250ms, as expected for the framerate. I'm not sure what the reason for the differences in the beginning is, perhaps it is related to buffering of the input stream or ffmpeg having to "catch up" after initialization.
Also, note that the "hiccups" are gone. Previously, with the /1000
, I got this warning:
[mkvtimestamp_v2 @ 0x55c03b1eb0] Non-monotonous DTS in output stream 1:0; previous: 1681737336750, current: 1681737336750; changing to 1681737336751. This may result in incorrect timestamps in the output file.
It complains that the timestamps of two succeeding frames are the same, which is very unlikely given the very low framerate. This already indicates that these timestamps must be wrong.
Overall, the raw RTCTIME timestamps seem plausible, and imply that the division by 1000 is not working properly for some reason. In my case, I can simply remove it, because timestamp generation seems not to be limited by precision/timestamp length (as mentioned in the reference answer) in my ffmpeg version, and my processing tools are self-written and have no problems either. Your results may vary with standard tools such as mkvtoolnix, but I haven't tried it.