int ff_framequeue_add(FFFrameQueue *fq, AVFrame *frame)
{
    FFFrameBucket *b;

    check_consistency(fq);
    if (fq->queued == fq->allocated) {
        if (fq->allocated == 1) {
            size_t na = 8;
            FFFrameBucket *nq = av_realloc_array(NULL, na, sizeof(*nq));
            if (!nq)
                return AVERROR(ENOMEM);
            nq[0] = fq->queue[0];
            fq->queue = nq;
            fq->allocated = na;
        } else {
            size_t na = fq->allocated << 1;
            FFFrameBucket *nq = av_realloc_array(fq->queue, na, sizeof(*nq));
            if (!nq)
                return AVERROR(ENOMEM);
            if (fq->tail + fq->queued > fq->allocated)
                memmove(nq + fq->allocated, nq,
                        (fq->tail + fq->queued - fq->allocated) * sizeof(*nq));
            fq->queue = nq;
            fq->allocated = na;
        }
    }
    b = bucket(fq, fq->queued);
    b->frame = frame;
    fq->queued++;
    fq->total_frames_head++;
    fq->total_samples_head += frame->nb_samples;
    check_consistency(fq);
    return 0;
}