]> git.sesse.net Git - vlc/blob - modules/access/v4l2/demux.c
v4l2: get aspect ratio from V4L2 crop capabilities (rather than user)
[vlc] / modules / access / v4l2 / demux.c
1 /*****************************************************************************
2  * demux.c : V4L2 raw video demux module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2011 the VideoLAN team
5  *
6  * Authors: Benjamin Pracht <bigben at videolan dot org>
7  *          Richard Hosking <richard at hovis dot net>
8  *          Antoine Cellerier <dionoea at videolan d.t org>
9  *          Dennis Lou <dlou99 at yahoo dot com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation; either version 2.1 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <math.h>
31 #include <errno.h>
32 #include <assert.h>
33 #include <fcntl.h>
34 #include <sys/ioctl.h>
35 #include <sys/mman.h>
36 #include <poll.h>
37
38 #include <vlc_common.h>
39 #include <vlc_demux.h>
40 #include <vlc_fs.h>
41
42 #include "v4l2.h"
43
44 static int DemuxControl( demux_t *, int, va_list );
45 static int Demux( demux_t * );
46 static int InitVideo (demux_t *, int);
47
48 int DemuxOpen( vlc_object_t *obj )
49 {
50     demux_t *demux = (demux_t *)obj;
51
52     demux_sys_t *sys = calloc( 1, sizeof( demux_sys_t ) );
53     if( unlikely(sys == NULL) )
54         return VLC_ENOMEM;
55     demux->p_sys = sys;
56
57     ParseMRL( obj, demux->psz_location );
58
59     char *path = var_InheritString (obj, CFG_PREFIX"dev");
60     if (unlikely(path == NULL))
61         goto error; /* probably OOM */
62     msg_Dbg (obj, "opening device '%s'", path);
63
64     int rawfd = vlc_open (path, O_RDWR);
65     if (rawfd == -1)
66     {
67         msg_Err (obj, "cannot open device '%s': %m", path);
68         free (path);
69         goto error;
70     }
71     free (path);
72
73     int fd = v4l2_fd_open (rawfd, 0);
74     if (fd == -1)
75     {
76         msg_Warn (obj, "cannot initialize user-space library: %m");
77         /* fallback to direct kernel mode anyway */
78         fd = rawfd;
79     }
80
81     if (InitVideo (demux, fd))
82     {
83         v4l2_close (fd);
84         goto error;
85     }
86
87     sys->i_fd = fd;
88     sys->controls = ControlsInit (VLC_OBJECT(demux), fd);
89     demux->pf_demux = Demux;
90     demux->pf_control = DemuxControl;
91     demux->info.i_update = 0;
92     demux->info.i_title = 0;
93     demux->info.i_seekpoint = 0;
94     return VLC_SUCCESS;
95 error:
96     free (sys);
97     return VLC_EGENERIC;
98 }
99
100 typedef struct
101 {
102     uint32_t v4l2;
103     vlc_fourcc_t vlc;
104     uint32_t red;
105     uint32_t green;
106     uint32_t blue;
107 } vlc_v4l2_fmt_t;
108
109 /* NOTE: Currently vlc_v4l2_fmt_rank() assumes format are sorted in order of
110  * decreasing preference. */
111 static const vlc_v4l2_fmt_t v4l2_fmts[] =
112 {
113     /* Planar YUV 4:2:0 */
114     { V4L2_PIX_FMT_YUV420,   VLC_CODEC_I420, 0, 0, 0 },
115     { V4L2_PIX_FMT_YVU420,   VLC_CODEC_YV12, 0, 0, 0 },
116     { V4L2_PIX_FMT_YUV422P,  VLC_CODEC_I422, 0, 0, 0 },
117     /* Packed YUV 4:2:2 */
118     { V4L2_PIX_FMT_YUYV,     VLC_CODEC_YUYV, 0, 0, 0 },
119     { V4L2_PIX_FMT_UYVY,     VLC_CODEC_UYVY, 0, 0, 0 },
120     { V4L2_PIX_FMT_YVYU,     VLC_CODEC_YVYU, 0, 0, 0 },
121     { V4L2_PIX_FMT_VYUY,     VLC_CODEC_VYUY, 0, 0, 0 },
122
123     { V4L2_PIX_FMT_YUV411P,  VLC_CODEC_I411, 0, 0, 0 },
124
125     { V4L2_PIX_FMT_YUV410,   VLC_CODEC_I410, 0, 0, 0 },
126 //  { V4L2_PIX_FMT_YVU410     },
127
128 //  { V4L2_PIX_FMT_NV24,      },
129 //  { V4L2_PIX_FMT_NV42,      },
130 //  { V4L2_PIX_FMT_NV16,     VLC_CODEC_NV16, 0, 0, 0 },
131 //  { V4L2_PIX_FMT_NV61,     VLC_CODEC_NV61, 0, 0, 0 },
132     { V4L2_PIX_FMT_NV12,     VLC_CODEC_NV12, 0, 0, 0 },
133     { V4L2_PIX_FMT_NV21,     VLC_CODEC_NV21, 0, 0, 0 },
134
135     /* V4L2-documented but VLC-unsupported misc. YUV formats */
136 //  { V4L2_PIX_FMT_Y41P       },
137 //  { V4L2_PIX_FMT_NV12MT,    },
138 //  { V4L2_PIX_FMT_M420,      },
139
140     /* Packed RGB */
141 #ifdef WORDS_BIGENDIAN
142     { V4L2_PIX_FMT_RGB32,    VLC_CODEC_RGB32,   0xFF00, 0xFF0000, 0xFF000000 },
143     { V4L2_PIX_FMT_BGR32,    VLC_CODEC_RGB32, 0xFF000000, 0xFF0000,   0xFF00 },
144     { V4L2_PIX_FMT_RGB24,    VLC_CODEC_RGB24,   0xFF0000, 0x00FF00, 0x0000FF },
145     { V4L2_PIX_FMT_BGR24,    VLC_CODEC_RGB24,   0x0000FF, 0x00FF00, 0xFF0000 },
146 //  { V4L2_PIX_FMT_BGR666,    },
147 //  { V4L2_PIX_FMT_RGB565,    },
148     { V4L2_PIX_FMT_RGB565X,  VLC_CODEC_RGB16,     0x001F,   0x07E0,   0xF800 },
149 //  { V4L2_PIX_FMT_RGB555,    },
150     { V4L2_PIX_FMT_RGB555X,  VLC_CODEC_RGB15,     0x001F,   0x03E0,   0x7C00 },
151 //  { V4L2_PIX_FMT_RGB444,   VLC_CODEC_RGB12,     0x000F,   0xF000,   0x0F00 },
152 #else
153     { V4L2_PIX_FMT_RGB32,    VLC_CODEC_RGB32,   0x0000FF, 0x00FF00, 0xFF0000 },
154     { V4L2_PIX_FMT_BGR32,    VLC_CODEC_RGB32,   0xFF0000, 0x00FF00, 0x0000FF },
155     { V4L2_PIX_FMT_RGB24,    VLC_CODEC_RGB24,   0x0000FF, 0x00FF00, 0xFF0000 },
156     { V4L2_PIX_FMT_BGR24,    VLC_CODEC_RGB24,   0xFF0000, 0x00FF00, 0x0000FF },
157 //  { V4L2_PIX_FMT_BGR666,    },
158     { V4L2_PIX_FMT_RGB565,   VLC_CODEC_RGB16,     0x001F,   0x07E0,   0xF800 },
159 //  { V4L2_PIX_FMT_RGB565X,   },
160     { V4L2_PIX_FMT_RGB555,   VLC_CODEC_RGB15,     0x001F,   0x03E0,   0x7C00 },
161 //  { V4L2_PIX_FMT_RGB555X,   },
162 //  { V4L2_PIX_FMT_RGB444,   VLC_CODEC_RGB12,     0x0F00,   0x00F0,   0x000F },
163 #endif
164 //  { V4L2_PIX_FMT_RGB332,   VLC_CODEC_RGB8,        0xC0,     0x38,     0x07 },
165
166     /* Bayer (sub-sampled RGB). Not supported. */
167 //  { V4L2_PIX_FMT_SBGGR16,  }
168 //  { V4L2_PIX_FMT_SRGGB12,  }
169 //  { V4L2_PIX_FMT_SGRBG12,  }
170 //  { V4L2_PIX_FMT_SGBRG12,  }
171 //  { V4L2_PIX_FMT_SBGGR12,  }
172 //  { V4L2_PIX_FMT_SRGGB10,  }
173 //  { V4L2_PIX_FMT_SGRBG10,  }
174 //  { V4L2_PIX_FMT_SGBRG10,  }
175 //  { V4L2_PIX_FMT_SBGGR10,  }
176 //  { V4L2_PIX_FMT_SBGGR8,   }
177 //  { V4L2_PIX_FMT_SGBRG8,   }
178 //  { V4L2_PIX_FMT_SGRBG8,   }
179 //  { V4L2_PIX_FMT_SRGGB8,   }
180
181     /* Compressed data types */
182     { V4L2_PIX_FMT_JPEG,   VLC_CODEC_MJPG, 0, 0, 0 },
183 #ifdef V4L2_PIX_FMT_H264
184     { V4L2_PIX_FMT_H264,   VLC_CODEC_H264, 0, 0, 0 },
185     /* FIXME: fill p_extra for avc1... */
186 //  { V4L2_PIX_FMT_H264_NO_SC, VLC_FOURCC('a','v','c','1'), 0, 0, 0 }
187     { V4L2_PIX_FMT_MPEG4,  VLC_CODEC_MP4V, 0, 0, 0 },
188     { V4L2_PIX_FMT_XVID,   VLC_CODEC_MP4V, 0, 0, 0 },
189     { V4L2_PIX_FMT_H263,   VLC_CODEC_H263, 0, 0, 0 },
190     { V4L2_PIX_FMT_MPEG2,  VLC_CODEC_MPGV, 0, 0, 0 },
191     { V4L2_PIX_FMT_MPEG1,  VLC_CODEC_MPGV, 0, 0, 0 },
192     { V4L2_PIX_FMT_VC1_ANNEX_G, VLC_CODEC_VC1, 0, 0, 0 },
193     { V4L2_PIX_FMT_VC1_ANNEX_L, VLC_CODEC_VC1, 0, 0, 0 },
194 #endif
195     //V4L2_PIX_FMT_MPEG -> use access
196
197     /* Reserved formats */
198     { V4L2_PIX_FMT_MJPEG,   VLC_CODEC_MJPG, 0, 0, 0 },
199     //V4L2_PIX_FMT_DV -> use access
200
201     /* Grey scale */
202 //  { V4L2_PIX_FMT_Y16,       },
203 //  { V4L2_PIX_FMT_Y12,       },
204 //  { V4L2_PIX_FMT_Y10,       },
205 //  { V4L2_PIX_FMT_Y10BPACK,  },
206     { V4L2_PIX_FMT_GREY,     VLC_CODEC_GREY, 0, 0, 0 },
207 };
208
209 static const vlc_v4l2_fmt_t *vlc_from_v4l2_fourcc (uint32_t fourcc)
210 {
211      for (size_t i = 0; i < sizeof (v4l2_fmts) / sizeof (v4l2_fmts[0]); i++)
212          if (v4l2_fmts[i].v4l2 == fourcc)
213              return v4l2_fmts + i;
214      return NULL;
215 }
216
217 static size_t vlc_v4l2_fmt_rank (const vlc_v4l2_fmt_t *fmt)
218 {
219     if (fmt == NULL)
220         return SIZE_MAX;
221
222     ptrdiff_t d = fmt - v4l2_fmts;
223     assert (d >= 0);
224     assert (d < (ptrdiff_t)(sizeof (v4l2_fmts) / sizeof (v4l2_fmts[0])));
225     return d;
226 }
227
228 static vlc_fourcc_t var_InheritFourCC (vlc_object_t *obj, const char *varname)
229 {
230     char *str = var_InheritString (obj, varname);
231     if (str == NULL)
232         return 0;
233
234     vlc_fourcc_t fourcc = vlc_fourcc_GetCodecFromString (VIDEO_ES, str);
235     if (fourcc == 0)
236         msg_Err (obj, "invalid codec %s", str);
237     free (str);
238     return fourcc;
239 }
240 #define var_InheritFourCC(o, v) var_InheritFourCC(VLC_OBJECT(o), v)
241
242 static void GetAR (int fd, unsigned *restrict num, unsigned *restrict den)
243 {
244     struct v4l2_cropcap cropcap = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
245
246     /* TODO: get CROPCAP only once (see ResetCrop()). */
247     if (v4l2_ioctl (fd, VIDIOC_CROPCAP, &cropcap) < 0)
248     {
249         *num = *den = 1;
250         return;
251     }
252     *num = cropcap.pixelaspect.numerator;
253     *den = cropcap.pixelaspect.denominator;
254 }
255
256 static int InitVideo (demux_t *demux, int fd)
257 {
258     demux_sys_t *sys = demux->p_sys;
259     enum v4l2_buf_type buf_type;
260
261     /* Get device capabilites */
262     struct v4l2_capability cap;
263     if (v4l2_ioctl (fd, VIDIOC_QUERYCAP, &cap) < 0)
264     {
265         msg_Err (demux, "cannot get device capabilities: %m");
266         return -1;
267     }
268
269     msg_Dbg (demux, "device %s using driver %s (version %u.%u.%u) on %s",
270             cap.card, cap.driver, (cap.version >> 16) & 0xFF,
271             (cap.version >> 8) & 0xFF, cap.version & 0xFF, cap.bus_info);
272
273     uint32_t caps;
274 #ifdef V4L2_CAP_DEVICE_CAPS
275     if (cap.capabilities & V4L2_CAP_DEVICE_CAPS)
276     {
277         msg_Dbg (demux, " with capabilities 0x%08"PRIX32" "
278                  "(overall 0x%08"PRIX32")", cap.device_caps, cap.capabilities);
279         caps = cap.device_caps;
280     }
281     else
282 #endif
283     {
284         msg_Dbg (demux, " with unknown capabilities  "
285                  "(overall 0x%08"PRIX32")", cap.capabilities);
286         caps = cap.capabilities;
287     }
288     if (!(caps & V4L2_CAP_VIDEO_CAPTURE))
289     {
290         msg_Err (demux, "not a video capture device");
291         return -1;
292     }
293
294     if (caps & V4L2_CAP_STREAMING)
295         sys->io = IO_METHOD_MMAP;
296     else if (caps & V4L2_CAP_READWRITE)
297         sys->io = IO_METHOD_READ;
298     else
299     {
300         msg_Err (demux, "no supported I/O method");
301         return -1;
302     }
303
304     if (SetupInput (VLC_OBJECT(demux), fd))
305         return -1;
306
307     /* Picture format negotiation */
308     const vlc_v4l2_fmt_t *selected = NULL;
309     vlc_fourcc_t reqfourcc = var_InheritFourCC (demux, CFG_PREFIX"chroma");
310     bool native = false;
311
312     for (struct v4l2_fmtdesc codec = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
313          v4l2_ioctl (fd, VIDIOC_ENUM_FMT, &codec) >= 0;
314          codec.index++)
315     {   /* Enumerate available chromas */
316         const vlc_v4l2_fmt_t *dsc = vlc_from_v4l2_fourcc (codec.pixelformat);
317
318         msg_Dbg (demux, " %s %s format %4.4s (%4.4s): %s",
319               (codec.flags & V4L2_FMT_FLAG_EMULATED) ? "emulates" : "supports",
320               (codec.flags & V4L2_FMT_FLAG_COMPRESSED) ? "compressed" : "raw",
321                  (char *)&codec.pixelformat,
322                  (dsc != NULL) ? (const char *)&dsc->vlc : "N.A.",
323                  codec.description);
324
325         if (dsc == NULL)
326             continue; /* ignore VLC-unsupported codec */
327
328         if (dsc->vlc == reqfourcc)
329         {
330             msg_Dbg (demux, "  matches the requested format");
331             selected = dsc;
332             break; /* always select the requested format if found */
333         }
334
335         if (codec.flags & V4L2_FMT_FLAG_EMULATED)
336         {
337             if (native)
338                 continue; /* ignore emulated format if possible */
339         }
340         else
341             native = true;
342
343         if (vlc_v4l2_fmt_rank (dsc) > vlc_v4l2_fmt_rank (selected))
344             continue; /* ignore if rank is worse */
345
346         selected = dsc;
347     }
348
349     if (selected == NULL)
350     {
351         msg_Err (demux, "cannot negotiate supported video format");
352         return -1;
353     }
354     msg_Dbg (demux, "selected format %4.4s (%4.4s)",
355              (const char *)&selected->v4l2, (const char *)&selected->vlc);
356
357     /* Find best resolution and frame rate available */
358     struct v4l2_format fmt;
359     struct v4l2_streamparm parm;
360     if (SetupFormat (demux, fd, selected->v4l2, &fmt, &parm))
361         return -1;
362
363 #if 0
364     uint32_t width = var_InheritInteger (demux, CFG_PREFIX"width");
365     if (width != (uint32_t)-1)
366         fmt.fmt.pix.width = width; /* override width */
367     uint32_t height = var_InheritInteger (demux, CFG_PREFIX"height");
368     if (height != (uint32_t)-1)
369         fmt.fmt.pix.height = height; /* override height */
370 #endif
371
372     /* Print extra info */
373     msg_Dbg (demux, "%d bytes maximum for complete image",
374              fmt.fmt.pix.sizeimage);
375     /* Check interlacing */
376     switch (fmt.fmt.pix.field)
377     {
378         case V4L2_FIELD_NONE:
379             msg_Dbg (demux, "Interlacing setting: progressive");
380             break;
381         case V4L2_FIELD_TOP:
382             msg_Dbg (demux, "Interlacing setting: top field only");
383             break;
384         case V4L2_FIELD_BOTTOM:
385             msg_Dbg (demux, "Interlacing setting: bottom field only");
386             break;
387         case V4L2_FIELD_INTERLACED:
388             msg_Dbg (demux, "Interlacing setting: interleaved");
389             /*if (NTSC)
390                 sys->i_block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
391             else*/
392                 sys->i_block_flags = BLOCK_FLAG_TOP_FIELD_FIRST;
393             break;
394         case V4L2_FIELD_SEQ_TB:
395             msg_Dbg (demux, "Interlacing setting: sequential top bottom (TODO)");
396             break;
397         case V4L2_FIELD_SEQ_BT:
398             msg_Dbg (demux, "Interlacing setting: sequential bottom top (TODO)");
399             break;
400         case V4L2_FIELD_ALTERNATE:
401             msg_Dbg (demux, "Interlacing setting: alternate fields (TODO)");
402             fmt.fmt.pix.height *= 2;
403             break;
404         case V4L2_FIELD_INTERLACED_TB:
405             msg_Dbg (demux, "Interlacing setting: interleaved top bottom");
406             sys->i_block_flags = BLOCK_FLAG_TOP_FIELD_FIRST;
407             break;
408         case V4L2_FIELD_INTERLACED_BT:
409             msg_Dbg (demux, "Interlacing setting: interleaved bottom top");
410             sys->i_block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST;
411             break;
412         default:
413             msg_Warn (demux, "Interlacing setting: unknown type (%d)",
414                       fmt.fmt.pix.field);
415             break;
416     }
417
418     /* Declare our unique elementary (video) stream */
419     es_format_t es_fmt;
420
421     es_format_Init (&es_fmt, VIDEO_ES, selected->vlc);
422     es_fmt.video.i_rmask = selected->red;
423     es_fmt.video.i_gmask = selected->green;
424     es_fmt.video.i_bmask = selected->blue;
425     es_fmt.video.i_width = fmt.fmt.pix.width;
426     es_fmt.video.i_height = fmt.fmt.pix.height;
427     es_fmt.video.i_frame_rate = parm.parm.capture.timeperframe.denominator;
428     es_fmt.video.i_frame_rate_base = parm.parm.capture.timeperframe.numerator;
429     GetAR (fd, &es_fmt.video.i_sar_num, &es_fmt.video.i_sar_den);
430
431     msg_Dbg (demux, "added new video ES %4.4s %ux%u", (char *)&es_fmt.i_codec,
432              es_fmt.video.i_width, es_fmt.video.i_height);
433     msg_Dbg (demux, " frame rate: %u/%u", es_fmt.video.i_frame_rate,
434              es_fmt.video.i_frame_rate_base);
435     msg_Dbg (demux, " aspect ratio: %u/%u", es_fmt.video.i_sar_num,
436              es_fmt.video.i_sar_den);
437     sys->p_es = es_out_Add (demux->out, &es_fmt);
438
439     /* Init I/O method */
440     switch (sys->io)
441     {
442     case IO_METHOD_READ:
443         sys->blocksize = fmt.fmt.pix.sizeimage;
444         break;
445
446     case IO_METHOD_MMAP:
447         if (InitMmap (VLC_OBJECT(demux), sys, fd))
448             return -1;
449         for (unsigned int i = 0; i < sys->i_nbuffers; i++)
450         {
451             struct v4l2_buffer buf = {
452                 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
453                 .memory = V4L2_MEMORY_MMAP,
454                 .index = i,
455             };
456
457             if (v4l2_ioctl (fd, VIDIOC_QBUF, &buf) < 0)
458             {
459                 msg_Err (demux, "cannot queue buffer: %m");
460                 return -1;
461             }
462         }
463
464         buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
465         if (v4l2_ioctl (fd, VIDIOC_STREAMON, &buf_type) < 0)
466         {
467             msg_Err (demux, "cannot start streaming: %m");
468             return -1;
469         }
470         break;
471
472     default:
473         assert (0);
474     }
475
476     return 0;
477 }
478
479 void DemuxClose( vlc_object_t *obj )
480 {
481     demux_t *demux = (demux_t *)obj;
482     demux_sys_t *sys = demux->p_sys;
483     int fd = sys->i_fd;
484
485     /* Stop video capture */
486     switch( sys->io )
487     {
488         case IO_METHOD_READ:
489             /* Nothing to do */
490             break;
491
492         case IO_METHOD_MMAP:
493         {
494             /* NOTE: Some buggy drivers hang if buffers are not unmapped before
495              * streamoff */
496             for( unsigned i = 0; i < sys->i_nbuffers; i++ )
497             {
498                 struct v4l2_buffer buf = {
499                     .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
500                     .memory = V4L2_MEMORY_MMAP,
501                 };
502                 v4l2_ioctl( fd, VIDIOC_DQBUF, &buf );
503             }
504             enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
505             v4l2_ioctl( sys->i_fd, VIDIOC_STREAMOFF, &buf_type );
506             break;
507         }
508     }
509
510     /* Free Video Buffers */
511     if( sys->p_buffers ) {
512         switch( sys->io )
513         {
514         case IO_METHOD_READ:
515             free( sys->p_buffers[0].start );
516             break;
517
518         case IO_METHOD_MMAP:
519             for( unsigned i = 0; i < sys->i_nbuffers; ++i )
520                 v4l2_munmap( sys->p_buffers[i].start,
521                              sys->p_buffers[i].length );
522             break;
523         }
524         free( sys->p_buffers );
525     }
526
527     ControlsDeinit( obj, sys->controls );
528     v4l2_close( fd );
529     free( sys );
530 }
531
532 static int DemuxControl( demux_t *demux, int query, va_list args )
533 {
534     switch( query )
535     {
536         /* Special for access_demux */
537         case DEMUX_CAN_PAUSE:
538         case DEMUX_CAN_SEEK:
539         case DEMUX_CAN_CONTROL_PACE:
540             *va_arg( args, bool * ) = false;
541             return VLC_SUCCESS;
542
543         case DEMUX_GET_PTS_DELAY:
544             *va_arg(args,int64_t *) = INT64_C(1000)
545                 * var_InheritInteger( demux, "live-caching" );
546             return VLC_SUCCESS;
547
548         case DEMUX_GET_TIME:
549             *va_arg( args, int64_t * ) = mdate();
550             return VLC_SUCCESS;
551
552         /* TODO implement others */
553         default:
554             return VLC_EGENERIC;
555     }
556
557     return VLC_EGENERIC;
558 }
559
560 /** Gets a frame in read/write mode */
561 static block_t *BlockRead( vlc_object_t *obj, int fd, size_t size )
562 {
563     block_t *block = block_Alloc( size );
564     if( unlikely(block == NULL) )
565         return NULL;
566
567     ssize_t val = v4l2_read( fd, block->p_buffer, size );
568     if( val == -1 )
569     {
570         block_Release( block );
571         switch( errno )
572         {
573             case EAGAIN:
574                 return NULL;
575             case EIO: /* could be ignored per specification */
576                 /* fall through */
577             default:
578                 msg_Err( obj, "cannot read frame: %m" );
579                 return NULL;
580         }
581     }
582     block->i_buffer = val;
583     return block;
584 }
585
586 static int Demux( demux_t *demux )
587 {
588     demux_sys_t *sys = demux->p_sys;
589     struct pollfd ufd;
590
591     ufd.fd = sys->i_fd;
592     ufd.events = POLLIN|POLLPRI;
593     /* Wait for data */
594     /* FIXME: remove timeout */
595     while( poll( &ufd, 1, 500 ) == -1 )
596         if( errno != EINTR )
597         {
598             msg_Err( demux, "poll error: %m" );
599             return -1;
600         }
601
602     if( ufd.revents == 0 )
603         return 1;
604
605     block_t *block;
606
607     if( sys->io == IO_METHOD_READ )
608         block = BlockRead( VLC_OBJECT(demux), ufd.fd, sys->blocksize );
609     else
610         block = GrabVideo( VLC_OBJECT(demux), sys );
611     if( block == NULL )
612         return 1;
613
614     block->i_pts = block->i_dts = mdate();
615     block->i_flags |= sys->i_block_flags;
616     es_out_Control( demux->out, ES_OUT_SET_PCR, block->i_pts );
617     es_out_Send( demux->out, sys->p_es, block );
618     return 1;
619 }