static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                 const AVFrame *pict, int *got_packet)
{
    A64Context *c = avctx->priv_data;
    AVFrame *const p = (AVFrame *) & c->picture;

    int frame;
    int x, y;
    int b_height;
    int b_width;

    int req_size, ret;
    uint8_t *buf = NULL;

    int *charmap     = c->mc_charmap;
    uint8_t *colram  = c->mc_colram;
    uint8_t *charset = c->mc_charset;
    int *meta        = c->mc_meta_charset;
    int *best_cb     = c->mc_best_cb;

    int charset_size = 0x800 * (INTERLACED + 1);
    int colram_size  = 0x100 * c->mc_use_5col;
    int screen_size;

    if(CROP_SCREENS) {
        b_height = FFMIN(avctx->height,C64YRES) >> 3;
        b_width  = FFMIN(avctx->width ,C64XRES) >> 3;
        screen_size = b_width * b_height;
    } else {
        b_height = C64YRES >> 3;
        b_width  = C64XRES >> 3;
        screen_size = 0x400;
    }

    /* no data, means end encoding asap */
    if (!pict) {
        /* all done, end encoding */
        if (!c->mc_lifetime) return 0;
        /* no more frames in queue, prepare to flush remaining frames */
        if (!c->mc_frame_counter) {
            c->mc_lifetime = 0;
        }
        /* still frames in queue so limit lifetime to remaining frames */
        else c->mc_lifetime = c->mc_frame_counter;
    /* still new data available */
    } else {
        /* fill up mc_meta_charset with data until lifetime exceeds */
        if (c->mc_frame_counter < c->mc_lifetime) {
            *p = *pict;
            p->pict_type = AV_PICTURE_TYPE_I;
            p->key_frame = 1;
            to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter);
            c->mc_frame_counter++;
            if (c->next_pts == AV_NOPTS_VALUE)
                c->next_pts = pict->pts;
            /* lifetime is not reached so wait for next frame first */
            return 0;
        }
    }

    /* lifetime reached so now convert X frames at once */
    if (c->mc_frame_counter == c->mc_lifetime) {
        req_size = 0;
        /* any frames to encode? */
        if (c->mc_lifetime) {
            req_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
            if ((ret = ff_alloc_packet(pkt, req_size)) < 0) {
                av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", req_size);
                return ret;
            }
            buf = pkt->data;

            /* calc optimal new charset + charmaps */
            ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);
            ff_do_elbg  (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);

            /* create colorram map and a c64 readable charset */
            render_charset(avctx, charset, colram);

            /* copy charset to buf */
            memcpy(buf, charset, charset_size);

            /* advance pointers */
            buf      += charset_size;
            charset  += charset_size;
        }

        /* write x frames to buf */
        for (frame = 0; frame < c->mc_lifetime; frame++) {
            /* copy charmap to buf. buf is uchar*, charmap is int*, so no memcpy here, sorry */
            for (y = 0; y < b_height; y++) {
                for (x = 0; x < b_width; x++) {
                    buf[y * b_width + x] = charmap[y * b_width + x];
                }
            }
            /* advance pointers */
            buf += screen_size;
            req_size += screen_size;

            /* compress and copy colram to buf */
            if (c->mc_use_5col) {
                a64_compress_colram(buf, charmap, colram);
                /* advance pointers */
                buf += colram_size;
                req_size += colram_size;
            }

            /* advance to next charmap */
            charmap += 1000;
        }

        AV_WB32(avctx->extradata + 4,  c->mc_frame_counter);
        AV_WB32(avctx->extradata + 8,  charset_size);
        AV_WB32(avctx->extradata + 12, screen_size + colram_size);

        /* reset counter */
        c->mc_frame_counter = 0;

        pkt->pts = pkt->dts = c->next_pts;
        c->next_pts         = AV_NOPTS_VALUE;

        pkt->size   = req_size;
        pkt->flags |= AV_PKT_FLAG_KEY;
        *got_packet = !!req_size;
    }
    return 0;
}