[Ffmpeg-cvslog] r7981 - trunk/libavformat/v4l2.c
lucabe
subversion
Wed Feb 14 14:25:24 CET 2007
Author: lucabe
Date: Wed Feb 14 14:25:24 2007
New Revision: 7981
Modified:
trunk/libavformat/v4l2.c
Log:
Pass the v4l2 buffer into the AVPacket, instead of allocating a new buffer
and copying the frame into it (remove a memcpy())
Modified: trunk/libavformat/v4l2.c
==============================================================================
--- trunk/libavformat/v4l2.c (original)
+++ trunk/libavformat/v4l2.c Wed Feb 14 14:25:24 2007
@@ -59,6 +59,11 @@
unsigned int *buf_len;
};
+struct buff_data {
+ int index;
+ int fd;
+};
+
struct fmt_map {
enum PixelFormat ff_fmt;
int32_t v4l2_fmt;
@@ -293,10 +298,32 @@
return -1;
}
-static int mmap_read_frame(AVFormatContext *ctx, void *frame, int64_t *ts)
+static void mmap_release_buffer(AVPacket *pkt)
+{
+ struct v4l2_buffer buf;
+ int res, fd;
+ struct buff_data *buf_descriptor = pkt->priv;
+
+ memset(&buf, 0, sizeof(struct v4l2_buffer));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = buf_descriptor->index;
+ fd = buf_descriptor->fd;
+ av_free(buf_descriptor);
+
+ res = ioctl (fd, VIDIOC_QBUF, &buf);
+ if (res < 0) {
+ av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
+ }
+ pkt->data = NULL;
+ pkt->size = 0;
+}
+
+static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
{
struct video_data *s = ctx->priv_data;
struct v4l2_buffer buf;
+ struct buff_data *buf_descriptor;
int res;
memset(&buf, 0, sizeof(struct v4l2_buffer));
@@ -319,20 +346,28 @@
}
/* Image is at s->buff_start[buf.index] */
- memcpy(frame, s->buf_start[buf.index], buf.bytesused);
- *ts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
-
- res = ioctl (s->fd, VIDIOC_QBUF, &buf);
- if (res < 0) {
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
+ pkt->data= s->buf_start[buf.index];
+ pkt->size = buf.bytesused;
+ pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
+ pkt->destruct = mmap_release_buffer;
+ buf_descriptor = av_malloc(sizeof(struct buff_data));
+ if (buf_descriptor == NULL) {
+ /* Something went wrong... Since av_malloc() failed, we cannot even
+ * allocate a buffer for memcopying into it
+ */
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
+ res = ioctl (s->fd, VIDIOC_QBUF, &buf);
return -1;
}
+ buf_descriptor->fd = s->fd;
+ buf_descriptor->index = buf.index;
+ pkt->priv = buf_descriptor;
return s->buf_len[buf.index];
}
-static int read_frame(AVFormatContext *ctx, void *frame, int64_t *ts)
+static int read_frame(AVFormatContext *ctx, AVPacket *pkt)
{
return -1;
}
@@ -500,13 +535,14 @@
struct video_data *s = s1->priv_data;
int res;
- if (av_new_packet(pkt, s->frame_size) < 0)
- return AVERROR_IO;
-
if (s->io_method == io_mmap) {
- res = mmap_read_frame(s1, pkt->data, &pkt->pts);
+ av_init_packet(pkt);
+ res = mmap_read_frame(s1, pkt);
} else if (s->io_method == io_read) {
- res = read_frame(s1, pkt->data, &pkt->pts);
+ if (av_new_packet(pkt, s->frame_size) < 0)
+ return AVERROR_IO;
+
+ res = read_frame(s1, pkt);
} else {
return AVERROR_IO;
}
More information about the ffmpeg-cvslog
mailing list