Libav
|
00001 /* 00002 * Video4Linux2 grab interface 00003 * Copyright (c) 2000,2001 Fabrice Bellard 00004 * Copyright (c) 2006 Luca Abeni 00005 * 00006 * Part of this file is based on the V4L2 video capture example 00007 * (http://v4l2spec.bytesex.org/v4l2spec/capture.c) 00008 * 00009 * Thanks to Michael Niedermayer for providing the mapping between 00010 * V4L2_PIX_FMT_* and PIX_FMT_* 00011 * 00012 * 00013 * This file is part of FFmpeg. 00014 * 00015 * FFmpeg is free software; you can redistribute it and/or 00016 * modify it under the terms of the GNU Lesser General Public 00017 * License as published by the Free Software Foundation; either 00018 * version 2.1 of the License, or (at your option) any later version. 00019 * 00020 * FFmpeg is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 * Lesser General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU Lesser General Public 00026 * License along with FFmpeg; if not, write to the Free Software 00027 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00028 */ 00029 00030 #undef __STRICT_ANSI__ //workaround due to broken kernel headers 00031 #include "config.h" 00032 #include "libavformat/avformat.h" 00033 #include <unistd.h> 00034 #include <fcntl.h> 00035 #include <sys/ioctl.h> 00036 #include <sys/mman.h> 00037 #include <sys/time.h> 00038 #if HAVE_SYS_VIDEOIO_H 00039 #include <sys/videoio.h> 00040 #else 00041 #include <asm/types.h> 00042 #include <linux/videodev2.h> 00043 #endif 00044 #include <time.h> 00045 #include <strings.h> 00046 00047 static const int desired_video_buffers = 256; 00048 00049 enum io_method { 00050 io_read, 00051 io_mmap, 00052 io_userptr 00053 }; 00054 00055 struct video_data { 00056 int fd; 00057 int frame_format; /* V4L2_PIX_FMT_* */ 00058 enum io_method io_method; 00059 int width, height; 00060 int frame_size; 00061 int top_field_first; 00062 00063 int buffers; 00064 void **buf_start; 00065 unsigned int *buf_len; 00066 }; 00067 00068 struct buff_data { 00069 int index; 00070 int fd; 00071 }; 00072 00073 struct fmt_map { 00074 enum PixelFormat ff_fmt; 00075 enum CodecID codec_id; 00076 uint32_t v4l2_fmt; 00077 }; 00078 00079 static struct fmt_map fmt_conversion_table[] = { 00080 { 00081 .ff_fmt = PIX_FMT_YUV420P, 00082 .codec_id = CODEC_ID_RAWVIDEO, 00083 .v4l2_fmt = V4L2_PIX_FMT_YUV420, 00084 }, 00085 { 00086 .ff_fmt = PIX_FMT_YUV422P, 00087 .codec_id = CODEC_ID_RAWVIDEO, 00088 .v4l2_fmt = V4L2_PIX_FMT_YUV422P, 00089 }, 00090 { 00091 .ff_fmt = PIX_FMT_YUYV422, 00092 .codec_id = CODEC_ID_RAWVIDEO, 00093 .v4l2_fmt = V4L2_PIX_FMT_YUYV, 00094 }, 00095 { 00096 .ff_fmt = PIX_FMT_UYVY422, 00097 .codec_id = CODEC_ID_RAWVIDEO, 00098 .v4l2_fmt = V4L2_PIX_FMT_UYVY, 00099 }, 00100 { 00101 .ff_fmt = PIX_FMT_YUV411P, 00102 .codec_id = CODEC_ID_RAWVIDEO, 00103 .v4l2_fmt = V4L2_PIX_FMT_YUV411P, 00104 }, 00105 { 00106 .ff_fmt = PIX_FMT_YUV410P, 00107 .codec_id = CODEC_ID_RAWVIDEO, 00108 .v4l2_fmt = V4L2_PIX_FMT_YUV410, 00109 }, 00110 { 00111 .ff_fmt = PIX_FMT_RGB555, 00112 .codec_id = CODEC_ID_RAWVIDEO, 00113 .v4l2_fmt = V4L2_PIX_FMT_RGB555, 00114 }, 00115 { 00116 .ff_fmt = PIX_FMT_RGB565, 00117 .codec_id = CODEC_ID_RAWVIDEO, 00118 .v4l2_fmt = V4L2_PIX_FMT_RGB565, 00119 }, 00120 { 00121 .ff_fmt = PIX_FMT_BGR24, 00122 .codec_id = CODEC_ID_RAWVIDEO, 00123 .v4l2_fmt = V4L2_PIX_FMT_BGR24, 00124 }, 00125 { 00126 .ff_fmt = PIX_FMT_RGB24, 00127 .codec_id = CODEC_ID_RAWVIDEO, 00128 .v4l2_fmt = V4L2_PIX_FMT_RGB24, 00129 }, 00130 { 00131 .ff_fmt = PIX_FMT_BGRA, 00132 .codec_id = CODEC_ID_RAWVIDEO, 00133 .v4l2_fmt = V4L2_PIX_FMT_BGR32, 00134 }, 00135 { 00136 .ff_fmt = PIX_FMT_GRAY8, 00137 .codec_id = CODEC_ID_RAWVIDEO, 00138 .v4l2_fmt = V4L2_PIX_FMT_GREY, 00139 }, 00140 { 00141 .ff_fmt = PIX_FMT_NONE, 00142 .codec_id = CODEC_ID_MJPEG, 00143 .v4l2_fmt = V4L2_PIX_FMT_MJPEG, 00144 }, 00145 { 00146 .ff_fmt = PIX_FMT_NONE, 00147 .codec_id = CODEC_ID_MJPEG, 00148 .v4l2_fmt = V4L2_PIX_FMT_JPEG, 00149 }, 00150 }; 00151 00152 static int device_open(AVFormatContext *ctx, uint32_t *capabilities) 00153 { 00154 struct v4l2_capability cap; 00155 int fd; 00156 int res, err; 00157 int flags = O_RDWR; 00158 00159 if (ctx->flags & AVFMT_FLAG_NONBLOCK) { 00160 flags |= O_NONBLOCK; 00161 } 00162 fd = open(ctx->filename, flags, 0); 00163 if (fd < 0) { 00164 av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n", 00165 ctx->filename, strerror(errno)); 00166 00167 return AVERROR(errno); 00168 } 00169 00170 res = ioctl(fd, VIDIOC_QUERYCAP, &cap); 00171 // ENOIOCTLCMD definition only availble on __KERNEL__ 00172 if (res < 0 && ((err = errno) == 515)) { 00173 av_log(ctx, AV_LOG_ERROR, "QUERYCAP not implemented, probably V4L device but not supporting V4L2\n"); 00174 close(fd); 00175 00176 return AVERROR(515); 00177 } 00178 if (res < 0) { 00179 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n", 00180 strerror(errno)); 00181 close(fd); 00182 00183 return AVERROR(err); 00184 } 00185 if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) { 00186 av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n"); 00187 close(fd); 00188 00189 return AVERROR(ENODEV); 00190 } 00191 *capabilities = cap.capabilities; 00192 00193 return fd; 00194 } 00195 00196 static int device_init(AVFormatContext *ctx, int *width, int *height, uint32_t pix_fmt) 00197 { 00198 struct video_data *s = ctx->priv_data; 00199 int fd = s->fd; 00200 struct v4l2_format fmt; 00201 int res; 00202 00203 memset(&fmt, 0, sizeof(struct v4l2_format)); 00204 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00205 fmt.fmt.pix.width = *width; 00206 fmt.fmt.pix.height = *height; 00207 fmt.fmt.pix.pixelformat = pix_fmt; 00208 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 00209 res = ioctl(fd, VIDIOC_S_FMT, &fmt); 00210 if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) { 00211 av_log(ctx, AV_LOG_INFO, "The V4L2 driver changed the video from %dx%d to %dx%d\n", *width, *height, fmt.fmt.pix.width, fmt.fmt.pix.height); 00212 *width = fmt.fmt.pix.width; 00213 *height = fmt.fmt.pix.height; 00214 } 00215 00216 if (pix_fmt != fmt.fmt.pix.pixelformat) { 00217 av_log(ctx, AV_LOG_DEBUG, "The V4L2 driver changed the pixel format from 0x%08X to 0x%08X\n", pix_fmt, fmt.fmt.pix.pixelformat); 00218 res = -1; 00219 } 00220 00221 return res; 00222 } 00223 00224 static int first_field(int fd) 00225 { 00226 int res; 00227 v4l2_std_id std; 00228 00229 res = ioctl(fd, VIDIOC_G_STD, &std); 00230 if (res < 0) { 00231 return 0; 00232 } 00233 if (std & V4L2_STD_NTSC) { 00234 return 0; 00235 } 00236 00237 return 1; 00238 } 00239 00240 static uint32_t fmt_ff2v4l(enum PixelFormat pix_fmt, enum CodecID codec_id) 00241 { 00242 int i; 00243 00244 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { 00245 if ((codec_id == CODEC_ID_NONE || 00246 fmt_conversion_table[i].codec_id == codec_id) && 00247 (pix_fmt == PIX_FMT_NONE || 00248 fmt_conversion_table[i].ff_fmt == pix_fmt)) { 00249 return fmt_conversion_table[i].v4l2_fmt; 00250 } 00251 } 00252 00253 return 0; 00254 } 00255 00256 static enum PixelFormat fmt_v4l2ff(uint32_t v4l2_fmt, enum CodecID codec_id) 00257 { 00258 int i; 00259 00260 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { 00261 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt && 00262 fmt_conversion_table[i].codec_id == codec_id) { 00263 return fmt_conversion_table[i].ff_fmt; 00264 } 00265 } 00266 00267 return PIX_FMT_NONE; 00268 } 00269 00270 static enum CodecID fmt_v4l2codec(uint32_t v4l2_fmt) 00271 { 00272 int i; 00273 00274 for (i = 0; i < FF_ARRAY_ELEMS(fmt_conversion_table); i++) { 00275 if (fmt_conversion_table[i].v4l2_fmt == v4l2_fmt) { 00276 return fmt_conversion_table[i].codec_id; 00277 } 00278 } 00279 00280 return CODEC_ID_NONE; 00281 } 00282 00283 static int mmap_init(AVFormatContext *ctx) 00284 { 00285 struct video_data *s = ctx->priv_data; 00286 struct v4l2_requestbuffers req; 00287 int i, res; 00288 00289 memset(&req, 0, sizeof(struct v4l2_requestbuffers)); 00290 req.count = desired_video_buffers; 00291 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00292 req.memory = V4L2_MEMORY_MMAP; 00293 res = ioctl (s->fd, VIDIOC_REQBUFS, &req); 00294 if (res < 0) { 00295 if (errno == EINVAL) { 00296 av_log(ctx, AV_LOG_ERROR, "Device does not support mmap\n"); 00297 } else { 00298 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_REQBUFS)\n"); 00299 } 00300 00301 return AVERROR(errno); 00302 } 00303 00304 if (req.count < 2) { 00305 av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n"); 00306 00307 return AVERROR(ENOMEM); 00308 } 00309 s->buffers = req.count; 00310 s->buf_start = av_malloc(sizeof(void *) * s->buffers); 00311 if (s->buf_start == NULL) { 00312 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n"); 00313 00314 return AVERROR(ENOMEM); 00315 } 00316 s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers); 00317 if (s->buf_len == NULL) { 00318 av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n"); 00319 av_free(s->buf_start); 00320 00321 return AVERROR(ENOMEM); 00322 } 00323 00324 for (i = 0; i < req.count; i++) { 00325 struct v4l2_buffer buf; 00326 00327 memset(&buf, 0, sizeof(struct v4l2_buffer)); 00328 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00329 buf.memory = V4L2_MEMORY_MMAP; 00330 buf.index = i; 00331 res = ioctl (s->fd, VIDIOC_QUERYBUF, &buf); 00332 if (res < 0) { 00333 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n"); 00334 00335 return AVERROR(errno); 00336 } 00337 00338 s->buf_len[i] = buf.length; 00339 if (s->frame_size > 0 && s->buf_len[i] < s->frame_size) { 00340 av_log(ctx, AV_LOG_ERROR, "Buffer len [%d] = %d != %d\n", i, s->buf_len[i], s->frame_size); 00341 00342 return -1; 00343 } 00344 s->buf_start[i] = mmap (NULL, buf.length, 00345 PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, buf.m.offset); 00346 if (s->buf_start[i] == MAP_FAILED) { 00347 av_log(ctx, AV_LOG_ERROR, "mmap: %s\n", strerror(errno)); 00348 00349 return AVERROR(errno); 00350 } 00351 } 00352 00353 return 0; 00354 } 00355 00356 static int read_init(AVFormatContext *ctx) 00357 { 00358 return -1; 00359 } 00360 00361 static void mmap_release_buffer(AVPacket *pkt) 00362 { 00363 struct v4l2_buffer buf; 00364 int res, fd; 00365 struct buff_data *buf_descriptor = pkt->priv; 00366 00367 if (pkt->data == NULL) { 00368 return; 00369 } 00370 00371 memset(&buf, 0, sizeof(struct v4l2_buffer)); 00372 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00373 buf.memory = V4L2_MEMORY_MMAP; 00374 buf.index = buf_descriptor->index; 00375 fd = buf_descriptor->fd; 00376 av_free(buf_descriptor); 00377 00378 res = ioctl (fd, VIDIOC_QBUF, &buf); 00379 if (res < 0) { 00380 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); 00381 } 00382 pkt->data = NULL; 00383 pkt->size = 0; 00384 } 00385 00386 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) 00387 { 00388 struct video_data *s = ctx->priv_data; 00389 struct v4l2_buffer buf; 00390 struct buff_data *buf_descriptor; 00391 int res; 00392 00393 memset(&buf, 0, sizeof(struct v4l2_buffer)); 00394 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00395 buf.memory = V4L2_MEMORY_MMAP; 00396 00397 /* FIXME: Some special treatment might be needed in case of loss of signal... */ 00398 while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR)); 00399 if (res < 0) { 00400 if (errno == EAGAIN) { 00401 pkt->size = 0; 00402 00403 return AVERROR(EAGAIN); 00404 } 00405 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", strerror(errno)); 00406 00407 return AVERROR(errno); 00408 } 00409 assert (buf.index < s->buffers); 00410 if (s->frame_size > 0 && buf.bytesused != s->frame_size) { 00411 av_log(ctx, AV_LOG_ERROR, "The v4l2 frame is %d bytes, but %d bytes are expected\n", buf.bytesused, s->frame_size); 00412 00413 return AVERROR_INVALIDDATA; 00414 } 00415 00416 /* Image is at s->buff_start[buf.index] */ 00417 pkt->data= s->buf_start[buf.index]; 00418 pkt->size = buf.bytesused; 00419 pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; 00420 pkt->destruct = mmap_release_buffer; 00421 buf_descriptor = av_malloc(sizeof(struct buff_data)); 00422 if (buf_descriptor == NULL) { 00423 /* Something went wrong... Since av_malloc() failed, we cannot even 00424 * allocate a buffer for memcopying into it 00425 */ 00426 av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); 00427 res = ioctl (s->fd, VIDIOC_QBUF, &buf); 00428 00429 return AVERROR(ENOMEM); 00430 } 00431 buf_descriptor->fd = s->fd; 00432 buf_descriptor->index = buf.index; 00433 pkt->priv = buf_descriptor; 00434 00435 return s->buf_len[buf.index]; 00436 } 00437 00438 static int read_frame(AVFormatContext *ctx, AVPacket *pkt) 00439 { 00440 return -1; 00441 } 00442 00443 static int mmap_start(AVFormatContext *ctx) 00444 { 00445 struct video_data *s = ctx->priv_data; 00446 enum v4l2_buf_type type; 00447 int i, res; 00448 00449 for (i = 0; i < s->buffers; i++) { 00450 struct v4l2_buffer buf; 00451 00452 memset(&buf, 0, sizeof(struct v4l2_buffer)); 00453 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00454 buf.memory = V4L2_MEMORY_MMAP; 00455 buf.index = i; 00456 00457 res = ioctl (s->fd, VIDIOC_QBUF, &buf); 00458 if (res < 0) { 00459 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", strerror(errno)); 00460 00461 return AVERROR(errno); 00462 } 00463 } 00464 00465 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00466 res = ioctl (s->fd, VIDIOC_STREAMON, &type); 00467 if (res < 0) { 00468 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n", strerror(errno)); 00469 00470 return AVERROR(errno); 00471 } 00472 00473 return 0; 00474 } 00475 00476 static void mmap_close(struct video_data *s) 00477 { 00478 enum v4l2_buf_type type; 00479 int i; 00480 00481 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00482 /* We do not check for the result, because we could 00483 * not do anything about it anyway... 00484 */ 00485 ioctl(s->fd, VIDIOC_STREAMOFF, &type); 00486 for (i = 0; i < s->buffers; i++) { 00487 munmap(s->buf_start[i], s->buf_len[i]); 00488 } 00489 av_free(s->buf_start); 00490 av_free(s->buf_len); 00491 } 00492 00493 static int v4l2_set_parameters( AVFormatContext *s1, AVFormatParameters *ap ) 00494 { 00495 struct video_data *s = s1->priv_data; 00496 struct v4l2_input input; 00497 struct v4l2_standard standard; 00498 int i; 00499 00500 if(ap->channel>=0) { 00501 /* set tv video input */ 00502 memset (&input, 0, sizeof (input)); 00503 input.index = ap->channel; 00504 if(ioctl (s->fd, VIDIOC_ENUMINPUT, &input) < 0) { 00505 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n"); 00506 return AVERROR(EIO); 00507 } 00508 00509 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n", 00510 ap->channel, input.name); 00511 if(ioctl (s->fd, VIDIOC_S_INPUT, &input.index) < 0 ) { 00512 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set input(%d) failed\n", 00513 ap->channel); 00514 return AVERROR(EIO); 00515 } 00516 } 00517 00518 if(ap->standard) { 00519 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n", 00520 ap->standard ); 00521 /* set tv standard */ 00522 memset (&standard, 0, sizeof (standard)); 00523 for(i=0;;i++) { 00524 standard.index = i; 00525 if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) { 00526 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", 00527 ap->standard); 00528 return AVERROR(EIO); 00529 } 00530 00531 if(!strcasecmp(standard.name, ap->standard)) { 00532 break; 00533 } 00534 } 00535 00536 av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s, id: %"PRIu64"\n", 00537 ap->standard, (uint64_t)standard.id); 00538 if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) { 00539 av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl set standard(%s) failed\n", 00540 ap->standard); 00541 return AVERROR(EIO); 00542 } 00543 } 00544 00545 return 0; 00546 } 00547 00548 static uint32_t device_try_init(AVFormatContext *s1, 00549 const AVFormatParameters *ap, 00550 int *width, 00551 int *height, 00552 enum CodecID *codec_id) 00553 { 00554 uint32_t desired_format = fmt_ff2v4l(ap->pix_fmt, s1->video_codec_id); 00555 00556 if (desired_format == 0 || 00557 device_init(s1, width, height, desired_format) < 0) { 00558 int i; 00559 00560 desired_format = 0; 00561 for (i = 0; i<FF_ARRAY_ELEMS(fmt_conversion_table); i++) { 00562 if (s1->video_codec_id == CODEC_ID_NONE || 00563 fmt_conversion_table[i].codec_id == s1->video_codec_id) { 00564 desired_format = fmt_conversion_table[i].v4l2_fmt; 00565 if (device_init(s1, width, height, desired_format) >= 0) { 00566 break; 00567 } 00568 desired_format = 0; 00569 } 00570 } 00571 } 00572 if (desired_format != 0) { 00573 *codec_id = fmt_v4l2codec(desired_format); 00574 assert(*codec_id != CODEC_ID_NONE); 00575 } 00576 00577 return desired_format; 00578 } 00579 00580 static int v4l2_read_header(AVFormatContext *s1, AVFormatParameters *ap) 00581 { 00582 struct video_data *s = s1->priv_data; 00583 AVStream *st; 00584 int res; 00585 uint32_t desired_format, capabilities; 00586 enum CodecID codec_id; 00587 00588 st = av_new_stream(s1, 0); 00589 if (!st) { 00590 return AVERROR(ENOMEM); 00591 } 00592 av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ 00593 00594 s->width = ap->width; 00595 s->height = ap->height; 00596 00597 capabilities = 0; 00598 s->fd = device_open(s1, &capabilities); 00599 if (s->fd < 0) { 00600 return AVERROR(EIO); 00601 } 00602 av_log(s1, AV_LOG_VERBOSE, "[%d]Capabilities: %x\n", s->fd, capabilities); 00603 00604 if (!s->width && !s->height) { 00605 struct v4l2_format fmt; 00606 00607 av_log(s1, AV_LOG_VERBOSE, "Querying the device for the current frame size\n"); 00608 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00609 if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) { 00610 av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n", strerror(errno)); 00611 return AVERROR(errno); 00612 } 00613 s->width = fmt.fmt.pix.width; 00614 s->height = fmt.fmt.pix.height; 00615 av_log(s1, AV_LOG_VERBOSE, "Setting frame size to %dx%d\n", s->width, s->height); 00616 } 00617 00618 desired_format = device_try_init(s1, ap, &s->width, &s->height, &codec_id); 00619 if (desired_format == 0) { 00620 av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for " 00621 "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, ap->pix_fmt); 00622 close(s->fd); 00623 00624 return AVERROR(EIO); 00625 } 00626 if (avcodec_check_dimensions(s1, s->width, s->height) < 0) 00627 return AVERROR(EINVAL); 00628 s->frame_format = desired_format; 00629 00630 if( v4l2_set_parameters( s1, ap ) < 0 ) 00631 return AVERROR(EIO); 00632 00633 st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id); 00634 s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height); 00635 if (capabilities & V4L2_CAP_STREAMING) { 00636 s->io_method = io_mmap; 00637 res = mmap_init(s1); 00638 if (res == 0) { 00639 res = mmap_start(s1); 00640 } 00641 } else { 00642 s->io_method = io_read; 00643 res = read_init(s1); 00644 } 00645 if (res < 0) { 00646 close(s->fd); 00647 00648 return AVERROR(EIO); 00649 } 00650 s->top_field_first = first_field(s->fd); 00651 00652 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00653 st->codec->codec_id = codec_id; 00654 st->codec->width = s->width; 00655 st->codec->height = s->height; 00656 st->codec->time_base.den = ap->time_base.den; 00657 st->codec->time_base.num = ap->time_base.num; 00658 st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8; 00659 00660 return 0; 00661 } 00662 00663 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) 00664 { 00665 struct video_data *s = s1->priv_data; 00666 int res; 00667 00668 if (s->io_method == io_mmap) { 00669 av_init_packet(pkt); 00670 res = mmap_read_frame(s1, pkt); 00671 } else if (s->io_method == io_read) { 00672 if (av_new_packet(pkt, s->frame_size) < 0) 00673 return AVERROR(EIO); 00674 00675 res = read_frame(s1, pkt); 00676 } else { 00677 return AVERROR(EIO); 00678 } 00679 if (res < 0) { 00680 return res; 00681 } 00682 00683 if (s1->streams[0]->codec->coded_frame) { 00684 s1->streams[0]->codec->coded_frame->interlaced_frame = 1; 00685 s1->streams[0]->codec->coded_frame->top_field_first = s->top_field_first; 00686 } 00687 00688 return pkt->size; 00689 } 00690 00691 static int v4l2_read_close(AVFormatContext *s1) 00692 { 00693 struct video_data *s = s1->priv_data; 00694 00695 if (s->io_method == io_mmap) { 00696 mmap_close(s); 00697 } 00698 00699 close(s->fd); 00700 return 0; 00701 } 00702 00703 AVInputFormat v4l2_demuxer = { 00704 "video4linux2", 00705 NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"), 00706 sizeof(struct video_data), 00707 NULL, 00708 v4l2_read_header, 00709 v4l2_read_packet, 00710 v4l2_read_close, 00711 .flags = AVFMT_NOFILE, 00712 };