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;