mirror of
https://github.com/librempeg/librempeg
synced 2024-11-23 11:39:47 +00:00
Pass the v4l2 buffer into the AVPacket, instead of allocating a new buffer
and copying the frame into it (remove a memcpy()) Originally committed as revision 7981 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
a492ad9f63
commit
41536a6078
@ -59,6 +59,11 @@ struct video_data {
|
||||
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 @@ static int read_init(AVFormatContext *ctx)
|
||||
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 @@ static int mmap_read_frame(AVFormatContext *ctx, void *frame, int64_t *ts)
|
||||
}
|
||||
|
||||
/* 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 @@ static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user