static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)

{

    struct video_data *s = ctx->priv_data;

    struct v4l2_buffer buf = {

        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,

        .memory = V4L2_MEMORY_MMAP

    };

    struct pollfd p = { .fd = s->fd, .events = POLLIN };

    int res;



    res = poll(&p, 1, s->timeout);

    if (res < 0)

        return AVERROR(errno);



    if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))

        return AVERROR(EAGAIN);



    /* FIXME: Some special treatment might be needed in case of loss of signal... */

    while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));

    if (res < 0) {

        if (errno == EAGAIN) {

            pkt->size = 0;



            return AVERROR(EAGAIN);

        }

        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",

               strerror(errno));



        return AVERROR(errno);

    }



    if (buf.index >= s->buffers) {

        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");

        return AVERROR(EINVAL);

    }

    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);

    // always keep at least one buffer queued

    av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);



    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {

        av_log(ctx, AV_LOG_ERROR,

               "The v4l2 frame is %d bytes, but %d bytes are expected\n",

               buf.bytesused, s->frame_size);



        return AVERROR_INVALIDDATA;

    }



    /* Image is at s->buff_start[buf.index] */

    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {

        /* when we start getting low on queued buffers, fall back on copying data */

        res = av_new_packet(pkt, buf.bytesused);

        if (res < 0) {

            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");

            return res;

        }

        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);



        res = ioctl(s->fd, VIDIOC_QBUF, &buf);

        if (res < 0) {

            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");

            av_free_packet(pkt);

            return AVERROR(errno);

        }

        avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);

    } else {

        struct buff_data *buf_descriptor;



        pkt->data     = s->buf_start[buf.index];

        pkt->size     = buf.bytesused;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

        pkt->destruct = dummy_release_buffer;

FF_ENABLE_DEPRECATION_WARNINGS

#endif



        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 memcpying into it

             */

            av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");

            res = ioctl(s->fd, VIDIOC_QBUF, &buf);



            return AVERROR(ENOMEM);

        }

        buf_descriptor->fd    = s->fd;

        buf_descriptor->index = buf.index;

        buf_descriptor->s     = s;



        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,

                                    buf_descriptor, 0);

        if (!pkt->buf) {

            av_freep(&buf_descriptor);

            return AVERROR(ENOMEM);

        }

    }

    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;



    return s->buf_len[buf.index];

}

static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)

{

    struct video_data *s = ctx->priv_data;

    struct v4l2_buffer buf = {

        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,

        .memory = V4L2_MEMORY_MMAP

    };

    struct pollfd p = { .fd = s->fd, .events = POLLIN };

    int res;



    res = poll(&p, 1, s->timeout);

    if (res < 0)

        return AVERROR(errno);



    if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))

        return AVERROR(EAGAIN);



    

    while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));

    if (res < 0) {

        if (errno == EAGAIN) {

            pkt->size = 0;



            return AVERROR(EAGAIN);

        }

        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",

               strerror(errno));



        return AVERROR(errno);

    }



    if (buf.index >= s->buffers) {

        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");

        return AVERROR(EINVAL);

    }

    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);

    

    av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);



    if (s->frame_size > 0 && buf.bytesused != s->frame_size) {

        av_log(ctx, AV_LOG_ERROR,

               "The v4l2 frame is %d bytes, but %d bytes are expected\n",

               buf.bytesused, s->frame_size);



        return AVERROR_INVALIDDATA;

    }



    

    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {

        

        res = av_new_packet(pkt, buf.bytesused);

        if (res < 0) {

            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");

            return res;

        }

        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);



        res = ioctl(s->fd, VIDIOC_QBUF, &buf);

        if (res < 0) {

            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");

            av_free_packet(pkt);

            return AVERROR(errno);

        }

        avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);

    } else {

        struct buff_data *buf_descriptor;



        pkt->data     = s->buf_start[buf.index];

        pkt->size     = buf.bytesused;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

        pkt->destruct = dummy_release_buffer;

FF_ENABLE_DEPRECATION_WARNINGS

#endif



        buf_descriptor = av_malloc(sizeof(struct buff_data));

        if (buf_descriptor == NULL) {

            





            av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");

            res = ioctl(s->fd, VIDIOC_QBUF, &buf);



            return AVERROR(ENOMEM);

        }

        buf_descriptor->fd    = s->fd;

        buf_descriptor->index = buf.index;

        buf_descriptor->s     = s;



        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,

                                    buf_descriptor, 0);

        if (!pkt->buf) {

            av_freep(&buf_descriptor);

            return AVERROR(ENOMEM);

        }

    }

    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;



    return s->buf_len[buf.index];

}

static int FUNC_0(AVFormatContext *VAR_0, AVPacket *VAR_1)

{

    struct video_data *VAR_2 = VAR_0->priv_data;

    struct v4l2_buffer VAR_3 = {

        .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,

        .memory = V4L2_MEMORY_MMAP

    };

    struct pollfd VAR_4 = { .fd = VAR_2->fd, .events = POLLIN };

    int VAR_5;



    VAR_5 = poll(&VAR_4, 1, VAR_2->timeout);

    if (VAR_5 < 0)

        return AVERROR(errno);



    if (!(VAR_4.revents & (POLLIN | POLLERR | POLLHUP)))

        return AVERROR(EAGAIN);



    

    while ((VAR_5 = ioctl(VAR_2->fd, VIDIOC_DQBUF, &VAR_3)) < 0 && (errno == EINTR));

    if (VAR_5 < 0) {

        if (errno == EAGAIN) {

            VAR_1->size = 0;



            return AVERROR(EAGAIN);

        }

        av_log(VAR_0, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %VAR_2\n",

               strerror(errno));



        return AVERROR(errno);

    }



    if (VAR_3.index >= VAR_2->buffers) {

        av_log(VAR_0, AV_LOG_ERROR, "Invalid buffer index received.\n");

        return AVERROR(EINVAL);

    }

    avpriv_atomic_int_add_and_fetch(&VAR_2->buffers_queued, -1);

    

    av_assert0(avpriv_atomic_int_get(&VAR_2->buffers_queued) >= 1);



    if (VAR_2->frame_size > 0 && VAR_3.bytesused != VAR_2->frame_size) {

        av_log(VAR_0, AV_LOG_ERROR,

               "The v4l2 frame is %d bytes, but %d bytes are expected\n",

               VAR_3.bytesused, VAR_2->frame_size);



        return AVERROR_INVALIDDATA;

    }



    

    if (avpriv_atomic_int_get(&VAR_2->buffers_queued) == FFMAX(VAR_2->buffers / 8, 1)) {

        

        VAR_5 = av_new_packet(VAR_1, VAR_3.bytesused);

        if (VAR_5 < 0) {

            av_log(VAR_0, AV_LOG_ERROR, "Error allocating a packet.\n");

            return VAR_5;

        }

        memcpy(VAR_1->data, VAR_2->buf_start[VAR_3.index], VAR_3.bytesused);



        VAR_5 = ioctl(VAR_2->fd, VIDIOC_QBUF, &VAR_3);

        if (VAR_5 < 0) {

            av_log(VAR_0, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");

            av_free_packet(VAR_1);

            return AVERROR(errno);

        }

        avpriv_atomic_int_add_and_fetch(&VAR_2->buffers_queued, 1);

    } else {

        struct buff_data *VAR_6;



        VAR_1->data     = VAR_2->buf_start[VAR_3.index];

        VAR_1->size     = VAR_3.bytesused;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

        VAR_1->destruct = dummy_release_buffer;

FF_ENABLE_DEPRECATION_WARNINGS

#endif



        VAR_6 = av_malloc(sizeof(struct buff_data));

        if (VAR_6 == NULL) {

            





            av_log(VAR_0, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");

            VAR_5 = ioctl(VAR_2->fd, VIDIOC_QBUF, &VAR_3);



            return AVERROR(ENOMEM);

        }

        VAR_6->fd    = VAR_2->fd;

        VAR_6->index = VAR_3.index;

        VAR_6->VAR_2     = VAR_2;



        VAR_1->VAR_3 = av_buffer_create(VAR_1->data, VAR_1->size, mmap_release_buffer,

                                    VAR_6, 0);

        if (!VAR_1->VAR_3) {

            av_freep(&VAR_6);

            return AVERROR(ENOMEM);

        }

    }

    VAR_1->pts = VAR_3.timestamp.tv_sec * INT64_C(1000000) + VAR_3.timestamp.tv_usec;



    return VAR_2->buf_len[VAR_3.index];

}

static int FUNC_0(AVFormatContext *VAR_0, AVPacket *VAR_1)
{ struct video_data *VAR_2 = VAR_0->priv_data; struct v4l2_buffer VAR_3 = { .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.memory = V4L2_MEMORY_MMAP
}; struct pollfd VAR_4 = { .fd = VAR_2->fd, .events = POLLIN }; int VAR_5; VAR_5 = poll(&VAR_4, 1, VAR_2->timeout); if (VAR_5 < 0)
return AVERROR(errno); if (!(VAR_4.revents & (POLLIN | POLLERR | POLLHUP)))
return AVERROR(EAGAIN); while ((VAR_5 = ioctl(VAR_2->fd, VIDIOC_DQBUF, &VAR_3)) < 0 && (errno == EINTR)); if (VAR_5 < 0) { if (errno == EAGAIN) { VAR_1->size = 0; return AVERROR(EAGAIN); } av_log(VAR_0, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %VAR_2\n",
strerror(errno)); return AVERROR(errno); } if (VAR_3.index >= VAR_2->buffers) { av_log(VAR_0, AV_LOG_ERROR, "Invalid buffer index received.\n"); return AVERROR(EINVAL); } avpriv_atomic_int_add_and_fetch(&VAR_2->buffers_queued, -1); av_assert0(avpriv_atomic_int_get(&VAR_2->buffers_queued) >= 1); if (VAR_2->frame_size > 0 && VAR_3.bytesused != VAR_2->frame_size) { av_log(VAR_0, AV_LOG_ERROR,
"The v4l2 frame is %d bytes, but %d bytes are expected\n",
VAR_3.bytesused, VAR_2->frame_size); return AVERROR_INVALIDDATA; } if (avpriv_atomic_int_get(&VAR_2->buffers_queued) == FFMAX(VAR_2->buffers / 8, 1)) { VAR_5 = av_new_packet(VAR_1, VAR_3.bytesused); if (VAR_5 < 0) { av_log(VAR_0, AV_LOG_ERROR, "Error allocating a packet.\n"); return VAR_5; } memcpy(VAR_1->data, VAR_2->buf_start[VAR_3.index], VAR_3.bytesused); VAR_5 = ioctl(VAR_2->fd, VIDIOC_QBUF, &VAR_3); if (VAR_5 < 0) { av_log(VAR_0, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n"); av_free_packet(VAR_1); return AVERROR(errno); } avpriv_atomic_int_add_and_fetch(&VAR_2->buffers_queued, 1); } else { struct buff_data *VAR_6; VAR_1->data     = VAR_2->buf_start[VAR_3.index]; VAR_1->size     = VAR_3.bytesused; #if FF_API_DESTRUCT_PACKET
FF_DISABLE_DEPRECATION_WARNINGS
VAR_1->destruct = dummy_release_buffer; FF_ENABLE_DEPRECATION_WARNINGS
#endif
VAR_6 = av_malloc(sizeof(struct buff_data)); if (VAR_6 == NULL) { av_log(VAR_0, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); VAR_5 = ioctl(VAR_2->fd, VIDIOC_QBUF, &VAR_3); return AVERROR(ENOMEM); } VAR_6->fd    = VAR_2->fd; VAR_6->index = VAR_3.index; VAR_6->VAR_2     = VAR_2; VAR_1->VAR_3 = av_buffer_create(VAR_1->data, VAR_1->size, mmap_release_buffer,
VAR_6, 0); if (!VAR_1->VAR_3) { av_freep(&VAR_6); return AVERROR(ENOMEM); } } VAR_1->pts = VAR_3.timestamp.tv_sec * INT64_C(1000000) + VAR_3.timestamp.tv_usec; return VAR_2->buf_len[VAR_3.index]; }