From 5f1b247ee7c47821da301eddad539f8e35652cf5 Mon Sep 17 00:00:00 2001
From: Giorgio Vazzana <mywing81@gmail.com>
Date: Fri, 8 May 2015 17:25:15 +0200
Subject: [PATCH] lavd/v4l2: produce a 0 byte packet when a dequeued buffer is
flagged with V4L2_BUF_FLAG_ERROR
Fixes ticket #4030.
---
libavdevice/v4l2.c | 37 ++++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index b0fa765..6137cef 100644
|
a
|
b
|
static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
|
| 499 | 499 | }; |
| 500 | 500 | int res; |
| 501 | 501 | |
| | 502 | pkt->size = 0; |
| | 503 | |
| 502 | 504 | /* FIXME: Some special treatment might be needed in case of loss of signal... */ |
| 503 | 505 | while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR)); |
| 504 | 506 | if (res < 0) { |
| 505 | | if (errno == EAGAIN) { |
| 506 | | pkt->size = 0; |
| | 507 | if (errno == EAGAIN) |
| 507 | 508 | return AVERROR(EAGAIN); |
| 508 | | } |
| | 509 | |
| 509 | 510 | res = AVERROR(errno); |
| 510 | 511 | av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n", |
| 511 | 512 | av_err2str(res)); |
| … |
… |
static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
|
| 520 | 521 | // always keep at least one buffer queued |
| 521 | 522 | av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1); |
| 522 | 523 | |
| 523 | | /* CPIA is a compressed format and we don't know the exact number of bytes |
| 524 | | * used by a frame, so set it here as the driver announces it. |
| 525 | | */ |
| 526 | | if (ctx->video_codec_id == AV_CODEC_ID_CPIA) |
| 527 | | s->frame_size = buf.bytesused; |
| | 524 | if (buf.flags & V4L2_BUF_FLAG_ERROR) { |
| | 525 | av_log(ctx, AV_LOG_WARNING, |
| | 526 | "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n", |
| | 527 | buf.bytesused); |
| | 528 | buf.bytesused = 0; |
| | 529 | } else { |
| | 530 | /* CPIA is a compressed format and we don't know the exact number of bytes |
| | 531 | * used by a frame, so set it here as the driver announces it. */ |
| | 532 | if (ctx->video_codec_id == AV_CODEC_ID_CPIA) |
| | 533 | s->frame_size = buf.bytesused; |
| 528 | 534 | |
| 529 | | if (s->frame_size > 0 && buf.bytesused != s->frame_size) { |
| 530 | | av_log(ctx, AV_LOG_ERROR, |
| 531 | | "The v4l2 frame is %d bytes, but %d bytes are expected. Flags: 0x%08X\n", |
| 532 | | buf.bytesused, s->frame_size, buf.flags); |
| 533 | | enqueue_buffer(s, &buf); |
| 534 | | return AVERROR_INVALIDDATA; |
| | 535 | if (s->frame_size > 0 && buf.bytesused != s->frame_size) { |
| | 536 | av_log(ctx, AV_LOG_ERROR, |
| | 537 | "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n", |
| | 538 | buf.bytesused, s->frame_size, buf.flags); |
| | 539 | enqueue_buffer(s, &buf); |
| | 540 | return AVERROR_INVALIDDATA; |
| | 541 | } |
| 535 | 542 | } |
| 536 | 543 | |
| 537 | 544 | /* Image is at s->buff_start[buf.index] */ |
| … |
… |
FF_ENABLE_DEPRECATION_WARNINGS
|
| 586 | 593 | pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec; |
| 587 | 594 | convert_timestamp(ctx, &pkt->pts); |
| 588 | 595 | |
| 589 | | return s->buf_len[buf.index]; |
| | 596 | return pkt->size; |
| 590 | 597 | } |
| 591 | 598 | |
| 592 | 599 | static int mmap_start(AVFormatContext *ctx) |