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 #define V4L_ALLFORMATS 3
00073 #define V4L_RAWFORMATS 1
00074 #define V4L_COMPFORMATS 2
00075
00076 struct video_data {
00077 AVClass *class;
00078 int fd;
00079 int frame_format;
00080 int width, height;
00081 int frame_size;
00082 int interlaced;
00083 int top_field_first;
00084
00085 int buffers;
00086 void **buf_start;
00087 unsigned int *buf_len;
00088 char *standard;
00089 int channel;
00090 char *video_size;
00092 char *pixel_format;
00093 int list_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)
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
00141 fd = v4l2_open(ctx->filename, flags, 0);
00142 if (fd < 0) {
00143 err = errno;
00144
00145 av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",
00146 ctx->filename, strerror(err));
00147
00148 return AVERROR(err);
00149 }
00150 #if CONFIG_LIBV4L2
00151 fd_libv4l = v4l2_fd_open(fd, 0);
00152 if (fd < 0) {
00153 err = AVERROR(errno);
00154 av_log(ctx, AV_LOG_ERROR, "Cannot open video device with libv4l neither %s : %s\n",
00155 ctx->filename, strerror(errno));
00156 return err;
00157 }
00158 fd = fd_libv4l;
00159 #endif
00160
00161 res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
00162 if (res < 0) {
00163 err = errno;
00164 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
00165 strerror(err));
00166
00167 goto fail;
00168 }
00169
00170 av_log(ctx, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n",
00171 fd, cap.capabilities);
00172
00173 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00174 av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
00175 err = ENODEV;
00176
00177 goto fail;
00178 }
00179
00180 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
00181 av_log(ctx, AV_LOG_ERROR,
00182 "The device does not support the streaming I/O method.\n");
00183 err = ENOSYS;
00184
00185 goto fail;
00186 }
00187
00188 return fd;
00189
00190 fail:
00191 v4l2_close(fd);
00192 return AVERROR(err);
00193 }
00194
00195 static int device_init(AVFormatContext *ctx, int *width, int *height,
00196 uint32_t pix_fmt)
00197 {
00198 struct video_data *s = ctx->priv_data;
00199 int fd = s->fd;
00200 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
00201 struct v4l2_pix_format *pix = &fmt.fmt.pix;
00202
00203 int res;
00204
00205 pix->width = *width;
00206 pix->height = *height;
00207 pix->pixelformat = pix_fmt;
00208 pix->field = V4L2_FIELD_ANY;
00209
00210 res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
00211
00212 if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
00213 av_log(ctx, AV_LOG_INFO,
00214 "The V4L2 driver changed the video from %dx%d to %dx%d\n",
00215 *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
00216 *width = fmt.fmt.pix.width;
00217 *height = fmt.fmt.pix.height;
00218 }
00219
00220 if (pix_fmt != fmt.fmt.pix.pixelformat) {
00221 av_log(ctx, AV_LOG_DEBUG,
00222 "The V4L2 driver changed the pixel format "
00223 "from 0x%08X to 0x%08X\n",
00224 pix_fmt, fmt.fmt.pix.pixelformat);
00225 res = -1;
00226 }
00227
00228 if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
00229 av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver using the interlaced mode");
00230 s->interlaced = 1;
00231 }
00232
00233 return res;
00234 }
00235
00236 static int first_field(int fd)
00237 {
00238 int res;
00239 v4l2_std_id std;
00240
00241 res = v4l2_ioctl(fd, VIDIOC_G_STD, &std);
00242 if (res < 0) {
00243 return 0;
00244 }
00245 if (std & V4L2_STD_NTSC) {
00246 return 0;
00247 }
00248
00249 return 1;
00250 }
00251
00252 static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id)
00253 {
00254 int i;
00255
00256 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00257 if ((codec_id == CODEC_ID_NONE ||
00258 fmt_conversion_table[i].codec_id == codec_id) &&
00259 (pix_fmt == PIX_FMT_NONE ||
00260 fmt_conversion_table[i].ff_fmt == pix_fmt)) {
00261 return fmt_conversion_table[i].v4l2_fmt;
00262 }
00263 }
00264
00265 return 0;
00266 }
00267
00268 static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id)
00269 {
00270 int i;
00271
00272 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00273 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
00274 fmt_conversion_table[i].codec_id == codec_id) {
00275 return fmt_conversion_table[i].ff_fmt;
00276 }
00277 }
00278
00279 return PIX_FMT_NONE;
00280 }
00281
00282 static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt)
00283 {
00284 int i;
00285
00286 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00287 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
00288 return fmt_conversion_table[i].codec_id;
00289 }
00290 }
00291
00292 return CODEC_ID_NONE;
00293 }
00294
00295 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
00296 static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
00297 {
00298 struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
00299
00300 while(!ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
00301 switch (vfse.type) {
00302 case V4L2_FRMSIZE_TYPE_DISCRETE:
00303 av_log(ctx, AV_LOG_INFO, " %ux%u",
00304 vfse.discrete.width, vfse.discrete.height);
00305 break;
00306 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
00307 case V4L2_FRMSIZE_TYPE_STEPWISE:
00308 av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
00309 vfse.stepwise.min_width,
00310 vfse.stepwise.max_width,
00311 vfse.stepwise.step_width,
00312 vfse.stepwise.min_height,
00313 vfse.stepwise.max_height,
00314 vfse.stepwise.step_height);
00315 }
00316 vfse.index++;
00317 }
00318 }
00319 #endif
00320
00321 static void list_formats(AVFormatContext *ctx, int fd, int type)
00322 {
00323 struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
00324
00325 while(!ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
00326 enum CodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
00327 enum PixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
00328
00329 vfd.index++;
00330
00331 if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
00332 type & V4L_RAWFORMATS) {
00333 const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
00334 av_log(ctx, AV_LOG_INFO, "R : %9s : %20s :",
00335 fmt_name ? fmt_name : "Unsupported",
00336 vfd.description);
00337 } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
00338 type & V4L_COMPFORMATS) {
00339 AVCodec *codec = avcodec_find_encoder(codec_id);
00340 av_log(ctx, AV_LOG_INFO, "C : %9s : %20s :",
00341 codec ? codec->name : "Unsupported",
00342 vfd.description);
00343 } else {
00344 continue;
00345 }
00346
00347 #ifdef V4L2_FMT_FLAG_EMULATED
00348 if (vfd.flags & V4L2_FMT_FLAG_EMULATED) {
00349 av_log(ctx, AV_LOG_WARNING, "%s", "Emulated");
00350 continue;
00351 }
00352 #endif
00353 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
00354 list_framesizes(ctx, fd, vfd.pixelformat);
00355 #endif
00356 av_log(ctx, AV_LOG_INFO, "\n");
00357 }
00358 }
00359
00360 static int mmap_init(AVFormatContext *ctx)
00361 {
00362 int i, res;
00363 struct video_data *s = ctx->priv_data;
00364 struct v4l2_requestbuffers req = {
00365 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
00366 .count = desired_video_buffers,
00367 .memory = V4L2_MEMORY_MMAP
00368 };
00369
00370 res = v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req);
00371 if (res < 0) {
00372 if (errno == EINVAL) {
00373 av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n");
00374 } else {
00375 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n");
00376 }
00377 return AVERROR(errno);
00378 }
00379
00380 if (req.count < 2) {
00381 av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
00382 return AVERROR(ENOMEM);
00383 }
00384 s->buffers = req.count;
00385 s->buf_start = av_malloc(sizeof(void *) * s->buffers);
00386 if (s->buf_start == NULL) {
00387 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
00388 return AVERROR(ENOMEM);
00389 }
00390 s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
00391 if (s->buf_len == NULL) {
00392 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
00393 av_free(s->buf_start);
00394 return AVERROR(ENOMEM);
00395 }
00396
00397 for (i = 0; i < req.count; i++) {
00398 struct v4l2_buffer buf = {
00399 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
00400 .index = i,
00401 .memory = V4L2_MEMORY_MMAP
00402 };
00403 res = v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
00404 if (res < 0) {
00405 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
00406 return AVERROR(errno);
00407 }
00408
00409 s->buf_len[i] = buf.length;
00410 if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
00411 av_log(ctx, AV_LOG_ERROR,
00412 "Buffer len [%d] = %d != %d\n",
00413 i, s->buf_len[i], s->frame_size);
00414
00415 return -1;
00416 }
00417 s->buf_start[i] = v4l2_mmap(NULL, buf.length,
00418 PROT_READ | PROT_WRITE, MAP_SHARED,
00419 s->fd, buf.m.offset);
00420
00421 if (s->buf_start[i] == MAP_FAILED) {
00422 av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
00423 return AVERROR(errno);
00424 }
00425 }
00426
00427 return 0;
00428 }
00429
00430 static void mmap_release_buffer(AVPacket *pkt)
00431 {
00432 struct v4l2_buffer buf = { 0 };
00433 int res, fd;
00434 struct buff_data *buf_descriptor = pkt->priv;
00435
00436 if (pkt->data == NULL)
00437 return;
00438
00439 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00440 buf.memory = V4L2_MEMORY_MMAP;
00441 buf.index = buf_descriptor->index;
00442 fd = buf_descriptor->fd;
00443 av_free(buf_descriptor);
00444
00445 res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
00446 if (res < 0)
00447 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
00448 strerror(errno));
00449
00450 pkt->data = NULL;
00451 pkt->size = 0;
00452 }
00453
00454 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
00455 {
00456 struct video_data *s = ctx->priv_data;
00457 struct v4l2_buffer buf = {
00458 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
00459 .memory = V4L2_MEMORY_MMAP
00460 };
00461 struct buff_data *buf_descriptor;
00462 int res;
00463
00464
00465 while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
00466 if (res < 0) {
00467 if (errno == EAGAIN) {
00468 pkt->size = 0;
00469 return AVERROR(EAGAIN);
00470 }
00471 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
00472 strerror(errno));
00473
00474 return AVERROR(errno);
00475 }
00476 assert(buf.index < s->buffers);
00477 if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
00478 av_log(ctx, AV_LOG_ERROR,
00479 "The v4l2 frame is %d bytes, but %d bytes are expected\n",
00480 buf.bytesused, s->frame_size);
00481
00482 return AVERROR_INVALIDDATA;
00483 }
00484
00485
00486 pkt->data= s->buf_start[buf.index];
00487 pkt->size = buf.bytesused;
00488 pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
00489 pkt->destruct = mmap_release_buffer;
00490 buf_descriptor = av_malloc(sizeof(struct buff_data));
00491 if (buf_descriptor == NULL) {
00492
00493
00494
00495 av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
00496 res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
00497
00498 return AVERROR(ENOMEM);
00499 }
00500 buf_descriptor->fd = s->fd;
00501 buf_descriptor->index = buf.index;
00502 pkt->priv = buf_descriptor;
00503
00504 return s->buf_len[buf.index];
00505 }
00506
00507 static int mmap_start(AVFormatContext *ctx)
00508 {
00509 struct video_data *s = ctx->priv_data;
00510 enum v4l2_buf_type type;
00511 int i, res;
00512
00513 for (i = 0; i < s->buffers; i++) {
00514 struct v4l2_buffer buf = {
00515 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
00516 .index = i,
00517 .memory = V4L2_MEMORY_MMAP
00518 };
00519
00520 res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
00521 if (res < 0) {
00522 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
00523 strerror(errno));
00524
00525 return AVERROR(errno);
00526 }
00527 }
00528
00529 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00530 res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
00531 if (res < 0) {
00532 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
00533 strerror(errno));
00534
00535 return AVERROR(errno);
00536 }
00537
00538 return 0;
00539 }
00540
00541 static void mmap_close(struct video_data *s)
00542 {
00543 enum v4l2_buf_type type;
00544 int i;
00545
00546 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00547
00548
00549
00550 v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
00551 for (i = 0; i < s->buffers; i++) {
00552 v4l2_munmap(s->buf_start[i], s->buf_len[i]);
00553 }
00554 av_free(s->buf_start);
00555 av_free(s->buf_len);
00556 }
00557
00558 static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
00559 {
00560 struct video_data *s = s1->priv_data;
00561 struct v4l2_input input = { 0 };
00562 struct v4l2_standard standard = { 0 };
00563 struct v4l2_streamparm streamparm = { 0 };
00564 struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;
00565 AVRational framerate_q = { 0 };
00566 int i, ret;
00567
00568 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00569
00570 if (s->framerate &&
00571 (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
00572 av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
00573 s->framerate);
00574 return ret;
00575 }
00576
00577
00578 input.index = s->channel;
00579 if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
00580 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");
00581 return AVERROR(EIO);
00582 }
00583
00584 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",
00585 s->channel, input.name);
00586 if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
00587 av_log(s1, AV_LOG_ERROR,
00588 "The V4L2 driver ioctl set input(%d) failed\n",
00589 s->channel);
00590 return AVERROR(EIO);
00591 }
00592
00593 if (s->standard) {
00594 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",
00595 s->standard);
00596
00597 for(i=0;;i++) {
00598 standard.index = i;
00599 ret = v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard);
00600 if (ret < 0 || !av_strcasecmp(standard.name, s->standard))
00601 break;
00602 }
00603 if (ret < 0) {
00604 av_log(s1, AV_LOG_ERROR, "Unknown standard '%s'\n", s->standard);
00605 return ret;
00606 }
00607
00608 av_log(s1, AV_LOG_DEBUG,
00609 "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
00610 s->standard, (uint64_t)standard.id);
00611 if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
00612 av_log(s1, AV_LOG_ERROR,
00613 "The V4L2 driver ioctl set standard(%s) failed\n",
00614 s->standard);
00615 return AVERROR(EIO);
00616 }
00617 }
00618
00619 if (framerate_q.num && framerate_q.den) {
00620 av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
00621 framerate_q.den, framerate_q.num);
00622 tpf->numerator = framerate_q.den;
00623 tpf->denominator = framerate_q.num;
00624
00625 if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
00626 av_log(s1, AV_LOG_ERROR,
00627 "ioctl set time per frame(%d/%d) failed\n",
00628 framerate_q.den, framerate_q.num);
00629 return AVERROR(EIO);
00630 }
00631
00632 if (framerate_q.num != tpf->denominator ||
00633 framerate_q.den != tpf->numerator) {
00634 av_log(s1, AV_LOG_INFO,
00635 "The driver changed the time per frame from "
00636 "%d/%d to %d/%d\n",
00637 framerate_q.den, framerate_q.num,
00638 tpf->numerator, tpf->denominator);
00639 }
00640 } else {
00641 if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
00642 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",
00643 strerror(errno));
00644 return AVERROR(errno);
00645 }
00646 }
00647 s1->streams[0]->codec->time_base.den = tpf->denominator;
00648 s1->streams[0]->codec->time_base.num = tpf->numerator;
00649
00650 return 0;
00651 }
00652
00653 static uint32_t device_try_init(AVFormatContext *s1,
00654 enum PixelFormat pix_fmt,
00655 int *width,
00656 int *height,
00657 enum CodecID *codec_id)
00658 {
00659 uint32_t desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
00660
00661 if (desired_format == 0 ||
00662 device_init(s1, width, height, desired_format) < 0) {
00663 int i;
00664
00665 desired_format = 0;
00666 for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
00667 if (s1->video_codec_id == CODEC_ID_NONE ||
00668 fmt_conversion_table[i].codec_id == s1->video_codec_id) {
00669 desired_format = fmt_conversion_table[i].v4l2_fmt;
00670 if (device_init(s1, width, height, desired_format) >= 0) {
00671 break;
00672 }
00673 desired_format = 0;
00674 }
00675 }
00676 }
00677
00678 if (desired_format != 0) {
00679 *codec_id = fmt_v4l2codec(desired_format);
00680 assert(*codec_id != CODEC_ID_NONE);
00681 }
00682
00683 return desired_format;
00684 }
00685
00686 static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap)
00687 {
00688 struct video_data *s = s1->priv_data;
00689 AVStream *st;
00690 int res = 0;
00691 uint32_t desired_format;
00692 enum CodecID codec_id;
00693 enum PixelFormat pix_fmt = PIX_FMT_NONE;
00694
00695 st = avformat_new_stream(s1, NULL);
00696 if (!st) {
00697 res = AVERROR(ENOMEM);
00698 goto out;
00699 }
00700
00701 s->fd = device_open(s1);
00702 if (s->fd < 0) {
00703 res = s->fd;
00704 goto out;
00705 }
00706
00707 if (s->list_format) {
00708 list_formats(s1, s->fd, s->list_format);
00709 res = AVERROR_EXIT;
00710 goto out;
00711 }
00712
00713 avpriv_set_pts_info(st, 64, 1, 1000000);
00714
00715 if (s->video_size &&
00716 (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
00717 av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
00718 s->video_size);
00719 goto out;
00720 }
00721
00722 if (s->pixel_format) {
00723 AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
00724
00725 if (codec)
00726 s1->video_codec_id = codec->id;
00727
00728 pix_fmt = av_get_pix_fmt(s->pixel_format);
00729
00730 if (pix_fmt == PIX_FMT_NONE && !codec) {
00731 av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
00732 s->pixel_format);
00733
00734 res = AVERROR(EINVAL);
00735 goto out;
00736 }
00737 }
00738
00739 if (!s->width && !s->height) {
00740 struct v4l2_format fmt;
00741
00742 av_log(s1, AV_LOG_VERBOSE,
00743 "Querying the device for the current frame size\n");
00744 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00745 if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
00746 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
00747 strerror(errno));
00748 res = AVERROR(errno);
00749 goto out;
00750 }
00751
00752 s->width = fmt.fmt.pix.width;
00753 s->height = fmt.fmt.pix.height;
00754 av_log(s1, AV_LOG_VERBOSE,
00755 "Setting frame size to %dx%d\n", s->width, s->height);
00756 }
00757
00758 desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
00759 &codec_id);
00760 if (desired_format == 0) {
00761 av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
00762 "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
00763 v4l2_close(s->fd);
00764
00765 res = AVERROR(EIO);
00766 goto out;
00767 }
00768 if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
00769 goto out;
00770
00771 s->frame_format = desired_format;
00772
00773 if ((res = v4l2_set_parameters(s1, ap)) < 0)
00774 goto out;
00775
00776 st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
00777 s->frame_size =
00778 avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
00779
00780 if ((res = mmap_init(s1)) ||
00781 (res = mmap_start(s1)) < 0) {
00782 v4l2_close(s->fd);
00783 goto out;
00784 }
00785
00786 s->top_field_first = first_field(s->fd);
00787
00788 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00789 st->codec->codec_id = codec_id;
00790 if (codec_id == CODEC_ID_RAWVIDEO)
00791 st->codec->codec_tag =
00792 avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
00793 st->codec->width = s->width;
00794 st->codec->height = s->height;
00795 st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
00796
00797 out:
00798 return res;
00799 }
00800
00801 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
00802 {
00803 struct video_data *s = s1->priv_data;
00804 AVFrame *frame = s1->streams[0]->codec->coded_frame;
00805 int res;
00806
00807 av_init_packet(pkt);
00808 if ((res = mmap_read_frame(s1, pkt)) < 0) {
00809 return res;
00810 }
00811
00812 if (frame && s->interlaced) {
00813 frame->interlaced_frame = 1;
00814 frame->top_field_first = s->top_field_first;
00815 }
00816
00817 return pkt->size;
00818 }
00819
00820 static int v4l2_read_close(AVFormatContext *s1)
00821 {
00822 struct video_data *s = s1->priv_data;
00823
00824 mmap_close(s);
00825
00826 v4l2_close(s->fd);
00827 return 0;
00828 }
00829
00830 #define OFFSET(x) offsetof(struct video_data, x)
00831 #define DEC AV_OPT_FLAG_DECODING_PARAM
00832
00833 static const AVOption options[] = {
00834 { "standard", "TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC },
00835 { "channel", "TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC },
00836 { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00837 { "pixel_format", "Preferred pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00838 { "input_format", "Preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00839 { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00840 { "list_formats", "List available formats and exit", OFFSET(list_format), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, DEC, "list_formats" },
00841 { "all", "Show all available formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_ALLFORMATS }, 0, INT_MAX, DEC, "list_formats" },
00842 { "raw", "Show only non-compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_RAWFORMATS }, 0, INT_MAX, DEC, "list_formats" },
00843 { "compressed", "Show only compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.dbl = V4L_COMPFORMATS }, 0, INT_MAX, DEC, "list_formats" },
00844 { NULL },
00845 };
00846
00847 static const AVClass v4l2_class = {
00848 .class_name = "V4L2 indev",
00849 .item_name = av_default_item_name,
00850 .option = options,
00851 .version = LIBAVUTIL_VERSION_INT,
00852 };
00853
00854 AVInputFormat ff_v4l2_demuxer = {
00855 .name = "video4linux2,v4l2",
00856 .long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
00857 .priv_data_size = sizeof(struct video_data),
00858 .read_header = v4l2_read_header,
00859 .read_packet = v4l2_read_packet,
00860 .read_close = v4l2_read_close,
00861 .flags = AVFMT_NOFILE,
00862 .priv_class = &v4l2_class,
00863 };