v4l.c
Go to the documentation of this file.
1 /*
2  * Linux video grab interface
3  * Copyright (c) 2000,2001 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avdevice.h"
23 
24 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
25 #include "config.h"
26 #include "libavutil/rational.h"
27 #include "libavutil/imgutils.h"
28 #include "libavutil/log.h"
29 #include "libavutil/opt.h"
30 #include "libavformat/internal.h"
31 #include "libavcodec/dsputil.h"
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/ioctl.h>
35 #include <sys/mman.h>
36 #include <sys/time.h>
37 #define _LINUX_TIME_H 1
38 #include <linux/videodev.h>
39 #include <time.h>
40 #include "avdevice.h"
41 
42 typedef struct {
43  AVClass *class;
44  int fd;
45  int frame_format; /* see VIDEO_PALETTE_xxx */
46  int use_mmap;
48  int64_t time_frame;
50  struct video_capability video_cap;
51  struct video_audio audio_saved;
52  struct video_window video_win;
54  struct video_mbuf gb_buffers;
55  struct video_mmap gb_buf;
56  int gb_frame;
57  int standard;
58 } VideoData;
59 
60 static const struct {
61  int palette;
62  int depth;
64 } video_formats [] = {
65  {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = AV_PIX_FMT_YUV420P },
66  {.palette = VIDEO_PALETTE_YUV422, .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 },
67  {.palette = VIDEO_PALETTE_UYVY, .depth = 16, .pix_fmt = AV_PIX_FMT_UYVY422 },
68  {.palette = VIDEO_PALETTE_YUYV, .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 },
69  /* NOTE: v4l uses BGR24, not RGB24 */
70  {.palette = VIDEO_PALETTE_RGB24, .depth = 24, .pix_fmt = AV_PIX_FMT_BGR24 },
71  {.palette = VIDEO_PALETTE_RGB565, .depth = 16, .pix_fmt = AV_PIX_FMT_BGR565 },
72  {.palette = VIDEO_PALETTE_GREY, .depth = 8, .pix_fmt = AV_PIX_FMT_GRAY8 },
73 };
74 
75 
76 static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
77 {
78  VideoData *s = s1->priv_data;
79  AVStream *st;
80  int video_fd;
81  int desired_palette, desired_depth;
82  struct video_tuner tuner;
83  struct video_audio audio;
84  struct video_picture pict;
85  int j;
86  int vformat_num = FF_ARRAY_ELEMS(video_formats);
87 
88  av_log(s1, AV_LOG_WARNING, "V4L input device is deprecated and will be removed in the next release.");
89 
90  if (ap->time_base.den <= 0) {
91  av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den);
92  return -1;
93  }
94  s->time_base = ap->time_base;
95 
96  s->video_win.width = ap->width;
97  s->video_win.height = ap->height;
98 
99  st = avformat_new_stream(s1, NULL);
100  if (!st)
101  return AVERROR(ENOMEM);
102  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
103 
104  video_fd = open(s1->filename, O_RDWR);
105  if (video_fd < 0) {
106  av_log(s1, AV_LOG_ERROR, "%s: %s\n", s1->filename, strerror(errno));
107  goto fail;
108  }
109 
110  if (ioctl(video_fd, VIDIOCGCAP, &s->video_cap) < 0) {
111  av_log(s1, AV_LOG_ERROR, "VIDIOCGCAP: %s\n", strerror(errno));
112  goto fail;
113  }
114 
115  if (!(s->video_cap.type & VID_TYPE_CAPTURE)) {
116  av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n");
117  goto fail;
118  }
119 
120  /* no values set, autodetect them */
121  if (s->video_win.width <= 0 || s->video_win.height <= 0) {
122  if (ioctl(video_fd, VIDIOCGWIN, &s->video_win, sizeof(s->video_win)) < 0) {
123  av_log(s1, AV_LOG_ERROR, "VIDIOCGWIN: %s\n", strerror(errno));
124  goto fail;
125  }
126  }
127 
128  if(av_image_check_size(s->video_win.width, s->video_win.height, 0, s1) < 0)
129  return -1;
130 
131  desired_palette = -1;
132  desired_depth = -1;
133  for (j = 0; j < vformat_num; j++) {
134  if (ap->pix_fmt == video_formats[j].pix_fmt) {
135  desired_palette = video_formats[j].palette;
136  desired_depth = video_formats[j].depth;
137  break;
138  }
139  }
140 
141  /* set tv standard */
142  if (!ioctl(video_fd, VIDIOCGTUNER, &tuner)) {
143  tuner.mode = s->standard;
144  ioctl(video_fd, VIDIOCSTUNER, &tuner);
145  }
146 
147  /* unmute audio */
148  audio.audio = 0;
149  ioctl(video_fd, VIDIOCGAUDIO, &audio);
150  memcpy(&s->audio_saved, &audio, sizeof(audio));
151  audio.flags &= ~VIDEO_AUDIO_MUTE;
152  ioctl(video_fd, VIDIOCSAUDIO, &audio);
153 
154  ioctl(video_fd, VIDIOCGPICT, &pict);
155  av_dlog(s1, "v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n",
156  pict.colour, pict.hue, pict.brightness, pict.contrast, pict.whiteness);
157  /* try to choose a suitable video format */
158  pict.palette = desired_palette;
159  pict.depth= desired_depth;
160  if (desired_palette == -1 || ioctl(video_fd, VIDIOCSPICT, &pict) < 0) {
161  for (j = 0; j < vformat_num; j++) {
162  pict.palette = video_formats[j].palette;
163  pict.depth = video_formats[j].depth;
164  if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict))
165  break;
166  }
167  if (j >= vformat_num)
168  goto fail1;
169  }
170 
171  if (ioctl(video_fd, VIDIOCGMBUF, &s->gb_buffers) < 0) {
172  /* try to use read based access */
173  int val;
174 
175  s->video_win.x = 0;
176  s->video_win.y = 0;
177  s->video_win.chromakey = -1;
178  s->video_win.flags = 0;
179 
180  if (ioctl(video_fd, VIDIOCSWIN, s->video_win) < 0) {
181  av_log(s1, AV_LOG_ERROR, "VIDIOCSWIN: %s\n", strerror(errno));
182  goto fail;
183  }
184 
185  s->frame_format = pict.palette;
186 
187  val = 1;
188  if (ioctl(video_fd, VIDIOCCAPTURE, &val) < 0) {
189  av_log(s1, AV_LOG_ERROR, "VIDIOCCAPTURE: %s\n", strerror(errno));
190  goto fail;
191  }
192 
193  s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;
194  s->use_mmap = 0;
195  } else {
196  s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, 0);
197  if ((unsigned char*)-1 == s->video_buf) {
198  s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_PRIVATE, video_fd, 0);
199  if ((unsigned char*)-1 == s->video_buf) {
200  av_log(s1, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
201  goto fail;
202  }
203  }
204  s->gb_frame = 0;
205  s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;
206 
207  /* start to grab the first frame */
208  s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames;
209  s->gb_buf.height = s->video_win.height;
210  s->gb_buf.width = s->video_win.width;
211  s->gb_buf.format = pict.palette;
212 
213  if (ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) {
214  if (errno != EAGAIN) {
215  fail1:
216  av_log(s1, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno));
217  } else {
218  av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not receive any video signal\n");
219  }
220  goto fail;
221  }
222  for (j = 1; j < s->gb_buffers.frames; j++) {
223  s->gb_buf.frame = j;
224  ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf);
225  }
226  s->frame_format = s->gb_buf.format;
227  s->use_mmap = 1;
228  }
229 
230  for (j = 0; j < vformat_num; j++) {
231  if (s->frame_format == video_formats[j].palette) {
232  s->frame_size = s->video_win.width * s->video_win.height * video_formats[j].depth / 8;
233  st->codec->pix_fmt = video_formats[j].pix_fmt;
234  break;
235  }
236  }
237 
238  if (j >= vformat_num)
239  goto fail;
240 
241  s->fd = video_fd;
242 
245  st->codec->width = s->video_win.width;
246  st->codec->height = s->video_win.height;
247  st->codec->time_base = s->time_base;
248  st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
249 
250  return 0;
251  fail:
252  if (video_fd >= 0)
253  close(video_fd);
254  return AVERROR(EIO);
255 }
256 
258 {
259  uint8_t *ptr;
260 
261  while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 &&
262  (errno == EAGAIN || errno == EINTR));
263 
264  ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame];
265  memcpy(buf, ptr, s->frame_size);
266 
267  /* Setup to capture the next frame */
268  s->gb_buf.frame = s->gb_frame;
269  if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) {
270  if (errno == EAGAIN)
271  av_log(NULL, AV_LOG_ERROR, "Cannot Sync\n");
272  else
273  av_log(NULL, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno));
274  return AVERROR(EIO);
275  }
276 
277  /* This is now the grabbing frame */
278  s->gb_frame = (s->gb_frame + 1) % s->gb_buffers.frames;
279 
280  return s->frame_size;
281 }
282 
284 {
285  VideoData *s = s1->priv_data;
286  int64_t curtime, delay;
287  struct timespec ts;
288 
289  /* Calculate the time of the next frame */
290  s->time_frame += INT64_C(1000000);
291 
292  /* wait based on the frame rate */
293  for(;;) {
294  curtime = av_gettime();
295  delay = s->time_frame * s->time_base.num / s->time_base.den - curtime;
296  if (delay <= 0) {
297  if (delay < INT64_C(-1000000) * s->time_base.num / s->time_base.den) {
298  /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */
299  s->time_frame += INT64_C(1000000);
300  }
301  break;
302  }
303  ts.tv_sec = delay / 1000000;
304  ts.tv_nsec = (delay % 1000000) * 1000;
305  nanosleep(&ts, NULL);
306  }
307 
308  if (av_new_packet(pkt, s->frame_size) < 0)
309  return AVERROR(EIO);
310 
311  pkt->pts = curtime;
312 
313  /* read one frame */
314  if (s->use_mmap) {
315  return v4l_mm_read_picture(s, pkt->data);
316  } else {
317  if (read(s->fd, pkt->data, pkt->size) != pkt->size)
318  return AVERROR(EIO);
319  return s->frame_size;
320  }
321 }
322 
324 {
325  VideoData *s = s1->priv_data;
326 
327  if (s->use_mmap)
328  munmap(s->video_buf, s->gb_buffers.size);
329 
330  /* mute audio. we must force it because the BTTV driver does not
331  return its state correctly */
332  s->audio_saved.flags |= VIDEO_AUDIO_MUTE;
333  ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved);
334 
335  close(s->fd);
336  return 0;
337 }
338 
339 static const AVOption options[] = {
340  { "standard", "", offsetof(VideoData, standard), AV_OPT_TYPE_INT, {.i64 = VIDEO_MODE_NTSC}, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
341  { "PAL", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_PAL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
342  { "SECAM", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
343  { "NTSC", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_NTSC}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
344  { NULL },
345 };
346 
347 static const AVClass v4l_class = {
348  .class_name = "V4L indev",
349  .item_name = av_default_item_name,
350  .option = options,
351  .version = LIBAVUTIL_VERSION_INT,
352 };
353 
355  .name = "video4linux,v4l",
356  .long_name = NULL_IF_CONFIG_SMALL("Video4Linux device grab"),
357  .priv_data_size = sizeof(VideoData),
361  .flags = AVFMT_NOFILE,
362  .priv_class = &v4l_class,
363 };
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:85
const char * s
Definition: avisynth_c.h:668
AVOption.
Definition: opt.h:251
av_default_item_name
misc image utilities
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
struct video_capability video_cap
Definition: v4l.c:50
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int num
numerator
Definition: rational.h:44
static const struct @106 video_formats[]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int use_mmap
Definition: v4l.c:46
#define FF_ARRAY_ELEMS(a)
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Format I/O context.
Definition: avformat.h:944
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:55
struct video_window video_win
Definition: v4l.c:52
uint8_t
AVOptions.
static AVPacket pkt
Definition: demuxing.c:56
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
static double av_q2d(AVRational a)
Convert rational to double.
Definition: rational.h:69
uint8_t * data
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
enum AVPixelFormat pix_fmt
Definition: v4l.c:63
AVRational time_base
Definition: v4l.c:47
Main libavdevice API header.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
Definition: v4l.c:283
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
Definition: bktr.c:53
int fd
Definition: v4l.c:44
int depth
Definition: v4l.c:62
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:231
static const AVClass v4l_class
Definition: v4l.c:347
int bit_rate
the average bitrate
char filename[1024]
input or output filename
Definition: avformat.h:994
int width
picture width / height.
static int v4l_mm_read_picture(VideoData *s, uint8_t *buf)
Definition: v4l.c:257
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:71
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:517
struct video_mmap gb_buf
Definition: v4l.c:55
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
enum AVMediaType codec_type
enum AVCodecID codec_id
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:69
void * buf
Definition: avisynth_c.h:594
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
int standard
Definition: bktr.c:59
Describe the class of an AVClass context structure.
Definition: log.h:50
rational number numerator/denominator
Definition: rational.h:43
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:282
uint8_t * video_buf
Definition: v4l.c:53
#define s1
Definition: regdef.h:38
static const AVOption options[]
Definition: v4l.c:339
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define AV_PIX_FMT_BGR565
Definition: pixfmt.h:272
static int flags
Definition: cpu.c:23
int frame_format
Definition: v4l.c:45
int palette
Definition: v4l.c:61
int frame_size
Definition: v4l.c:49
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
Y , 8bpp.
Definition: pixfmt.h:76
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:345
rational numbers
static int grab_read_close(AVFormatContext *s1)
Definition: v4l.c:323
int gb_frame
Definition: v4l.c:56
int den
denominator
Definition: rational.h:45
DSP utils.
struct video_mbuf gb_buffers
Definition: v4l.c:54
static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
Definition: v4l.c:76
AVInputFormat ff_v4l_demuxer
Definition: v4l.c:354
void * priv_data
Format private data.
Definition: avformat.h:964
int64_t time_frame
Definition: v4l.c:48
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
struct video_audio audio_saved
Definition: v4l.c:51
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...