In particular:
1) save errno before it (possibly) gets overwritten by other calls
2) do not forget to enqueue the buffer again in case of error
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -610,15 +610,17 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) |
610 | 610 |
res = av_new_packet(pkt, buf.bytesused); |
611 | 611 |
if (res < 0) { |
612 | 612 |
av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n"); |
613 |
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0) |
|
614 |
+ avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); |
|
613 | 615 |
return res; |
614 | 616 |
} |
615 | 617 |
memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused); |
616 | 618 |
|
617 |
- res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf); |
|
618 |
- if (res < 0) { |
|
619 |
- av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); |
|
619 |
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) < 0) { |
|
620 |
+ res = AVERROR(errno); |
|
621 |
+ av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n", av_err2str(res)); |
|
620 | 622 |
av_free_packet(pkt); |
621 |
- return AVERROR(errno); |
|
623 |
+ return res; |
|
622 | 624 |
} |
623 | 625 |
avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); |
624 | 626 |
} else { |
... | ... |
@@ -636,7 +638,8 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) |
636 | 636 |
* allocate a buffer for memcpying into it |
637 | 637 |
*/ |
638 | 638 |
av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); |
639 |
- res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf); |
|
639 |
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0) |
|
640 |
+ avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); |
|
640 | 641 |
|
641 | 642 |
return AVERROR(ENOMEM); |
642 | 643 |
} |
... | ... |
@@ -647,6 +650,9 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt) |
647 | 647 |
pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer, |
648 | 648 |
buf_descriptor, 0); |
649 | 649 |
if (!pkt->buf) { |
650 |
+ av_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n"); |
|
651 |
+ if (v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf) == 0) |
|
652 |
+ avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1); |
|
650 | 653 |
av_freep(&buf_descriptor); |
651 | 654 |
return AVERROR(ENOMEM); |
652 | 655 |
} |