Discussion:
[FFmpeg-user] Getting precise start time from wall-clock for capture
Arthur Wait
2015-05-18 02:03:35 UTC
Permalink
Hi all,

I'm using FFMPEG to record video from several cameras attached to several
networked computers. The computers' clocks are all synced. I'd like to be
able to get a precise date/time for the first captured frame; this will
allow me to easily sync the recordings later on. I've found that just
getting the date/time from the command line is not accurate enough--it
reflects the time that the file is first written to disk, but not the time
that the first frame is captured.

I found a similar question posted to StackOverflow (
https://stackoverflow.com/questions/21262786/accurate-ffmpeg-capture-start-time),
and he describes the requirement quite well, though no one seemed to have a
workable solution (I tried the suggestions posted).

Anyone else have ideas for this?

Thanks very much!

Art
Nicolas George
2015-05-18 11:09:44 UTC
Permalink
Post by Arthur Wait
I'm using FFMPEG to record video from several cameras attached to several
networked computers. The computers' clocks are all synced. I'd like to be
able to get a precise date/time for the first captured frame
All captured frames should have a timestamp attached, usually to the
microsecond; an option may be needed to have it based on the wall clock. You
did not bother to tell what kind of capture you are doing, so it is not
possible to point you to the exact place in the documentation.

Please remember to follow the mailing list's netiquette, in particular not
hijacking threads (too late for that this time) but all of it.

Regards,
--
Nicolas George
Arthur Wait
2015-05-18 15:42:35 UTC
Permalink
Thanks Nicolas.
Post by Nicolas George
Please remember to follow the mailing list's netiquette,
in particular not hijacking threads (too late for that this time)
but all of it.
Apologies for hijacking the thread (though I'm not clear as to what in
particular I did in that regard--I started the thread).
Post by Nicolas George
You did not bother to tell what kind of capture you are doing,
so it is not possible to point you to the exact place in the
documentation.
The capture I'm doing is v4l2 to nvenc to matroska. Here's the command line
I've been using:

ffmpeg -f v4l2 -framerate 60 -video_size 1920x1080 -i /dev/video0 -r
2997/100 -f matroska -c:v nvenc -b:v 25000k -minrate 25000k -maxrate 25000k
-g 1 -profile:v high -preset hq my_video.mkv

Thanks again for any tips you can provide.
Nicolas George
2015-05-18 16:38:18 UTC
Permalink
Post by Arthur Wait
Apologies for hijacking the thread (though I'm not clear as to what in
particular I did in that regard--I started the thread).
No real harm done, ans sorry for the harsh tone. Your initial message has
That means you wrote it by replying to this message.
Post by Arthur Wait
The capture I'm doing is v4l2 to nvenc to matroska.
Then frames have timestamps provided by the kernel:

ffprobe -i /dev/video0 -of compact -show_packets
[...]
packet|codec_type=video|stream_index=0|pts=1392045174616|pts_time=1392045.174616|...

As you can see, this is the monotonic clock (and my uptime here is 16 days),
but lavd can convert for you:

http://ffmpeg.org/ffmpeg-devices.html#video4linux2_002c-v4l2

With that, you just need to do whatever you want with the timestamps. By
default, ffmpeg will normalize the timestamps before any filtering or
encoding, but you can disable that with the "-copyts" option.

Regards,
--
Nicolas George
Arthur Wait
2015-05-18 19:35:00 UTC
Permalink
Fantastic Nicolas, thanks so much! This is exactly what I needed.

Arthur
Post by Nicolas George
ffprobe -i /dev/video0 -of compact -show_packets
[...]
packet|codec_type=video|stream_index=0|pts=1392045174616|pts_time=1392045.174616|...
As you can see, this is the monotonic clock (and my uptime here is 16 days),
Moritz Barsnick
2015-05-18 20:41:03 UTC
Permalink
Post by Nicolas George
As you can see, this is the monotonic clock (and my uptime here is 16 days),
http://ffmpeg.org/ffmpeg-devices.html#video4linux2_002c-v4l2
I tried that, because I wanted to answer the question as well. It was
Post by Nicolas George
With that, you just need to do whatever you want with the timestamps. By
default, ffmpeg will normalize the timestamps before any filtering or
encoding, but you can disable that with the "-copyts" option.
I see the timestamp of the first frame "reset" to 0 - is that what you
mean with "normalize"?

From the description of the v4l2 device, I had expected the wallclock
to be copied to the timestamps (PTS, right?), but they began with 0 for
the first frame. I then tried to add
"-vf setpts=RTCSTART+PTS-STARTPTS"
but that was apparently a long shot - it didn't help.

So I added "-copyts", but again to no avail. The first frame always
shows:
pkt_pts=0
pkt_pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
best_effort_timestamp=0
best_effort_timestamp_time=0.000000

I was hoping to be able to hint the original poster to grab the start
time from the PTS of the first frame.

So: How to get wallclock timestamps into the video?

For reference, my attempt. (The input obviously has the correct
wallclock time: 1431981242.712328.)

$ ffmpeg -f v4l2 -input_format yuv420p -timestamps abs -i /dev/video1 -t 1 -c:v libx264 -copyts ~/tmp/video1.mkv -y
ffmpeg version 2.6.git Copyright (c) 2000-2015 the FFmpeg developers
built with icc (ICC) 14.0.3 20140422
configuration: --prefix=/usr/new/tools/video/install/ffmpeg/2015-05-11 --cc=icc --cxx=icpc --enable-gpl --enable-version3 --enable-nonfree --disable-shared --enable-gnutls --enable-libcdio --
enable-libfreetype --enable-libx264 --enable-libmp3lame --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libass --enable-libv
4l2 --enable-libvidstab --enable-libfdk-aac --enable-libsmbclient --enable-libquvi --enable-libzvbi --enable-libzmq --extra-ldflags=-L/usr/new/tools/video/install/fdk-aac/current/lib --extra-cf
lags=-I/usr/new/tools/video/install/fdk-aac/current/include
libavutil 54. 23.101 / 54. 23.101
libavcodec 56. 38.100 / 56. 38.100
libavformat 56. 32.100 / 56. 32.100
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 16.101 / 5. 16.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
[video4linux2,v4l2 @ 0xa60bd00] Detected absolute timestamps
Input #0, video4linux2,v4l2, from '/dev/video1':
Duration: N/A, start: 1431981242.712328, bitrate: 124416 kb/s
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 720x576, 124416 kb/s, 25 fps, 25 tbr, 1000k tbn, 1000k tbc
[libx264 @ 0xa60de20] using cpu capabilities: MMX2 SSE2 Cache64
[libx264 @ 0xa60de20] profile High, level 3.0
[libx264 @ 0xa60de20] 264 - core 142 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, matroska, to '/home/barsnick/tmp/video1.mkv':
Metadata:
encoder : Lavf56.32.100
Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), yuv420p, 720x576, q=-1--1, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc56.38.100 libx264
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0xa60de20] non-strictly-monotonic PTS
Last message repeated 12 times
[libx264 @ 0xa60de20] non-strictly-monotonic PTS0:00:00.00 bitrate=N/A
Last message repeated 10 times
frame= 24 fps=2.6 q=-1.0 Lsize= 2129kB time=-23860:55:45.88 bitrate=N/A
video:2128kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.039607%
[libx264 @ 0xa60de20] frame I:1 Avg QP:38.00 size: 90932
[libx264 @ 0xa60de20] frame P:23 Avg QP:38.00 size: 90753
[libx264 @ 0xa60de20] mb I I16..4: 0.0% 70.0% 30.0%
[libx264 @ 0xa60de20] mb P I16..4: 0.9% 85.8% 13.1% P16..4: 0.0% 0.1% 0.1% 0.0% 0.0% skip: 0.0%
[libx264 @ 0xa60de20] 8x8 transform intra:85.3% inter:65.0%
[libx264 @ 0xa60de20] coded y,uvDC,uvAC intra: 100.0% 0.0% 0.0% inter: 100.0% 0.0% 0.0%
[libx264 @ 0xa60de20] i16 v,h,dc,p: 0% 7% 81% 13%
[libx264 @ 0xa60de20] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 1% 42% 29% 2% 3% 2% 8% 2% 11%
[libx264 @ 0xa60de20] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 2% 34% 18% 5% 6% 3% 13% 3% 15%
[libx264 @ 0xa60de20] i8c dc,h,v,p: 100% 0% 0% 0%
[libx264 @ 0xa60de20] Weighted P-Frames: Y:4.3% UV:0.0%
[libx264 @ 0xa60de20] ref P L0: 34.2% 8.8% 32.1% 23.8% 1.2%
[libx264 @ 0xa60de20] kb/s:inf

Moritz
Arthur Wait
2015-05-18 20:51:17 UTC
Permalink
Post by Moritz Barsnick
I see the timestamp of the first frame "reset" to 0 - is that what you
mean with "normalize"?
Here's what seems to have worked for me:

ffmpeg -f v4l2 -framerate 60 -video_size 1920x1080 -ts mono2abs -i
/dev/video-static -r 2997/100 -f matroska -c:v nvenc -b:v 25000k -minrate
25000k -maxrate 25000k -g 1 -profile:v high -preset hq -copyts output.mkv

It took me a few tries to get the -ts mono2abs and -copyts into the right
location, but now I believe I'm getting good wall-clock time (at least, it
looks logical to me). I'm still doing some testing, though...

Loading...