annotate ffmpeg/libavdevice/v4l2.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2000,2001 Fabrice Bellard
yading@10 3 * Copyright (c) 2006 Luca Abeni
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * Video4Linux2 grab interface
yading@10 25 *
yading@10 26 * Part of this file is based on the V4L2 video capture example
yading@10 27 * (http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html)
yading@10 28 *
yading@10 29 * Thanks to Michael Niedermayer for providing the mapping between
yading@10 30 * V4L2_PIX_FMT_* and AV_PIX_FMT_*
yading@10 31 */
yading@10 32
yading@10 33 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
yading@10 34 #include "config.h"
yading@10 35 #include "libavformat/internal.h"
yading@10 36 #include <unistd.h>
yading@10 37 #include <fcntl.h>
yading@10 38 #include <sys/ioctl.h>
yading@10 39 #include <sys/mman.h>
yading@10 40 #include <sys/time.h>
yading@10 41 #if HAVE_SYS_VIDEOIO_H
yading@10 42 #include <sys/videoio.h>
yading@10 43 #else
yading@10 44 #if HAVE_ASM_TYPES_H
yading@10 45 #include <asm/types.h>
yading@10 46 #endif
yading@10 47 #include <linux/videodev2.h>
yading@10 48 #endif
yading@10 49 #include "libavutil/atomic.h"
yading@10 50 #include "libavutil/avassert.h"
yading@10 51 #include "libavutil/imgutils.h"
yading@10 52 #include "libavutil/log.h"
yading@10 53 #include "libavutil/opt.h"
yading@10 54 #include "avdevice.h"
yading@10 55 #include "timefilter.h"
yading@10 56 #include "libavutil/parseutils.h"
yading@10 57 #include "libavutil/pixdesc.h"
yading@10 58 #include "libavutil/time.h"
yading@10 59 #include "libavutil/avstring.h"
yading@10 60
yading@10 61 #if CONFIG_LIBV4L2
yading@10 62 #include <libv4l2.h>
yading@10 63 #else
yading@10 64 #define v4l2_open open
yading@10 65 #define v4l2_close close
yading@10 66 #define v4l2_dup dup
yading@10 67 #define v4l2_ioctl ioctl
yading@10 68 #define v4l2_read read
yading@10 69 #define v4l2_mmap mmap
yading@10 70 #define v4l2_munmap munmap
yading@10 71 #endif
yading@10 72
yading@10 73 static const int desired_video_buffers = 256;
yading@10 74
yading@10 75 #define V4L_ALLFORMATS 3
yading@10 76 #define V4L_RAWFORMATS 1
yading@10 77 #define V4L_COMPFORMATS 2
yading@10 78
yading@10 79 /**
yading@10 80 * Return timestamps to the user exactly as returned by the kernel
yading@10 81 */
yading@10 82 #define V4L_TS_DEFAULT 0
yading@10 83 /**
yading@10 84 * Autodetect the kind of timestamps returned by the kernel and convert to
yading@10 85 * absolute (wall clock) timestamps.
yading@10 86 */
yading@10 87 #define V4L_TS_ABS 1
yading@10 88 /**
yading@10 89 * Assume kernel timestamps are from the monotonic clock and convert to
yading@10 90 * absolute timestamps.
yading@10 91 */
yading@10 92 #define V4L_TS_MONO2ABS 2
yading@10 93
yading@10 94 /**
yading@10 95 * Once the kind of timestamps returned by the kernel have been detected,
yading@10 96 * the value of the timefilter (NULL or not) determines whether a conversion
yading@10 97 * takes place.
yading@10 98 */
yading@10 99 #define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
yading@10 100
yading@10 101 struct video_data {
yading@10 102 AVClass *class;
yading@10 103 int fd;
yading@10 104 int frame_format; /* V4L2_PIX_FMT_* */
yading@10 105 int width, height;
yading@10 106 int frame_size;
yading@10 107 int interlaced;
yading@10 108 int top_field_first;
yading@10 109 int ts_mode;
yading@10 110 TimeFilter *timefilter;
yading@10 111 int64_t last_time_m;
yading@10 112
yading@10 113 int buffers;
yading@10 114 volatile int buffers_queued;
yading@10 115 void **buf_start;
yading@10 116 unsigned int *buf_len;
yading@10 117 char *standard;
yading@10 118 v4l2_std_id std_id;
yading@10 119 int channel;
yading@10 120 char *pixel_format; /**< Set by a private option. */
yading@10 121 int list_format; /**< Set by a private option. */
yading@10 122 int list_standard; /**< Set by a private option. */
yading@10 123 char *framerate; /**< Set by a private option. */
yading@10 124 };
yading@10 125
yading@10 126 struct buff_data {
yading@10 127 struct video_data *s;
yading@10 128 int index;
yading@10 129 };
yading@10 130
yading@10 131 struct fmt_map {
yading@10 132 enum AVPixelFormat ff_fmt;
yading@10 133 enum AVCodecID codec_id;
yading@10 134 uint32_t v4l2_fmt;
yading@10 135 };
yading@10 136
yading@10 137 static struct fmt_map fmt_conversion_table[] = {
yading@10 138 //ff_fmt codec_id v4l2_fmt
yading@10 139 { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420 },
yading@10 140 { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420 },
yading@10 141 { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
yading@10 142 { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV },
yading@10 143 { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY },
yading@10 144 { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
yading@10 145 { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410 },
yading@10 146 { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU410 },
yading@10 147 { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555 },
yading@10 148 { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X },
yading@10 149 { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565 },
yading@10 150 { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X },
yading@10 151 { AV_PIX_FMT_BGR24, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24 },
yading@10 152 { AV_PIX_FMT_RGB24, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24 },
yading@10 153 { AV_PIX_FMT_BGR0, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32 },
yading@10 154 { AV_PIX_FMT_0RGB, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB32 },
yading@10 155 { AV_PIX_FMT_GRAY8, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_GREY },
yading@10 156 #ifdef V4L2_PIX_FMT_Y16
yading@10 157 { AV_PIX_FMT_GRAY16LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_Y16 },
yading@10 158 #endif
yading@10 159 { AV_PIX_FMT_NV12, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_NV12 },
yading@10 160 { AV_PIX_FMT_NONE, AV_CODEC_ID_MJPEG, V4L2_PIX_FMT_MJPEG },
yading@10 161 { AV_PIX_FMT_NONE, AV_CODEC_ID_MJPEG, V4L2_PIX_FMT_JPEG },
yading@10 162 #ifdef V4L2_PIX_FMT_H264
yading@10 163 { AV_PIX_FMT_NONE, AV_CODEC_ID_H264, V4L2_PIX_FMT_H264 },
yading@10 164 #endif
yading@10 165 #ifdef V4L2_PIX_FMT_CPIA1
yading@10 166 { AV_PIX_FMT_NONE, AV_CODEC_ID_CPIA, V4L2_PIX_FMT_CPIA1 },
yading@10 167 #endif
yading@10 168 };
yading@10 169
yading@10 170 static int device_open(AVFormatContext *ctx)
yading@10 171 {
yading@10 172 struct v4l2_capability cap;
yading@10 173 int fd;
yading@10 174 int ret;
yading@10 175 int flags = O_RDWR;
yading@10 176
yading@10 177 if (ctx->flags & AVFMT_FLAG_NONBLOCK) {
yading@10 178 flags |= O_NONBLOCK;
yading@10 179 }
yading@10 180
yading@10 181 fd = v4l2_open(ctx->filename, flags, 0);
yading@10 182 if (fd < 0) {
yading@10 183 ret = AVERROR(errno);
yading@10 184 av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s: %s\n",
yading@10 185 ctx->filename, av_err2str(ret));
yading@10 186 return ret;
yading@10 187 }
yading@10 188
yading@10 189 if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
yading@10 190 ret = AVERROR(errno);
yading@10 191 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
yading@10 192 av_err2str(ret));
yading@10 193 goto fail;
yading@10 194 }
yading@10 195
yading@10 196 av_log(ctx, AV_LOG_VERBOSE, "fd:%d capabilities:%x\n",
yading@10 197 fd, cap.capabilities);
yading@10 198
yading@10 199 if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
yading@10 200 av_log(ctx, AV_LOG_ERROR, "Not a video capture device.\n");
yading@10 201 ret = AVERROR(ENODEV);
yading@10 202 goto fail;
yading@10 203 }
yading@10 204
yading@10 205 if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
yading@10 206 av_log(ctx, AV_LOG_ERROR,
yading@10 207 "The device does not support the streaming I/O method.\n");
yading@10 208 ret = AVERROR(ENOSYS);
yading@10 209 goto fail;
yading@10 210 }
yading@10 211
yading@10 212 return fd;
yading@10 213
yading@10 214 fail:
yading@10 215 v4l2_close(fd);
yading@10 216 return ret;
yading@10 217 }
yading@10 218
yading@10 219 static int device_init(AVFormatContext *ctx, int *width, int *height,
yading@10 220 uint32_t pix_fmt)
yading@10 221 {
yading@10 222 struct video_data *s = ctx->priv_data;
yading@10 223 int fd = s->fd;
yading@10 224 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
yading@10 225 struct v4l2_pix_format *pix = &fmt.fmt.pix;
yading@10 226
yading@10 227 int res = 0;
yading@10 228
yading@10 229 pix->width = *width;
yading@10 230 pix->height = *height;
yading@10 231 pix->pixelformat = pix_fmt;
yading@10 232 pix->field = V4L2_FIELD_ANY;
yading@10 233
yading@10 234 if (v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt) < 0)
yading@10 235 res = AVERROR(errno);
yading@10 236
yading@10 237 if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
yading@10 238 av_log(ctx, AV_LOG_INFO,
yading@10 239 "The V4L2 driver changed the video from %dx%d to %dx%d\n",
yading@10 240 *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height);
yading@10 241 *width = fmt.fmt.pix.width;
yading@10 242 *height = fmt.fmt.pix.height;
yading@10 243 }
yading@10 244
yading@10 245 if (pix_fmt != fmt.fmt.pix.pixelformat) {
yading@10 246 av_log(ctx, AV_LOG_DEBUG,
yading@10 247 "The V4L2 driver changed the pixel format "
yading@10 248 "from 0x%08X to 0x%08X\n",
yading@10 249 pix_fmt, fmt.fmt.pix.pixelformat);
yading@10 250 res = AVERROR(EINVAL);
yading@10 251 }
yading@10 252
yading@10 253 if (fmt.fmt.pix.field == V4L2_FIELD_INTERLACED) {
yading@10 254 av_log(ctx, AV_LOG_DEBUG,
yading@10 255 "The V4L2 driver is using the interlaced mode\n");
yading@10 256 s->interlaced = 1;
yading@10 257 }
yading@10 258
yading@10 259 return res;
yading@10 260 }
yading@10 261
yading@10 262 static int first_field(int fd)
yading@10 263 {
yading@10 264 int res;
yading@10 265 v4l2_std_id std;
yading@10 266
yading@10 267 res = v4l2_ioctl(fd, VIDIOC_G_STD, &std);
yading@10 268 if (res < 0) {
yading@10 269 return 0;
yading@10 270 }
yading@10 271 if (std & V4L2_STD_NTSC) {
yading@10 272 return 0;
yading@10 273 }
yading@10 274
yading@10 275 return 1;
yading@10 276 }
yading@10 277
yading@10 278 static uint32_t fmt_ff2v4l(enum AVPixelFormat pix_fmt, enum AVCodecID codec_id)
yading@10 279 {
yading@10 280 int i;
yading@10 281
yading@10 282 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
yading@10 283 if ((codec_id == AV_CODEC_ID_NONE ||
yading@10 284 fmt_conversion_table[i].codec_id == codec_id) &&
yading@10 285 (pix_fmt == AV_PIX_FMT_NONE ||
yading@10 286 fmt_conversion_table[i].ff_fmt == pix_fmt)) {
yading@10 287 return fmt_conversion_table[i].v4l2_fmt;
yading@10 288 }
yading@10 289 }
yading@10 290
yading@10 291 return 0;
yading@10 292 }
yading@10 293
yading@10 294 static enum AVPixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum AVCodecID codec_id)
yading@10 295 {
yading@10 296 int i;
yading@10 297
yading@10 298 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
yading@10 299 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt &&
yading@10 300 fmt_conversion_table[i].codec_id == codec_id) {
yading@10 301 return fmt_conversion_table[i].ff_fmt;
yading@10 302 }
yading@10 303 }
yading@10 304
yading@10 305 return AV_PIX_FMT_NONE;
yading@10 306 }
yading@10 307
yading@10 308 static enum AVCodecID fmt_v4l2codec(uint32_t v4l2_fmt)
yading@10 309 {
yading@10 310 int i;
yading@10 311
yading@10 312 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
yading@10 313 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) {
yading@10 314 return fmt_conversion_table[i].codec_id;
yading@10 315 }
yading@10 316 }
yading@10 317
yading@10 318 return AV_CODEC_ID_NONE;
yading@10 319 }
yading@10 320
yading@10 321 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
yading@10 322 static void list_framesizes(AVFormatContext *ctx, int fd, uint32_t pixelformat)
yading@10 323 {
yading@10 324 struct v4l2_frmsizeenum vfse = { .pixel_format = pixelformat };
yading@10 325
yading@10 326 while(!v4l2_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &vfse)) {
yading@10 327 switch (vfse.type) {
yading@10 328 case V4L2_FRMSIZE_TYPE_DISCRETE:
yading@10 329 av_log(ctx, AV_LOG_INFO, " %ux%u",
yading@10 330 vfse.discrete.width, vfse.discrete.height);
yading@10 331 break;
yading@10 332 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
yading@10 333 case V4L2_FRMSIZE_TYPE_STEPWISE:
yading@10 334 av_log(ctx, AV_LOG_INFO, " {%u-%u, %u}x{%u-%u, %u}",
yading@10 335 vfse.stepwise.min_width,
yading@10 336 vfse.stepwise.max_width,
yading@10 337 vfse.stepwise.step_width,
yading@10 338 vfse.stepwise.min_height,
yading@10 339 vfse.stepwise.max_height,
yading@10 340 vfse.stepwise.step_height);
yading@10 341 }
yading@10 342 vfse.index++;
yading@10 343 }
yading@10 344 }
yading@10 345 #endif
yading@10 346
yading@10 347 static void list_formats(AVFormatContext *ctx, int fd, int type)
yading@10 348 {
yading@10 349 struct v4l2_fmtdesc vfd = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
yading@10 350
yading@10 351 while(!v4l2_ioctl(fd, VIDIOC_ENUM_FMT, &vfd)) {
yading@10 352 enum AVCodecID codec_id = fmt_v4l2codec(vfd.pixelformat);
yading@10 353 enum AVPixelFormat pix_fmt = fmt_v4l2ff(vfd.pixelformat, codec_id);
yading@10 354
yading@10 355 vfd.index++;
yading@10 356
yading@10 357 if (!(vfd.flags & V4L2_FMT_FLAG_COMPRESSED) &&
yading@10 358 type & V4L_RAWFORMATS) {
yading@10 359 const char *fmt_name = av_get_pix_fmt_name(pix_fmt);
yading@10 360 av_log(ctx, AV_LOG_INFO, "Raw : %9s : %20s :",
yading@10 361 fmt_name ? fmt_name : "Unsupported",
yading@10 362 vfd.description);
yading@10 363 } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED &&
yading@10 364 type & V4L_COMPFORMATS) {
yading@10 365 AVCodec *codec = avcodec_find_decoder(codec_id);
yading@10 366 av_log(ctx, AV_LOG_INFO, "Compressed: %9s : %20s :",
yading@10 367 codec ? codec->name : "Unsupported",
yading@10 368 vfd.description);
yading@10 369 } else {
yading@10 370 continue;
yading@10 371 }
yading@10 372
yading@10 373 #ifdef V4L2_FMT_FLAG_EMULATED
yading@10 374 if (vfd.flags & V4L2_FMT_FLAG_EMULATED)
yading@10 375 av_log(ctx, AV_LOG_INFO, " Emulated :");
yading@10 376 #endif
yading@10 377 #if HAVE_STRUCT_V4L2_FRMIVALENUM_DISCRETE
yading@10 378 list_framesizes(ctx, fd, vfd.pixelformat);
yading@10 379 #endif
yading@10 380 av_log(ctx, AV_LOG_INFO, "\n");
yading@10 381 }
yading@10 382 }
yading@10 383
yading@10 384 static void list_standards(AVFormatContext *ctx)
yading@10 385 {
yading@10 386 int ret;
yading@10 387 struct video_data *s = ctx->priv_data;
yading@10 388 struct v4l2_standard standard;
yading@10 389
yading@10 390 if (s->std_id == 0)
yading@10 391 return;
yading@10 392
yading@10 393 for (standard.index = 0; ; standard.index++) {
yading@10 394 if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
yading@10 395 ret = AVERROR(errno);
yading@10 396 if (ret == AVERROR(EINVAL)) {
yading@10 397 break;
yading@10 398 } else {
yading@10 399 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
yading@10 400 return;
yading@10 401 }
yading@10 402 }
yading@10 403 av_log(ctx, AV_LOG_INFO, "%2d, %16llx, %s\n",
yading@10 404 standard.index, standard.id, standard.name);
yading@10 405 }
yading@10 406 }
yading@10 407
yading@10 408 static int mmap_init(AVFormatContext *ctx)
yading@10 409 {
yading@10 410 int i, res;
yading@10 411 struct video_data *s = ctx->priv_data;
yading@10 412 struct v4l2_requestbuffers req = {
yading@10 413 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
yading@10 414 .count = desired_video_buffers,
yading@10 415 .memory = V4L2_MEMORY_MMAP
yading@10 416 };
yading@10 417
yading@10 418 if (v4l2_ioctl(s->fd, VIDIOC_REQBUFS, &req) < 0) {
yading@10 419 res = AVERROR(errno);
yading@10 420 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS): %s\n", av_err2str(res));
yading@10 421 return res;
yading@10 422 }
yading@10 423
yading@10 424 if (req.count < 2) {
yading@10 425 av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
yading@10 426 return AVERROR(ENOMEM);
yading@10 427 }
yading@10 428 s->buffers = req.count;
yading@10 429 s->buf_start = av_malloc(sizeof(void *) * s->buffers);
yading@10 430 if (s->buf_start == NULL) {
yading@10 431 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
yading@10 432 return AVERROR(ENOMEM);
yading@10 433 }
yading@10 434 s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
yading@10 435 if (s->buf_len == NULL) {
yading@10 436 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
yading@10 437 av_free(s->buf_start);
yading@10 438 return AVERROR(ENOMEM);
yading@10 439 }
yading@10 440
yading@10 441 for (i = 0; i < req.count; i++) {
yading@10 442 struct v4l2_buffer buf = {
yading@10 443 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
yading@10 444 .index = i,
yading@10 445 .memory = V4L2_MEMORY_MMAP
yading@10 446 };
yading@10 447 if (v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf) < 0) {
yading@10 448 res = AVERROR(errno);
yading@10 449 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF): %s\n", av_err2str(res));
yading@10 450 return res;
yading@10 451 }
yading@10 452
yading@10 453 s->buf_len[i] = buf.length;
yading@10 454 if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) {
yading@10 455 av_log(ctx, AV_LOG_ERROR,
yading@10 456 "buf_len[%d] = %d < expected frame size %d\n",
yading@10 457 i, s->buf_len[i], s->frame_size);
yading@10 458 return AVERROR(ENOMEM);
yading@10 459 }
yading@10 460 s->buf_start[i] = v4l2_mmap(NULL, buf.length,
yading@10 461 PROT_READ | PROT_WRITE, MAP_SHARED,
yading@10 462 s->fd, buf.m.offset);
yading@10 463
yading@10 464 if (s->buf_start[i] == MAP_FAILED) {
yading@10 465 res = AVERROR(errno);
yading@10 466 av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", av_err2str(res));
yading@10 467 return res;
yading@10 468 }
yading@10 469 }
yading@10 470
yading@10 471 return 0;
yading@10 472 }
yading@10 473
yading@10 474 #if FF_API_DESTRUCT_PACKET
yading@10 475 static void dummy_release_buffer(AVPacket *pkt)
yading@10 476 {
yading@10 477 av_assert0(0);
yading@10 478 }
yading@10 479 #endif
yading@10 480
yading@10 481 static void mmap_release_buffer(void *opaque, uint8_t *data)
yading@10 482 {
yading@10 483 struct v4l2_buffer buf = { 0 };
yading@10 484 int res;
yading@10 485 struct buff_data *buf_descriptor = opaque;
yading@10 486 struct video_data *s = buf_descriptor->s;
yading@10 487
yading@10 488 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
yading@10 489 buf.memory = V4L2_MEMORY_MMAP;
yading@10 490 buf.index = buf_descriptor->index;
yading@10 491 av_free(buf_descriptor);
yading@10 492
yading@10 493 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
yading@10 494 res = AVERROR(errno);
yading@10 495 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
yading@10 496 av_err2str(res));
yading@10 497 }
yading@10 498
yading@10 499 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
yading@10 500 }
yading@10 501
yading@10 502 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
yading@10 503 static int64_t av_gettime_monotonic(void)
yading@10 504 {
yading@10 505 struct timespec tv;
yading@10 506
yading@10 507 clock_gettime(CLOCK_MONOTONIC, &tv);
yading@10 508 return (int64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
yading@10 509 }
yading@10 510 #endif
yading@10 511
yading@10 512 static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts)
yading@10 513 {
yading@10 514 struct video_data *s = ctx->priv_data;
yading@10 515 int64_t now;
yading@10 516
yading@10 517 now = av_gettime();
yading@10 518 if (s->ts_mode == V4L_TS_ABS &&
yading@10 519 ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE) {
yading@10 520 av_log(ctx, AV_LOG_INFO, "Detected absolute timestamps\n");
yading@10 521 s->ts_mode = V4L_TS_CONVERT_READY;
yading@10 522 return 0;
yading@10 523 }
yading@10 524 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
yading@10 525 now = av_gettime_monotonic();
yading@10 526 if (s->ts_mode == V4L_TS_MONO2ABS ||
yading@10 527 (ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE)) {
yading@10 528 AVRational tb = {AV_TIME_BASE, 1};
yading@10 529 int64_t period = av_rescale_q(1, tb, ctx->streams[0]->avg_frame_rate);
yading@10 530 av_log(ctx, AV_LOG_INFO, "Detected monotonic timestamps, converting\n");
yading@10 531 /* microseconds instead of seconds, MHz instead of Hz */
yading@10 532 s->timefilter = ff_timefilter_new(1, period, 1.0E-6);
yading@10 533 s->ts_mode = V4L_TS_CONVERT_READY;
yading@10 534 return 0;
yading@10 535 }
yading@10 536 #endif
yading@10 537 av_log(ctx, AV_LOG_ERROR, "Unknown timestamps\n");
yading@10 538 return AVERROR(EIO);
yading@10 539 }
yading@10 540
yading@10 541 static int convert_timestamp(AVFormatContext *ctx, int64_t *ts)
yading@10 542 {
yading@10 543 struct video_data *s = ctx->priv_data;
yading@10 544
yading@10 545 if (s->ts_mode) {
yading@10 546 int r = init_convert_timestamp(ctx, *ts);
yading@10 547 if (r < 0)
yading@10 548 return r;
yading@10 549 }
yading@10 550 #if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
yading@10 551 if (s->timefilter) {
yading@10 552 int64_t nowa = av_gettime();
yading@10 553 int64_t nowm = av_gettime_monotonic();
yading@10 554 ff_timefilter_update(s->timefilter, nowa, nowm - s->last_time_m);
yading@10 555 s->last_time_m = nowm;
yading@10 556 *ts = ff_timefilter_eval(s->timefilter, *ts - nowm);
yading@10 557 }
yading@10 558 #endif
yading@10 559 return 0;
yading@10 560 }
yading@10 561
yading@10 562 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
yading@10 563 {
yading@10 564 struct video_data *s = ctx->priv_data;
yading@10 565 struct v4l2_buffer buf = {
yading@10 566 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
yading@10 567 .memory = V4L2_MEMORY_MMAP
yading@10 568 };
yading@10 569 int res;
yading@10 570
yading@10 571 /* FIXME: Some special treatment might be needed in case of loss of signal... */
yading@10 572 while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
yading@10 573 if (res < 0) {
yading@10 574 if (errno == EAGAIN) {
yading@10 575 pkt->size = 0;
yading@10 576 return AVERROR(EAGAIN);
yading@10 577 }
yading@10 578 res = AVERROR(errno);
yading@10 579 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", av_err2str(res));
yading@10 580 return res;
yading@10 581 }
yading@10 582
yading@10 583 if (buf.index >= s->buffers) {
yading@10 584 av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
yading@10 585 return AVERROR(EINVAL);
yading@10 586 }
yading@10 587 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);
yading@10 588 // always keep at least one buffer queued
yading@10 589 av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);
yading@10 590
yading@10 591 /* CPIA is a compressed format and we don't know the exact number of bytes
yading@10 592 * used by a frame, so set it here as the driver announces it.
yading@10 593 */
yading@10 594 if (ctx->video_codec_id == AV_CODEC_ID_CPIA)
yading@10 595 s->frame_size = buf.bytesused;
yading@10 596
yading@10 597 if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
yading@10 598 av_log(ctx, AV_LOG_ERROR,
yading@10 599 "The v4l2 frame is %d bytes, but %d bytes are expected\n",
yading@10 600 buf.bytesused, s->frame_size);
yading@10 601 return AVERROR_INVALIDDATA;
yading@10 602 }
yading@10 603
yading@10 604 /* Image is at s->buff_start[buf.index] */
yading@10 605 if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
yading@10 606 /* when we start getting low on queued buffers, fallback to copying data */
yading@10 607 res = av_new_packet(pkt, buf.bytesused);
yading@10 608 if (res < 0) {
yading@10 609 av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
yading@10 610 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
yading@10 611 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
yading@10 612 return res;
yading@10 613 }
yading@10 614 memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
yading@10 615
yading@10 616 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
yading@10 617 res = AVERROR(errno);
yading@10 618 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
yading@10 619 av_free_packet(pkt);
yading@10 620 return res;
yading@10 621 }
yading@10 622 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
yading@10 623 } else {
yading@10 624 struct buff_data *buf_descriptor;
yading@10 625
yading@10 626 pkt->data = s->buf_start[buf.index];
yading@10 627 pkt->size = buf.bytesused;
yading@10 628 #if FF_API_DESTRUCT_PACKET
yading@10 629 pkt->destruct = dummy_release_buffer;
yading@10 630 #endif
yading@10 631
yading@10 632 buf_descriptor = av_malloc(sizeof(struct buff_data));
yading@10 633 if (buf_descriptor == NULL) {
yading@10 634 /* Something went wrong... Since av_malloc() failed, we cannot even
yading@10 635 * allocate a buffer for memcpying into it
yading@10 636 */
yading@10 637 av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
yading@10 638 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
yading@10 639 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
yading@10 640
yading@10 641 return AVERROR(ENOMEM);
yading@10 642 }
yading@10 643 buf_descriptor->index = buf.index;
yading@10 644 buf_descriptor->s = s;
yading@10 645
yading@10 646 pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
yading@10 647 buf_descriptor, 0);
yading@10 648 if (!pkt->buf) {
yading@10 649 av_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");
yading@10 650 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0)
yading@10 651 avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
yading@10 652 av_freep(&buf_descriptor);
yading@10 653 return AVERROR(ENOMEM);
yading@10 654 }
yading@10 655 }
yading@10 656 pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
yading@10 657 convert_timestamp(ctx, &pkt->pts);
yading@10 658
yading@10 659 return s->buf_len[buf.index];
yading@10 660 }
yading@10 661
yading@10 662 static int mmap_start(AVFormatContext *ctx)
yading@10 663 {
yading@10 664 struct video_data *s = ctx->priv_data;
yading@10 665 enum v4l2_buf_type type;
yading@10 666 int i, res;
yading@10 667
yading@10 668 for (i = 0; i < s->buffers; i++) {
yading@10 669 struct v4l2_buffer buf = {
yading@10 670 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
yading@10 671 .index = i,
yading@10 672 .memory = V4L2_MEMORY_MMAP
yading@10 673 };
yading@10 674
yading@10 675 if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) {
yading@10 676 res = AVERROR(errno);
yading@10 677 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res));
yading@10 678 return res;
yading@10 679 }
yading@10 680 }
yading@10 681 s->buffers_queued = s->buffers;
yading@10 682
yading@10 683 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
yading@10 684 if (v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type) < 0) {
yading@10 685 res = AVERROR(errno);
yading@10 686 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", av_err2str(res));
yading@10 687 return res;
yading@10 688 }
yading@10 689
yading@10 690 return 0;
yading@10 691 }
yading@10 692
yading@10 693 static void mmap_close(struct video_data *s)
yading@10 694 {
yading@10 695 enum v4l2_buf_type type;
yading@10 696 int i;
yading@10 697
yading@10 698 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
yading@10 699 /* We do not check for the result, because we could
yading@10 700 * not do anything about it anyway...
yading@10 701 */
yading@10 702 v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
yading@10 703 for (i = 0; i < s->buffers; i++) {
yading@10 704 v4l2_munmap(s->buf_start[i], s->buf_len[i]);
yading@10 705 }
yading@10 706 av_free(s->buf_start);
yading@10 707 av_free(s->buf_len);
yading@10 708 }
yading@10 709
yading@10 710 static int v4l2_set_parameters(AVFormatContext *s1)
yading@10 711 {
yading@10 712 struct video_data *s = s1->priv_data;
yading@10 713 struct v4l2_standard standard = { 0 };
yading@10 714 struct v4l2_streamparm streamparm = { 0 };
yading@10 715 struct v4l2_fract *tpf;
yading@10 716 AVRational framerate_q = { 0 };
yading@10 717 int i, ret;
yading@10 718
yading@10 719 if (s->framerate &&
yading@10 720 (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {
yading@10 721 av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",
yading@10 722 s->framerate);
yading@10 723 return ret;
yading@10 724 }
yading@10 725
yading@10 726 if (s->standard) {
yading@10 727 if (s->std_id) {
yading@10 728 ret = 0;
yading@10 729 av_log(s1, AV_LOG_DEBUG, "Setting standard: %s\n", s->standard);
yading@10 730 /* set tv standard */
yading@10 731 for (i = 0; ; i++) {
yading@10 732 standard.index = i;
yading@10 733 if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
yading@10 734 ret = AVERROR(errno);
yading@10 735 break;
yading@10 736 }
yading@10 737 if (!av_strcasecmp(standard.name, s->standard))
yading@10 738 break;
yading@10 739 }
yading@10 740 if (ret < 0) {
yading@10 741 av_log(s1, AV_LOG_ERROR, "Unknown or unsupported standard '%s'\n", s->standard);
yading@10 742 return ret;
yading@10 743 }
yading@10 744
yading@10 745 if (v4l2_ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
yading@10 746 ret = AVERROR(errno);
yading@10 747 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_STD): %s\n", av_err2str(ret));
yading@10 748 return ret;
yading@10 749 }
yading@10 750 } else {
yading@10 751 av_log(s1, AV_LOG_WARNING,
yading@10 752 "This device does not support any standard\n");
yading@10 753 }
yading@10 754 }
yading@10 755
yading@10 756 /* get standard */
yading@10 757 if (v4l2_ioctl(s->fd, VIDIOC_G_STD, &s->std_id) == 0) {
yading@10 758 tpf = &standard.frameperiod;
yading@10 759 for (i = 0; ; i++) {
yading@10 760 standard.index = i;
yading@10 761 if (v4l2_ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
yading@10 762 ret = AVERROR(errno);
yading@10 763 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMSTD): %s\n", av_err2str(ret));
yading@10 764 return ret;
yading@10 765 }
yading@10 766 if (standard.id == s->std_id) {
yading@10 767 av_log(s1, AV_LOG_DEBUG,
yading@10 768 "Current standard: %s, id: %"PRIu64", frameperiod: %d/%d\n",
yading@10 769 standard.name, (uint64_t)standard.id, tpf->numerator, tpf->denominator);
yading@10 770 break;
yading@10 771 }
yading@10 772 }
yading@10 773 } else {
yading@10 774 tpf = &streamparm.parm.capture.timeperframe;
yading@10 775 }
yading@10 776
yading@10 777 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
yading@10 778 if (v4l2_ioctl(s->fd, VIDIOC_G_PARM, &streamparm) < 0) {
yading@10 779 ret = AVERROR(errno);
yading@10 780 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n", av_err2str(ret));
yading@10 781 return ret;
yading@10 782 }
yading@10 783
yading@10 784 if (framerate_q.num && framerate_q.den) {
yading@10 785 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
yading@10 786 tpf = &streamparm.parm.capture.timeperframe;
yading@10 787
yading@10 788 av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",
yading@10 789 framerate_q.den, framerate_q.num);
yading@10 790 tpf->numerator = framerate_q.den;
yading@10 791 tpf->denominator = framerate_q.num;
yading@10 792
yading@10 793 if (v4l2_ioctl(s->fd, VIDIOC_S_PARM, &streamparm) < 0) {
yading@10 794 ret = AVERROR(errno);
yading@10 795 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_PARM): %s\n", av_err2str(ret));
yading@10 796 return ret;
yading@10 797 }
yading@10 798
yading@10 799 if (framerate_q.num != tpf->denominator ||
yading@10 800 framerate_q.den != tpf->numerator) {
yading@10 801 av_log(s1, AV_LOG_INFO,
yading@10 802 "The driver changed the time per frame from "
yading@10 803 "%d/%d to %d/%d\n",
yading@10 804 framerate_q.den, framerate_q.num,
yading@10 805 tpf->numerator, tpf->denominator);
yading@10 806 }
yading@10 807 } else {
yading@10 808 av_log(s1, AV_LOG_WARNING,
yading@10 809 "The driver does not allow to change time per frame\n");
yading@10 810 }
yading@10 811 }
yading@10 812 s1->streams[0]->avg_frame_rate.num = tpf->denominator;
yading@10 813 s1->streams[0]->avg_frame_rate.den = tpf->numerator;
yading@10 814 s1->streams[0]->r_frame_rate = s1->streams[0]->avg_frame_rate;
yading@10 815
yading@10 816 return 0;
yading@10 817 }
yading@10 818
yading@10 819 static int device_try_init(AVFormatContext *s1,
yading@10 820 enum AVPixelFormat pix_fmt,
yading@10 821 int *width,
yading@10 822 int *height,
yading@10 823 uint32_t *desired_format,
yading@10 824 enum AVCodecID *codec_id)
yading@10 825 {
yading@10 826 int ret, i;
yading@10 827
yading@10 828 *desired_format = fmt_ff2v4l(pix_fmt, s1->video_codec_id);
yading@10 829
yading@10 830 if (*desired_format) {
yading@10 831 ret = device_init(s1, width, height, *desired_format);
yading@10 832 if (ret < 0) {
yading@10 833 *desired_format = 0;
yading@10 834 if (ret != AVERROR(EINVAL))
yading@10 835 return ret;
yading@10 836 }
yading@10 837 }
yading@10 838
yading@10 839 if (!*desired_format) {
yading@10 840 for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) {
yading@10 841 if (s1->video_codec_id == AV_CODEC_ID_NONE ||
yading@10 842 fmt_conversion_table[i].codec_id == s1->video_codec_id) {
yading@10 843 av_log(s1, AV_LOG_DEBUG, "Trying to set codec:%s pix_fmt:%s\n",
yading@10 844 avcodec_get_name(fmt_conversion_table[i].codec_id),
yading@10 845 (char *)av_x_if_null(av_get_pix_fmt_name(fmt_conversion_table[i].ff_fmt), "none"));
yading@10 846
yading@10 847 *desired_format = fmt_conversion_table[i].v4l2_fmt;
yading@10 848 ret = device_init(s1, width, height, *desired_format);
yading@10 849 if (ret >= 0)
yading@10 850 break;
yading@10 851 else if (ret != AVERROR(EINVAL))
yading@10 852 return ret;
yading@10 853 *desired_format = 0;
yading@10 854 }
yading@10 855 }
yading@10 856
yading@10 857 if (*desired_format == 0) {
yading@10 858 av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "
yading@10 859 "codec '%s' (id %d), pixel format '%s' (id %d)\n",
yading@10 860 avcodec_get_name(s1->video_codec_id), s1->video_codec_id,
yading@10 861 (char *)av_x_if_null(av_get_pix_fmt_name(pix_fmt), "none"), pix_fmt);
yading@10 862 ret = AVERROR(EINVAL);
yading@10 863 }
yading@10 864 }
yading@10 865
yading@10 866 *codec_id = fmt_v4l2codec(*desired_format);
yading@10 867 av_assert0(*codec_id != AV_CODEC_ID_NONE);
yading@10 868 return ret;
yading@10 869 }
yading@10 870
yading@10 871 static int v4l2_read_header(AVFormatContext *s1)
yading@10 872 {
yading@10 873 struct video_data *s = s1->priv_data;
yading@10 874 AVStream *st;
yading@10 875 int res = 0;
yading@10 876 uint32_t desired_format;
yading@10 877 enum AVCodecID codec_id = AV_CODEC_ID_NONE;
yading@10 878 enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
yading@10 879 struct v4l2_input input = { 0 };
yading@10 880
yading@10 881 st = avformat_new_stream(s1, NULL);
yading@10 882 if (!st)
yading@10 883 return AVERROR(ENOMEM);
yading@10 884
yading@10 885 #if CONFIG_LIBV4L2
yading@10 886 /* silence libv4l2 logging. if fopen() fails v4l2_log_file will be NULL
yading@10 887 and errors will get sent to stderr */
yading@10 888 v4l2_log_file = fopen("/dev/null", "w");
yading@10 889 #endif
yading@10 890
yading@10 891 s->fd = device_open(s1);
yading@10 892 if (s->fd < 0)
yading@10 893 return s->fd;
yading@10 894
yading@10 895 if (s->channel != -1) {
yading@10 896 /* set video input */
yading@10 897 av_log(s1, AV_LOG_DEBUG, "Selecting input_channel: %d\n", s->channel);
yading@10 898 if (v4l2_ioctl(s->fd, VIDIOC_S_INPUT, &s->channel) < 0) {
yading@10 899 res = AVERROR(errno);
yading@10 900 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_S_INPUT): %s\n", av_err2str(res));
yading@10 901 return res;
yading@10 902 }
yading@10 903 } else {
yading@10 904 /* get current video input */
yading@10 905 if (v4l2_ioctl(s->fd, VIDIOC_G_INPUT, &s->channel) < 0) {
yading@10 906 res = AVERROR(errno);
yading@10 907 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_INPUT): %s\n", av_err2str(res));
yading@10 908 return res;
yading@10 909 }
yading@10 910 }
yading@10 911
yading@10 912 /* enum input */
yading@10 913 input.index = s->channel;
yading@10 914 if (v4l2_ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
yading@10 915 res = AVERROR(errno);
yading@10 916 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_ENUMINPUT): %s\n", av_err2str(res));
yading@10 917 return res;
yading@10 918 }
yading@10 919 s->std_id = input.std;
yading@10 920 av_log(s1, AV_LOG_DEBUG, "Current input_channel: %d, input_name: %s\n",
yading@10 921 s->channel, input.name);
yading@10 922
yading@10 923 if (s->list_format) {
yading@10 924 list_formats(s1, s->fd, s->list_format);
yading@10 925 return AVERROR_EXIT;
yading@10 926 }
yading@10 927
yading@10 928 if (s->list_standard) {
yading@10 929 list_standards(s1);
yading@10 930 return AVERROR_EXIT;
yading@10 931 }
yading@10 932
yading@10 933 avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
yading@10 934
yading@10 935 if (s->pixel_format) {
yading@10 936 AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
yading@10 937
yading@10 938 if (codec)
yading@10 939 s1->video_codec_id = codec->id;
yading@10 940
yading@10 941 pix_fmt = av_get_pix_fmt(s->pixel_format);
yading@10 942
yading@10 943 if (pix_fmt == AV_PIX_FMT_NONE && !codec) {
yading@10 944 av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
yading@10 945 s->pixel_format);
yading@10 946
yading@10 947 return AVERROR(EINVAL);
yading@10 948 }
yading@10 949 }
yading@10 950
yading@10 951 if (!s->width && !s->height) {
yading@10 952 struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE };
yading@10 953
yading@10 954 av_log(s1, AV_LOG_VERBOSE,
yading@10 955 "Querying the device for the current frame size\n");
yading@10 956 if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
yading@10 957 res = AVERROR(errno);
yading@10 958 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", av_err2str(res));
yading@10 959 return res;
yading@10 960 }
yading@10 961
yading@10 962 s->width = fmt.fmt.pix.width;
yading@10 963 s->height = fmt.fmt.pix.height;
yading@10 964 av_log(s1, AV_LOG_VERBOSE,
yading@10 965 "Setting frame size to %dx%d\n", s->width, s->height);
yading@10 966 }
yading@10 967
yading@10 968 res = device_try_init(s1, pix_fmt, &s->width, &s->height, &desired_format, &codec_id);
yading@10 969 if (res < 0) {
yading@10 970 v4l2_close(s->fd);
yading@10 971 return res;
yading@10 972 }
yading@10 973
yading@10 974 /* If no pixel_format was specified, the codec_id was not known up
yading@10 975 * until now. Set video_codec_id in the context, as codec_id will
yading@10 976 * not be available outside this function
yading@10 977 */
yading@10 978 if (codec_id != AV_CODEC_ID_NONE && s1->video_codec_id == AV_CODEC_ID_NONE)
yading@10 979 s1->video_codec_id = codec_id;
yading@10 980
yading@10 981 if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
yading@10 982 return res;
yading@10 983
yading@10 984 s->frame_format = desired_format;
yading@10 985
yading@10 986 if ((res = v4l2_set_parameters(s1)) < 0)
yading@10 987 return res;
yading@10 988
yading@10 989 st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
yading@10 990 s->frame_size =
yading@10 991 avpicture_get_size(st->codec->pix_fmt, s->width, s->height);
yading@10 992
yading@10 993 if ((res = mmap_init(s1)) ||
yading@10 994 (res = mmap_start(s1)) < 0) {
yading@10 995 v4l2_close(s->fd);
yading@10 996 return res;
yading@10 997 }
yading@10 998
yading@10 999 s->top_field_first = first_field(s->fd);
yading@10 1000
yading@10 1001 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@10 1002 st->codec->codec_id = codec_id;
yading@10 1003 if (codec_id == AV_CODEC_ID_RAWVIDEO)
yading@10 1004 st->codec->codec_tag =
yading@10 1005 avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
yading@10 1006 if (desired_format == V4L2_PIX_FMT_YVU420)
yading@10 1007 st->codec->codec_tag = MKTAG('Y', 'V', '1', '2');
yading@10 1008 else if (desired_format == V4L2_PIX_FMT_YVU410)
yading@10 1009 st->codec->codec_tag = MKTAG('Y', 'V', 'U', '9');
yading@10 1010 st->codec->width = s->width;
yading@10 1011 st->codec->height = s->height;
yading@10 1012 st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;
yading@10 1013
yading@10 1014 return 0;
yading@10 1015 }
yading@10 1016
yading@10 1017 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
yading@10 1018 {
yading@10 1019 struct video_data *s = s1->priv_data;
yading@10 1020 AVFrame *frame = s1->streams[0]->codec->coded_frame;
yading@10 1021 int res;
yading@10 1022
yading@10 1023 av_init_packet(pkt);
yading@10 1024 if ((res = mmap_read_frame(s1, pkt)) < 0) {
yading@10 1025 return res;
yading@10 1026 }
yading@10 1027
yading@10 1028 if (frame && s->interlaced) {
yading@10 1029 frame->interlaced_frame = 1;
yading@10 1030 frame->top_field_first = s->top_field_first;
yading@10 1031 }
yading@10 1032
yading@10 1033 return pkt->size;
yading@10 1034 }
yading@10 1035
yading@10 1036 static int v4l2_read_close(AVFormatContext *s1)
yading@10 1037 {
yading@10 1038 struct video_data *s = s1->priv_data;
yading@10 1039
yading@10 1040 if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
yading@10 1041 av_log(s1, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
yading@10 1042 "close.\n");
yading@10 1043
yading@10 1044 mmap_close(s);
yading@10 1045
yading@10 1046 v4l2_close(s->fd);
yading@10 1047 return 0;
yading@10 1048 }
yading@10 1049
yading@10 1050 #define OFFSET(x) offsetof(struct video_data, x)
yading@10 1051 #define DEC AV_OPT_FLAG_DECODING_PARAM
yading@10 1052
yading@10 1053 static const AVOption options[] = {
yading@10 1054 { "standard", "set TV standard, used only by analog frame grabber", OFFSET(standard), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC },
yading@10 1055 { "channel", "set TV channel, used only by frame grabber", OFFSET(channel), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, DEC },
yading@10 1056 { "video_size", "set frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
yading@10 1057 { "pixel_format", "set preferred pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
yading@10 1058 { "input_format", "set preferred pixel format (for raw video) or codec name", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
yading@10 1059 { "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
yading@10 1060
yading@10 1061 { "list_formats", "list available formats and exit", OFFSET(list_format), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC, "list_formats" },
yading@10 1062 { "all", "show all available formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.i64 = V4L_ALLFORMATS }, 0, INT_MAX, DEC, "list_formats" },
yading@10 1063 { "raw", "show only non-compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.i64 = V4L_RAWFORMATS }, 0, INT_MAX, DEC, "list_formats" },
yading@10 1064 { "compressed", "show only compressed formats", OFFSET(list_format), AV_OPT_TYPE_CONST, {.i64 = V4L_COMPFORMATS }, 0, INT_MAX, DEC, "list_formats" },
yading@10 1065
yading@10 1066 { "list_standards", "list supported standards and exit", OFFSET(list_standard), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, DEC, "list_standards" },
yading@10 1067 { "all", "show all supported standards", OFFSET(list_standard), AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, DEC, "list_standards" },
yading@10 1068
yading@10 1069 { "timestamps", "set type of timestamps for grabbed frames", OFFSET(ts_mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, DEC, "timestamps" },
yading@10 1070 { "ts", "set type of timestamps for grabbed frames", OFFSET(ts_mode), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, DEC, "timestamps" },
yading@10 1071 { "default", "use timestamps from the kernel", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_DEFAULT }, 0, 2, DEC, "timestamps" },
yading@10 1072 { "abs", "use absolute timestamps (wall clock)", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_ABS }, 0, 2, DEC, "timestamps" },
yading@10 1073 { "mono2abs", "force conversion from monotonic to absolute timestamps", OFFSET(ts_mode), AV_OPT_TYPE_CONST, {.i64 = V4L_TS_MONO2ABS }, 0, 2, DEC, "timestamps" },
yading@10 1074
yading@10 1075 { NULL },
yading@10 1076 };
yading@10 1077
yading@10 1078 static const AVClass v4l2_class = {
yading@10 1079 .class_name = "V4L2 indev",
yading@10 1080 .item_name = av_default_item_name,
yading@10 1081 .option = options,
yading@10 1082 .version = LIBAVUTIL_VERSION_INT,
yading@10 1083 };
yading@10 1084
yading@10 1085 AVInputFormat ff_v4l2_demuxer = {
yading@10 1086 .name = "video4linux2,v4l2",
yading@10 1087 .long_name = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
yading@10 1088 .priv_data_size = sizeof(struct video_data),
yading@10 1089 .read_header = v4l2_read_header,
yading@10 1090 .read_packet = v4l2_read_packet,
yading@10 1091 .read_close = v4l2_read_close,
yading@10 1092 .flags = AVFMT_NOFILE,
yading@10 1093 .priv_class = &v4l2_class,
yading@10 1094 };