00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00033 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
00034 #include "config.h"
00035 #include "libavformat/internal.h"
00036 #include <unistd.h>
00037 #include <fcntl.h>
00038 #include <sys/ioctl.h>
00039 #include <sys/mman.h>
00040 #include <sys/time.h>
00041 #if HAVE_SYS_VIDEOIO_H
00042 #include <sys/videoio.h>
00043 #else
00044 #if HAVE_ASM_TYPES_H
00045 #include <asm/types.h>
00046 #endif
00047 #include <linux/videodev2.h>
00048 #endif
00049 #include <time.h>
00050 #include "libavutil/imgutils.h"
00051 #include "libavutil/log.h"
00052 #include "libavutil/opt.h"
00053 #include "avdevice.h"
00054 #include "libavutil/parseutils.h"
00055 #include "libavutil/pixdesc.h"
00056 #include "libavutil/avstring.h"
00057
00058 #if CONFIG_LIBV4L2
00059 #include <libv4l2.h>
00060 #else
00061 #define v4l2_open open
00062 #define v4l2_close close
00063 #define v4l2_dup dup
00064 #define v4l2_ioctl ioctl
00065 #define v4l2_read read
00066 #define v4l2_mmap mmap
00067 #define v4l2_munmap munmap
00068 #endif
00069
00070 static const int desired_video_buffers = 256;
00071
00072 enum io_method {
00073 io_read,
00074 io_mmap,
00075 io_userptr
00076 };
00077
00078 struct video_data {
00079 AVClass *class;
00080 int fd;
00081 int frame_format;
00082 enum io_method io_method;
00083 int width, height;
00084 int frame_size;
00085 int top_field_first;
00086
00087 int buffers;
00088 void **buf_start;
00089 unsigned int *buf_len;
00090 char *standard;
00091 int channel;
00092 char *video_size;
00093 char *pixel_format;
00094 char *framerate;
00095 };
00096
00097 struct buff_data {
00098 int index;
00099 int fd;
00100 };
00101
00102 struct fmt_map {
00103 enum PixelFormat ff_fmt;
00104 enum CodecID codec_id;
00105 uint32_t v4l2_fmt;
00106 };
00107
00108 static struct fmt_map fmt_conversion_table[] = {
00109
00110 { PIX_FMT_YUV420P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420 },
00111 { PIX_FMT_YUV422P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
00112 { PIX_FMT_YUYV422, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV },
00113 { PIX_FMT_UYVY422, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY },
00114 { PIX_FMT_YUV411P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
00115 { PIX_FMT_YUV410P, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410 },
00116 { PIX_FMT_RGB555, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555 },
00117 { PIX_FMT_RGB565, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565 },
00118 { PIX_FMT_BGR24, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24 },
00119 { PIX_FMT_RGB24, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24 },
00120 { PIX_FMT_BGRA, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32 },
00121 { PIX_FMT_GRAY8, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY },
00122 { PIX_FMT_NV12, CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12 },
00123 { PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_MJPEG },
00124 { PIX_FMT_NONE, CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG },
00125 };
00126
00127 static int device_open(AVFormatContext *ctx, uint32_t *capabilities)
00128 {
00129 struct v4l2_capability cap;
00130 int fd;
00131 #if CONFIG_LIBV4L2
00132 int fd_libv4l;
00133 #endif
00134 int res, err;
00135 int flags = O_RDWR;
00136
00137 if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
00138 flags |= O_NONBLOCK;
00139 }
00140 fd = v4l2_open(ctx->filename, flags, 0);
00141 if (fd < 0) {
00142 av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
00143 ctx->filename, strerror(errno));
00144 return AVERROR(errno);
00145 }
00146 #if CONFIG_LIBV4L2
00147 fd_libv4l = v4l2_fd_open(fd, 0);
00148 if (fd < 0) {
00149 err = AVERROR(errno);
00150 av_log(ctx, AV_LOG_ERROR, "Cannot open video device with libv4l neither %s : %s\n",
00151 ctx->filename, strerror(errno));
00152 return err;
00153 }
00154 fd = fd_libv4l;
00155 #endif
00156
00157 res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
00158
00159 if (res < 0 && ((err = errno) == 515)) {
00160 av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n");
00161 v4l2_close(fd);
00162
00163 return AVERROR(515);
00164 }
00165 if (res < 0) {
00166 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
00167 strerror(errno));
00168 v4l2_close(fd);
00169 return AVERROR(err);
00170 }
00171 if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
00172 av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n");
00173 v4l2_close(fd);
00174 return AVERROR(ENODEV);
00175 }
00176 *capabilities = cap.capabilities;
00177
00178 return fd;
00179 }
00180
00181 static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt)
00182 {
00183 struct video_data *s = ctx->priv_data;
00184 int fd = s->fd;
00185 struct v4l2_format fmt = {0};
00186 int res;
00187
00188 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00189 fmt.fmt.pix.width = *width;
00190 fmt.fmt.pix.height = *height;
00191 fmt.fmt.pix.pixelformat = pix_fmt;
00192 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00193 res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
00194 if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
00195 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);
00196 *width = fmt.fmt.pix.width;
00197 *height = fmt.fmt.pix.height;
00198 }
00199
00200 if (pix_fmt != fmt.fmt.pix.pixelformat) {
00201 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);
00202 res = -1;
00203 }
00204
00205 return res;
00206 }
00207
00208 static int first_field(int fd)
00209 {
00210 int res;
00211 v4l2_std_id std;
00212
00213 res = v4l2_ioctl(fd, VIDIOC_G_STD, &std);
00214 if (res < 0) {
00215 return 0;
00216 }
00217 if (std & V4L2_STD_NTSC) {
00218 return 0;
00219 }
00220
00221 return 1;
00222 }
00223
00224 static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id)
00225 {
00226 int i;
00227
00228 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00229 if ((codec_id == CODEC_ID_NONE ||
00230 fmt_conversion_table[i].codec_id == codec_id) &&
00231 (pix_fmt == PIX_FMT_NONE ||
00232 fmt_conversion_table[i].ff_fmt == pix_fmt)) {
00233 return fmt_conversion_table[i].v4l2_fmt;
00234 }
00235 }
00236
00237 return 0;
00238 }
00239
00240 static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id)
00241 {
00242 int i;
00243
00244 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00245 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
00246 fmt_conversion_table[i].codec_id == codec_id) {
00247 return fmt_conversion_table[i].ff_fmt;
00248 }
00249 }
00250
00251 return PIX_FMT_NONE;
00252 }
00253
00254 static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt)
00255 {
00256 int i;
00257
00258 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00259 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
00260 return fmt_conversion_table[i].codec_id;
00261 }
00262 }
00263
00264 return CODEC_ID_NONE;
00265 }
00266
00267 static int mmap_init(AVFormatContext *ctx)
00268 {
00269 struct video_data *s = ctx->priv_data;
00270 struct v4l2_requestbuffers req = {0};
00271 int i, res;
00272
00273 req.count = desired_video_buffers;
00274 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00275 req.memory = V4L2_MEMORY_MMAP;
00276 res = v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req);
00277 if (res < 0) {
00278 if (errno == EINVAL) {
00279 av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
00280 } else {
00281 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
00282 }
00283 return AVERROR(errno);
00284 }
00285
00286 if (req.count < 2) {
00287 av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
00288 return AVERROR(ENOMEM);
00289 }
00290 s->buffers = req.count;
00291 s->buf_start = av_malloc(sizeof(void *) * s->buffers);
00292 if (s->buf_start == NULL) {
00293 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
00294 return AVERROR(ENOMEM);
00295 }
00296 s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
00297 if (s->buf_len == NULL) {
00298 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
00299 av_free(s->buf_start);
00300 return AVERROR(ENOMEM);
00301 }
00302
00303 for (i = 0; i < req.count; i++) {
00304 struct v4l2_buffer buf = {0};
00305
00306 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00307 buf.memory = V4L2_MEMORY_MMAP;
00308 buf.index = i;
00309 res = v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
00310 if (res < 0) {
00311 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
00312 return AVERROR(errno);
00313 }
00314
00315 s->buf_len[i] = buf.length;
00316 if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
00317 av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size);
00318
00319 return -1;
00320 }
00321 s->buf_start[i] = v4l2_mmap(NULL, buf.length,
00322 PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset);
00323 if (s->buf_start[i] == MAP_FAILED) {
00324 av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
00325 return AVERROR(errno);
00326 }
00327 }
00328
00329 return 0;
00330 }
00331
00332 static int read_init(AVFormatContext *ctx)
00333 {
00334 return -1;
00335 }
00336
00337 static void mmap_release_buffer(AVPacket *pkt)
00338 {
00339 struct v4l2_buffer buf = {0};
00340 int res, fd;
00341 struct buff_data *buf_descriptor = pkt->priv;
00342
00343 if (pkt->data == NULL) {
00344 return;
00345 }
00346
00347 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00348 buf.memory = V4L2_MEMORY_MMAP;
00349 buf.index = buf_descriptor->index;
00350 fd = buf_descriptor->fd;
00351 av_free(buf_descriptor);
00352
00353 res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
00354 if (res < 0) {
00355 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
00356 }
00357 pkt->data = NULL;
00358 pkt->size = 0;
00359 }
00360
00361 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
00362 {
00363 struct video_data *s = ctx->priv_data;
00364 struct v4l2_buffer buf = {0};
00365 struct buff_data *buf_descriptor;
00366 int res;
00367
00368 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00369 buf.memory = V4L2_MEMORY_MMAP;
00370
00371
00372 while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
00373 if (res < 0) {
00374 if (errno == EAGAIN) {
00375 pkt->size = 0;
00376 return AVERROR(EAGAIN);
00377 }
00378 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno));
00379
00380 return AVERROR(errno);
00381 }
00382 assert(buf.index < s->buffers);
00383 if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
00384 av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size);
00385 return AVERROR_INVALIDDATA;
00386 }
00387
00388
00389 pkt->data= s->buf_start[buf.index];
00390 pkt->size = buf.bytesused;
00391 pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
00392 pkt->destruct = mmap_release_buffer;
00393 buf_descriptor = av_malloc(sizeof(struct buff_data));
00394 if (buf_descriptor == NULL) {
00395
00396
00397
00398 av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
00399 res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
00400
00401 return AVERROR(ENOMEM);
00402 }
00403 buf_descriptor->fd = s->fd;
00404 buf_descriptor->index = buf.index;
00405 pkt->priv = buf_descriptor;
00406
00407 return s->buf_len[buf.index];
00408 }
00409
00410 static int read_frame(AVFormatContext *ctx, AVPacket *pkt)
00411 {
00412 return -1;
00413 }
00414
00415 static int mmap_start(AVFormatContext *ctx)
00416 {
00417 struct video_data *s = ctx->priv_data;
00418 enum v4l2_buf_type type;
00419 int i, res;
00420
00421 for (i = 0; i < s->buffers; i++) {
00422 struct v4l2_buffer buf = {0};
00423
00424 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00425 buf.memory = V4L2_MEMORY_MMAP;
00426 buf.index = i;
00427
00428 res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
00429 if (res < 0) {
00430 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno));
00431 return AVERROR(errno);
00432 }
00433 }
00434
00435 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00436 res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
00437 if (res < 0) {
00438 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno));
00439 return AVERROR(errno);
00440 }
00441
00442 return 0;
00443 }
00444
00445 static void mmap_close(struct video_data *s)
00446 {
00447 enum v4l2_buf_type type;
00448 int i;
00449
00450 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00451
00452
00453
00454 v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
00455 for (i = 0; i < s->buffers; i++) {
00456 v4l2_munmap(s->buf_start[i], s->buf_len[i]);
00457 }
00458 av_free(s->buf_start);
00459 av_free(s->buf_len);
00460 }
00461
00462 static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
00463 {
00464 struct video_data *s = s1->priv_data;
00465 struct v4l2_input input = {0};
00466 struct v4l2_standard standard = {0};
00467 struct v4l2_streamparm streamparm = {0};
00468 struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
00469 int i, ret;
00470 AVRational framerate_q={0};
00471
00472 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00473
00474 if (s->framerate && (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
00475 av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", s->framerate);
00476 return ret;
00477 }
00478
00479
00480 input.index = s->channel;
00481 if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
00482 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
00483 return AVERROR(EIO);
00484 }
00485
00486 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
00487 s->channel, input.name);
00488 if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
00489 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n",
00490 s->channel);
00491 return AVERROR(EIO);
00492 }
00493
00494 if (s->standard) {
00495 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
00496 s->standard);
00497
00498 for (i = 0;; i++) {
00499 standard.index = i;
00500 ret = v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard);
00501 if (ret < 0 || !av_strcasecmp(standard.name, s->standard))
00502 break;
00503 }
00504 if (ret < 0) {
00505 av_log(s1, AV_LOG_ERROR, "Unknown standard '%s'\n", s->standard);
00506 return ret;
00507 }
00508
00509 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
00510 s->standard, (uint64_t)standard.id);
00511 if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
00512 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n",
00513 s->standard);
00514 return AVERROR(EIO);
00515 }
00516 }
00517
00518 if (framerate_q.num && framerate_q.den) {
00519 av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
00520 framerate_q.den, framerate_q.num);
00521 tpf->numerator = framerate_q.den;
00522 tpf->denominator = framerate_q.num;
00523 if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
00524 av_log(s1, AV_LOG_ERROR,
00525 "ioctl set time per frame(%d/%d) failed\n",
00526 framerate_q.den, framerate_q.num);
00527 return AVERROR(EIO);
00528 }
00529
00530 if (framerate_q.num != tpf->denominator ||
00531 framerate_q.den != tpf->numerator) {
00532 av_log(s1, AV_LOG_INFO,
00533 "The driver changed the time per frame from %d/%d to %d/%d\n",
00534 framerate_q.den, framerate_q.num,
00535 tpf->numerator, tpf->denominator);
00536 }
00537 } else {
00538
00539 if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
00540 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", strerror(errno));
00541 return AVERROR(errno);
00542 }
00543 }
00544 s1->streams[0]->codec->time_base.den = tpf->denominator;
00545 s1->streams[0]->codec->time_base.num = tpf->numerator;
00546
00547 return 0;
00548 }
00549
00550 static uint32_t device_try_init(AVFormatContext *s1,
00551 enum PixelFormat pix_fmt,
00552 int *width,
00553 int *height,
00554 enum CodecID *codec_id)
00555 {
00556 uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
00557
00558 if (desired_format == 0 ||
00559 device_init(s1, width, height, desired_format) < 0) {
00560 int i;
00561
00562 desired_format = 0;
00563 for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00564 if (s1->video_codec_id == CODEC_ID_NONE ||
00565 fmt_conversion_table[i].codec_id == s1->video_codec_id) {
00566 desired_format = fmt_conversion_table[i].v4l2_fmt;
00567 if (device_init(s1, width, height, desired_format) >= 0) {
00568 break;
00569 }
00570 desired_format = 0;
00571 }
00572 }
00573 }
00574 if (desired_format != 0) {
00575 *codec_id = fmt_v4l2codec(desired_format);
00576 assert(*codec_id != CODEC_ID_NONE);
00577 }
00578
00579 return desired_format;
00580 }
00581
00582 static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
00583 {
00584 struct video_data *s = s1->priv_data;
00585 AVStream *st;
00586 int res = 0;
00587 uint32_t desired_format, capabilities;
00588 enum CodecID codec_id;
00589 enum PixelFormat pix_fmt = PIX_FMT_NONE;
00590
00591 st = avformat_new_stream(s1, NULL);
00592 if (!st) {
00593 res = AVERROR(ENOMEM);
00594 goto out;
00595 }
00596 avpriv_set_pts_info(st, 64, 1, 1000000);
00597
00598 if (s->video_size && (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
00599 av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size);
00600 goto out;
00601 }
00602 if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
00603 av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
00604 res = AVERROR(EINVAL);
00605 goto out;
00606 }
00607
00608 capabilities = 0;
00609 s->fd = device_open(s1, &capabilities);
00610 if (s->fd < 0) {
00611 res = AVERROR(EIO);
00612 goto out;
00613 }
00614 av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities);
00615
00616 if (!s->width && !s->height) {
00617 struct v4l2_format fmt;
00618
00619 av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n");
00620 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00621 if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
00622 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno));
00623 res = AVERROR(errno);
00624 goto out;
00625 }
00626 s->width = fmt.fmt.pix.width;
00627 s->height = fmt.fmt.pix.height;
00628 av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height);
00629 }
00630
00631 desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height, &codec_id);
00632 if (desired_format == 0) {
00633 av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
00634 "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
00635 v4l2_close(s->fd);
00636
00637 res = AVERROR(EIO);
00638 goto out;
00639 }
00640 if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
00641 goto out;
00642 s->frame_format = desired_format;
00643
00644 if ((res = v4l2_set_parameters(s1, ap)) < 0)
00645 goto out;
00646
00647 st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
00648 s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
00649 if (capabilities & V4L2_CAP_STREAMING) {
00650 s->io_method = io_mmap;
00651 res = mmap_init(s1);
00652 if (res == 0) {
00653 res = mmap_start(s1);
00654 }
00655 } else {
00656 s->io_method = io_read;
00657 res = read_init(s1);
00658 }
00659 if (res < 0) {
00660 v4l2_close(s->fd);
00661 res = AVERROR(EIO);
00662 goto out;
00663 }
00664 s->top_field_first = first_field(s->fd);
00665
00666 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00667 st->codec->codec_id = codec_id;
00668 st->codec->width = s->width;
00669 st->codec->height = s->height;
00670 st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
00671
00672 out:
00673 return res;
00674 }
00675
00676 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
00677 {
00678 struct video_data *s = s1->priv_data;
00679 int res;
00680
00681 if (s->io_method == io_mmap) {
00682 av_init_packet(pkt);
00683 res = mmap_read_frame(s1, pkt);
00684 } else if (s->io_method == io_read) {
00685 if (av_new_packet(pkt, s->frame_size) < 0)
00686 return AVERROR(EIO);
00687
00688 res = read_frame(s1, pkt);
00689 } else {
00690 return AVERROR(EIO);
00691 }
00692 if (res < 0) {
00693 return res;
00694 }
00695
00696 if (s1->streams[0]->codec->coded_frame) {
00697 s1->streams[0]->codec->coded_frame->interlaced_frame = 1;
00698 s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first;
00699 }
00700
00701 return pkt->size;
00702 }
00703
00704 static int v4l2_read_close(AVFormatContext *s1)
00705 {
00706 struct video_data *s = s1->priv_data;
00707
00708 if (s->io_method == io_mmap) {
00709 mmap_close(s);
00710 }
00711
00712 v4l2_close(s->fd);
00713 return 0;
00714 }
00715
00716 #define OFFSET(x) offsetof(struct video_data, x)
00717 #define DEC AV_OPT_FLAG_DECODING_PARAM
00718
00719 static const AVOption options[] = {
00720 { "standard", "", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
00721 { "channel", "", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
00722 { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00723 { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00724 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00725 { NULL },
00726 };
00727
00728 static const AVClass v4l2_class = {
00729 .class_name = "V4L2 indev",
00730 .item_name = av_default_item_name,
00731 .option = options,
00732 .version = LIBAVUTIL_VERSION_INT,
00733 };
00734
00735 AVInputFormat ff_v4l2_demuxer = {
00736 .name = "video4linux2,v4l2",
00737 .long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
00738 .priv_data_size = sizeof(struct video_data),
00739 .read_header = v4l2_read_header,
00740 .read_packet = v4l2_read_packet,
00741 .read_close = v4l2_read_close,
00742 .flags = AVFMT_NOFILE,
00743 .priv_class = &v4l2_class,
00744 };