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