Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
12292f35
Commit
12292f35
authored
Mar 03, 2012
by
Nicolas George
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v4l2: allow to convert monotonic timestamps.
parent
8a9ae37f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
1 deletion
+104
-1
configure
configure
+2
-0
indevs.texi
doc/indevs.texi
+7
-0
Makefile
libavdevice/Makefile
+1
-1
v4l2.c
libavdevice/v4l2.c
+94
-0
No files found.
configure
View file @
12292f35
...
...
@@ -1157,6 +1157,7 @@ HAVE_LIST="
attribute_may_alias
attribute_packed
cbrtf
clock_gettime
closesocket
cmov
dcbzl
...
...
@@ -3048,6 +3049,7 @@ fi
# Solaris has nanosleep in -lrt, OpenSolaris no longer needs that
check_func nanosleep
||
{
check_func nanosleep
-lrt
&&
add_extralibs
-lrt
;
}
check_func clock_gettime
||
{
check_func clock_gettime
-lrt
&&
add_extralibs
-lrt
;
}
check_func fcntl
check_func fork
check_func getaddrinfo
$network_extralibs
...
...
doc/indevs.texi
View file @
12292f35
...
...
@@ -520,6 +520,13 @@ supported using @command{-list_formats all} for Video4Linux2 devices.
Some usage examples of the video4linux2 devices with ffmpeg and ffplay:
The time base for the timestamps is 1 microsecond. Depending on the kernel
version and configuration, the timestamps may be derived from the real time
clock (origin at the Unix Epoch) or the monotonic clock (origin usually at
boot time, unaffected by NTP or manual changes to the clock). The
@option{-timestamps abs} or @option{-ts abs} option can be used to force
conversion into the real time clock.
Note that if FFmpeg is build with v4l-utils support ("--enable-libv4l2"
option), it will always be used.
@example
...
...
libavdevice/Makefile
View file @
12292f35
...
...
@@ -28,7 +28,7 @@ OBJS-$(CONFIG_PULSE_INDEV) += pulse.o
OBJS-$(CONFIG_SDL_OUTDEV)
+=
sdl.o
OBJS-$(CONFIG_SNDIO_INDEV)
+=
sndio_common.o
sndio_dec.o
OBJS-$(CONFIG_SNDIO_OUTDEV)
+=
sndio_common.o
sndio_enc.o
OBJS-$(CONFIG_V4L2_INDEV)
+=
v4l2.o
OBJS-$(CONFIG_V4L2_INDEV)
+=
v4l2.o
timefilter.o
OBJS-$(CONFIG_V4L_INDEV)
+=
v4l.o
OBJS-$(CONFIG_VFWCAP_INDEV)
+=
vfwcap.o
OBJS-$(CONFIG_X11_GRAB_DEVICE_INDEV)
+=
x11grab.o
...
...
libavdevice/v4l2.c
View file @
12292f35
...
...
@@ -51,6 +51,7 @@
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "avdevice.h"
#include "timefilter.h"
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avstring.h"
...
...
@@ -73,6 +74,28 @@ static const int desired_video_buffers = 256;
#define V4L_RAWFORMATS 1
#define V4L_COMPFORMATS 2
/**
* Return timestamps to the user exactly as returned by the kernel
*/
#define V4L_TS_DEFAULT 0
/**
* Autodetect the kind of timestamps returned by the kernel and convert to
* absolute (wall clock) timestamps.
*/
#define V4L_TS_ABS 1
/**
* Assume kernel timestamps are from the monotonic clock and convert to
* absolute timestamps.
*/
#define V4L_TS_MONO2ABS 2
/**
* Once the kind of timestamps returned by the kernel have been detected,
* the value of the timefilter (NULL or not) determines whether a conversion
* takes place.
*/
#define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
struct
video_data
{
AVClass
*
class
;
int
fd
;
...
...
@@ -81,6 +104,9 @@ struct video_data {
int
frame_size
;
int
interlaced
;
int
top_field_first
;
int
ts_mode
;
TimeFilter
*
timefilter
;
int64_t
last_time_m
;
int
buffers
;
void
**
buf_start
;
...
...
@@ -455,6 +481,66 @@ static void mmap_release_buffer(AVPacket *pkt)
pkt
->
size
=
0
;
}
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
static
int64_t
av_gettime_monotonic
(
void
)
{
struct
timespec
tv
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
tv
);
return
(
int64_t
)
tv
.
tv_sec
*
1000000
+
tv
.
tv_nsec
/
1000
;
}
#endif
static
int
init_convert_timestamp
(
AVFormatContext
*
ctx
,
int64_t
ts
)
{
struct
video_data
*
s
=
ctx
->
priv_data
;
int64_t
now
;
now
=
av_gettime
();
if
(
s
->
ts_mode
==
V4L_TS_ABS
&&
ts
<=
now
+
1
*
AV_TIME_BASE
&&
ts
>=
now
-
10
*
AV_TIME_BASE
)
{
av_log
(
ctx
,
AV_LOG_INFO
,
"Detected absolute timestamps
\n
"
);
s
->
ts_mode
=
V4L_TS_CONVERT_READY
;
return
0
;
}
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
now
=
av_gettime_monotonic
();
if
(
s
->
ts_mode
==
V4L_TS_MONO2ABS
||
(
ts
<=
now
+
1
*
AV_TIME_BASE
&&
ts
>=
now
-
10
*
AV_TIME_BASE
))
{
int64_t
period
=
av_rescale_q
(
1
,
ctx
->
streams
[
0
]
->
codec
->
time_base
,
AV_TIME_BASE_Q
);
av_log
(
ctx
,
AV_LOG_INFO
,
"Detected monotonic timestamps, converting
\n
"
);
/* microseconds instead of seconds, MHz instead of Hz */
s
->
timefilter
=
ff_timefilter_new
(
1
,
period
,
1.0E-6
);
s
->
ts_mode
=
V4L_TS_CONVERT_READY
;
return
0
;
}
#endif
av_log
(
ctx
,
AV_LOG_ERROR
,
"Unknown timestamps
\n
"
);
return
AVERROR
(
EIO
);
}
static
int
convert_timestamp
(
AVFormatContext
*
ctx
,
int64_t
*
ts
)
{
struct
video_data
*
s
=
ctx
->
priv_data
;
if
(
s
->
ts_mode
)
{
int
r
=
init_convert_timestamp
(
ctx
,
*
ts
);
if
(
r
<
0
)
return
r
;
}
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
if
(
s
->
timefilter
)
{
int64_t
nowa
=
av_gettime
();
int64_t
nowm
=
av_gettime_monotonic
();
ff_timefilter_update
(
s
->
timefilter
,
nowa
,
nowm
-
s
->
last_time_m
);
s
->
last_time_m
=
nowm
;
*
ts
=
ff_timefilter_eval
(
s
->
timefilter
,
*
ts
-
nowm
);
}
#endif
return
0
;
}
static
int
mmap_read_frame
(
AVFormatContext
*
ctx
,
AVPacket
*
pkt
)
{
struct
video_data
*
s
=
ctx
->
priv_data
;
...
...
@@ -490,6 +576,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
pkt
->
data
=
s
->
buf_start
[
buf
.
index
];
pkt
->
size
=
buf
.
bytesused
;
pkt
->
pts
=
buf
.
timestamp
.
tv_sec
*
INT64_C
(
1000000
)
+
buf
.
timestamp
.
tv_usec
;
res
=
convert_timestamp
(
ctx
,
&
pkt
->
pts
);
if
(
res
<
0
)
return
res
;
pkt
->
destruct
=
mmap_release_buffer
;
buf_descriptor
=
av_malloc
(
sizeof
(
struct
buff_data
));
if
(
buf_descriptor
==
NULL
)
{
...
...
@@ -847,6 +936,11 @@ static const AVOption options[] = {
{
"all"
,
"Show all available formats"
,
OFFSET
(
list_format
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_ALLFORMATS
},
0
,
INT_MAX
,
DEC
,
"list_formats"
},
{
"raw"
,
"Show only non-compressed formats"
,
OFFSET
(
list_format
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_RAWFORMATS
},
0
,
INT_MAX
,
DEC
,
"list_formats"
},
{
"compressed"
,
"Show only compressed formats"
,
OFFSET
(
list_format
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_COMPFORMATS
},
0
,
INT_MAX
,
DEC
,
"list_formats"
},
{
"timestamps"
,
"Kind of timestamps for grabbed frames"
,
OFFSET
(
ts_mode
),
AV_OPT_TYPE_INT
,
{.
dbl
=
0
},
0
,
2
,
DEC
,
"timestamps"
},
{
"default"
,
"Use timestamps from the kernel"
,
OFFSET
(
ts_mode
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_TS_DEFAULT
},
0
,
2
,
DEC
,
"timestamps"
},
{
"abs"
,
"Use absolute timestamps (wall clock)"
,
OFFSET
(
ts_mode
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_TS_ABS
},
0
,
2
,
DEC
,
"timestamps"
},
{
"mono2abs"
,
"Force conversion from monotonic to absolute timestamps"
,
OFFSET
(
ts_mode
),
AV_OPT_TYPE_CONST
,
{.
dbl
=
V4L_TS_MONO2ABS
},
0
,
2
,
DEC
,
"timestamps"
},
{
"ts"
,
"Kind of timestamps for grabbed frames"
,
OFFSET
(
ts_mode
),
AV_OPT_TYPE_INT
,
{.
dbl
=
0
},
0
,
2
,
DEC
,
"timestamps"
},
{
NULL
},
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment