Mercurial > libavformat.hg
comparison v4l2.c @ 1793:951d219ab67b libavformat
Pass the v4l2 buffer into the AVPacket, instead of allocating a new buffer
and copying the frame into it (remove a memcpy())
author | lucabe |
---|---|
date | Wed, 14 Feb 2007 13:25:24 +0000 |
parents | eb16c64144ee |
children | 62792a60f740 |
comparison
equal
deleted
inserted
replaced
1792:662780b00ceb | 1793:951d219ab67b |
---|---|
57 int buffers; | 57 int buffers; |
58 void **buf_start; | 58 void **buf_start; |
59 unsigned int *buf_len; | 59 unsigned int *buf_len; |
60 }; | 60 }; |
61 | 61 |
62 struct buff_data { | |
63 int index; | |
64 int fd; | |
65 }; | |
66 | |
62 struct fmt_map { | 67 struct fmt_map { |
63 enum PixelFormat ff_fmt; | 68 enum PixelFormat ff_fmt; |
64 int32_t v4l2_fmt; | 69 int32_t v4l2_fmt; |
65 }; | 70 }; |
66 | 71 |
291 static int read_init(AVFormatContext *ctx) | 296 static int read_init(AVFormatContext *ctx) |
292 { | 297 { |
293 return -1; | 298 return -1; |
294 } | 299 } |
295 | 300 |
296 static int mmap_read_frame(AVFormatContext *ctx, void *frame, int64_t *ts) | 301 static void mmap_release_buffer(AVPacket *pkt) |
297 { | 302 { |
298 struct video_data *s = ctx->priv_data; | |
299 struct v4l2_buffer buf; | 303 struct v4l2_buffer buf; |
300 int res; | 304 int res, fd; |
305 struct buff_data *buf_descriptor = pkt->priv; | |
301 | 306 |
302 memset(&buf, 0, sizeof(struct v4l2_buffer)); | 307 memset(&buf, 0, sizeof(struct v4l2_buffer)); |
303 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 308 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
304 buf.memory = V4L2_MEMORY_MMAP; | 309 buf.memory = V4L2_MEMORY_MMAP; |
310 buf.index = buf_descriptor->index; | |
311 fd = buf_descriptor->fd; | |
312 av_free(buf_descriptor); | |
313 | |
314 res = ioctl (fd, VIDIOC_QBUF, &buf); | |
315 if (res < 0) { | |
316 av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); | |
317 } | |
318 pkt->data = NULL; | |
319 pkt->size = 0; | |
320 } | |
321 | |
322 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) | |
323 { | |
324 struct video_data *s = ctx->priv_data; | |
325 struct v4l2_buffer buf; | |
326 struct buff_data *buf_descriptor; | |
327 int res; | |
328 | |
329 memset(&buf, 0, sizeof(struct v4l2_buffer)); | |
330 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
331 buf.memory = V4L2_MEMORY_MMAP; | |
305 | 332 |
306 /* FIXME: Some special treatment might be needed in case of loss of signal... */ | 333 /* FIXME: Some special treatment might be needed in case of loss of signal... */ |
307 while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && | 334 while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && |
308 ((errno == EAGAIN) || (errno == EINTR))); | 335 ((errno == EAGAIN) || (errno == EINTR))); |
309 if (res < 0) { | 336 if (res < 0) { |
317 | 344 |
318 return -1; | 345 return -1; |
319 } | 346 } |
320 | 347 |
321 /* Image is at s->buff_start[buf.index] */ | 348 /* Image is at s->buff_start[buf.index] */ |
322 memcpy(frame, s->buf_start[buf.index], buf.bytesused); | 349 pkt->data= s->buf_start[buf.index]; |
323 *ts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; | 350 pkt->size = buf.bytesused; |
324 | 351 pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; |
325 res = ioctl (s->fd, VIDIOC_QBUF, &buf); | 352 pkt->destruct = mmap_release_buffer; |
326 if (res < 0) { | 353 buf_descriptor = av_malloc(sizeof(struct buff_data)); |
327 av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); | 354 if (buf_descriptor == NULL) { |
328 | 355 /* Something went wrong... Since av_malloc() failed, we cannot even |
329 return -1; | 356 * allocate a buffer for memcopying into it |
330 } | 357 */ |
358 av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); | |
359 res = ioctl (s->fd, VIDIOC_QBUF, &buf); | |
360 | |
361 return -1; | |
362 } | |
363 buf_descriptor->fd = s->fd; | |
364 buf_descriptor->index = buf.index; | |
365 pkt->priv = buf_descriptor; | |
331 | 366 |
332 return s->buf_len[buf.index]; | 367 return s->buf_len[buf.index]; |
333 } | 368 } |
334 | 369 |
335 static int read_frame(AVFormatContext *ctx, void *frame, int64_t *ts) | 370 static int read_frame(AVFormatContext *ctx, AVPacket *pkt) |
336 { | 371 { |
337 return -1; | 372 return -1; |
338 } | 373 } |
339 | 374 |
340 static int mmap_start(AVFormatContext *ctx) | 375 static int mmap_start(AVFormatContext *ctx) |
498 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) | 533 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt) |
499 { | 534 { |
500 struct video_data *s = s1->priv_data; | 535 struct video_data *s = s1->priv_data; |
501 int res; | 536 int res; |
502 | 537 |
503 if (av_new_packet(pkt, s->frame_size) < 0) | |
504 return AVERROR_IO; | |
505 | |
506 if (s->io_method == io_mmap) { | 538 if (s->io_method == io_mmap) { |
507 res = mmap_read_frame(s1, pkt->data, &pkt->pts); | 539 av_init_packet(pkt); |
540 res = mmap_read_frame(s1, pkt); | |
508 } else if (s->io_method == io_read) { | 541 } else if (s->io_method == io_read) { |
509 res = read_frame(s1, pkt->data, &pkt->pts); | 542 if (av_new_packet(pkt, s->frame_size) < 0) |
543 return AVERROR_IO; | |
544 | |
545 res = read_frame(s1, pkt); | |
510 } else { | 546 } else { |
511 return AVERROR_IO; | 547 return AVERROR_IO; |
512 } | 548 } |
513 if (res < 0) { | 549 if (res < 0) { |
514 return AVERROR_IO; | 550 return AVERROR_IO; |