diff mbox

[FFmpeg-devel] libavdevice/v4l2: fix invalid access to struct v4l2_buffer

Message ID 20170920131454.8727-1-jara.beran@gmail.com
State Accepted
Commit 00a1e1337f22376909338a5319a378b2e2afdde8
Headers show

Commit Message

Jaroslav Beran Sept. 20, 2017, 1:14 p.m. UTC
In case we are short of queued buffers, at first v4l2_buffer was enqueued to kernel so it's not owned by
user-space anymore. After that it's timestamp field was read, but it might be overwritten by driver at
that moment. It resulted in invalid timestamp sometimes.
---
 libavdevice/v4l2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Michael Niedermayer Sept. 23, 2017, 10:02 p.m. UTC | #1
On Wed, Sep 20, 2017 at 03:14:54PM +0200, Jaroslav Beran wrote:
> In case we are short of queued buffers, at first v4l2_buffer was enqueued to kernel so it's not owned by
> user-space anymore. After that it's timestamp field was read, but it might be overwritten by driver at
> that moment. It resulted in invalid timestamp sometimes.
> ---
>  libavdevice/v4l2.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

will apply

thanks

[...]
diff mbox

Patch

diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 17451cdb60..f087badf5c 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -492,6 +492,7 @@  static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
         .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
         .memory = V4L2_MEMORY_MMAP
     };
+    struct timeval buf_ts;
     int res;
 
     pkt->size = 0;
@@ -508,6 +509,8 @@  static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
         return res;
     }
 
+    buf_ts = buf.timestamp;
+
     if (buf.index >= s->buffers) {
         av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
         return AVERROR(EINVAL);
@@ -583,7 +586,7 @@  static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
             return AVERROR(ENOMEM);
         }
     }
-    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
+    pkt->pts = buf_ts.tv_sec * INT64_C(1000000) + buf_ts.tv_usec;
     convert_timestamp(ctx, &pkt->pts);
 
     return pkt->size;