30
30
#undef __STRICT_ANSI__ //workaround due to broken kernel headers
31
31
#include "config.h"
32
32
#include "libavformat/avformat.h"
33
#include "libavformat/internal.h"
33
34
#include <unistd.h>
35
36
#include <sys/ioctl.h>
36
37
#include <sys/mman.h>
37
38
#include <sys/time.h>
38
40
#if HAVE_SYS_VIDEOIO_H
39
41
#include <sys/videoio.h>
41
#include <asm/types.h>
42
43
#include <linux/videodev2.h>
46
46
#include "libavutil/imgutils.h"
47
47
#include "libavutil/log.h"
48
48
#include "libavutil/opt.h"
49
49
#include "libavutil/parseutils.h"
50
50
#include "libavutil/pixdesc.h"
51
#include "libavutil/avstring.h"
52
#include "libavutil/mathematics.h"
52
54
static const int desired_video_buffers = 256;
56
#define V4L_ALLFORMATS 3
57
#define V4L_RAWFORMATS 1
58
#define V4L_COMPFORMATS 2
60
60
struct video_data {
63
63
int frame_format; /* V4L2_PIX_FMT_* */
64
enum io_method io_method;
67
68
int top_field_first;
116
119
if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
117
120
flags |= O_NONBLOCK;
119
123
fd = open(ctx->filename, flags, 0);
121
127
av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
122
ctx->filename, strerror(errno));
128
ctx->filename, strerror(err));
124
return AVERROR(errno);
127
133
res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
128
// ENOIOCTLCMD definition only availble on __KERNEL__
129
if (res < 0 && ((err = errno) == 515)) {
130
av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
136
136
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
142
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
143
av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n");
146
return AVERROR(ENODEV);
148
*capabilities = cap.capabilities;
142
av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n",
143
fd, cap.capabilities);
145
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
146
av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
152
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
153
av_log(ctx, AV_LOG_ERROR,
154
"The device does not support the streaming I/O method.\n");
153
static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt)
167
static int device_init(AVFormatContext *ctx, int *width, int *height,
155
170
struct video_data *s = ctx->priv_data;
157
struct v4l2_format fmt;
172
struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
173
struct v4l2_pix_format *pix = &fmt.fmt.pix;
160
memset(&fmt, 0, sizeof(struct v4l2_format));
161
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
162
fmt.fmt.pix.width = *width;
163
fmt.fmt.pix.height = *height;
164
fmt.fmt.pix.pixelformat = pix_fmt;
165
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
178
pix->height = *height;
179
pix->pixelformat = pix_fmt;
180
pix->field = V4L2_FIELD_ANY;
166
182
res = ioctl(fd, VIDIOC_S_FMT, &fmt);
167
184
if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
168
av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
185
av_log(ctx, AV_LOG_INFO,
186
"The V4L2 driver changed the video from %dx%d to %dx%d\n",
187
*width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
169
188
*width = fmt.fmt.pix.width;
170
189
*height = fmt.fmt.pix.height;
173
192
if (pix_fmt != fmt.fmt.pix.pixelformat) {
174
av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver changed the pixel format from 0x%08X to 0x%08X\n", pix_fmt, fmt.fmt.pix.pixelformat);
193
av_log(ctx, AV_LOG_DEBUG,
194
"The V4L2 driver changed the pixel format "
195
"from 0x%08X to 0x%08X\n",
196
pix_fmt, fmt.fmt.pix.pixelformat);
200
if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
201
av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
237
264
return CODEC_ID_NONE;
267
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
268
static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
270
struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
272
while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
274
case V4L2_FRMSIZE_TYPE_DISCRETE:
275
av_log(ctx, AV_LOG_INFO, " %ux%u",
276
vfse.discrete.width, vfse.discrete.height);
278
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
279
case V4L2_FRMSIZE_TYPE_STEPWISE:
280
av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
281
vfse.stepwise.min_width,
282
vfse.stepwise.max_width,
283
vfse.stepwise.step_width,
284
vfse.stepwise.min_height,
285
vfse.stepwise.max_height,
286
vfse.stepwise.step_height);
293
static void list_formats(AVFormatContext *ctx, int fd, int type)
295
struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
297
while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
298
enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
299
enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
303
if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
304
type & V4L_RAWFORMATS) {
305
const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
306
av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
307
fmt_name ? fmt_name : "Unsupported",
309
} else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
310
type & V4L_COMPFORMATS) {
311
AVCodec *codec = avcodec_find_encoder(codec_id);
312
av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
313
codec ? codec->name : "Unsupported",
319
#ifdef V4L2_FMT_FLAG_EMULATED
320
if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
321
av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
325
#if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
326
list_framesizes(ctx, fd, vfd.pixelformat);
328
av_log(ctx, AV_LOG_INFO, "\n");
240
332
static int mmap_init(AVFormatContext *ctx)
242
335
struct video_data *s = ctx->priv_data;
243
struct v4l2_requestbuffers req;
336
struct v4l2_requestbuffers req = {
337
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
338
.count = desired_video_buffers,
339
.memory = V4L2_MEMORY_MMAP
246
memset(&req, 0, sizeof(struct v4l2_requestbuffers));
247
req.count = desired_video_buffers;
248
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
249
req.memory = V4L2_MEMORY_MMAP;
250
342
res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
252
344
if (errno == EINVAL) {
295
387
s->buf_len[i] = buf.length;
296
388
if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
297
av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size);
389
av_log(ctx, AV_LOG_ERROR,
390
"Buffer len [%d] = %d != %d\n",
391
i, s->buf_len[i], s->frame_size);
301
s->buf_start[i] = mmap (NULL, buf.length,
302
PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
395
s->buf_start[i] = mmap(NULL, buf.length,
396
PROT_READ | PROT_WRITE, MAP_SHARED,
397
s->fd, buf.m.offset);
303
399
if (s->buf_start[i] == MAP_FAILED) {
304
400
av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
343
433
static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
345
435
struct video_data *s = ctx->priv_data;
346
struct v4l2_buffer buf;
436
struct v4l2_buffer buf = {
437
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
438
.memory = V4L2_MEMORY_MMAP
347
440
struct buff_data *buf_descriptor;
441
struct pollfd p = { .fd = s->fd, .events = POLLIN };
350
memset(&buf, 0, sizeof(struct v4l2_buffer));
351
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
352
buf.memory = V4L2_MEMORY_MMAP;
444
res = poll(&p, 1, s->timeout);
446
return AVERROR(errno);
448
if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))
449
return AVERROR(EAGAIN);
354
451
/* FIXME: Some special treatment might be needed in case of loss of signal... */
355
452
while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
360
457
return AVERROR(EAGAIN);
362
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno));
459
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
364
462
return AVERROR(errno);
366
464
assert (buf.index < s->buffers);
367
465
if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
368
av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size);
466
av_log(ctx, AV_LOG_ERROR,
467
"The v4l2 frame is %d bytes, but %d bytes are expected\n",
468
buf.bytesused, s->frame_size);
370
470
return AVERROR_INVALIDDATA;
406
501
for (i = 0; i < s->buffers; i++) {
407
struct v4l2_buffer buf;
409
memset(&buf, 0, sizeof(struct v4l2_buffer));
410
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
411
buf.memory = V4L2_MEMORY_MMAP;
502
struct v4l2_buffer buf = {
503
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
505
.memory = V4L2_MEMORY_MMAP
414
508
res = ioctl(s->fd, VIDIOC_QBUF, &buf);
416
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
510
av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
418
513
return AVERROR(errno);
450
546
static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
452
548
struct video_data *s = s1->priv_data;
453
struct v4l2_input input;
454
struct v4l2_standard standard;
549
struct v4l2_input input = { 0 };
550
struct v4l2_standard standard = { 0 };
455
551
struct v4l2_streamparm streamparm = { 0 };
456
552
struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
553
AVRational framerate_q = { 0 };
460
556
streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
462
if (s->framerate && (ret = av_parse_video_rate(&fps, s->framerate)) < 0) {
463
av_log(s1, AV_LOG_ERROR, "Couldn't parse framerate.\n");
559
(ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
560
av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
466
#if FF_API_FORMAT_PARAMETERS
468
s->channel = ap->channel;
469
if (ap->time_base.num)
470
fps = (AVRational){ap->time_base.den, ap->time_base.num};
473
565
/* set tv video input */
474
memset (&input, 0, sizeof (input));
475
566
input.index = s->channel;
476
567
if (ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
477
568
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
481
572
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
482
573
s->channel, input.name);
483
574
if (ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
484
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n",
575
av_log(s1, AV_LOG_ERROR,
576
"The V4L2 driver ioctl set input(%d) failed\n",
486
578
return AVERROR(EIO);
489
#if FF_API_FORMAT_PARAMETERS
491
av_freep(&s->standard);
492
s->standard = av_strdup(ap->standard);
496
581
if (s->standard) {
497
582
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
499
584
/* set tv standard */
500
memset (&standard, 0, sizeof (standard));
502
586
standard.index = i;
503
587
if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
504
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
588
av_log(s1, AV_LOG_ERROR,
589
"The V4L2 driver ioctl set standard(%s) failed\n",
506
591
return AVERROR(EIO);
509
if (!strcasecmp(standard.name, s->standard)) {
594
if (!av_strcasecmp(standard.name, s->standard)) {
514
av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
599
av_log(s1, AV_LOG_DEBUG,
600
"The V4L2 driver set standard: %s, id: %"PRIu64"\n",
515
601
s->standard, (uint64_t)standard.id);
516
602
if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
517
av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
603
av_log(s1, AV_LOG_ERROR,
604
"The V4L2 driver ioctl set standard(%s) failed\n",
519
606
return AVERROR(EIO);
523
if (fps.num && fps.den) {
610
if (framerate_q.num && framerate_q.den) {
524
611
av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
526
tpf->numerator = fps.den;
527
tpf->denominator = fps.num;
612
framerate_q.den, framerate_q.num);
613
tpf->numerator = framerate_q.den;
614
tpf->denominator = framerate_q.num;
528
616
if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
529
617
av_log(s1, AV_LOG_ERROR,
530
618
"ioctl set time per frame(%d/%d) failed\n",
619
framerate_q.den, framerate_q.num);
532
620
return AVERROR(EIO);
535
if (fps.num != tpf->denominator ||
536
fps.den != tpf->numerator) {
623
if (framerate_q.num != tpf->denominator ||
624
framerate_q.den != tpf->numerator) {
537
625
av_log(s1, AV_LOG_INFO,
538
"The driver changed the time per frame from %d/%d to %d/%d\n",
626
"The driver changed the time per frame from "
628
framerate_q.den, framerate_q.num,
540
629
tpf->numerator, tpf->denominator);
543
/* if timebase value is not set, read the timebase value from the driver */
544
632
if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
545
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", strerror(errno));
633
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
546
635
return AVERROR(errno);
549
638
s1->streams[0]->codec->time_base.den = tpf->denominator;
550
639
s1->streams[0]->codec->time_base.num = tpf->numerator;
642
av_rescale_q(1, s1->streams[0]->codec->time_base,
643
(AVRational){1, 1000});
589
683
struct video_data *s = s1->priv_data;
592
uint32_t desired_format, capabilities;
686
uint32_t desired_format;
593
687
enum CodecID codec_id;
594
688
enum PixelFormat pix_fmt = PIX_FMT_NONE;
596
st = av_new_stream(s1, 0);
690
st = avformat_new_stream(s1, NULL);
598
692
res = AVERROR(ENOMEM);
601
av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
603
if (s->video_size && (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
604
av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
607
if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
608
av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
609
res = AVERROR(EINVAL);
612
#if FF_API_FORMAT_PARAMETERS
614
s->width = ap->width;
616
s->height = ap->height;
618
pix_fmt = ap->pix_fmt;
622
s->fd = device_open(s1, &capabilities);
696
s->fd = device_open(s1);
627
av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities);
702
if (s->list_format) {
703
list_formats(s1, s->fd, s->list_format);
708
avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
711
(res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
712
av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
717
if (s->pixel_format) {
718
AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
721
s1->video_codec_id = codec->id;
723
pix_fmt = av_get_pix_fmt(s->pixel_format);
725
if (pix_fmt == PIX_FMT_NONE && !codec) {
726
av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
729
res = AVERROR(EINVAL);
629
734
if (!s->width && !s->height) {
630
735
struct v4l2_format fmt;
632
av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n");
737
av_log(s1, AV_LOG_VERBOSE,
738
"Querying the device for the current frame size\n");
633
739
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
634
740
if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
635
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno));
741
av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
636
743
res = AVERROR(errno);
639
747
s->width = fmt.fmt.pix.width;
640
748
s->height = fmt.fmt.pix.height;
641
av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height);
749
av_log(s1, AV_LOG_VERBOSE,
750
"Setting frame size to %dx%d\n", s->width, s->height);
644
desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, &codec_id);
753
desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
645
755
if (desired_format == 0) {
646
756
av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
647
757
"codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
650
760
res = AVERROR(EIO);
653
764
if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
655
767
s->frame_format = desired_format;
657
769
if ((res = v4l2_set_parameters(s1, ap) < 0))
660
772
st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
661
s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
662
if (capabilities & V4L2_CAP_STREAMING) {
663
s->io_method = io_mmap;
666
res = mmap_start(s1);
669
s->io_method = io_read;
774
avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
776
if ((res = mmap_init(s1)) ||
777
(res = mmap_start(s1)) < 0) {
678
782
s->top_field_first = first_field(s->fd);
680
784
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
681
785
st->codec->codec_id = codec_id;
786
if (codec_id == CODEC_ID_RAWVIDEO)
787
st->codec->codec_tag =
788
avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
682
789
st->codec->width = s->width;
683
790
st->codec->height = s->height;
684
791
st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
690
797
static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
692
799
struct video_data *s = s1->priv_data;
800
AVFrame *frame = s1->streams[0]->codec->coded_frame;
695
if (s->io_method == io_mmap) {
697
res = mmap_read_frame(s1, pkt);
698
} else if (s->io_method == io_read) {
699
if (av_new_packet(pkt, s->frame_size) < 0)
702
res = read_frame(s1, pkt);
804
if ((res = mmap_read_frame(s1, pkt)) < 0) {
710
if (s1->streams[0]->codec->coded_frame) {
711
s1->streams[0]->codec->coded_frame->interlaced_frame = 1;
712
s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first;
808
if (frame && s->interlaced) {
809
frame->interlaced_frame = 1;
810
frame->top_field_first = s->top_field_first;
715
813
return pkt->size;
730
826
#define OFFSET(x) offsetof(struct video_data, x)
731
827
#define DEC AV_OPT_FLAG_DECODING_PARAM
732
828
static const AVOption options[] = {
733
{ "standard", "", offsetof(struct video_data, standard), FF_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
734
{ "channel", "", offsetof(struct video_data, channel), FF_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
735
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
736
{ "pixel_format", "", OFFSET(pixel_format), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
737
{ "framerate", "", OFFSET(framerate), FF_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
829
{ "standard", "TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC },
830
{ "channel", "TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC },
831
{ "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
832
{ "pixel_format", "Preferred pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
833
{ "input_format", "Preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
834
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
835
{ "list_formats", "List available formats and exit", OFFSET(list_format), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC, "list_formats" },
836
{ "all", "Show all available formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_ALLFORMATS }, 0, INT_MAX, DEC, "list_formats" },
837
{ "raw", "Show only non-compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_RAWFORMATS }, 0, INT_MAX, DEC, "list_formats" },
838
{ "compressed", "Show only compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_COMPFORMATS }, 0, INT_MAX, DEC, "list_formats" },
748
849
AVInputFormat ff_v4l2_demuxer = {
750
NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
751
sizeof(struct video_data),
756
.flags = AVFMT_NOFILE,
757
.priv_class = &v4l2_class,
850
.name = "video4linux2",
851
.long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
852
.priv_data_size = sizeof(struct video_data),
853
.read_header = v4l2_read_header,
854
.read_packet = v4l2_read_packet,
855
.read_close = v4l2_read_close,
856
.flags = AVFMT_NOFILE,
857
.priv_class = &v4l2_class,