void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx)

{

    mm_flags = mm_support();

    if (avctx->dsp_mask) {

        if (avctx->dsp_mask & FF_MM_FORCE)

            mm_flags |= (avctx->dsp_mask & 0xffff);

        else

            mm_flags &= ~(avctx->dsp_mask & 0xffff);

    }

#if 0

    av_log(avctx, AV_LOG_INFO, "libavcodec: CPU flags:");

    if (mm_flags & MM_MMX)

        av_log(avctx, AV_LOG_INFO, " mmx");

    if (mm_flags & MM_MMXEXT)

        av_log(avctx, AV_LOG_INFO, " mmxext");

    if (mm_flags & MM_3DNOW)

        av_log(avctx, AV_LOG_INFO, " 3dnow");

    if (mm_flags & MM_SSE)

        av_log(avctx, AV_LOG_INFO, " sse");

    if (mm_flags & MM_SSE2)

        av_log(avctx, AV_LOG_INFO, " sse2");

    av_log(avctx, AV_LOG_INFO, "\n");

#endif

    if (mm_flags & MM_MMX) {

        const int idct_algo= avctx->idct_algo;

#ifdef CONFIG_ENCODERS

        const int dct_algo = avctx->dct_algo;

        if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){

            if(mm_flags & MM_SSE2){

                c->fdct = ff_fdct_sse2;

            }else if(mm_flags & MM_MMXEXT){

                c->fdct = ff_fdct_mmx2;

            }else{

                c->fdct = ff_fdct_mmx;

            }

        }

#endif //CONFIG_ENCODERS

        if(avctx->lowres==0){

            if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SIMPLEMMX){

                c->idct_put= ff_simple_idct_put_mmx;

                c->idct_add= ff_simple_idct_add_mmx;

                c->idct    = ff_simple_idct_mmx;

                c->idct_permutation_type= FF_SIMPLE_IDCT_PERM;

#ifdef CONFIG_GPL

            }else if(idct_algo==FF_IDCT_LIBMPEG2MMX){

                if(mm_flags & MM_MMXEXT){

                    c->idct_put= ff_libmpeg2mmx2_idct_put;

                    c->idct_add= ff_libmpeg2mmx2_idct_add;

                    c->idct    = ff_mmxext_idct;

                }else{

                    c->idct_put= ff_libmpeg2mmx_idct_put;

                    c->idct_add= ff_libmpeg2mmx_idct_add;

                    c->idct    = ff_mmx_idct;

                }

                c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;

#endif

            }else if((ENABLE_VP3_DECODER || ENABLE_VP5_DECODER || ENABLE_VP6_DECODER) &&

                     idct_algo==FF_IDCT_VP3 &&

                     avctx->codec->id!=CODEC_ID_THEORA &&

                     !(avctx->flags & CODEC_FLAG_BITEXACT)){

                if(mm_flags & MM_SSE2){

                    c->idct_put= ff_vp3_idct_put_sse2;

                    c->idct_add= ff_vp3_idct_add_sse2;

                    c->idct    = ff_vp3_idct_sse2;

                    c->idct_permutation_type= FF_TRANSPOSE_IDCT_PERM;

                }else{

                    ff_vp3_dsp_init_mmx();

                    c->idct_put= ff_vp3_idct_put_mmx;

                    c->idct_add= ff_vp3_idct_add_mmx;

                    c->idct    = ff_vp3_idct_mmx;

                    c->idct_permutation_type= FF_PARTTRANS_IDCT_PERM;

                }

            }else if(idct_algo==FF_IDCT_CAVS){

                    c->idct_permutation_type= FF_TRANSPOSE_IDCT_PERM;

            }else if(idct_algo==FF_IDCT_XVIDMMX){

                if(mm_flags & MM_MMXEXT){

                    c->idct_put= ff_idct_xvid_mmx2_put;

                    c->idct_add= ff_idct_xvid_mmx2_add;

                    c->idct    = ff_idct_xvid_mmx2;

                }else{

                    c->idct_put= ff_idct_xvid_mmx_put;

                    c->idct_add= ff_idct_xvid_mmx_add;

                    c->idct    = ff_idct_xvid_mmx;

                }

            }

        }

#ifdef CONFIG_ENCODERS

        c->get_pixels = get_pixels_mmx;

        c->diff_pixels = diff_pixels_mmx;

#endif //CONFIG_ENCODERS

        c->put_pixels_clamped = put_pixels_clamped_mmx;

        c->put_signed_pixels_clamped = put_signed_pixels_clamped_mmx;

        c->add_pixels_clamped = add_pixels_clamped_mmx;

        c->clear_blocks = clear_blocks_mmx;

#ifdef CONFIG_ENCODERS

        c->pix_sum = pix_sum16_mmx;

#endif //CONFIG_ENCODERS

        c->put_pixels_tab[0][0] = put_pixels16_mmx;

        c->put_pixels_tab[0][1] = put_pixels16_x2_mmx;

        c->put_pixels_tab[0][2] = put_pixels16_y2_mmx;

        c->put_pixels_tab[0][3] = put_pixels16_xy2_mmx;

        c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mmx;

        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmx;

        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmx;

        c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_mmx;

        c->avg_pixels_tab[0][0] = avg_pixels16_mmx;

        c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmx;

        c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmx;

        c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx;

        c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_mmx;

        c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_mmx;

        c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_mmx;

        c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_mmx;

        c->put_pixels_tab[1][0] = put_pixels8_mmx;

        c->put_pixels_tab[1][1] = put_pixels8_x2_mmx;

        c->put_pixels_tab[1][2] = put_pixels8_y2_mmx;

        c->put_pixels_tab[1][3] = put_pixels8_xy2_mmx;

        c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mmx;

        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmx;

        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx;

        c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_mmx;

        c->avg_pixels_tab[1][0] = avg_pixels8_mmx;

        c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx;

        c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx;

        c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx;

        c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_mmx;

        c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x2_mmx;

        c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y2_mmx;

        c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy2_mmx;

        c->gmc= gmc_mmx;

        c->add_bytes= add_bytes_mmx;

#ifdef CONFIG_ENCODERS

        c->diff_bytes= diff_bytes_mmx;

        c->sum_abs_dctelem= sum_abs_dctelem_mmx;

        c->hadamard8_diff[0]= hadamard8_diff16_mmx;

        c->hadamard8_diff[1]= hadamard8_diff_mmx;

        c->pix_norm1 = pix_norm1_mmx;

        c->sse[0] = (mm_flags & MM_SSE2) ? sse16_sse2 : sse16_mmx;

          c->sse[1] = sse8_mmx;

        c->vsad[4]= vsad_intra16_mmx;

        c->nsse[0] = nsse16_mmx;

        c->nsse[1] = nsse8_mmx;

        if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

            c->vsad[0] = vsad16_mmx;

        }

        if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

            c->try_8x8basis= try_8x8basis_mmx;

        }

        c->add_8x8basis= add_8x8basis_mmx;

        c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx;

#endif //CONFIG_ENCODERS

        if (ENABLE_ANY_H263) {

            c->h263_v_loop_filter= h263_v_loop_filter_mmx;

            c->h263_h_loop_filter= h263_h_loop_filter_mmx;

        }

        c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_mmx;

        c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_mmx;

        c->h264_idct_dc_add=

        c->h264_idct_add= ff_h264_idct_add_mmx;

        c->h264_idct8_dc_add=

        c->h264_idct8_add= ff_h264_idct8_add_mmx;

        if (mm_flags & MM_MMXEXT) {

            c->prefetch = prefetch_mmx2;

            c->put_pixels_tab[0][1] = put_pixels16_x2_mmx2;

            c->put_pixels_tab[0][2] = put_pixels16_y2_mmx2;

            c->avg_pixels_tab[0][0] = avg_pixels16_mmx2;

            c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmx2;

            c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmx2;

            c->put_pixels_tab[1][1] = put_pixels8_x2_mmx2;

            c->put_pixels_tab[1][2] = put_pixels8_y2_mmx2;

            c->avg_pixels_tab[1][0] = avg_pixels8_mmx2;

            c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx2;

            c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx2;

#ifdef CONFIG_ENCODERS

            c->sum_abs_dctelem= sum_abs_dctelem_mmx2;

            c->hadamard8_diff[0]= hadamard8_diff16_mmx2;

            c->hadamard8_diff[1]= hadamard8_diff_mmx2;

            c->vsad[4]= vsad_intra16_mmx2;

#endif //CONFIG_ENCODERS

            c->h264_idct_dc_add= ff_h264_idct_dc_add_mmx2;

            c->h264_idct8_dc_add= ff_h264_idct8_dc_add_mmx2;

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmx2;

                c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmx2;

                c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmx2;

                c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx2;

                c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx2;

                c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx2;

#ifdef CONFIG_ENCODERS

                c->vsad[0] = vsad16_mmx2;

#endif //CONFIG_ENCODERS

            }

#if 1

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_mmx2)

            SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_mmx2)

#endif

//FIXME 3dnow too

#define dspfunc(PFX, IDX, NUM) \

    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_mmx2; \

    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_mmx2; \

    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_mmx2; \

    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_mmx2; \

    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_mmx2; \

    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_mmx2; \

    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_mmx2; \

    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_mmx2

            dspfunc(put_h264_qpel, 0, 16);

            dspfunc(put_h264_qpel, 1, 8);

            dspfunc(put_h264_qpel, 2, 4);

            dspfunc(avg_h264_qpel, 0, 16);

            dspfunc(avg_h264_qpel, 1, 8);

            dspfunc(avg_h264_qpel, 2, 4);

            dspfunc(put_2tap_qpel, 0, 16);

            dspfunc(put_2tap_qpel, 1, 8);

            dspfunc(avg_2tap_qpel, 0, 16);

            dspfunc(avg_2tap_qpel, 1, 8);

#undef dspfunc

            c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_mmx2;

            c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_mmx2;

            c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_mmx2;

            c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_mmx2;

            c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_mmx2;

            c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_mmx2;

            c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_mmx2;

            c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_mmx2;

            c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_mmx2;

            c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_mmx2;

            c->h264_loop_filter_strength= h264_loop_filter_strength_mmx2;

            c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_mmx2;

            c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_mmx2;

            c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_mmx2;

            c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_mmx2;

            c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_mmx2;

            c->weight_h264_pixels_tab[5]= ff_h264_weight_4x8_mmx2;

            c->weight_h264_pixels_tab[6]= ff_h264_weight_4x4_mmx2;

            c->weight_h264_pixels_tab[7]= ff_h264_weight_4x2_mmx2;

            c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_mmx2;

            c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_mmx2;

            c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_mmx2;

            c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_mmx2;

            c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_mmx2;

            c->biweight_h264_pixels_tab[5]= ff_h264_biweight_4x8_mmx2;

            c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2;

            c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2;

#ifdef CONFIG_CAVS_DECODER

            ff_cavsdsp_init_mmx2(c, avctx);

#endif

#ifdef CONFIG_ENCODERS

            c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2;

#endif //CONFIG_ENCODERS

        } else if (mm_flags & MM_3DNOW) {

            c->prefetch = prefetch_3dnow;

            c->put_pixels_tab[0][1] = put_pixels16_x2_3dnow;

            c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow;

            c->avg_pixels_tab[0][0] = avg_pixels16_3dnow;

            c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow;

            c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow;

            c->put_pixels_tab[1][1] = put_pixels8_x2_3dnow;

            c->put_pixels_tab[1][2] = put_pixels8_y2_3dnow;

            c->avg_pixels_tab[1][0] = avg_pixels8_3dnow;

            c->avg_pixels_tab[1][1] = avg_pixels8_x2_3dnow;

            c->avg_pixels_tab[1][2] = avg_pixels8_y2_3dnow;

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow;

                c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow;

                c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_3dnow;

                c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_3dnow;

                c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow;

                c->avg_pixels_tab[1][3] = avg_pixels8_xy2_3dnow;

            }

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_3dnow)

            SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_3dnow)

#define dspfunc(PFX, IDX, NUM) \

    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_3dnow; \

    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_3dnow; \

    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_3dnow; \

    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_3dnow; \

    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_3dnow; \

    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_3dnow; \

    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_3dnow; \

    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_3dnow

            dspfunc(put_h264_qpel, 0, 16);

            dspfunc(put_h264_qpel, 1, 8);

            dspfunc(put_h264_qpel, 2, 4);

            dspfunc(avg_h264_qpel, 0, 16);

            dspfunc(avg_h264_qpel, 1, 8);

            dspfunc(avg_h264_qpel, 2, 4);

            dspfunc(put_2tap_qpel, 0, 16);

            dspfunc(put_2tap_qpel, 1, 8);

            dspfunc(avg_2tap_qpel, 0, 16);

            dspfunc(avg_2tap_qpel, 1, 8);

            c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_3dnow;

            c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_3dnow;

        }

#ifdef CONFIG_ENCODERS

        if(mm_flags & MM_SSE2){

            c->sum_abs_dctelem= sum_abs_dctelem_sse2;

            c->hadamard8_diff[0]= hadamard8_diff16_sse2;

            c->hadamard8_diff[1]= hadamard8_diff_sse2;

        }

#ifdef HAVE_SSSE3

        if(mm_flags & MM_SSSE3){

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->try_8x8basis= try_8x8basis_ssse3;

            }

            c->add_8x8basis= add_8x8basis_ssse3;

            c->sum_abs_dctelem= sum_abs_dctelem_ssse3;

            c->hadamard8_diff[0]= hadamard8_diff16_ssse3;

            c->hadamard8_diff[1]= hadamard8_diff_ssse3;

        }

#endif

#endif

#ifdef CONFIG_SNOW_DECODER

#if 0

        if(mm_flags & MM_SSE2){

            c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;

            c->vertical_compose97i = ff_snow_vertical_compose97i_sse2;

            c->inner_add_yblock = ff_snow_inner_add_yblock_sse2;

        }

        else{

            c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx;

            c->vertical_compose97i = ff_snow_vertical_compose97i_mmx;

            c->inner_add_yblock = ff_snow_inner_add_yblock_mmx;

        }

#endif

#endif

        if(mm_flags & MM_3DNOW){

#ifdef CONFIG_ENCODERS

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->try_8x8basis= try_8x8basis_3dnow;

            }

            c->add_8x8basis= add_8x8basis_3dnow;

#endif //CONFIG_ENCODERS

            c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;

            c->vector_fmul = vector_fmul_3dnow;

            if(!(avctx->flags & CODEC_FLAG_BITEXACT))

                c->float_to_int16 = float_to_int16_3dnow;

        }

        if(mm_flags & MM_3DNOWEXT)

            c->vector_fmul_reverse = vector_fmul_reverse_3dnow2;

        if(mm_flags & MM_SSE){

            c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse;

            c->vector_fmul = vector_fmul_sse;

            c->float_to_int16 = float_to_int16_sse;

            c->vector_fmul_reverse = vector_fmul_reverse_sse;

            c->vector_fmul_add_add = vector_fmul_add_add_sse;

        }

        if(mm_flags & MM_3DNOW)

            c->vector_fmul_add_add = vector_fmul_add_add_3dnow; // faster than sse

    }

#ifdef CONFIG_ENCODERS

    dsputil_init_pix_mmx(c, avctx);

#endif //CONFIG_ENCODERS

#if 0

    // for speed testing

    get_pixels = just_return;

    put_pixels_clamped = just_return;

    add_pixels_clamped = just_return;

    pix_abs16x16 = just_return;

    pix_abs16x16_x2 = just_return;

    pix_abs16x16_y2 = just_return;

    pix_abs16x16_xy2 = just_return;

    put_pixels_tab[0] = just_return;

    put_pixels_tab[1] = just_return;

    put_pixels_tab[2] = just_return;

    put_pixels_tab[3] = just_return;

    put_no_rnd_pixels_tab[0] = just_return;

    put_no_rnd_pixels_tab[1] = just_return;

    put_no_rnd_pixels_tab[2] = just_return;

    put_no_rnd_pixels_tab[3] = just_return;

    avg_pixels_tab[0] = just_return;

    avg_pixels_tab[1] = just_return;

    avg_pixels_tab[2] = just_return;

    avg_pixels_tab[3] = just_return;

    avg_no_rnd_pixels_tab[0] = just_return;

    avg_no_rnd_pixels_tab[1] = just_return;

    avg_no_rnd_pixels_tab[2] = just_return;

    avg_no_rnd_pixels_tab[3] = just_return;

    //av_fdct = just_return;

    //ff_idct = just_return;

#endif

}


static int nppscale_resize(AVFilterContext *ctx, NPPScaleStageContext *stage,

                           AVFrame *out, AVFrame *in)

{

    NPPScaleContext *s = ctx->priv;

    NppStatus err;

    int i;

    for (i = 0; i < FF_ARRAY_ELEMS(in->data) && in->data[i]; i++) {

        int iw = stage->planes_in[i].width;

        int ih = stage->planes_in[i].height;

        int ow = stage->planes_out[i].width;

        int oh = stage->planes_out[i].height;

        err = nppiResizeSqrPixel_8u_C1R(in->data[i], (NppiSize){ iw, ih },

                                        in->linesize[i], (NppiRect){ 0, 0, iw, ih },

                                        out->data[i], out->linesize[i],

                                        (NppiRect){ 0, 0, ow, oh },

                                        (double)ow / iw, (double)oh / ih,

                                        0.0, 0.0, s->interp_algo);

        if (err != NPP_SUCCESS) {

            av_log(ctx, AV_LOG_ERROR, "NPP resize error: %d\n", err);

            return AVERROR_UNKNOWN;

        }

    }

    return 0;

}


static int init_report(const char *env)

{

    const char *filename_template = "%p-%t.log";

    char *key, *val;

    int ret, count = 0;

    time_t now;

    struct tm *tm;

    AVBPrint filename;

    if (report_file) /* already opened */

        return 0;

    time(&now);

    tm = localtime(&now);

    while (env && *env) {

        if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {

            if (count)

                av_log(NULL, AV_LOG_ERROR,

                       "Failed to parse FFREPORT environment variable: %s\n",

                       av_err2str(ret));

            break;

        }

        if (*env)

            env++;

        count++;

        if (!strcmp(key, "file")) {

            filename_template = val;

            val = NULL;

        } else {

            av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);

        }

        av_free(val);

        av_free(key);

    }

    av_bprint_init(&filename, 0, 1);

    expand_filename_template(&filename, filename_template, tm);

    if (!av_bprint_is_complete(&filename)) {

        av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");

        return AVERROR(ENOMEM);

    }

    report_file = fopen(filename.str, "w");

    if (!report_file) {

        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",

               filename.str, strerror(errno));

        return AVERROR(errno);

    }

    av_log_set_callback(log_callback_report);

    av_log(NULL, AV_LOG_INFO,

           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"

           "Report written to \"%s\"\n",

           program_name,

           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,

           tm->tm_hour, tm->tm_min, tm->tm_sec,

           filename.str);

    av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));

    av_bprint_finalize(&filename, NULL);

    return 0;

}


void apic_deliver_pic_intr(DeviceState *dev, int level)

{

    APICCommonState *s = APIC_COMMON(dev);

    if (level) {

        apic_local_deliver(s, APIC_LVT_LINT0);

    } else {

        uint32_t lvt = s->lvt[APIC_LVT_LINT0];

        switch ((lvt >> 8) & 7) {

        case APIC_DM_FIXED:

            if (!(lvt & APIC_LVT_LEVEL_TRIGGER))

                break;

            apic_reset_bit(s->irr, lvt & 0xff);

            /* fall through */

        case APIC_DM_EXTINT:

            cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_HARD);

            break;

        }

    }

}


void rgb15tobgr16(const uint8_t *src, uint8_t *dst, unsigned int src_size)

{

	unsigned i;

	unsigned num_pixels = src_size >> 1;

	for(i=0; i<num_pixels; i++)

	{

	    unsigned b,g,r;

	    register uint16_t rgb;

	    rgb = src[2*i];

	    r = rgb&0x1F;

	    g = (rgb&0x3E0)>>5;

	    b = (rgb&0x7C00)>>10;

	    dst[2*i] = (b&0x1F) | ((g&0x3F)<<5) | ((r&0x1F)<<11);

	}

}


static void vnc_connect(VncDisplay *vd, int csock, int skipauth)

{

    VncState *vs = g_malloc0(sizeof(VncState));

    int i;

    vs->csock = csock;

    if (skipauth) {

	vs->auth = VNC_AUTH_NONE;

#ifdef CONFIG_VNC_TLS

	vs->subauth = VNC_AUTH_INVALID;

#endif

    } else {

	vs->auth = vd->auth;

#ifdef CONFIG_VNC_TLS

	vs->subauth = vd->subauth;

#endif

    }

    vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));

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

        vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));

    }

    VNC_DEBUG("New client on socket %d\n", csock);

    dcl->idle = 0;

    socket_set_nonblock(vs->csock);

    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);

    vnc_client_cache_addr(vs);

    vnc_qmp_event(vs, QEVENT_VNC_CONNECTED);

    vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);

    vs->vd = vd;

    vs->ds = vd->ds;

    vs->last_x = -1;

    vs->last_y = -1;

    vs->as.freq = 44100;

    vs->as.nchannels = 2;

    vs->as.fmt = AUD_FMT_S16;

    vs->as.endianness = 0;

#ifdef CONFIG_VNC_THREAD

    qemu_mutex_init(&vs->output_mutex);

#endif

    QTAILQ_INSERT_HEAD(&vd->clients, vs, next);

    vga_hw_update();

    vnc_write(vs, "RFB 003.008\n", 12);

    vnc_flush(vs);

    vnc_read_when(vs, protocol_version, 12);

    reset_keys(vs);

    if (vs->vd->lock_key_sync)

        vs->led = qemu_add_led_event_handler(kbd_leds, vs);

    vs->mouse_mode_notifier.notify = check_pointer_type_change;

    qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);

    vnc_init_timer(vd);

    /* vs might be free()ed here */

}


void pcnet_h_reset(void *opaque)

{

    PCNetState *s = opaque;

    int i;

    uint16_t checksum;

    /* Initialize the PROM */

    memcpy(s->prom, s->conf.macaddr.a, 6);

    s->prom[12] = s->prom[13] = 0x00;

    s->prom[14] = s->prom[15] = 0x57;

    for (i = 0,checksum = 0; i < 16; i++)

        checksum += s->prom[i];

    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);

    s->bcr[BCR_MSRDA] = 0x0005;

    s->bcr[BCR_MSWRA] = 0x0005;

    s->bcr[BCR_MC   ] = 0x0002;

    s->bcr[BCR_LNKST] = 0x00c0;

    s->bcr[BCR_LED1 ] = 0x0084;

    s->bcr[BCR_LED2 ] = 0x0088;

    s->bcr[BCR_LED3 ] = 0x0090;

    s->bcr[BCR_FDC  ] = 0x0000;

    s->bcr[BCR_BSBC ] = 0x9001;

    s->bcr[BCR_EECAS] = 0x0002;

    s->bcr[BCR_SWS  ] = 0x0200;

    s->bcr[BCR_PLAT ] = 0xff06;

    pcnet_s_reset(s);

    pcnet_update_irq(s);

    pcnet_poll_timer(s);

}


void avformat_close_input(AVFormatContext **ps)

{

    AVFormatContext *s = *ps;

    AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?

                       NULL : s->pb;

    flush_packet_queue(s);

    if (s->iformat->read_close)

        s->iformat->read_close(s);

    avformat_free_context(s);

    *ps = NULL;

    if (pb)

        avio_close(pb);

}


static int decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             uint8_t *buf, int buf_size)

{

    H264Context *h = avctx->priv_data;

    MpegEncContext *s = &h->s;

    AVFrame *pict = data;

    int buf_index;

    s->flags= avctx->flags;

    s->flags2= avctx->flags2;

   /* no supplementary picture */

    if (buf_size == 0) {

        return 0;

    }

    if(s->flags&CODEC_FLAG_TRUNCATED){

        int next= find_frame_end(h, buf, buf_size);

        if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )

            return buf_size;

//printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index);

    }

    if(h->is_avc && !h->got_avcC) {

        int i, cnt, nalsize;

        unsigned char *p = avctx->extradata;

        if(avctx->extradata_size < 7) {

            av_log(avctx, AV_LOG_ERROR, "avcC too short\n");

            return -1;

        }

        if(*p != 1) {

            av_log(avctx, AV_LOG_ERROR, "Unknown avcC version %d\n", *p);

            return -1;

        }

        /* sps and pps in the avcC always have length coded with 2 bytes,

           so put a fake nal_length_size = 2 while parsing them */

        h->nal_length_size = 2;

        // Decode sps from avcC

        cnt = *(p+5) & 0x1f; // Number of sps

        p += 6;

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

            nalsize = BE_16(p) + 2;

            if(decode_nal_units(h, p, nalsize) < 0) {

                av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i);

                return -1;

            }

            p += nalsize;

        }

        // Decode pps from avcC

        cnt = *(p++); // Number of pps

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

            nalsize = BE_16(p) + 2;

            if(decode_nal_units(h, p, nalsize)  != nalsize) {

                av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i);

                return -1;

            }

            p += nalsize;

        }

        // Now store right nal length size, that will be use to parse all other nals

        h->nal_length_size = ((*(((char*)(avctx->extradata))+4))&0x03)+1;

        // Do not reparse avcC

        h->got_avcC = 1;

    }

    if(!h->is_avc && s->avctx->extradata_size && s->picture_number==0){

        if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0)

            return -1;

    }

    buf_index=decode_nal_units(h, buf, buf_size);

    if(buf_index < 0)

        return -1;

    //FIXME do something with unavailable reference frames

//    if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_index, buf_size);

    if(!s->current_picture_ptr){

        av_log(h->s.avctx, AV_LOG_DEBUG, "error, NO frame\n");

        return -1;

    }

    {

        Picture *out = s->current_picture_ptr;

#if 0 //decode order

        *data_size = sizeof(AVFrame);

#else

        /* Sort B-frames into display order */

        Picture *cur = s->current_picture_ptr;

        Picture *prev = h->delayed_output_pic;

        int out_idx = 0;

        int pics = 0;

        int out_of_order;

        int cross_idr = 0;

        int dropped_frame = 0;

        int i;

        if(h->sps.bitstream_restriction_flag

           && s->avctx->has_b_frames < h->sps.num_reorder_frames){

            s->avctx->has_b_frames = h->sps.num_reorder_frames;

            s->low_delay = 0;

        }

        while(h->delayed_pic[pics]) pics++;

        h->delayed_pic[pics++] = cur;

        if(cur->reference == 0)

            cur->reference = 1;

        for(i=0; h->delayed_pic[i]; i++)

            if(h->delayed_pic[i]->key_frame || h->delayed_pic[i]->poc==0)

                cross_idr = 1;

        out = h->delayed_pic[0];

        for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame; i++)

            if(h->delayed_pic[i]->poc < out->poc){

                out = h->delayed_pic[i];

                out_idx = i;

            }

        out_of_order = !cross_idr && prev && out->poc < prev->poc;

        if(prev && pics <= s->avctx->has_b_frames)

            out = prev;

        else if((out_of_order && pics-1 == s->avctx->has_b_frames && pics < 15)

           || (s->low_delay &&

            ((!cross_idr && prev && out->poc > prev->poc + 2)

             || cur->pict_type == B_TYPE)))

        {

            s->low_delay = 0;

            s->avctx->has_b_frames++;

            out = prev;

        }

        else if(out_of_order)

            out = prev;

        if(out_of_order || pics > s->avctx->has_b_frames){

            dropped_frame = (out != h->delayed_pic[out_idx]);

            for(i=out_idx; h->delayed_pic[i]; i++)

                h->delayed_pic[i] = h->delayed_pic[i+1];

        }

        if(prev == out && !dropped_frame)

            *data_size = 0;

        else

            *data_size = sizeof(AVFrame);

        if(prev && prev != out && prev->reference == 1)

            prev->reference = 0;

        h->delayed_output_pic = out;

#endif

        if(out)

            *pict= *(AVFrame*)out;

        else

            av_log(avctx, AV_LOG_DEBUG, "no picture\n");

    }

    assert(pict->data[0] || !*data_size);

    ff_print_debug_info(s, pict);

//printf("out %d\n", (int)pict->data[0]);

#if 0 //?

    /* Return the Picture timestamp as the frame number */

    /* we substract 1 because it is added on utils.c    */

    avctx->frame_number = s->picture_number - 1;

#endif

    return get_consumed_bytes(s, buf_index, buf_size);

}


int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,

                       AVInputFormat *fmt,

                       int buf_size,

                       AVFormatParameters *ap)

{

    int err, probe_size;

    AVProbeData probe_data, *pd = &probe_data;

    ByteIOContext *pb = NULL;

    pd->filename = "";

    if (filename)

        pd->filename = filename;

    pd->buf = NULL;

    pd->buf_size = 0;

    if (!fmt) {

        /* guess format if no file can be opened */

        fmt = av_probe_input_format(pd, 0);

    }

    /* Do not open file if the format does not need it. XXX: specific

       hack needed to handle RTSP/TCP */

    if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {

        /* if no file needed do not try to open one */

        if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0) {

            goto fail;

        }

        if (buf_size > 0) {

            url_setbufsize(pb, buf_size);

        }

        for(probe_size= PROBE_BUF_MIN; probe_size<=PROBE_BUF_MAX && !fmt; probe_size<<=1){

            int score= probe_size < PROBE_BUF_MAX ? AVPROBE_SCORE_MAX/4 : 0;

            /* read probe data */

            pd->buf= av_realloc(pd->buf, probe_size + AVPROBE_PADDING_SIZE);

            pd->buf_size = get_buffer(pb, pd->buf, probe_size);

            memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);

            if (url_fseek(pb, 0, SEEK_SET) < 0) {

                url_fclose(pb);

                if (url_fopen(&pb, filename, URL_RDONLY) < 0) {

                    pb = NULL;

                    err = AVERROR(EIO);

                    goto fail;

                }

            }

            /* guess file format */

            fmt = av_probe_input_format2(pd, 1, &score);

        }

        av_freep(&pd->buf);

    }

    /* if still no format found, error */

    if (!fmt) {

        err = AVERROR_NOFMT;

        goto fail;

    }

    /* check filename in case an image number is expected */

    if (fmt->flags & AVFMT_NEEDNUMBER) {

        if (!av_filename_number_test(filename)) {

            err = AVERROR_NUMEXPECTED;

            goto fail;

        }

    }

    err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);

    if (err)

        goto fail;

    return 0;

 fail:

    av_freep(&pd->buf);

    if (pb)

        url_fclose(pb);

    *ic_ptr = NULL;

    return err;

}


static void digic_load_rom(DigicBoardState *s, hwaddr addr,

                           hwaddr max_size, const char *def_filename)

{

    target_long rom_size;

    const char *filename;

    if (qtest_enabled()) {

        /* qtest runs no code so don't attempt a ROM load which

         * could fail and result in a spurious test failure.

         */

        return;

    }

    if (bios_name) {

        filename = bios_name;

    } else {

        filename = def_filename;

    }

    if (filename) {

        char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);

        if (!fn) {

            error_report("Couldn't find rom image '%s'.", filename);

            exit(1);

        }

        rom_size = load_image_targphys(fn, addr, max_size);

        if (rom_size < 0 || rom_size > max_size) {

            error_report("Couldn't load rom image '%s'.", filename);

            exit(1);

        }

    }

}


static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,

                                   AVCodecContext *avctx)

{

    HEVCParserContext *ctx = s->priv_data;

    GetBitContext *gb = &nal->gb;

    HEVCPPS *pps;

    HEVCSPS *sps;

    unsigned int pps_id;

    get_bits1(gb);          // first slice in pic

    if (IS_IRAP_NAL(nal))

        get_bits1(gb);      // no output of prior pics

    pps_id = get_ue_golomb_long(gb);

    if (pps_id >= HEVC_MAX_PPS_COUNT || !ctx->ps.pps_list[pps_id]) {

        av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);

        return AVERROR_INVALIDDATA;

    }

    pps = (HEVCPPS*)ctx->ps.pps_list[pps_id]->data;

    sps = (HEVCSPS*)ctx->ps.sps_list[pps->sps_id]->data;

    /* export the stream parameters */

    s->coded_width  = sps->width;

    s->coded_height = sps->height;

    s->width        = sps->output_width;

    s->height       = sps->output_height;

    s->format       = sps->pix_fmt;

    avctx->profile  = sps->ptl.general_ptl.profile_idc;

    avctx->level    = sps->ptl.general_ptl.level_idc;

    /* ignore the rest for now*/

    return 0;

}


void helper_store_msr(CPUPPCState *env, target_ulong val)

{

    uint32_t excp = hreg_store_msr(env, val, 0);

    if (excp != 0) {

        CPUState *cs = CPU(ppc_env_get_cpu(env));

        cs->interrupt_request |= CPU_INTERRUPT_EXITTB;

        raise_exception(env, excp);

    }

}


static int do_qsv_decode(AVCodecContext *avctx, QSVContext *q,

                  AVFrame *frame, int *got_frame,

                  AVPacket *avpkt)

{

    QSVFrame *out_frame;

    mfxFrameSurface1 *insurf;

    mfxFrameSurface1 *outsurf;

    mfxSyncPoint *sync;

    mfxBitstream bs = { { { 0 } } };

    int ret;

    int n_out_frames;

    int buffered = 0;

    int flush    = !avpkt->size || q->reinit_pending;

    if (!q->engine_ready) {

        ret = qsv_decode_init(avctx, q, avpkt);

        if (ret)

            return ret;

    }

    if (!flush) {

        if (av_fifo_size(q->input_fifo)) {

            /* we have got rest of previous packet into buffer */

            if (av_fifo_space(q->input_fifo) < avpkt->size) {

                ret = av_fifo_grow(q->input_fifo, avpkt->size);

                if (ret < 0)

                    return ret;

            }

            av_fifo_generic_write(q->input_fifo, avpkt->data, avpkt->size, NULL);

            bs.Data       = q->input_fifo->rptr;

            bs.DataLength = av_fifo_size(q->input_fifo);

            buffered = 1;

        } else {

            bs.Data       = avpkt->data;

            bs.DataLength = avpkt->size;

        }

        bs.MaxLength  = bs.DataLength;

        bs.TimeStamp  = avpkt->pts;

    }

    sync = av_mallocz(sizeof(*sync));

    if (!sync) {

        av_freep(&sync);

        return AVERROR(ENOMEM);

    }

    while (1) {

        ret = get_surface(avctx, q, &insurf);

        if (ret < 0)

            return ret;

        do {

            ret = MFXVideoDECODE_DecodeFrameAsync(q->session, flush ? NULL : &bs,

                                                  insurf, &outsurf, sync);

            if (ret != MFX_WRN_DEVICE_BUSY)

                break;

            av_usleep(500);

        } while (1);

        if (MFX_WRN_VIDEO_PARAM_CHANGED==ret) {

            /* TODO: handle here minor sequence header changing */

        } else if (MFX_ERR_INCOMPATIBLE_VIDEO_PARAM==ret) {

            av_fifo_reset(q->input_fifo);

            flush = q->reinit_pending = 1;

            continue;

        }

        if (*sync) {

            QSVFrame *out_frame = find_frame(q, outsurf);

            if (!out_frame) {

                av_freep(&sync);

                av_log(avctx, AV_LOG_ERROR,

                       "The returned surface does not correspond to any frame\n");

                return AVERROR_BUG;

            }

            out_frame->queued = 1;

            av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);

            av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);

            continue;

        } else {

            av_freep(&sync);

        }

        if (MFX_ERR_MORE_SURFACE != ret && ret < 0)

            break;

    }

    /* make sure we do not enter an infinite loop if the SDK

     * did not consume any data and did not return anything */

    if (!*sync && !bs.DataOffset && !flush) {

        av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");

        bs.DataOffset = avpkt->size;

    }

    if (buffered) {

        qsv_fifo_relocate(q->input_fifo, bs.DataOffset);

    } else if (bs.DataOffset!=avpkt->size) {

        /* some data of packet was not consumed. store it to local buffer */

        av_fifo_generic_write(q->input_fifo, avpkt->data+bs.DataOffset,

                              avpkt->size - bs.DataOffset, NULL);

    }

    if (MFX_ERR_MORE_DATA!=ret && ret < 0) {

        av_freep(&sync);

        av_log(avctx, AV_LOG_ERROR, "Error %d during QSV decoding.\n", ret);

        return ff_qsv_error(ret);

    }

    n_out_frames = av_fifo_size(q->async_fifo) / (sizeof(out_frame)+sizeof(sync));

    if (n_out_frames > q->async_depth || (flush && n_out_frames) ) {

        AVFrame *src_frame;

        av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);

        av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);

        out_frame->queued = 0;

        do {

            ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);

        } while (ret == MFX_WRN_IN_EXECUTION);

        av_freep(&sync);

        src_frame = out_frame->frame;

        ret = av_frame_ref(frame, src_frame);

        if (ret < 0)

            return ret;

        outsurf = out_frame->surface;

        frame->pkt_pts = frame->pts = outsurf->Data.TimeStamp;

        frame->repeat_pict =

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;

        frame->top_field_first =

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;

        frame->interlaced_frame =

            !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);

        *got_frame = 1;

    }

    return avpkt->size;

}


static int local_rename(FsContext *ctx, const char *oldpath,

                        const char *newpath)

{

    int err;

    char *buffer, *buffer1;

    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {

        err = local_create_mapped_attr_dir(ctx, newpath);

        if (err < 0) {

            return err;

        }

        /* rename the .virtfs_metadata files */

        buffer = local_mapped_attr_path(ctx, oldpath);

        buffer1 = local_mapped_attr_path(ctx, newpath);

        err = rename(buffer, buffer1);

        g_free(buffer);

        g_free(buffer1);

        if (err < 0 && errno != ENOENT) {

            return err;

        }

    }

    buffer = rpath(ctx, oldpath);

    buffer1 = rpath(ctx, newpath);

    err = rename(buffer, buffer1);

    g_free(buffer);

    g_free(buffer1);

    return err;

}


static int16_t long_term_filter(DSPContext *dsp, int pitch_delay_int,

                                const int16_t* residual, int16_t *residual_filt,

                                int subframe_size)

{

    int i, k, tmp, tmp2;

    int sum;

    int L_temp0;

    int L_temp1;

    int64_t L64_temp0;

    int64_t L64_temp1;

    int16_t shift;

    int corr_int_num, corr_int_den;

    int ener;

    int16_t sh_ener;

    int16_t gain_num,gain_den; //selected signal's gain numerator and denominator

    int16_t sh_gain_num, sh_gain_den;

    int gain_num_square;

    int16_t gain_long_num,gain_long_den; //filtered through long interpolation filter signal's gain numerator and denominator

    int16_t sh_gain_long_num, sh_gain_long_den;

    int16_t best_delay_int, best_delay_frac;

    int16_t delayed_signal_offset;

    int lt_filt_factor_a, lt_filt_factor_b;

    int16_t * selected_signal;

    const int16_t * selected_signal_const; //Necessary to avoid compiler warning

    int16_t sig_scaled[SUBFRAME_SIZE + RES_PREV_DATA_SIZE];

    int16_t delayed_signal[ANALYZED_FRAC_DELAYS][SUBFRAME_SIZE+1];

    int corr_den[ANALYZED_FRAC_DELAYS][2];

    tmp = 0;

    for(i=0; i<subframe_size + RES_PREV_DATA_SIZE; i++)

        tmp |= FFABS(residual[i]);

    if(!tmp)

        shift = 3;

    else

        shift = av_log2(tmp) - 11;

    if (shift > 0)

        for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++)

            sig_scaled[i] = residual[i] >> shift;

    else

        for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++)

            sig_scaled[i] = residual[i] << -shift;

    /* Start of best delay searching code */

    gain_num = 0;

    ener = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE,

                                    sig_scaled + RES_PREV_DATA_SIZE,

                                    subframe_size);

    if (ener) {

        sh_ener = FFMAX(av_log2(ener) - 14, 0);

        ener >>= sh_ener;

        /* Search for best pitch delay.

                       sum{ r(n) * r(k,n) ] }^2

           R'(k)^2 := -------------------------

                       sum{ r(k,n) * r(k,n) }

           R(T)    :=  sum{ r(n) * r(n-T) ] }

           where

           r(n-T) is integer delayed signal with delay T

           r(k,n) is non-integer delayed signal with integer delay best_delay

           and fractional delay k */

        /* Find integer delay best_delay which maximizes correlation R(T).

           This is also equals to numerator of R'(0),

           since the fine search (second step) is done with 1/8

           precision around best_delay. */

        corr_int_num = 0;

        best_delay_int = pitch_delay_int - 1;

        for (i = pitch_delay_int - 1; i <= pitch_delay_int + 1; i++) {

            sum = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE,

                                           sig_scaled + RES_PREV_DATA_SIZE - i,

                                           subframe_size);

            if (sum > corr_int_num) {

                corr_int_num = sum;

                best_delay_int = i;

            }

        }

        if (corr_int_num) {

            /* Compute denominator of pseudo-normalized correlation R'(0). */

            corr_int_den = dsp->scalarproduct_int16(sig_scaled - best_delay_int + RES_PREV_DATA_SIZE,

                                                    sig_scaled - best_delay_int + RES_PREV_DATA_SIZE,

                                                    subframe_size);

            /* Compute signals with non-integer delay k (with 1/8 precision),

               where k is in [0;6] range.

               Entire delay is qual to best_delay+(k+1)/8

               This is archieved by applying an interpolation filter of

               legth 33 to source signal. */

            for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {

                ff_acelp_interpolate(&delayed_signal[k][0],

                                     &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int],

                                     ff_g729_interp_filt_short,

                                     ANALYZED_FRAC_DELAYS+1,

                                     8 - k - 1,

                                     SHORT_INT_FILT_LEN,

                                     subframe_size + 1);

            }

            /* Compute denominator of pseudo-normalized correlation R'(k).

                 corr_den[k][0] is square root of R'(k) denominator, for int(T) == int(T0)

                 corr_den[k][1] is square root of R'(k) denominator, for int(T) == int(T0)+1

              Also compute maximum value of above denominators over all k. */

            tmp = corr_int_den;

            for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {

                sum = dsp->scalarproduct_int16(&delayed_signal[k][1],

                                               &delayed_signal[k][1],

                                               subframe_size - 1);

                corr_den[k][0] = sum + delayed_signal[k][0            ] * delayed_signal[k][0            ];

                corr_den[k][1] = sum + delayed_signal[k][subframe_size] * delayed_signal[k][subframe_size];

                tmp = FFMAX3(tmp, corr_den[k][0], corr_den[k][1]);

            }

            sh_gain_den = av_log2(tmp) - 14;

            if (sh_gain_den >= 0) {

                sh_gain_num =  FFMAX(sh_gain_den, sh_ener);

                /* Loop through all k and find delay that maximizes

                   R'(k) correlation.

                   Search is done in [int(T0)-1; intT(0)+1] range

                   with 1/8 precision. */

                delayed_signal_offset = 1;

                best_delay_frac = 0;

                gain_den = corr_int_den >> sh_gain_den;

                gain_num = corr_int_num >> sh_gain_num;

                gain_num_square = gain_num * gain_num;

                for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {

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

                        int16_t gain_num_short, gain_den_short;

                        int gain_num_short_square;

                        /* Compute numerator of pseudo-normalized

                           correlation R'(k). */

                        sum = dsp->scalarproduct_int16(&delayed_signal[k][i],

                                                       sig_scaled + RES_PREV_DATA_SIZE,

                                                       subframe_size);

                        gain_num_short = FFMAX(sum >> sh_gain_num, 0);

                        /*

                                      gain_num_short_square                gain_num_square

                           R'(T)^2 = -----------------------, max R'(T)^2= --------------

                                           den                                 gain_den

                        */

                        gain_num_short_square = gain_num_short * gain_num_short;

                        gain_den_short = corr_den[k][i] >> sh_gain_den;

                        tmp = MULL(gain_num_short_square, gain_den, FRAC_BITS);

                        tmp2 = MULL(gain_num_square, gain_den_short, FRAC_BITS);

                        // R'(T)^2 > max R'(T)^2

                        if (tmp > tmp2) {

                            gain_num = gain_num_short;

                            gain_den = gain_den_short;

                            gain_num_square = gain_num_short_square;

                            delayed_signal_offset = i;

                            best_delay_frac = k + 1;

                        }

                    }

                }

                /*

                       R'(T)^2

                  2 * --------- < 1

                        R(0)

                */

                L64_temp0 =  (int64_t)gain_num_square  << ((sh_gain_num << 1) + 1);

                L64_temp1 = ((int64_t)gain_den * ener) << (sh_gain_den + sh_ener);

                if (L64_temp0 < L64_temp1)

                    gain_num = 0;

            } // if(sh_gain_den >= 0)

        } // if(corr_int_num)

    } // if(ener)

    /* End of best delay searching code  */

    if (!gain_num) {

        memcpy(residual_filt, residual + RES_PREV_DATA_SIZE, subframe_size * sizeof(int16_t));

        /* Long-term prediction gain is less than 3dB. Long-term postfilter is disabled. */

        return 0;

    }

    if (best_delay_frac) {

        /* Recompute delayed signal with an interpolation filter of length 129. */

        ff_acelp_interpolate(residual_filt,

                             &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int + delayed_signal_offset],

                             ff_g729_interp_filt_long,

                             ANALYZED_FRAC_DELAYS + 1,

                             8 - best_delay_frac,

                             LONG_INT_FILT_LEN,

                             subframe_size + 1);

        /* Compute R'(k) correlation's numerator. */

        sum = dsp->scalarproduct_int16(residual_filt,

                                       sig_scaled + RES_PREV_DATA_SIZE,

                                       subframe_size);

        if (sum < 0) {

            gain_long_num = 0;

            sh_gain_long_num = 0;

        } else {

            tmp = FFMAX(av_log2(sum) - 14, 0);

            sum >>= tmp;

            gain_long_num = sum;

            sh_gain_long_num = tmp;

        }

        /* Compute R'(k) correlation's denominator. */

        sum = dsp->scalarproduct_int16(residual_filt, residual_filt, subframe_size);

        tmp = FFMAX(av_log2(sum) - 14, 0);

        sum >>= tmp;

        gain_long_den = sum;

        sh_gain_long_den = tmp;

        /* Select between original and delayed signal.

           Delayed signal will be selected if it increases R'(k)

           correlation. */

        L_temp0 = gain_num * gain_num;

        L_temp0 = MULL(L_temp0, gain_long_den, FRAC_BITS);

        L_temp1 = gain_long_num * gain_long_num;

        L_temp1 = MULL(L_temp1, gain_den, FRAC_BITS);

        tmp = ((sh_gain_long_num - sh_gain_num) << 1) - (sh_gain_long_den - sh_gain_den);

        if (tmp > 0)

            L_temp0 >>= tmp;

        else

            L_temp1 >>= -tmp;

        /* Check if longer filter increases the values of R'(k). */

        if (L_temp1 > L_temp0) {

            /* Select long filter. */

            selected_signal = residual_filt;

            gain_num = gain_long_num;

            gain_den = gain_long_den;

            sh_gain_num = sh_gain_long_num;

            sh_gain_den = sh_gain_long_den;

        } else

            /* Select short filter. */

            selected_signal = &delayed_signal[best_delay_frac-1][delayed_signal_offset];

        /* Rescale selected signal to original value. */

        if (shift > 0)

            for (i = 0; i < subframe_size; i++)

                selected_signal[i] <<= shift;

        else

            for (i = 0; i < subframe_size; i++)

                selected_signal[i] >>= -shift;

        /* necessary to avoid compiler warning */

        selected_signal_const = selected_signal;

    } // if(best_delay_frac)

    else

        selected_signal_const = residual + RES_PREV_DATA_SIZE - (best_delay_int + 1 - delayed_signal_offset);

#ifdef G729_BITEXACT

    tmp = sh_gain_num - sh_gain_den;

    if (tmp > 0)

        gain_den >>= tmp;

    else

        gain_num >>= -tmp;

    if (gain_num > gain_den)

        lt_filt_factor_a = MIN_LT_FILT_FACTOR_A;

    else {

        gain_num >>= 2;

        gain_den >>= 1;

        lt_filt_factor_a = (gain_den << 15) / (gain_den + gain_num);

    }

#else

    L64_temp0 = ((int64_t)gain_num) << (sh_gain_num - 1);

    L64_temp1 = ((int64_t)gain_den) << sh_gain_den;

    lt_filt_factor_a = FFMAX((L64_temp1 << 15) / (L64_temp1 + L64_temp0), MIN_LT_FILT_FACTOR_A);

#endif

    /* Filter through selected filter. */

    lt_filt_factor_b = 32767 - lt_filt_factor_a + 1;

    ff_acelp_weighted_vector_sum(residual_filt, residual + RES_PREV_DATA_SIZE,

                                 selected_signal_const,

                                 lt_filt_factor_a, lt_filt_factor_b,

                                 1<<14, 15, subframe_size);

    // Long-term prediction gain is larger than 3dB.

    return 1;

}


void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,
                         MemoryRegion *mr, uint64_t align, bool gap,
                         Error **errp)
{
    int slot;
    MachineState *machine = MACHINE(qdev_get_machine());
    PCDIMMDevice *dimm = PC_DIMM(dev);
    Error *local_err = NULL;
    uint64_t existing_dimms_capacity = 0;
    uint64_t addr;
    addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);
    if (local_err) {
    addr = pc_dimm_get_free_addr(hpms->base,
                                 memory_region_size(&hpms->mr),
                                 !addr ? NULL : &addr, align, gap,
                                 memory_region_size(mr), &local_err);
    if (local_err) {
    existing_dimms_capacity = pc_existing_dimms_capacity(&local_err);
    if (local_err) {
    if (existing_dimms_capacity + memory_region_size(mr) >
        machine->maxram_size - machine->ram_size) {
        error_setg(&local_err, "not enough space, currently 0x%" PRIx64
                   " in use of total hot pluggable 0x" RAM_ADDR_FMT,
                   existing_dimms_capacity,
                   machine->maxram_size - machine->ram_size);
    object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);
    if (local_err) {
    trace_mhp_pc_dimm_assigned_address(addr);
    slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, &local_err);
    if (local_err) {
    slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
                                 machine->ram_slots, &local_err);
    if (local_err) {
    object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &local_err);
    if (local_err) {
    trace_mhp_pc_dimm_assigned_slot(slot);
    if (kvm_enabled() && !kvm_has_free_slot(machine)) {
        error_setg(&local_err, "hypervisor has no free memory slots left");
    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);
    vmstate_register_ram(mr, dev);
    numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);
out:
    error_propagate(errp, local_err);


static int64_t asf_read_pts(AVFormatContext *s, int64_t *ppos, int stream_index)

{

    ASFContext *asf = s->priv_data;

    AVPacket pkt1, *pkt = &pkt1;

    int64_t pos= *ppos;

    int64_t pts;

    // ensure we are on the packet boundry

    assert(pos % asf->packet_size == 0);

    url_fseek(&s->pb, pos + s->data_offset, SEEK_SET);

    do{

        pos= url_ftell(&s->pb) - s->data_offset;

        asf_reset_header(s);

        if (av_read_frame(s, pkt) < 0)

    	    return AV_NOPTS_VALUE;

        pts= pkt->pts;

        av_free_packet(pkt);

    }while(pkt->stream_index != stream_index);

    *ppos= pos;

    return pts;

}


static void serial_reset(void *opaque)

{

    SerialState *s = opaque;

    s->divider = 0;

    s->rbr = 0;

    s->ier = 0;

    s->iir = UART_IIR_NO_INT;

    s->lcr = 0;

    s->mcr = 0;

    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;

    s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;

    s->scr = 0;

    s->thr_ipending = 0;

    s->last_break_enable = 0;

    qemu_irq_lower(s->irq);

}


static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,

                                    uint16_t insn_hw1, int *is_branch)

{

    int32_t offset;

    uint16_t insn;

    int rt, rs, rd, rr;

    int16_t imm;

    uint32_t op, minor, mips32_op;

    uint32_t cond, fmt, cc;

    insn = lduw_code(ctx->pc + 2);

    ctx->opcode = (ctx->opcode << 16) | insn;

    rt = (ctx->opcode >> 21) & 0x1f;

    rs = (ctx->opcode >> 16) & 0x1f;

    rd = (ctx->opcode >> 11) & 0x1f;

    rr = (ctx->opcode >> 6) & 0x1f;

    imm = (int16_t) ctx->opcode;

    op = (ctx->opcode >> 26) & 0x3f;

    switch (op) {

    case POOL32A:

        minor = ctx->opcode & 0x3f;

        switch (minor) {

        case 0x00:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

            case SLL32:

                mips32_op = OPC_SLL;

                goto do_shifti;

            case SRA:

                mips32_op = OPC_SRA;

                goto do_shifti;

            case SRL32:

                mips32_op = OPC_SRL;

                goto do_shifti;

            case ROTR:

                mips32_op = OPC_ROTR;

            do_shifti:

                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case 0x10:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

                /* Arithmetic */

            case ADD:

                mips32_op = OPC_ADD;

                goto do_arith;

            case ADDU32:

                mips32_op = OPC_ADDU;

                goto do_arith;

            case SUB:

                mips32_op = OPC_SUB;

                goto do_arith;

            case SUBU32:

                mips32_op = OPC_SUBU;

                goto do_arith;

            case MUL:

                mips32_op = OPC_MUL;

            do_arith:

                gen_arith(env, ctx, mips32_op, rd, rs, rt);

                break;

                /* Shifts */

            case SLLV:

                mips32_op = OPC_SLLV;

                goto do_shift;

            case SRLV:

                mips32_op = OPC_SRLV;

                goto do_shift;

            case SRAV:

                mips32_op = OPC_SRAV;

                goto do_shift;

            case ROTRV:

                mips32_op = OPC_ROTRV;

            do_shift:

                gen_shift(env, ctx, mips32_op, rd, rs, rt);

                break;

                /* Logical operations */

            case AND:

                mips32_op = OPC_AND;

                goto do_logic;

            case OR32:

                mips32_op = OPC_OR;

                goto do_logic;

            case NOR:

                mips32_op = OPC_NOR;

                goto do_logic;

            case XOR32:

                mips32_op = OPC_XOR;

            do_logic:

                gen_logic(env, mips32_op, rd, rs, rt);

                break;

                /* Set less than */

            case SLT:

                mips32_op = OPC_SLT;

                goto do_slt;

            case SLTU:

                mips32_op = OPC_SLTU;

            do_slt:

                gen_slt(env, mips32_op, rd, rs, rt);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case 0x18:

            minor = (ctx->opcode >> 6) & 0xf;

            switch (minor) {

                /* Conditional moves */

            case MOVN:

                mips32_op = OPC_MOVN;

                goto do_cmov;

            case MOVZ:

                mips32_op = OPC_MOVZ;

            do_cmov:

                gen_cond_move(env, mips32_op, rd, rs, rt);

                break;

            case LWXS:

                gen_ldxs(ctx, rs, rt, rd);

                break;

            default:

                goto pool32a_invalid;

            }

            break;

        case INS:

            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);

            return;

        case EXT:

            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);

            return;

        case POOL32AXF:

            gen_pool32axf(env, ctx, rt, rs, is_branch);

            break;

        case 0x07:

            generate_exception(ctx, EXCP_BREAK);

            break;

        default:

        pool32a_invalid:

                MIPS_INVAL("pool32a");

                generate_exception(ctx, EXCP_RI);

                break;

        }

        break;

    case POOL32B:

        minor = (ctx->opcode >> 12) & 0xf;

        switch (minor) {

        case CACHE:

            /* Treat as no-op. */

            break;

        case LWC2:

        case SWC2:

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

            break;

        case LWP:

        case SWP:

#ifdef TARGET_MIPS64

        case LDP:

        case SDP:

#endif

            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        case LWM32:

        case SWM32:

#ifdef TARGET_MIPS64

        case LDM:

        case SDM:

#endif

            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        default:

            MIPS_INVAL("pool32b");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case POOL32F:

        if (env->CP0_Config1 & (1 << CP0C1_FP)) {

            minor = ctx->opcode & 0x3f;

            check_cp1_enabled(ctx);

            switch (minor) {

            case ALNV_PS:

                mips32_op = OPC_ALNV_PS;

                goto do_madd;

            case MADD_S:

                mips32_op = OPC_MADD_S;

                goto do_madd;

            case MADD_D:

                mips32_op = OPC_MADD_D;

                goto do_madd;

            case MADD_PS:

                mips32_op = OPC_MADD_PS;

                goto do_madd;

            case MSUB_S:

                mips32_op = OPC_MSUB_S;

                goto do_madd;

            case MSUB_D:

                mips32_op = OPC_MSUB_D;

                goto do_madd;

            case MSUB_PS:

                mips32_op = OPC_MSUB_PS;

                goto do_madd;

            case NMADD_S:

                mips32_op = OPC_NMADD_S;

                goto do_madd;

            case NMADD_D:

                mips32_op = OPC_NMADD_D;

                goto do_madd;

            case NMADD_PS:

                mips32_op = OPC_NMADD_PS;

                goto do_madd;

            case NMSUB_S:

                mips32_op = OPC_NMSUB_S;

                goto do_madd;

            case NMSUB_D:

                mips32_op = OPC_NMSUB_D;

                goto do_madd;

            case NMSUB_PS:

                mips32_op = OPC_NMSUB_PS;

            do_madd:

                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);

                break;

            case CABS_COND_FMT:

                cond = (ctx->opcode >> 6) & 0xf;

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 10) & 0x3;

                switch (fmt) {

                case 0x0:

                    gen_cmpabs_s(ctx, cond, rt, rs, cc);

                    break;

                case 0x1:

                    gen_cmpabs_d(ctx, cond, rt, rs, cc);

                    break;

                case 0x2:

                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case C_COND_FMT:

                cond = (ctx->opcode >> 6) & 0xf;

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 10) & 0x3;

                switch (fmt) {

                case 0x0:

                    gen_cmp_s(ctx, cond, rt, rs, cc);

                    break;

                case 0x1:

                    gen_cmp_d(ctx, cond, rt, rs, cc);

                    break;

                case 0x2:

                    gen_cmp_ps(ctx, cond, rt, rs, cc);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case POOL32FXF:

                gen_pool32fxf(env, ctx, rt, rs);

                break;

            case 0x00:

                /* PLL foo */

                switch ((ctx->opcode >> 6) & 0x7) {

                case PLL_PS:

                    mips32_op = OPC_PLL_PS;

                    goto do_ps;

                case PLU_PS:

                    mips32_op = OPC_PLU_PS;

                    goto do_ps;

                case PUL_PS:

                    mips32_op = OPC_PUL_PS;

                    goto do_ps;

                case PUU_PS:

                    mips32_op = OPC_PUU_PS;

                    goto do_ps;

                case CVT_PS_S:

                    mips32_op = OPC_CVT_PS_S;

                do_ps:

                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x08:

                /* [LS][WDU]XC1 */

                switch ((ctx->opcode >> 6) & 0x7) {

                case LWXC1:

                    mips32_op = OPC_LWXC1;

                    goto do_ldst_cp1;

                case SWXC1:

                    mips32_op = OPC_SWXC1;

                    goto do_ldst_cp1;

                case LDXC1:

                    mips32_op = OPC_LDXC1;

                    goto do_ldst_cp1;

                case SDXC1:

                    mips32_op = OPC_SDXC1;

                    goto do_ldst_cp1;

                case LUXC1:

                    mips32_op = OPC_LUXC1;

                    goto do_ldst_cp1;

                case SUXC1:

                    mips32_op = OPC_SUXC1;

                do_ldst_cp1:

                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x18:

                /* 3D insns */

                fmt = (ctx->opcode >> 9) & 0x3;

                switch ((ctx->opcode >> 6) & 0x7) {

                case RSQRT2_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        mips32_op = OPC_RSQRT2_S;

                        goto do_3d;

                    case FMT_SDPS_D:

                        mips32_op = OPC_RSQRT2_D;

                        goto do_3d;

                    case FMT_SDPS_PS:

                        mips32_op = OPC_RSQRT2_PS;

                        goto do_3d;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case RECIP2_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        mips32_op = OPC_RECIP2_S;

                        goto do_3d;

                    case FMT_SDPS_D:

                        mips32_op = OPC_RECIP2_D;

                        goto do_3d;

                    case FMT_SDPS_PS:

                        mips32_op = OPC_RECIP2_PS;

                        goto do_3d;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case ADDR_PS:

                    mips32_op = OPC_ADDR_PS;

                    goto do_3d;

                case MULR_PS:

                    mips32_op = OPC_MULR_PS;

                do_3d:

                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x20:

                /* MOV[FT].fmt and PREFX */

                cc = (ctx->opcode >> 13) & 0x7;

                fmt = (ctx->opcode >> 9) & 0x3;

                switch ((ctx->opcode >> 6) & 0x7) {

                case MOVF_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        gen_movcf_s(rs, rt, cc, 0);

                        break;

                    case FMT_SDPS_D:

                        gen_movcf_d(ctx, rs, rt, cc, 0);

                        break;

                    case FMT_SDPS_PS:

                        gen_movcf_ps(rs, rt, cc, 0);

                        break;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case MOVT_FMT:

                    switch (fmt) {

                    case FMT_SDPS_S:

                        gen_movcf_s(rs, rt, cc, 1);

                        break;

                    case FMT_SDPS_D:

                        gen_movcf_d(ctx, rs, rt, cc, 1);

                        break;

                    case FMT_SDPS_PS:

                        gen_movcf_ps(rs, rt, cc, 1);

                        break;

                    default:

                        goto pool32f_invalid;

                    }

                    break;

                case PREFX:

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

#define FINSN_3ARG_SDPS(prfx)                           \

                switch ((ctx->opcode >> 8) & 0x3) {     \

                case FMT_SDPS_S:                        \

                    mips32_op = OPC_##prfx##_S;         \

                    goto do_fpop;                       \

                case FMT_SDPS_D:                        \

                    mips32_op = OPC_##prfx##_D;         \

                    goto do_fpop;                       \

                case FMT_SDPS_PS:                       \

                    mips32_op = OPC_##prfx##_PS;        \

                    goto do_fpop;                       \

                default:                                \

                    goto pool32f_invalid;               \

                }

            case 0x30:

                /* regular FP ops */

                switch ((ctx->opcode >> 6) & 0x3) {

                case ADD_FMT:

                    FINSN_3ARG_SDPS(ADD);

                    break;

                case SUB_FMT:

                    FINSN_3ARG_SDPS(SUB);

                    break;

                case MUL_FMT:

                    FINSN_3ARG_SDPS(MUL);

                    break;

                case DIV_FMT:

                    fmt = (ctx->opcode >> 8) & 0x3;

                    if (fmt == 1) {

                        mips32_op = OPC_DIV_D;

                    } else if (fmt == 0) {

                        mips32_op = OPC_DIV_S;

                    } else {

                        goto pool32f_invalid;

                    }

                    goto do_fpop;

                default:

                    goto pool32f_invalid;

                }

                break;

            case 0x38:

                /* cmovs */

                switch ((ctx->opcode >> 6) & 0x3) {

                case MOVN_FMT:

                    FINSN_3ARG_SDPS(MOVN);

                    break;

                case MOVZ_FMT:

                    FINSN_3ARG_SDPS(MOVZ);

                    break;

                default:

                    goto pool32f_invalid;

                }

                break;

            do_fpop:

                gen_farith(ctx, mips32_op, rt, rs, rd, 0);

                break;

            default:

            pool32f_invalid:

                MIPS_INVAL("pool32f");

                generate_exception(ctx, EXCP_RI);

                break;

            }

        } else {

            generate_exception_err(ctx, EXCP_CpU, 1);

        }

        break;

    case POOL32I:

        minor = (ctx->opcode >> 21) & 0x1f;

        switch (minor) {

        case BLTZ:

            mips32_op = OPC_BLTZ;

            goto do_branch;

        case BLTZAL:

            mips32_op = OPC_BLTZAL;

            goto do_branch;

        case BLTZALS:

            mips32_op = OPC_BLTZALS;

            goto do_branch;

        case BGEZ:

            mips32_op = OPC_BGEZ;

            goto do_branch;

        case BGEZAL:

            mips32_op = OPC_BGEZAL;

            goto do_branch;

        case BGEZALS:

            mips32_op = OPC_BGEZALS;

            goto do_branch;

        case BLEZ:

            mips32_op = OPC_BLEZ;

            goto do_branch;

        case BGTZ:

            mips32_op = OPC_BGTZ;

        do_branch:

            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);

            *is_branch = 1;

            break;

            /* Traps */

        case TLTI:

            mips32_op = OPC_TLTI;

            goto do_trapi;

        case TGEI:

            mips32_op = OPC_TGEI;

            goto do_trapi;

        case TLTIU:

            mips32_op = OPC_TLTIU;

            goto do_trapi;

        case TGEIU:

            mips32_op = OPC_TGEIU;

            goto do_trapi;

        case TNEI:

            mips32_op = OPC_TNEI;

            goto do_trapi;

        case TEQI:

            mips32_op = OPC_TEQI;

        do_trapi:

            gen_trap(ctx, mips32_op, rs, -1, imm);

            break;

        case BNEZC:

        case BEQZC:

            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,

                               4, rs, 0, imm << 1);

            /* Compact branches don't have a delay slot, so just let

               the normal delay slot handling take us to the branch

               target. */

            break;

        case LUI:

            gen_logic_imm(env, OPC_LUI, rs, -1, imm);

            break;

        case SYNCI:

            break;

        case BC2F:

        case BC2T:

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

            break;

        case BC1F:

            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;

            goto do_cp1branch;

        case BC1T:

            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;

            goto do_cp1branch;

        case BC1ANY4F:

            mips32_op = OPC_BC1FANY4;

            goto do_cp1mips3d;

        case BC1ANY4T:

            mips32_op = OPC_BC1TANY4;

        do_cp1mips3d:

            check_cop1x(ctx);

            check_insn(env, ctx, ASE_MIPS3D);

            /* Fall through */

        do_cp1branch:

            gen_compute_branch1(env, ctx, mips32_op,

                                (ctx->opcode >> 18) & 0x7, imm << 1);

            *is_branch = 1;

            break;

        case BPOSGE64:

        case BPOSGE32:

            /* MIPS DSP: not implemented */

            /* Fall through */

        default:

            MIPS_INVAL("pool32i");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case POOL32C:

        minor = (ctx->opcode >> 12) & 0xf;

        switch (minor) {

        case LWL:

            mips32_op = OPC_LWL;

            goto do_ld_lr;

        case SWL:

            mips32_op = OPC_SWL;

            goto do_st_lr;

        case LWR:

            mips32_op = OPC_LWR;

            goto do_ld_lr;

        case SWR:

            mips32_op = OPC_SWR;

            goto do_st_lr;

#if defined(TARGET_MIPS64)

        case LDL:

            mips32_op = OPC_LDL;

            goto do_ld_lr;

        case SDL:

            mips32_op = OPC_SDL;

            goto do_st_lr;

        case LDR:

            mips32_op = OPC_LDR;

            goto do_ld_lr;

        case SDR:

            mips32_op = OPC_SDR;

            goto do_st_lr;

        case LWU:

            mips32_op = OPC_LWU;

            goto do_ld_lr;

        case LLD:

            mips32_op = OPC_LLD;

            goto do_ld_lr;

#endif

        case LL:

            mips32_op = OPC_LL;

            goto do_ld_lr;

        do_ld_lr:

            gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        do_st_lr:

            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

        case SC:

            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

#if defined(TARGET_MIPS64)

        case SCD:

            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));

            break;

#endif

        case PREF:

            /* Treat as no-op */

            break;

        default:

            MIPS_INVAL("pool32c");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case ADDI32:

        mips32_op = OPC_ADDI;

        goto do_addi;

    case ADDIU32:

        mips32_op = OPC_ADDIU;

    do_addi:

        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);

        break;

        /* Logical operations */

    case ORI32:

        mips32_op = OPC_ORI;

        goto do_logici;

    case XORI32:

        mips32_op = OPC_XORI;

        goto do_logici;

    case ANDI32:

        mips32_op = OPC_ANDI;

    do_logici:

        gen_logic_imm(env, mips32_op, rt, rs, imm);

        break;

        /* Set less than immediate */

    case SLTI32:

        mips32_op = OPC_SLTI;

        goto do_slti;

    case SLTIU32:

        mips32_op = OPC_SLTIU;

    do_slti:

        gen_slt_imm(env, mips32_op, rt, rs, imm);

        break;

    case JALX32:

        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;

        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);

        *is_branch = 1;

        break;

    case JALS32:

        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;

        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);

        *is_branch = 1;

        break;

    case BEQ32:

        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);

        *is_branch = 1;

        break;

    case BNE32:

        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);

        *is_branch = 1;

        break;

    case J32:

        gen_compute_branch(ctx, OPC_J, 4, rt, rs,

                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);

        *is_branch = 1;

        break;

    case JAL32:

        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,

                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);

        *is_branch = 1;

        break;

        /* Floating point (COP1) */

    case LWC132:

        mips32_op = OPC_LWC1;

        goto do_cop1;

    case LDC132:

        mips32_op = OPC_LDC1;

        goto do_cop1;

    case SWC132:

        mips32_op = OPC_SWC1;

        goto do_cop1;

    case SDC132:

        mips32_op = OPC_SDC1;

    do_cop1:

        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);

        break;

    case ADDIUPC:

        {

            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));

            int offset = SIMM(ctx->opcode, 0, 23) << 2;

            gen_addiupc(ctx, reg, offset, 0, 0);

        }

        break;

        /* Loads and stores */

    case LB32:

        mips32_op = OPC_LB;

        goto do_ld;

    case LBU32:

        mips32_op = OPC_LBU;

        goto do_ld;

    case LH32:

        mips32_op = OPC_LH;

        goto do_ld;

    case LHU32:

        mips32_op = OPC_LHU;

        goto do_ld;

    case LW32:

        mips32_op = OPC_LW;

        goto do_ld;

#ifdef TARGET_MIPS64

    case LD32:

        mips32_op = OPC_LD;

        goto do_ld;

    case SD32:

        mips32_op = OPC_SD;

        goto do_st;

#endif

    case SB32:

        mips32_op = OPC_SB;

        goto do_st;

    case SH32:

        mips32_op = OPC_SH;

        goto do_st;

    case SW32:

        mips32_op = OPC_SW;

        goto do_st;

    do_ld:

        gen_ld(env, ctx, mips32_op, rt, rs, imm);

        break;

    do_st:

        gen_st(ctx, mips32_op, rt, rs, imm);

        break;

    default:

        generate_exception(ctx, EXCP_RI);

        break;

    }

}


static int xmv_process_packet_header(AVFormatContext *s)

{

    XMVDemuxContext *xmv = s->priv_data;

    AVIOContext     *pb  = s->pb;

    uint8_t  data[8];

    uint16_t audio_track;

    uint64_t data_offset;

    /* Next packet size */

    xmv->next_packet_size = avio_rl32(pb);

    /* Packet video header */

    if (avio_read(pb, data, 8) != 8)

        return AVERROR(EIO);

    xmv->video.data_size     = AV_RL32(data) & 0x007FFFFF;

    xmv->video.current_frame = 0;

    xmv->video.frame_count   = (AV_RL32(data) >> 23) & 0xFF;

    xmv->video.has_extradata = (data[3] & 0x80) != 0;

    /* Adding the audio data sizes and the video data size keeps you 4 bytes

     * short for every audio track. But as playing around with XMV files with

     * ADPCM audio showed, taking the extra 4 bytes from the audio data gives

     * you either completely distorted audio or click (when skipping the

     * remaining 68 bytes of the ADPCM block). Subtracting 4 bytes for every

     * audio track from the video data works at least for the audio. Probably

     * some alignment thing?

     * The video data has (always?) lots of padding, so it should work out...

     */

    xmv->video.data_size -= xmv->audio_track_count * 4;

    xmv->current_stream = 0;

    if (!xmv->video.frame_count) {

        xmv->video.frame_count = 1;

        xmv->current_stream    = xmv->stream_count > 1;

    }

    /* Packet audio header */

    for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {

        XMVAudioPacket *packet = &xmv->audio[audio_track];

        if (avio_read(pb, data, 4) != 4)

            return AVERROR(EIO);

        packet->data_size = AV_RL32(data) & 0x007FFFFF;

        if ((packet->data_size == 0) && (audio_track != 0))

            /* This happens when I create an XMV with several identical audio

             * streams. From the size calculations, duplicating the previous

             * stream's size works out, but the track data itself is silent.

             * Maybe this should also redirect the offset to the previous track?

             */

            packet->data_size = xmv->audio[audio_track - 1].data_size;

        /* Carve up the audio data in frame_count slices */

        packet->frame_size  = packet->data_size  / xmv->video.frame_count;

        packet->frame_size -= packet->frame_size % packet->block_align;

    }

    /* Packet data offsets */

    data_offset = avio_tell(pb);

    xmv->video.data_offset = data_offset;

    data_offset += xmv->video.data_size;

    for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {

        xmv->audio[audio_track].data_offset = data_offset;

        data_offset += xmv->audio[audio_track].data_size;

    }

    /* Video frames header */

    /* Read new video extra data */

    if (xmv->video.data_size > 0) {

        if (xmv->video.has_extradata) {

            xmv_read_extradata(xmv->video.extradata, pb);

            xmv->video.data_size   -= 4;

            xmv->video.data_offset += 4;

            if (xmv->video.stream_index >= 0) {

                AVStream *vst = s->streams[xmv->video.stream_index];

                av_assert0(xmv->video.stream_index < s->nb_streams);

                if (vst->codec->extradata_size < 4) {

                    av_freep(&vst->codec->extradata);

                    ff_alloc_extradata(vst->codec, 4);

                }

                memcpy(vst->codec->extradata, xmv->video.extradata, 4);

            }

        }

    }

    return 0;

}


static av_cold int qtrle_decode_init(AVCodecContext *avctx)

{

    QtrleContext *s = avctx->priv_data;

    s->avctx = avctx;

    switch (avctx->bits_per_coded_sample) {

    case 1:

    case 33:

        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;

        break;

    case 2:

    case 4:

    case 8:

    case 34:

    case 36:

    case 40:

        avctx->pix_fmt = AV_PIX_FMT_PAL8;

        break;

    case 16:

        avctx->pix_fmt = AV_PIX_FMT_RGB555;

        break;

    case 24:

        avctx->pix_fmt = AV_PIX_FMT_RGB24;

        break;

    case 32:

        avctx->pix_fmt = AV_PIX_FMT_RGB32;

        break;

    default:

        av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",

            avctx->bits_per_coded_sample);

        return AVERROR_INVALIDDATA;

    }

    s->frame.data[0] = NULL;

    return 0;

}


static void fft_ref_init(int nbits, int inverse)

{

    int i, n = 1 << nbits;

    exptab = av_malloc((n / 2) * sizeof(*exptab));

    for (i = 0; i < (n/2); i++) {

        double alpha = 2 * M_PI * (float)i / (float)n;

        double c1 = cos(alpha), s1 = sin(alpha);

        if (!inverse)

            s1 = -s1;

        exptab[i].re = c1;

        exptab[i].im = s1;

    }

}


inline static int push_frame(AVFilterLink *outlink)

{

    AVFilterContext *ctx = outlink->src;

    AVFilterLink *inlink = ctx->inputs[0];

    ShowWavesContext *showwaves = outlink->src->priv;

    int nb_channels = inlink->channels;

    int ret, i;

    if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0)

        showwaves->req_fullfilled = 1;

    showwaves->outpicref = NULL;

    showwaves->buf_idx = 0;

    for (i = 0; i < nb_channels; i++)

        showwaves->buf_idy[i] = 0;

    return ret;

}


uint64_t helper_tick_get_count(void *opaque)

{

#if !defined(CONFIG_USER_ONLY)

    return cpu_tick_get_count(opaque);

#else

    return 0;

#endif

}


uint64_t helper_mulqv (uint64_t op1, uint64_t op2)

{

    uint64_t tl, th;

    muls64(&tl, &th, op1, op2);

    /* If th != 0 && th != -1, then we had an overflow */

    if (unlikely((th + 1) > 1)) {

        arith_excp(env, GETPC(), EXC_M_IOV, 0);

    }

    return tl;

}


static void dec_divu(DisasContext *dc)

{

    int l1;

    LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);

    if (!(dc->env->features & LM32_FEATURE_DIVIDE)) {

        cpu_abort(dc->env, "hardware divider is not available\n");

    }

    l1 = gen_new_label();

    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);

    tcg_gen_movi_tl(cpu_pc, dc->pc);

    t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);

    gen_set_label(l1);

    tcg_gen_divu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);

}


static void ffmpeg_cleanup(int ret)
{
    int i, j;
    if (do_benchmark) {
        int maxrss = getmaxrss() / 1024;
        av_log(NULL, AV_LOG_INFO, "bench: maxrss=%ikB\n", maxrss);
    }
    for (i = 0; i < nb_filtergraphs; i++) {
        FilterGraph *fg = filtergraphs[i];
        avfilter_graph_free(&fg->graph);
        for (j = 0; j < fg->nb_inputs; j++) {
            av_freep(&fg->inputs[j]->name);
            av_freep(&fg->inputs[j]);
        }
        av_freep(&fg->inputs);
        for (j = 0; j < fg->nb_outputs; j++) {
            av_freep(&fg->outputs[j]->name);
            av_freep(&fg->outputs[j]);
        }
        av_freep(&fg->outputs);
        av_freep(&fg->graph_desc);
        av_freep(&filtergraphs[i]);
    }
    av_freep(&filtergraphs);
    av_freep(&subtitle_out);
    /* close files */
    for (i = 0; i < nb_output_files; i++) {
        OutputFile *of = output_files[i];
        AVFormatContext *s;
        if (!of)
            continue;
        s = of->ctx;
        if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
            avio_closep(&s->pb);
        avformat_free_context(s);
        av_dict_free(&of->opts);
        av_freep(&output_files[i]);
    }
    for (i = 0; i < nb_output_streams; i++) {
        OutputStream *ost = output_streams[i];
        AVBitStreamFilterContext *bsfc;
        if (!ost)
            continue;
        bsfc = ost->bitstream_filters;
        while (bsfc) {
            AVBitStreamFilterContext *next = bsfc->next;
            av_bitstream_filter_close(bsfc);
            bsfc = next;
        }
        ost->bitstream_filters = NULL;
        av_frame_free(&ost->filtered_frame);
        av_frame_free(&ost->last_frame);
        av_parser_close(ost->parser);
        av_freep(&ost->forced_keyframes);
        av_expr_free(ost->forced_keyframes_pexpr);
        av_freep(&ost->avfilter);
        av_freep(&ost->logfile_prefix);
        av_freep(&ost->audio_channels_map);
        ost->audio_channels_mapped = 0;
        avcodec_free_context(&ost->enc_ctx);
        av_freep(&output_streams[i]);
    }
#if HAVE_PTHREADS
    free_input_threads();
#endif
    for (i = 0; i < nb_input_files; i++) {
        avformat_close_input(&input_files[i]->ctx);
        av_freep(&input_files[i]);
    }
    for (i = 0; i < nb_input_streams; i++) {
        InputStream *ist = input_streams[i];
        av_frame_free(&ist->decoded_frame);
        av_frame_free(&ist->filter_frame);
        av_dict_free(&ist->decoder_opts);
        avsubtitle_free(&ist->prev_sub.subtitle);
        av_frame_free(&ist->sub2video.frame);
        av_freep(&ist->filters);
        av_freep(&ist->hwaccel_device);
        avcodec_free_context(&ist->dec_ctx);
        av_freep(&input_streams[i]);
    }
    if (vstats_file) {
        if (fclose(vstats_file))
            av_log(NULL, AV_LOG_ERROR,
                   "Error closing vstats file, loss of information possible: %s\n",
                   av_err2str(AVERROR(errno)));
    }
    av_freep(&vstats_filename);
    av_freep(&input_streams);
    av_freep(&input_files);
    av_freep(&output_streams);
    av_freep(&output_files);
    uninit_opts();
    avformat_network_deinit();
    if (received_sigterm) {
        av_log(NULL, AV_LOG_INFO, "Exiting normally, received signal %d.\n",
               (int) received_sigterm);
    } else if (ret && transcode_init_done) {
        av_log(NULL, AV_LOG_INFO, "Conversion failed!\n");
    }
    term_exit();
    ffmpeg_exited = 1;
}


void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],

                   const uint8_t *src_data[4], const int src_linesizes[4],

                   enum PixelFormat pix_fmt, int width, int height)

{

    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];

    if (desc->flags & PIX_FMT_HWACCEL)

        return;

    if (desc->flags & PIX_FMT_PAL) {

        av_image_copy_plane(dst_data[0], dst_linesizes[0],

                            src_data[0], src_linesizes[0],

                            width, height);

        /* copy the palette */

        memcpy(dst_data[1], src_data[1], 4*256);

    } else {

        int i, planes_nb = 0;

        for (i = 0; i < desc->nb_components; i++)

            planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);

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

            int h = height;

            int bwidth = av_image_get_linesize(pix_fmt, width, i);

            if (i == 1 || i == 2) {

                h= -((-height)>>desc->log2_chroma_h);

            }

            av_image_copy_plane(dst_data[i], dst_linesizes[i],

                                src_data[i], src_linesizes[i],

                                bwidth, h);

        }

    }

}


static int webm_dash_manifest_cues(AVFormatContext *s)

{

    MatroskaDemuxContext *matroska = s->priv_data;

    EbmlList *seekhead_list = &matroska->seekhead;

    MatroskaSeekhead *seekhead = seekhead_list->elem;

    char *buf;

    int64_t cues_start = -1, cues_end = -1, before_pos, bandwidth;

    int i;

    // determine cues start and end positions

    for (i = 0; i < seekhead_list->nb_elem; i++)

        if (seekhead[i].id == MATROSKA_ID_CUES)

            break;

    if (i >= seekhead_list->nb_elem) return -1;

    before_pos = avio_tell(matroska->ctx->pb);

    cues_start = seekhead[i].pos + matroska->segment_start;

    if (avio_seek(matroska->ctx->pb, cues_start, SEEK_SET) == cues_start) {

        // cues_end is computed as cues_start + cues_length + length of the

        // Cues element ID + EBML length of the Cues element. cues_end is

        // inclusive and the above sum is reduced by 1.

        uint64_t cues_length = 0, cues_id = 0, bytes_read = 0;

        bytes_read += ebml_read_num(matroska, matroska->ctx->pb, 4, &cues_id);

        bytes_read += ebml_read_length(matroska, matroska->ctx->pb, &cues_length);

        cues_end = cues_start + cues_length + bytes_read - 1;

    }

    avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);

    if (cues_start == -1 || cues_end == -1) return -1;

    // parse the cues

    matroska_parse_cues(matroska);

    // cues start

    av_dict_set_int(&s->streams[0]->metadata, CUES_START, cues_start, 0);

    // cues end

    av_dict_set_int(&s->streams[0]->metadata, CUES_END, cues_end, 0);

    // bandwidth

    bandwidth = webm_dash_manifest_compute_bandwidth(s, cues_start);

    if (bandwidth < 0) return -1;

    av_dict_set_int(&s->streams[0]->metadata, BANDWIDTH, bandwidth, 0);

    // check if all clusters start with key frames

    av_dict_set_int(&s->streams[0]->metadata, CLUSTER_KEYFRAME, webm_clusters_start_with_keyframe(s), 0);

    // store cue point timestamps as a comma separated list for checking subsegment alignment in

    // the muxer. assumes that each timestamp cannot be more than 20 characters long.

    buf = av_malloc_array(s->streams[0]->nb_index_entries, 20 * sizeof(char));

    if (!buf) return -1;

    strcpy(buf, "");

    for (i = 0; i < s->streams[0]->nb_index_entries; i++) {

        snprintf(buf, (i + 1) * 20 * sizeof(char),

                 "%s%" PRId64, buf, s->streams[0]->index_entries[i].timestamp);

        if (i != s->streams[0]->nb_index_entries - 1)

            strncat(buf, ",", sizeof(char));

    }

    av_dict_set(&s->streams[0]->metadata, CUE_TIMESTAMPS, buf, 0);

    av_free(buf);

    return 0;

}


static void pxa2xx_screen_dump(void *opaque, const char *filename)

{

    /* TODO */

}