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

    };

    int res;



    pkt->size = 0;



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

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

    if (res < 0) {

        if (errno == EAGAIN)

            return AVERROR(EAGAIN);



        res = AVERROR(errno);

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

               av_err2str(res));

        return res;

    }



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

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

        return AVERROR(EINVAL);

    }

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

    // always keep at least one buffer queued

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



#ifdef V4L2_BUF_FLAG_ERROR

    if (buf.flags & V4L2_BUF_FLAG_ERROR) {

        av_log(ctx, AV_LOG_WARNING,

               "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",

               buf.bytesused);

        buf.bytesused = 0;

    } else

#endif

    {

        /* CPIA is a compressed format and we don't know the exact number of bytes

         * used by a frame, so set it here as the driver announces it. */

        if (ctx->video_codec_id == AV_CODEC_ID_CPIA)

            s->frame_size = buf.bytesused;



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

            av_log(ctx, AV_LOG_ERROR,

                   "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",

                   buf.bytesused, s->frame_size, buf.flags);

            enqueue_buffer(s, &buf);

            return AVERROR_INVALIDDATA;

        }

    }



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

    if (atomic_load(&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");

            enqueue_buffer(s, &buf);

            return res;

        }

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



        res = enqueue_buffer(s, &buf);

        if (res) {

            av_packet_unref(pkt);

            return res;

        }

    } else {

        struct buff_data *buf_descriptor;



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

        pkt->size     = buf.bytesused;



        buf_descriptor = av_malloc(sizeof(struct buff_data));

        if (!buf_descriptor) {

            /* 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");

            enqueue_buffer(s, &buf);



            return AVERROR(ENOMEM);

        }

        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_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");

            enqueue_buffer(s, &buf);

            av_freep(&buf_descriptor);

            return AVERROR(ENOMEM);

        }

    }

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

    convert_timestamp(ctx, &pkt->pts);



    return pkt->size;

}

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

    };

    int res;



    pkt->size = 0;



    

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

    if (res < 0) {

        if (errno == EAGAIN)

            return AVERROR(EAGAIN);



        res = AVERROR(errno);

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

               av_err2str(res));

        return res;

    }



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

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

        return AVERROR(EINVAL);

    }

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

    

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



#ifdef V4L2_BUF_FLAG_ERROR

    if (buf.flags & V4L2_BUF_FLAG_ERROR) {

        av_log(ctx, AV_LOG_WARNING,

               "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",

               buf.bytesused);

        buf.bytesused = 0;

    } else

#endif

    {

        



        if (ctx->video_codec_id == AV_CODEC_ID_CPIA)

            s->frame_size = buf.bytesused;



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

            av_log(ctx, AV_LOG_ERROR,

                   "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",

                   buf.bytesused, s->frame_size, buf.flags);

            enqueue_buffer(s, &buf);

            return AVERROR_INVALIDDATA;

        }

    }



    

    if (atomic_load(&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");

            enqueue_buffer(s, &buf);

            return res;

        }

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



        res = enqueue_buffer(s, &buf);

        if (res) {

            av_packet_unref(pkt);

            return res;

        }

    } else {

        struct buff_data *buf_descriptor;



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

        pkt->size     = buf.bytesused;



        buf_descriptor = av_malloc(sizeof(struct buff_data));

        if (!buf_descriptor) {

            





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

            enqueue_buffer(s, &buf);



            return AVERROR(ENOMEM);

        }

        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_log(ctx, AV_LOG_ERROR, "Failed to create a buffer\n");

            enqueue_buffer(s, &buf);

            av_freep(&buf_descriptor);

            return AVERROR(ENOMEM);

        }

    }

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

    convert_timestamp(ctx, &pkt->pts);



    return pkt->size;

}

    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
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

    };

    int VAR_4;



    VAR_1->size = 0;



    

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

    if (VAR_4 < 0) {

        if (errno == EAGAIN)

            return AVERROR(EAGAIN);



        VAR_4 = AVERROR(errno);

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

               av_err2str(VAR_4));

        return VAR_4;

    }



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

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

        return AVERROR(EINVAL);

    }

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

    

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



#ifdef V4L2_BUF_FLAG_ERROR

    if (VAR_3.flags & V4L2_BUF_FLAG_ERROR) {

        av_log(VAR_0, AV_LOG_WARNING,

               "Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",

               VAR_3.bytesused);

        VAR_3.bytesused = 0;

    } else

#endif

    {

        



        if (VAR_0->video_codec_id == AV_CODEC_ID_CPIA)

            VAR_2->frame_size = VAR_3.bytesused;



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

            av_log(VAR_0, AV_LOG_ERROR,

                   "Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",

                   VAR_3.bytesused, VAR_2->frame_size, VAR_3.flags);

            enqueue_buffer(VAR_2, &VAR_3);

            return AVERROR_INVALIDDATA;

        }

    }



    

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

        

        VAR_4 = av_new_packet(VAR_1, VAR_3.bytesused);

        if (VAR_4 < 0) {

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

            enqueue_buffer(VAR_2, &VAR_3);

            return VAR_4;

        }

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



        VAR_4 = enqueue_buffer(VAR_2, &VAR_3);

        if (VAR_4) {

            av_packet_unref(VAR_1);

            return VAR_4;

        }

    } else {

        struct buff_data *VAR_5;



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

        VAR_1->size     = VAR_3.bytesused;



        VAR_5 = av_malloc(sizeof(struct buff_data));

        if (!VAR_5) {

            





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

            enqueue_buffer(VAR_2, &VAR_3);



            return AVERROR(ENOMEM);

        }

        VAR_5->index = VAR_3.index;

        VAR_5->VAR_2     = VAR_2;



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

                                    VAR_5, 0);

        if (!VAR_1->VAR_3) {

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

            enqueue_buffer(VAR_2, &VAR_3);

            av_freep(&VAR_5);

            return AVERROR(ENOMEM);

        }

    }

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

    convert_timestamp(VAR_0, &VAR_1->pts);



    return VAR_1->size;

}

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
}; int VAR_4; VAR_1->size = 0; while ((VAR_4 = v4l2_ioctl(VAR_2->fd, VIDIOC_DQBUF, &VAR_3)) < 0 && (errno == EINTR)); if (VAR_4 < 0) { if (errno == EAGAIN)
return AVERROR(EAGAIN); VAR_4 = AVERROR(errno); av_log(VAR_0, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %VAR_2\n",
av_err2str(VAR_4)); return VAR_4; } if (VAR_3.index >= VAR_2->buffers) { av_log(VAR_0, AV_LOG_ERROR, "Invalid buffer index received.\n"); return AVERROR(EINVAL); } atomic_fetch_add(&VAR_2->buffers_queued, -1); av_assert0(atomic_load(&VAR_2->buffers_queued) >= 1); #ifdef V4L2_BUF_FLAG_ERROR
if (VAR_3.flags & V4L2_BUF_FLAG_ERROR) { av_log(VAR_0, AV_LOG_WARNING,
"Dequeued v4l2 buffer contains corrupted data (%d bytes).\n",
VAR_3.bytesused); VAR_3.bytesused = 0; } else #endif
{ if (VAR_0->video_codec_id == AV_CODEC_ID_CPIA)
VAR_2->frame_size = VAR_3.bytesused; if (VAR_2->frame_size > 0 && VAR_3.bytesused != VAR_2->frame_size) { av_log(VAR_0, AV_LOG_ERROR,
"Dequeued v4l2 buffer contains %d bytes, but %d were expected. Flags: 0x%08X.\n",
VAR_3.bytesused, VAR_2->frame_size, VAR_3.flags); enqueue_buffer(VAR_2, &VAR_3); return AVERROR_INVALIDDATA; } } if (atomic_load(&VAR_2->buffers_queued) == FFMAX(VAR_2->buffers / 8, 1)) { VAR_4 = av_new_packet(VAR_1, VAR_3.bytesused); if (VAR_4 < 0) { av_log(VAR_0, AV_LOG_ERROR, "Error allocating a packet.\n"); enqueue_buffer(VAR_2, &VAR_3); return VAR_4; } memcpy(VAR_1->data, VAR_2->buf_start[VAR_3.index], VAR_3.bytesused); VAR_4 = enqueue_buffer(VAR_2, &VAR_3); if (VAR_4) { av_packet_unref(VAR_1); return VAR_4; } } else { struct buff_data *VAR_5; VAR_1->data     = VAR_2->buf_start[VAR_3.index]; VAR_1->size     = VAR_3.bytesused; VAR_5 = av_malloc(sizeof(struct buff_data)); if (!VAR_5) { av_log(VAR_0, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n"); enqueue_buffer(VAR_2, &VAR_3); return AVERROR(ENOMEM); } VAR_5->index = VAR_3.index; VAR_5->VAR_2     = VAR_2; VAR_1->VAR_3 = av_buffer_create(VAR_1->data, VAR_1->size, mmap_release_buffer,
VAR_5, 0); if (!VAR_1->VAR_3) { av_log(VAR_0, AV_LOG_ERROR, "Failed to create a buffer\n"); enqueue_buffer(VAR_2, &VAR_3); av_freep(&VAR_5); return AVERROR(ENOMEM); } } VAR_1->pts = VAR_3.timestamp.tv_sec * INT64_C(1000000) + VAR_3.timestamp.tv_usec; convert_timestamp(VAR_0, &VAR_1->pts); return VAR_1->size; }