static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                                 const AVFrame *pict, int *got_packet)

{

    A64Context *c = avctx->priv_data;

    AVFrame *const p = avctx->coded_frame;



    int frame;

    int x, y;

    int b_height;

    int b_width;



    int req_size, ret;

    uint8_t *buf;



    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 */

            ret = ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb,

                               CHARSET_CHARS, 50, charmap, &c->randctx);

            if (ret < 0)

                return ret;

            ret = ff_do_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb,

                             CHARSET_CHARS, 50, charmap, &c->randctx);

            if (ret < 0)

                return ret;



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

}

static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                                 const AVFrame *pict, int *got_packet)

{

    A64Context *c = avctx->priv_data;

    AVFrame *const p = avctx->coded_frame;



    int frame;

    int x, y;

    int b_height;

    int b_width;



    int req_size, ret;

    uint8_t *buf;



    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;

    }



    

    if (!pict) {

        

        if (!c->mc_lifetime) return 0;

        

        if (!c->mc_frame_counter) {

            c->mc_lifetime = 0;

        }

        

        else c->mc_lifetime = c->mc_frame_counter;

    

    } else {

        

        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;

            

            return 0;

        }

    }



    

    if (c->mc_frame_counter == c->mc_lifetime) {

        req_size = 0;

        

        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;



            

            ret = ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb,

                               CHARSET_CHARS, 50, charmap, &c->randctx);

            if (ret < 0)

                return ret;

            ret = ff_do_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb,

                             CHARSET_CHARS, 50, charmap, &c->randctx);

            if (ret < 0)

                return ret;



            

            render_charset(avctx, charset, colram);



            

            memcpy(buf, charset, charset_size);



            

            buf      += charset_size;

            charset  += charset_size;

        }



        

        for (frame = 0; frame < c->mc_lifetime; frame++) {

            

            for (y = 0; y < b_height; y++) {

                for (x = 0; x < b_width; x++) {

                    buf[y * b_width + x] = charmap[y * b_width + x];

                }

            }

            

            buf += screen_size;

            req_size += screen_size;



            

            if (c->mc_use_5col) {

                a64_compress_colram(buf, charmap, colram);

                

                buf += colram_size;

                req_size += colram_size;

            }



            

            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);



        

        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;

}

static int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1,

                                 const AVFrame *VAR_2, int *VAR_3)

{

    A64Context *c = VAR_0->priv_data;

    AVFrame *const p = VAR_0->coded_frame;



    int VAR_4;

    int VAR_5, VAR_6;

    int VAR_7;

    int VAR_8;



    int VAR_9, VAR_10;

    uint8_t *buf;



    int *VAR_11     = c->mc_charmap;

    uint8_t *colram  = c->mc_colram;

    uint8_t *charset = c->mc_charset;

    int *VAR_12        = c->mc_meta_charset;

    int *VAR_13     = c->mc_best_cb;



    int VAR_14 = 0x800 * (INTERLACED + 1);

    int VAR_15  = 0x100 * c->mc_use_5col;

    int VAR_16;



    if(CROP_SCREENS) {

        VAR_7 = FFMIN(VAR_0->height,C64YRES) >> 3;

        VAR_8  = FFMIN(VAR_0->width ,C64XRES) >> 3;

        VAR_16 = VAR_8 * VAR_7;

    } else {

        VAR_7 = C64YRES >> 3;

        VAR_8  = C64XRES >> 3;

        VAR_16 = 0x400;

    }



    

    if (!VAR_2) {

        

        if (!c->mc_lifetime) return 0;

        

        if (!c->mc_frame_counter) {

            c->mc_lifetime = 0;

        }

        

        else c->mc_lifetime = c->mc_frame_counter;

    

    } else {

        

        if (c->mc_frame_counter < c->mc_lifetime) {

            *p = *VAR_2;

            p->pict_type = AV_PICTURE_TYPE_I;

            p->key_frame = 1;

            to_meta_with_crop(VAR_0, p, VAR_12 + 32000 * c->mc_frame_counter);

            c->mc_frame_counter++;

            if (c->next_pts == AV_NOPTS_VALUE)

                c->next_pts = VAR_2->pts;

            

            return 0;

        }

    }



    

    if (c->mc_frame_counter == c->mc_lifetime) {

        VAR_9 = 0;

        

        if (c->mc_lifetime) {

            VAR_9 = VAR_14 + c->mc_lifetime*(VAR_16 + VAR_15);

            if ((VAR_10 = ff_alloc_packet(VAR_1, VAR_9)) < 0) {

                av_log(VAR_0, AV_LOG_ERROR, "Error getting output packet of size %d.\n", VAR_9);

                return VAR_10;

            }

            buf = VAR_1->data;



            

            VAR_10 = ff_init_elbg(VAR_12, 32, 1000 * c->mc_lifetime, VAR_13,

                               CHARSET_CHARS, 50, VAR_11, &c->randctx);

            if (VAR_10 < 0)

                return VAR_10;

            VAR_10 = ff_do_elbg(VAR_12, 32, 1000 * c->mc_lifetime, VAR_13,

                             CHARSET_CHARS, 50, VAR_11, &c->randctx);

            if (VAR_10 < 0)

                return VAR_10;



            

            render_charset(VAR_0, charset, colram);



            

            memcpy(buf, charset, VAR_14);



            

            buf      += VAR_14;

            charset  += VAR_14;

        }



        

        for (VAR_4 = 0; VAR_4 < c->mc_lifetime; VAR_4++) {

            

            for (VAR_6 = 0; VAR_6 < VAR_7; VAR_6++) {

                for (VAR_5 = 0; VAR_5 < VAR_8; VAR_5++) {

                    buf[VAR_6 * VAR_8 + VAR_5] = VAR_11[VAR_6 * VAR_8 + VAR_5];

                }

            }

            

            buf += VAR_16;

            VAR_9 += VAR_16;



            

            if (c->mc_use_5col) {

                a64_compress_colram(buf, VAR_11, colram);

                

                buf += VAR_15;

                VAR_9 += VAR_15;

            }



            

            VAR_11 += 1000;

        }



        AV_WB32(VAR_0->extradata + 4,  c->mc_frame_counter);

        AV_WB32(VAR_0->extradata + 8,  VAR_14);

        AV_WB32(VAR_0->extradata + 12, VAR_16 + VAR_15);



        

        c->mc_frame_counter = 0;



        VAR_1->pts = VAR_1->dts = c->next_pts;

        c->next_pts         = AV_NOPTS_VALUE;



        VAR_1->size   = VAR_9;

        VAR_1->flags |= AV_PKT_FLAG_KEY;

        *VAR_3 = !!VAR_9;

    }

    return 0;

}

static int FUNC_0(AVCodecContext *VAR_0, AVPacket *VAR_1,
const AVFrame *VAR_2, int *VAR_3)
{ A64Context *c = VAR_0->priv_data; AVFrame *const p = VAR_0->coded_frame; int VAR_4; int VAR_5, VAR_6; int VAR_7; int VAR_8; int VAR_9, VAR_10; uint8_t *buf; int *VAR_11     = c->mc_charmap; uint8_t *colram  = c->mc_colram; uint8_t *charset = c->mc_charset; int *VAR_12        = c->mc_meta_charset; int *VAR_13     = c->mc_best_cb; int VAR_14 = 0x800 * (INTERLACED + 1); int VAR_15  = 0x100 * c->mc_use_5col; int VAR_16; if(CROP_SCREENS) { VAR_7 = FFMIN(VAR_0->height,C64YRES) >> 3; VAR_8  = FFMIN(VAR_0->width ,C64XRES) >> 3; VAR_16 = VAR_8 * VAR_7; } else { VAR_7 = C64YRES >> 3; VAR_8  = C64XRES >> 3; VAR_16 = 0x400; } if (!VAR_2) { if (!c->mc_lifetime) return 0; if (!c->mc_frame_counter) { c->mc_lifetime = 0; } else c->mc_lifetime = c->mc_frame_counter; } else { if (c->mc_frame_counter < c->mc_lifetime) { *p = *VAR_2; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; to_meta_with_crop(VAR_0, p, VAR_12 + 32000 * c->mc_frame_counter); c->mc_frame_counter++; if (c->next_pts == AV_NOPTS_VALUE)
c->next_pts = VAR_2->pts; return 0; } } if (c->mc_frame_counter == c->mc_lifetime) { VAR_9 = 0; if (c->mc_lifetime) { VAR_9 = VAR_14 + c->mc_lifetime*(VAR_16 + VAR_15); if ((VAR_10 = ff_alloc_packet(VAR_1, VAR_9)) < 0) { av_log(VAR_0, AV_LOG_ERROR, "Error getting output packet of size %d.\n", VAR_9); return VAR_10; } buf = VAR_1->data; VAR_10 = ff_init_elbg(VAR_12, 32, 1000 * c->mc_lifetime, VAR_13,
CHARSET_CHARS, 50, VAR_11, &c->randctx); if (VAR_10 < 0)
return VAR_10; VAR_10 = ff_do_elbg(VAR_12, 32, 1000 * c->mc_lifetime, VAR_13,
CHARSET_CHARS, 50, VAR_11, &c->randctx); if (VAR_10 < 0)
return VAR_10; render_charset(VAR_0, charset, colram); memcpy(buf, charset, VAR_14); buf      += VAR_14; charset  += VAR_14; } for (VAR_4 = 0; VAR_4 < c->mc_lifetime; VAR_4++) { for (VAR_6 = 0; VAR_6 < VAR_7; VAR_6++) { for (VAR_5 = 0; VAR_5 < VAR_8; VAR_5++) { buf[VAR_6 * VAR_8 + VAR_5] = VAR_11[VAR_6 * VAR_8 + VAR_5]; } } buf += VAR_16; VAR_9 += VAR_16; if (c->mc_use_5col) { a64_compress_colram(buf, VAR_11, colram); buf += VAR_15; VAR_9 += VAR_15; } VAR_11 += 1000; } AV_WB32(VAR_0->extradata + 4,  c->mc_frame_counter); AV_WB32(VAR_0->extradata + 8,  VAR_14); AV_WB32(VAR_0->extradata + 12, VAR_16 + VAR_15); c->mc_frame_counter = 0; VAR_1->pts = VAR_1->dts = c->next_pts; c->next_pts         = AV_NOPTS_VALUE; VAR_1->size   = VAR_9; VAR_1->flags |= AV_PKT_FLAG_KEY; *VAR_3 = !!VAR_9; } return 0; }