00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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;
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
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
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
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
00424
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
00483
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
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
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);
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 };