static int mimic_decode_frame(AVCodecContext *avctx, void *data,

                              int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;

    MimicContext *ctx  = avctx->priv_data;

    GetByteContext gb;

    int is_pframe;

    int width, height;

    int quality, num_coeffs;

    int res;



    if (buf_size <= MIMIC_HEADER_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");

        return AVERROR_INVALIDDATA;

    }



    bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);

    bytestream2_skip(&gb, 2); /* some constant (always 256) */

    quality    = bytestream2_get_le16u(&gb);

    width      = bytestream2_get_le16u(&gb);

    height     = bytestream2_get_le16u(&gb);

    bytestream2_skip(&gb, 4); /* some constant */

    is_pframe  = bytestream2_get_le32u(&gb);

    num_coeffs = bytestream2_get_byteu(&gb);

    bytestream2_skip(&gb, 3); /* some constant */



    if (!ctx->avctx) {

        int i;



        if (!(width == 160 && height == 120) &&

            !(width == 320 && height == 240)) {

            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");

            return AVERROR_INVALIDDATA;

        }



        ctx->avctx     = avctx;

        avctx->width   = width;

        avctx->height  = height;

        avctx->pix_fmt = AV_PIX_FMT_YUV420P;

        for (i = 0; i < 3; i++) {

            ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height,   3 + !!i);

            ctx->num_hblocks[i] =                width >> (3 + !!i);

        }

    } else if (width != ctx->avctx->width || height != ctx->avctx->height) {

        avpriv_request_sample(avctx, "Resolution changing");

        return AVERROR_PATCHWELCOME;

    }



    if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {

        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");

        return AVERROR_INVALIDDATA;

    }



    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);

    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :

                                                           AV_PICTURE_TYPE_I;

    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],

                                    AV_GET_BUFFER_FLAG_REF)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return res;

    }



    ctx->next_prev_index = ctx->cur_index;

    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;



    ff_thread_finish_setup(avctx);



    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);

    if (!ctx->swap_buf)

        return AVERROR(ENOMEM);



    ctx->bbdsp.bswap_buf(ctx->swap_buf,

                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),

                         swap_buf_size >> 2);

    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);



    res = decode(ctx, quality, num_coeffs, !is_pframe);

    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);

    if (res < 0) {

        if (!(avctx->active_thread_type & FF_THREAD_FRAME))

            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);

        return res;

    }



    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)

        return res;

    *got_frame      = 1;



    flip_swap_frame(data);



    ctx->prev_index = ctx->next_prev_index;

    ctx->cur_index  = ctx->next_cur_index;



    /* Only release frames that aren't used for backreferences anymore */

    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);



    return buf_size;

}

static int mimic_decode_frame(AVCodecContext *avctx, void *data,

                              int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;

    MimicContext *ctx  = avctx->priv_data;

    GetByteContext gb;

    int is_pframe;

    int width, height;

    int quality, num_coeffs;

    int res;



    if (buf_size <= MIMIC_HEADER_SIZE) {

        av_log(avctx, AV_LOG_ERROR, "insufficient data\n");

        return AVERROR_INVALIDDATA;

    }



    bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);

    bytestream2_skip(&gb, 2); 

    quality    = bytestream2_get_le16u(&gb);

    width      = bytestream2_get_le16u(&gb);

    height     = bytestream2_get_le16u(&gb);

    bytestream2_skip(&gb, 4); 

    is_pframe  = bytestream2_get_le32u(&gb);

    num_coeffs = bytestream2_get_byteu(&gb);

    bytestream2_skip(&gb, 3); 



    if (!ctx->avctx) {

        int i;



        if (!(width == 160 && height == 120) &&

            !(width == 320 && height == 240)) {

            av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");

            return AVERROR_INVALIDDATA;

        }



        ctx->avctx     = avctx;

        avctx->width   = width;

        avctx->height  = height;

        avctx->pix_fmt = AV_PIX_FMT_YUV420P;

        for (i = 0; i < 3; i++) {

            ctx->num_vblocks[i] = AV_CEIL_RSHIFT(height,   3 + !!i);

            ctx->num_hblocks[i] =                width >> (3 + !!i);

        }

    } else if (width != ctx->avctx->width || height != ctx->avctx->height) {

        avpriv_request_sample(avctx, "Resolution changing");

        return AVERROR_PATCHWELCOME;

    }



    if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {

        av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");

        return AVERROR_INVALIDDATA;

    }



    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);

    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :

                                                           AV_PICTURE_TYPE_I;

    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],

                                    AV_GET_BUFFER_FLAG_REF)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return res;

    }



    ctx->next_prev_index = ctx->cur_index;

    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;



    ff_thread_finish_setup(avctx);



    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);

    if (!ctx->swap_buf)

        return AVERROR(ENOMEM);



    ctx->bbdsp.bswap_buf(ctx->swap_buf,

                         (const uint32_t *) (buf + MIMIC_HEADER_SIZE),

                         swap_buf_size >> 2);

    init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);



    res = decode(ctx, quality, num_coeffs, !is_pframe);

    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);

    if (res < 0) {

        if (!(avctx->active_thread_type & FF_THREAD_FRAME))

            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);

        return res;

    }



    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)

        return res;

    *got_frame      = 1;



    flip_swap_frame(data);



    ctx->prev_index = ctx->next_prev_index;

    ctx->cur_index  = ctx->next_cur_index;



    

    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);



    return buf_size;

}

    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1,

                              int *VAR_2, AVPacket *VAR_3)

{

    const uint8_t *VAR_4 = VAR_3->VAR_1;

    int VAR_5       = VAR_3->size;

    int VAR_6  = VAR_5 - MIMIC_HEADER_SIZE;

    MimicContext *ctx  = VAR_0->priv_data;

    GetByteContext gb;

    int VAR_7;

    int VAR_8, VAR_9;

    int VAR_10, VAR_11;

    int VAR_12;



    if (VAR_5 <= MIMIC_HEADER_SIZE) {

        av_log(VAR_0, AV_LOG_ERROR, "insufficient VAR_1\n");

        return AVERROR_INVALIDDATA;

    }



    bytestream2_init(&gb, VAR_4, MIMIC_HEADER_SIZE);

    bytestream2_skip(&gb, 2); 

    VAR_10    = bytestream2_get_le16u(&gb);

    VAR_8      = bytestream2_get_le16u(&gb);

    VAR_9     = bytestream2_get_le16u(&gb);

    bytestream2_skip(&gb, 4); 

    VAR_7  = bytestream2_get_le32u(&gb);

    VAR_11 = bytestream2_get_byteu(&gb);

    bytestream2_skip(&gb, 3); 



    if (!ctx->VAR_0) {

        int VAR_13;



        if (!(VAR_8 == 160 && VAR_9 == 120) &&

            !(VAR_8 == 320 && VAR_9 == 240)) {

            av_log(VAR_0, AV_LOG_ERROR, "invalid VAR_8/VAR_9!\n");

            return AVERROR_INVALIDDATA;

        }



        ctx->VAR_0     = VAR_0;

        VAR_0->VAR_8   = VAR_8;

        VAR_0->VAR_9  = VAR_9;

        VAR_0->pix_fmt = AV_PIX_FMT_YUV420P;

        for (VAR_13 = 0; VAR_13 < 3; VAR_13++) {

            ctx->num_vblocks[VAR_13] = AV_CEIL_RSHIFT(VAR_9,   3 + !!VAR_13);

            ctx->num_hblocks[VAR_13] =                VAR_8 >> (3 + !!VAR_13);

        }

    } else if (VAR_8 != ctx->VAR_0->VAR_8 || VAR_9 != ctx->VAR_0->VAR_9) {

        avpriv_request_sample(VAR_0, "Resolution changing");

        return AVERROR_PATCHWELCOME;

    }



    if (VAR_7 && !ctx->frames[ctx->prev_index].f->VAR_1[0]) {

        av_log(VAR_0, AV_LOG_ERROR, "decoding must start with keyframe\n");

        return AVERROR_INVALIDDATA;

    }



    ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]);

    ctx->frames[ctx->cur_index].f->pict_type = VAR_7 ? AV_PICTURE_TYPE_P :

                                                           AV_PICTURE_TYPE_I;

    if ((VAR_12 = ff_thread_get_buffer(VAR_0, &ctx->frames[ctx->cur_index],

                                    AV_GET_BUFFER_FLAG_REF)) < 0) {

        av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n");

        return VAR_12;

    }



    ctx->next_prev_index = ctx->cur_index;

    ctx->next_cur_index  = (ctx->cur_index - 1) & 15;



    ff_thread_finish_setup(VAR_0);



    av_fast_padded_malloc(&ctx->swap_buf, &ctx->VAR_6, VAR_6);

    if (!ctx->swap_buf)

        return AVERROR(ENOMEM);



    ctx->bbdsp.bswap_buf(ctx->swap_buf,

                         (const uint32_t *) (VAR_4 + MIMIC_HEADER_SIZE),

                         VAR_6 >> 2);

    init_get_bits(&ctx->gb, ctx->swap_buf, VAR_6 << 3);



    VAR_12 = decode(ctx, VAR_10, VAR_11, !VAR_7);

    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);

    if (VAR_12 < 0) {

        if (!(VAR_0->active_thread_type & FF_THREAD_FRAME))

            ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]);

        return VAR_12;

    }



    if ((VAR_12 = av_frame_ref(VAR_1, ctx->frames[ctx->cur_index].f)) < 0)

        return VAR_12;

    *VAR_2      = 1;



    flip_swap_frame(VAR_1);



    ctx->prev_index = ctx->next_prev_index;

    ctx->cur_index  = ctx->next_cur_index;



    

    ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]);



    return VAR_5;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1,
int *VAR_2, AVPacket *VAR_3)
{ const uint8_t *VAR_4 = VAR_3->VAR_1; int VAR_5       = VAR_3->size; int VAR_6  = VAR_5 - MIMIC_HEADER_SIZE; MimicContext *ctx  = VAR_0->priv_data; GetByteContext gb; int VAR_7; int VAR_8, VAR_9; int VAR_10, VAR_11; int VAR_12; if (VAR_5 <= MIMIC_HEADER_SIZE) { av_log(VAR_0, AV_LOG_ERROR, "insufficient VAR_1\n"); return AVERROR_INVALIDDATA; } bytestream2_init(&gb, VAR_4, MIMIC_HEADER_SIZE); bytestream2_skip(&gb, 2); VAR_10    = bytestream2_get_le16u(&gb); VAR_8      = bytestream2_get_le16u(&gb); VAR_9     = bytestream2_get_le16u(&gb); bytestream2_skip(&gb, 4); VAR_7  = bytestream2_get_le32u(&gb); VAR_11 = bytestream2_get_byteu(&gb); bytestream2_skip(&gb, 3); if (!ctx->VAR_0) { int VAR_13; if (!(VAR_8 == 160 && VAR_9 == 120) &&
!(VAR_8 == 320 && VAR_9 == 240)) { av_log(VAR_0, AV_LOG_ERROR, "invalid VAR_8/VAR_9!\n"); return AVERROR_INVALIDDATA; } ctx->VAR_0     = VAR_0; VAR_0->VAR_8   = VAR_8; VAR_0->VAR_9  = VAR_9; VAR_0->pix_fmt = AV_PIX_FMT_YUV420P; for (VAR_13 = 0; VAR_13 < 3; VAR_13++) { ctx->num_vblocks[VAR_13] = AV_CEIL_RSHIFT(VAR_9,   3 + !!VAR_13); ctx->num_hblocks[VAR_13] =                VAR_8 >> (3 + !!VAR_13); } } else if (VAR_8 != ctx->VAR_0->VAR_8 || VAR_9 != ctx->VAR_0->VAR_9) { avpriv_request_sample(VAR_0, "Resolution changing"); return AVERROR_PATCHWELCOME; } if (VAR_7 && !ctx->frames[ctx->prev_index].f->VAR_1[0]) { av_log(VAR_0, AV_LOG_ERROR, "decoding must start with keyframe\n"); return AVERROR_INVALIDDATA; } ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]); ctx->frames[ctx->cur_index].f->pict_type = VAR_7 ? AV_PICTURE_TYPE_P :
AV_PICTURE_TYPE_I; if ((VAR_12 = ff_thread_get_buffer(VAR_0, &ctx->frames[ctx->cur_index],
AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n"); return VAR_12; } ctx->next_prev_index = ctx->cur_index; ctx->next_cur_index  = (ctx->cur_index - 1) & 15; ff_thread_finish_setup(VAR_0); av_fast_padded_malloc(&ctx->swap_buf, &ctx->VAR_6, VAR_6); if (!ctx->swap_buf)
return AVERROR(ENOMEM); ctx->bbdsp.bswap_buf(ctx->swap_buf,
(const uint32_t *) (VAR_4 + MIMIC_HEADER_SIZE),
VAR_6 >> 2); init_get_bits(&ctx->gb, ctx->swap_buf, VAR_6 << 3); VAR_12 = decode(ctx, VAR_10, VAR_11, !VAR_7); ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0); if (VAR_12 < 0) { if (!(VAR_0->active_thread_type & FF_THREAD_FRAME))
ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]); return VAR_12; } if ((VAR_12 = av_frame_ref(VAR_1, ctx->frames[ctx->cur_index].f)) < 0)
return VAR_12; *VAR_2      = 1; flip_swap_frame(VAR_1); ctx->prev_index = ctx->next_prev_index; ctx->cur_index  = ctx->next_cur_index; ff_thread_release_buffer(VAR_0, &ctx->frames[ctx->cur_index]); return VAR_5; }