int ff_h264_decode_mb_cabac(const H264Context *h, H264SliceContext *sl)

{

    int mb_xy;

    int mb_type, partition_count, cbp = 0;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;

    const int pixel_shift = h->pixel_shift;

    mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;

    ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {

        int skip;

        /* a skipped mb needs the aff flag from the following mb */

        if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 1 && sl->prev_mb_skipped)

            skip = sl->next_mb_skipped;

        else

            skip = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y );

        /* read skip flags */

        if( skip ) {

            if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {

                h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP;

                sl->next_mb_skipped = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y+1 );

                if(!sl->next_mb_skipped)

                    sl->mb_mbaff = sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);

            }

            decode_mb_skip(h, sl);

            h->cbp_table[mb_xy] = 0;

            h->chroma_pred_mode_table[mb_xy] = 0;

            sl->last_qscale_diff = 0;

            return 0;

        }

    }

    if (FRAME_MBAFF(h)) {

        if ((sl->mb_y & 1) == 0)

            sl->mb_mbaff =

            sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);

    }

    sl->prev_mb_skipped = 0;

    fill_decode_neighbors(h, sl, -(MB_FIELD(sl)));

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {

        int ctx = 0;

        assert(sl->slice_type_nos == AV_PICTURE_TYPE_B);

        if (!IS_DIRECT(sl->left_type[LTOP] - 1))

            ctx++;

        if (!IS_DIRECT(sl->top_type - 1))

            ctx++;

        if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+ctx] ) ){

            mb_type= 0; /* B_Direct_16x16 */

        }else if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+3] ) ) {

            mb_type= 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ); /* B_L[01]_16x16 */

        }else{

            int bits;

            bits = get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+4] ) << 3;

            bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 2;

            bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 1;

            bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );

            if( bits < 8 ){

                mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */

            }else if( bits == 13 ){

                mb_type = decode_cabac_intra_mb_type(sl, 32, 0);

                goto decode_intra_mb;

            }else if( bits == 14 ){

                mb_type= 11; /* B_L1_L0_8x16 */

            }else if( bits == 15 ){

                mb_type= 22; /* B_8x8 */

            }else{

                bits= ( bits<<1 ) + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );

                mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */

            }

        }

            partition_count = ff_h264_b_mb_type_info[mb_type].partition_count;

            mb_type         = ff_h264_b_mb_type_info[mb_type].type;

    } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {

        if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[14] ) == 0 ) {

            /* P-type */

            if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[15] ) == 0 ) {

                /* P_L0_D16x16, P_8x8 */

                mb_type= 3 * get_cabac_noinline( &sl->cabac, &sl->cabac_state[16] );

            } else {

                /* P_L0_D8x16, P_L0_D16x8 */

                mb_type= 2 - get_cabac_noinline( &sl->cabac, &sl->cabac_state[17] );

            }

            partition_count = ff_h264_p_mb_type_info[mb_type].partition_count;

            mb_type         = ff_h264_p_mb_type_info[mb_type].type;

        } else {

            mb_type = decode_cabac_intra_mb_type(sl, 17, 0);

            goto decode_intra_mb;

        }

    } else {

        mb_type = decode_cabac_intra_mb_type(sl, 3, 1);

        if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)

            mb_type--;

        assert(sl->slice_type_nos == AV_PICTURE_TYPE_I);

decode_intra_mb:

        partition_count = 0;

        cbp                      = ff_h264_i_mb_type_info[mb_type].cbp;

        sl->intra16x16_pred_mode = ff_h264_i_mb_type_info[mb_type].pred_mode;

        mb_type                  = ff_h264_i_mb_type_info[mb_type].type;

    }

    if (MB_FIELD(sl))

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[mb_xy] = sl->slice_num;

    if(IS_INTRA_PCM(mb_type)) {

        const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *

                            h->sps.bit_depth_luma >> 3;

        const uint8_t *ptr;

        // We assume these blocks are very rare so we do not optimize it.

        // FIXME The two following lines get the bitstream position in the cabac

        // decode, I think it should be done by a function in cabac.h (or cabac.c).

        ptr= sl->cabac.bytestream;

        if(sl->cabac.low&0x1) ptr--;

        if(CABAC_BITS==16){

            if(sl->cabac.low&0x1FF) ptr--;

        }

        // The pixels are stored in the same order as levels in h->mb array.

        if ((int) (sl->cabac.bytestream_end - ptr) < mb_size)

            return -1;

        sl->intra_pcm_ptr = ptr;

        ptr += mb_size;

        ff_init_cabac_decoder(&sl->cabac, ptr, sl->cabac.bytestream_end - ptr);

        // All blocks are present

        h->cbp_table[mb_xy] = 0xf7ef;

        h->chroma_pred_mode_table[mb_xy] = 0;

        // In deblocking, the quantizer is 0

        h->cur_pic.qscale_table[mb_xy] = 0;

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 48);

        h->cur_pic.mb_type[mb_xy] = mb_type;

        sl->last_qscale_diff = 0;

        return 0;

    }

    fill_decode_caches(h, sl, mb_type);

    if( IS_INTRA( mb_type ) ) {

        int i, pred_mode;

        if( IS_INTRA4x4( mb_type ) ) {

            if (dct8x8_allowed && get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size])) {

                mb_type |= MB_TYPE_8x8DCT;

                for( i = 0; i < 16; i+=4 ) {

                    int pred = pred_intra_mode(h, sl, i);

                    int mode = decode_cabac_mb_intra4x4_pred_mode(sl, pred);

                    fill_rectangle(&sl->intra4x4_pred_mode_cache[scan8[i]], 2, 2, 8, mode, 1);

                }

            } else {

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

                    int pred = pred_intra_mode(h, sl, i);

                    sl->intra4x4_pred_mode_cache[scan8[i]] = decode_cabac_mb_intra4x4_pred_mode(sl, pred);

                    ff_dlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,

                            sl->intra4x4_pred_mode_cache[scan8[i]]);

                }

            }

            write_back_intra_pred_mode(h, sl);

            if (ff_h264_check_intra4x4_pred_mode(sl->intra4x4_pred_mode_cache, h->avctx,

                                                 sl->top_samples_available, sl->left_samples_available) < 0 )

                return -1;

        } else {

            sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h->avctx, sl->top_samples_available,

                                                                     sl->left_samples_available, sl->intra16x16_pred_mode, 0);

            if (sl->intra16x16_pred_mode < 0) return -1;

        }

        if(decode_chroma){

            h->chroma_pred_mode_table[mb_xy] =

            pred_mode                        = decode_cabac_mb_chroma_pre_mode(h, sl);

            pred_mode= ff_h264_check_intra_pred_mode(h->avctx, sl->top_samples_available,

                                                     sl->left_samples_available, pred_mode, 1 );

            if( pred_mode < 0 ) return -1;

            sl->chroma_pred_mode = pred_mode;

        } else {

            sl->chroma_pred_mode = DC_128_PRED8x8;

        }

    } else if( partition_count == 4 ) {

        int i, j, sub_partition_count[4], list, ref[2][4];

        if (sl->slice_type_nos == AV_PICTURE_TYPE_B ) {

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

                sl->sub_mb_type[i] = decode_cabac_b_mb_sub_type(sl);

                sub_partition_count[i] = ff_h264_b_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;

                sl->sub_mb_type[i]     = ff_h264_b_sub_mb_type_info[sl->sub_mb_type[i]].type;

            }

            if (IS_DIRECT(sl->sub_mb_type[0] | sl->sub_mb_type[1] |

                          sl->sub_mb_type[2] | sl->sub_mb_type[3])) {

                ff_h264_pred_direct_motion(h, sl, &mb_type);

                sl->ref_cache[0][scan8[4]] =

                sl->ref_cache[1][scan8[4]] =

                sl->ref_cache[0][scan8[12]] =

                sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;

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

                        fill_rectangle(&sl->direct_cache[scan8[4*i]], 2, 2, 8, (sl->sub_mb_type[i] >> 1) & 0xFF, 1);

            }

        } else {

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

                sl->sub_mb_type[i] = decode_cabac_p_mb_sub_type(sl);

                sub_partition_count[i] = ff_h264_p_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;

                sl->sub_mb_type[i]     = ff_h264_p_sub_mb_type_info[sl->sub_mb_type[i]].type;

            }

        }

        for( list = 0; list < sl->list_count; list++ ) {

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

                    if(IS_DIRECT(sl->sub_mb_type[i])) continue;

                    if(IS_DIR(sl->sub_mb_type[i], 0, list)){

                        int rc = sl->ref_count[list] << MB_MBAFF(sl);

                        if (rc > 1) {

                            ref[list][i] = decode_cabac_mb_ref(sl, list, 4 * i);

                            if (ref[list][i] >= (unsigned) rc) {

                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);

                                return -1;

                            }

                        }else

                            ref[list][i] = 0;

                    } else {

                        ref[list][i] = -1;

                    }

                    sl->ref_cache[list][scan8[4 * i] + 1] =

                    sl->ref_cache[list][scan8[4 * i] + 8] = sl->ref_cache[list][scan8[4 * i] + 9] = ref[list][i];

                }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h, sl);

        for (list = 0; list < sl->list_count; list++) {

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

                sl->ref_cache[list][scan8[4 * i]] = sl->ref_cache[list][scan8[4 * i] + 1];

                if(IS_DIRECT(sl->sub_mb_type[i])){

                    fill_rectangle(sl->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2);

                    continue;

                }

                if(IS_DIR(sl->sub_mb_type[i], 0, list) && !IS_DIRECT(sl->sub_mb_type[i])){

                    const int sub_mb_type= sl->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mpx, mpy;

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2] = &sl->mv_cache[list][ scan8[index] ];

                        uint8_t (* mvd_cache)[2]= &sl->mvd_cache[list][ scan8[index] ];

                        pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);

                        DECODE_CABAC_MB_MVD(sl, list, index)

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                            mvd_cache[ 1 ][0]=

                            mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mpx;

                            mvd_cache[ 1 ][1]=

                            mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= mpy;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                            mvd_cache[ 1 ][0]=  mpx;

                            mvd_cache[ 1 ][1]= mpy;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                            mvd_cache[ 8 ][0]= mpx;

                            mvd_cache[ 8 ][1]= mpy;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                        mvd_cache[ 0 ][0]= mpx;

                        mvd_cache[ 0 ][1]= mpy;

                    }

                }else{

                    fill_rectangle(sl->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4);

                    fill_rectangle(sl->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2);

                }

            }

        }

    } else if( IS_DIRECT(mb_type) ) {

        ff_h264_pred_direct_motion(h, sl, &mb_type);

        fill_rectangle(sl->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2);

        fill_rectangle(sl->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    } else {

        int list, i;

        if(IS_16X16(mb_type)){

            for (list = 0; list < sl->list_count; list++) {

                if(IS_DIR(mb_type, 0, list)){

                    int ref, rc = sl->ref_count[list] << MB_MBAFF(sl);

                    if (rc > 1) {

                        ref= decode_cabac_mb_ref(sl, list, 0);

                        if (ref >= (unsigned) rc) {

                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);

                            return -1;

                        }

                    }else

                        ref=0;

                    fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);

                }

            }

            for (list = 0; list < sl->list_count; list++) {

                if(IS_DIR(mb_type, 0, list)){

                    int mx,my,mpx,mpy;

                    pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);

                    DECODE_CABAC_MB_MVD(sl, list, 0)

                    ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                    fill_rectangle(sl->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);

                    fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }

            }

        }

        else if(IS_16X8(mb_type)){

            for (list = 0; list < sl->list_count; list++) {

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

                        if(IS_DIR(mb_type, i, list)){

                            int ref, rc = sl->ref_count[list] << MB_MBAFF(sl);

                            if (rc > 1) {

                                ref= decode_cabac_mb_ref(sl, list, 8 * i);

                                if (ref >= (unsigned) rc) {

                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);

                                    return -1;

                                }

                            }else

                                ref=0;

                            fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);

                        }else

                            fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for (list = 0; list < sl->list_count; list++) {

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

                    if(IS_DIR(mb_type, i, list)){

                        int mx,my,mpx,mpy;

                        pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);

                        DECODE_CABAC_MB_MVD(sl, list, 8*i)

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);

                        fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 2);

                        fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                    }

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for (list = 0; list < sl->list_count; list++) {

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

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            int ref, rc = sl->ref_count[list] << MB_MBAFF(sl);

                            if (rc > 1) {

                                ref = decode_cabac_mb_ref(sl, list, 4 * i);

                                if (ref >= (unsigned) rc) {

                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);

                                    return -1;

                                }

                            }else

                                ref=0;

                            fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);

                        }else

                            fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for (list = 0; list < sl->list_count; list++) {

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

                    if(IS_DIR(mb_type, i, list)){

                        int mx,my,mpx,mpy;

                        pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);

                        DECODE_CABAC_MB_MVD(sl, list, 4*i)

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);

                        fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 2);

                        fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                    }

                }

            }

        }

    }

   if( IS_INTER( mb_type ) ) {

        h->chroma_pred_mode_table[mb_xy] = 0;

        write_back_motion(h, sl, mb_type);

   }

    if( !IS_INTRA16x16( mb_type ) ) {

        cbp  = decode_cabac_mb_cbp_luma(sl);

        if(decode_chroma)

            cbp |= decode_cabac_mb_cbp_chroma(sl) << 4;

    }

    h->cbp_table[mb_xy] = sl->cbp = cbp;

    if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {

        mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size]);

    }

    /* It would be better to do this in fill_decode_caches, but we don't know

     * the transform mode of the current macroblock there. */

    if (CHROMA444(h) && IS_8x8DCT(mb_type)){

        int i;

        uint8_t *nnz_cache = sl->non_zero_count_cache;

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

            if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) {

                nnz_cache[3+8* 1 + 2*8*i]=

                nnz_cache[3+8* 2 + 2*8*i]=

                nnz_cache[3+8* 6 + 2*8*i]=

                nnz_cache[3+8* 7 + 2*8*i]=

                nnz_cache[3+8*11 + 2*8*i]=

                nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;

            }

        }

        if (sl->top_type && !IS_8x8DCT(sl->top_type)){

            uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;

            AV_WN32A(&nnz_cache[4+8* 0], top_empty);

            AV_WN32A(&nnz_cache[4+8* 5], top_empty);

            AV_WN32A(&nnz_cache[4+8*10], top_empty);

        }

    }

    h->cur_pic.mb_type[mb_xy] = mb_type;

    if( cbp || IS_INTRA16x16( mb_type ) ) {

        const uint8_t *scan, *scan8x8;

        const uint32_t *qmul;

        if(IS_INTERLACED(mb_type)){

            scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;

            scan    = sl->qscale ? h->field_scan : h->field_scan_q0;

        }else{

            scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;

            scan    = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

        }

        // decode_cabac_mb_dqp

        if(get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + (sl->last_qscale_diff != 0)])){

            int val = 1;

            int ctx= 2;

            const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);

            while( get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + ctx] ) ) {

                ctx= 3;

                val++;

                if(val > 2*max_qp){ //prevent infinite loop

                    av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", sl->mb_x, sl->mb_y);

                    return -1;

                }

            }

            if( val&0x01 )

                val=   (val + 1)>>1 ;

            else

                val= -((val + 1)>>1);

            sl->last_qscale_diff = val;

            sl->qscale += val;

            if (((unsigned)sl->qscale) > max_qp){

                if (sl->qscale < 0) sl->qscale += max_qp + 1;

                else                sl->qscale -= max_qp + 1;

            }

            sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);

            sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);

        }else

            sl->last_qscale_diff=0;

        decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 0);

        if (CHROMA444(h)) {

            decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 1);

            decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 2);

        } else if (CHROMA422(h)) {

            if( cbp&0x30 ){

                int c;

                for (c = 0; c < 2; c++)

                    decode_cabac_residual_dc_422(h, sl, sl->mb + ((256 + 16*16*c) << pixel_shift), 3,

                                                 CHROMA_DC_BLOCK_INDEX + c,

                                                 ff_h264_chroma422_dc_scan, 8);

            }

            if( cbp&0x20 ) {

                int c, i, i8x8;

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

                    int16_t *mb = sl->mb + (16*(16 + 16*c) << pixel_shift);

                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];

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

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

                            const int index = 16 + 16 * c + 8*i8x8 + i;

                            decode_cabac_residual_nondc(h, sl, mb, 4, index, scan + 1, qmul, 15);

                            mb += 16<<pixel_shift;

                        }

                    }

                }

            } else {

                fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        } else /* yuv420 */ {

            if( cbp&0x30 ){

                int c;

                for (c = 0; c < 2; c++)

                    decode_cabac_residual_dc(h, sl, sl->mb + ((256 + 16 * 16 * c) << pixel_shift),

                                             3, CHROMA_DC_BLOCK_INDEX + c, ff_h264_chroma_dc_scan, 4);

            }

            if( cbp&0x20 ) {

                int c, i;

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

                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];

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

                        const int index = 16 + 16 * c + i;

                        decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15);

                    }

                }

            } else {

                fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        }

    } else {

        fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);

        fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

        fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

        sl->last_qscale_diff = 0;

    }

    h->cur_pic.qscale_table[mb_xy] = sl->qscale;

    write_back_non_zero_count(h, sl);

    return 0;

}


static void vnc_refresh(DisplayChangeListener *dcl)

{

    VncDisplay *vd = container_of(dcl, VncDisplay, dcl);

    VncState *vs, *vn;

    int has_dirty, rects = 0;

    graphic_hw_update(NULL);

    if (vnc_trylock_display(vd)) {

        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);

        return;

    }

    has_dirty = vnc_refresh_server_surface(vd);

    vnc_unlock_display(vd);

    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {

        rects += vnc_update_client(vs, has_dirty);

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

    }

    if (QTAILQ_EMPTY(&vd->clients)) {

        update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);

        return;

    }

    if (has_dirty && rects) {

        vd->dcl.update_interval /= 2;

        if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {

            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;

        }

    } else {

        vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;

        if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {

            vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;

        }

    }

}


static int int_pow(int i, int *exp_ptr)

{

    int e, er, eq, j;

    int a, a1;

    /* renormalize */

    a = i;

    e = POW_FRAC_BITS;

    while (a < (1 << (POW_FRAC_BITS - 1))) {

        a = a << 1;

        e--;

    }

    a -= (1 << POW_FRAC_BITS);

    a1 = 0;

    for(j = DEV_ORDER - 1; j >= 0; j--)

        a1 = POW_MULL(a, dev_4_3_coefs[j] + a1);

    a = (1 << POW_FRAC_BITS) + a1;

    /* exponent compute (exact) */

    e = e * 4;

    er = e % 3;

    eq = e / 3;

    a = POW_MULL(a, pow_mult3[er]);

    while (a >= 2 * POW_FRAC_ONE) {

        a = a >> 1;

        eq++;

    }

    /* convert to float */

    while (a < POW_FRAC_ONE) {

        a = a << 1;

        eq--;

    }

    /* now POW_FRAC_ONE <= a < 2 * POW_FRAC_ONE */

#if (POW_FRAC_BITS - 1) > FRAC_BITS

    a = (a + (1 << (POW_FRAC_BITS - FRAC_BITS - 1))) >> (POW_FRAC_BITS - FRAC_BITS);

    /* correct overflow */

    if (a >= 2 * (1 << FRAC_BITS)) {

        a = a >> 1;

        eq++;

    }

#endif

    *exp_ptr = eq;

    return a;

}


int monitor_set_cpu(int cpu_index)

{

    CPUState *cpu;

    cpu = qemu_get_cpu(cpu_index);

    if (cpu == NULL) {

        return -1;

    }

    cur_mon->mon_cpu = cpu;

    return 0;

}


unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,

                                    const AVDXVAContext *ctx,

                                    const AVFrame *frame)

{

    void *surface = get_surface(frame);

    unsigned i;

    for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {

#if CONFIG_D3D11VA

        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD && ctx->d3d11va.surface[i] == surface)

        {

            D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;

            ID3D11VideoDecoderOutputView_GetDesc(ctx->d3d11va.surface[i], &viewDesc);

            return viewDesc.Texture2D.ArraySlice;

        }

#endif

#if CONFIG_DXVA2

        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)

            return i;

#endif

    }

    assert(0);

    return 0;

}


uint32_t HELPER(mul32)(CPUOpenRISCState *env,

                       uint32_t ra, uint32_t rb)

{

    uint64_t result;

    uint32_t high, cy;

    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);

    result = (uint64_t)ra * rb;

    /* regisiers in or32 is 32bit, so 32 is NOT a magic number.

       or64 is not handled in this function, and not implement yet,

       TARGET_LONG_BITS for or64 is 64, it will break this function,

       so, we didn't use TARGET_LONG_BITS here.  */

    high = result >> 32;

    cy = result >> (32 - 1);

    if ((cy & 0x1) == 0x0) {

        if (high == 0x0) {

            return result;

        }

    }

    if ((cy & 0x1) == 0x1) {

        if (high == 0xffffffff) {

            return result;

        }

    }

    cpu->env.sr |= (SR_OV | SR_CY);

    if (cpu->env.sr & SR_OVE) {

        raise_exception(cpu, EXCP_RANGE);

    }

    return result;

}


static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,

                                 const AVFrame *frame, int *got_packet_ptr)

{

    int i, stereo, data_size, ret;

    const int16_t *in = frame ? (const int16_t *)frame->data[0] : NULL;

    uint8_t *out;

    ROQDPCMContext *context = avctx->priv_data;

    stereo = (avctx->channels == 2);

    if (!in && context->input_frames >= 8)

        return 0;

    if (in && context->input_frames < 8) {

        memcpy(&context->frame_buffer[context->buffered_samples * avctx->channels],

               in, avctx->frame_size * avctx->channels * sizeof(*in));

        context->buffered_samples += avctx->frame_size;

        if (context->input_frames == 0)

            context->first_pts = frame->pts;

        if (context->input_frames < 7) {

            context->input_frames++;

            return 0;

        in = context->frame_buffer;

    if (stereo) {

        context->lastSample[0] &= 0xFF00;

        context->lastSample[1] &= 0xFF00;

    if (context->input_frames == 7 || !in)

        data_size = avctx->channels * context->buffered_samples;

    else

        data_size = avctx->channels * avctx->frame_size;

    if ((ret = ff_alloc_packet2(avctx, avpkt, ROQ_HEADER_SIZE + data_size)))

        return ret;

    out = avpkt->data;

    bytestream_put_byte(&out, stereo ? 0x21 : 0x20);

    bytestream_put_byte(&out, 0x10);

    bytestream_put_le32(&out, data_size);

    if (stereo) {

        bytestream_put_byte(&out, (context->lastSample[1])>>8);

        bytestream_put_byte(&out, (context->lastSample[0])>>8);

    } else

        bytestream_put_le16(&out, context->lastSample[0]);

    /* Write the actual samples */

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

        *out++ = dpcm_predict(&context->lastSample[i & 1], *in++);

    avpkt->pts      = context->input_frames <= 7 ? context->first_pts : frame->pts;

    avpkt->duration = data_size / avctx->channels;

    context->input_frames++;

    if (!in)

        context->input_frames = FFMAX(context->input_frames, 8);

    *got_packet_ptr = 1;

    return 0;


static int find_optimal_param(uint32_t sum, int n)

{

    int k, k_opt;

    uint32_t nbits[MAX_RICE_PARAM+1];

    k_opt = 0;

    nbits[0] = UINT32_MAX;

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

        nbits[k] = rice_encode_count(sum, n, k);

        if(nbits[k] < nbits[k_opt]) {

            k_opt = k;

        }

    }

    return k_opt;

}


float64 HELPER(ucf64_sf2df)(float32 x, CPUUniCore32State *env)

{

    return float32_to_float64(x, &env->ucf64.fp_status);

}


static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,

                                         NetClientState *sender,

                                         unsigned flags,

                                         const struct iovec *iov,

                                         int iovcnt,

                                         NetPacketSent *sent_cb)

{

    RewriterState *s = FILTER_COLO_REWRITER(nf);

    Connection *conn;

    ConnectionKey key;

    Packet *pkt;

    ssize_t size = iov_size(iov, iovcnt);

    char *buf = g_malloc0(size);

    iov_to_buf(iov, iovcnt, 0, buf, size);

    pkt = packet_new(buf, size);

    /*

     * if we get tcp packet

     * we will rewrite it to make secondary guest's

     * connection established successfully

     */

    if (pkt && is_tcp_packet(pkt)) {

        fill_connection_key(pkt, &key);

        if (sender == nf->netdev) {

            /*

             * We need make tcp TX and RX packet

             * into one connection.

             */

            reverse_connection_key(&key);

        }

        conn = connection_get(s->connection_track_table,

                              &key,

                              NULL);

        if (sender == nf->netdev) {

            /* NET_FILTER_DIRECTION_TX */

            /* handle_primary_tcp_pkt */

        } else {

            /* NET_FILTER_DIRECTION_RX */

            /* handle_secondary_tcp_pkt */

        }

    }

    packet_destroy(pkt, NULL);

    pkt = NULL;

    return 0;

}


static void ts_str(char buffer[60], int64_t ts, AVRational base)

{

    if (ts == AV_NOPTS_VALUE) {

        strcpy(buffer, " NOPTS   ");

        return;

    }

    ts= av_rescale_q(ts, base, (AVRational){1, 1000000});

    snprintf(buffer, 60, "%c%Ld.%06Ld", ts<0 ? '-' : ' ', FFABS(ts)/1000000, FFABS(ts)%1000000);

}


static CCPrepare gen_prepare_cc(DisasContext *s, int b, TCGv reg)

{

    int inv, jcc_op, size, cond;

    CCPrepare cc;

    TCGv t0;

    inv = b & 1;

    jcc_op = (b >> 1) & 7;

    switch (s->cc_op) {

    case CC_OP_SUBB ... CC_OP_SUBQ:

        /* We optimize relational operators for the cmp/jcc case.  */

        size = s->cc_op - CC_OP_SUBB;

        switch (jcc_op) {

        case JCC_BE:

            tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);

            gen_extu(size, cpu_tmp4);

            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);

            cc = (CCPrepare) { .cond = TCG_COND_LEU, .reg = cpu_tmp4,

                               .reg2 = t0, .mask = -1, .use_reg2 = true };

            break;

        case JCC_L:

            cond = TCG_COND_LT;

            goto fast_jcc_l;

        case JCC_LE:

            cond = TCG_COND_LE;

        fast_jcc_l:

            tcg_gen_add_tl(cpu_tmp4, cpu_cc_dst, cpu_cc_src);

            gen_exts(size, cpu_tmp4);

            t0 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, true);

            cc = (CCPrepare) { .cond = cond, .reg = cpu_tmp4,

                               .reg2 = t0, .mask = -1, .use_reg2 = true };

            break;

        default:

            goto slow_jcc;

        }

        break;

    default:

    slow_jcc:

        /* This actually generates good code for JC, JZ and JS.  */

        switch (jcc_op) {

        case JCC_O:

            cc = gen_prepare_eflags_o(s, reg);

            break;

        case JCC_B:

            cc = gen_prepare_eflags_c(s, reg);

            break;

        case JCC_Z:

            cc = gen_prepare_eflags_z(s, reg);

            break;

        case JCC_BE:

            gen_compute_eflags(s);

            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,

                               .mask = CC_Z | CC_C };

            break;

        case JCC_S:

            cc = gen_prepare_eflags_s(s, reg);

            break;

        case JCC_P:

            cc = gen_prepare_eflags_p(s, reg);

            break;

        case JCC_L:

            gen_compute_eflags(s);

            if (TCGV_EQUAL(reg, cpu_cc_src)) {

                reg = cpu_tmp0;

            }

            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */

            tcg_gen_xor_tl(reg, reg, cpu_cc_src);

            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,

                               .mask = CC_S };

            break;

        default:

        case JCC_LE:

            gen_compute_eflags(s);

            if (TCGV_EQUAL(reg, cpu_cc_src)) {

                reg = cpu_tmp0;

            }

            tcg_gen_shri_tl(reg, cpu_cc_src, 4); /* CC_O -> CC_S */

            tcg_gen_xor_tl(reg, reg, cpu_cc_src);

            cc = (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,

                               .mask = CC_S | CC_Z };

            break;

        }

        break;

    }

    if (inv) {

        cc.cond = tcg_invert_cond(cc.cond);

    }

    return cc;

}


static void lz_unpack(const unsigned char *src, int src_len,

                      unsigned char *dest, int dest_len)

{

    const unsigned char *s;

    const unsigned char *s_end;

    unsigned char *d;

    unsigned char *d_end;

    unsigned char queue[QUEUE_SIZE];

    unsigned int qpos;

    unsigned int dataleft;

    unsigned int chainofs;

    unsigned int chainlen;

    unsigned int speclen;

    unsigned char tag;

    unsigned int i, j;

    s = src;

    s_end = src + src_len;

    d = dest;

    d_end = d + dest_len;

    if (s_end - s < 8)

        return;

    dataleft = AV_RL32(s);

    s += 4;

    memset(queue, 0x20, QUEUE_SIZE);

    if (AV_RL32(s) == 0x56781234) {

        s += 4;

        qpos = 0x111;

        speclen = 0xF + 3;

    } else {

        qpos = 0xFEE;

        speclen = 100;  /* no speclen */

    }

    while (s_end - s > 0 && dataleft > 0) {

        tag = *s++;

        if ((tag == 0xFF) && (dataleft > 8)) {

            if (d + 8 > d_end || s_end - s < 8)

                return;

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

                queue[qpos++] = *d++ = *s++;

                qpos &= QUEUE_MASK;

            }

            dataleft -= 8;

        } else {

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

                if (dataleft == 0)

                    break;

                if (tag & 0x01) {

                    if (d + 1 > d_end || s_end - s < 1)

                        return;

                    queue[qpos++] = *d++ = *s++;

                    qpos &= QUEUE_MASK;

                    dataleft--;

                } else {

                    if (s_end - s < 2)

                        return;

                    chainofs = *s++;

                    chainofs |= ((*s & 0xF0) << 4);

                    chainlen = (*s++ & 0x0F) + 3;

                    if (chainlen == speclen) {

                        if (s_end - s < 1)

                            return;

                        chainlen = *s++ + 0xF + 3;

                    }

                    if (d + chainlen > d_end)

                        return;

                    for (j = 0; j < chainlen; j++) {

                        *d = queue[chainofs++ & QUEUE_MASK];

                        queue[qpos++] = *d++;

                        qpos &= QUEUE_MASK;

                    }

                    dataleft -= chainlen;

                }

                tag >>= 1;

            }

        }

    }

}


static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)

{

    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;

    struct alsa_params_req req;

    struct alsa_params_obt obt;

    snd_pcm_t *handle;

    struct audsettings obt_as;

    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);

    req.freq = as->freq;

    req.nchannels = as->nchannels;

    req.period_size = conf.period_size_out;

    req.buffer_size = conf.buffer_size_out;

    req.size_in_usec = conf.size_in_usec_out;

    req.override_mask =

        (conf.period_size_out_overridden ? 1 : 0) |

        (conf.buffer_size_out_overridden ? 2 : 0);

    if (alsa_open (0, &req, &obt, &handle)) {

        return -1;

    }

    obt_as.freq = obt.freq;

    obt_as.nchannels = obt.nchannels;

    obt_as.fmt = obt.fmt;

    obt_as.endianness = obt.endianness;

    audio_pcm_init_info (&hw->info, &obt_as);

    hw->samples = obt.samples;

    alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift);

    if (!alsa->pcm_buf) {

        dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n",

               hw->samples, 1 << hw->info.shift);

        alsa_anal_close1 (&handle);

        return -1;

    }

    alsa->handle = handle;

    return 0;

}


static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)

{

    int x, y;

    unsigned char P[4];

    /* 4-color encoding */

    CHECK_STREAM_PTR(4);

    memcpy(P, s->stream_ptr, 4);

    s->stream_ptr += 4;

    if (P[0] <= P[1]) {

        if (P[2] <= P[3]) {

            /* 1 of 4 colors for each pixel, need 16 more bytes */

            CHECK_STREAM_PTR(16);

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

                /* get the next set of 8 2-bit flags */

                int flags = bytestream_get_le16(&s->stream_ptr);

                for (x = 0; x < 8; x++, flags >>= 2)

                    *s->pixel_ptr++ = P[flags & 0x03];

                s->pixel_ptr += s->line_inc;

            }

        } else {

            uint32_t flags;

            /* 1 of 4 colors for each 2x2 block, need 4 more bytes */

            CHECK_STREAM_PTR(4);

            flags = bytestream_get_le32(&s->stream_ptr);

            for (y = 0; y < 8; y += 2) {

                for (x = 0; x < 8; x += 2, flags >>= 2) {

                    s->pixel_ptr[x                ] =

                    s->pixel_ptr[x + 1            ] =

                    s->pixel_ptr[x +     s->stride] =

                    s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];

                }

                s->pixel_ptr += s->stride * 2;

            }

        }

    } else {

        uint64_t flags;

        /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */

        CHECK_STREAM_PTR(8);

        flags = bytestream_get_le64(&s->stream_ptr);

        if (P[2] <= P[3]) {

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

                for (x = 0; x < 8; x += 2, flags >>= 2) {

                    s->pixel_ptr[x    ] =

                    s->pixel_ptr[x + 1] = P[flags & 0x03];

                }

                s->pixel_ptr += s->stride;

            }

        } else {

            for (y = 0; y < 8; y += 2) {

                for (x = 0; x < 8; x++, flags >>= 2) {

                    s->pixel_ptr[x            ] =

                    s->pixel_ptr[x + s->stride] = P[flags & 0x03];

                }

                s->pixel_ptr += s->stride * 2;

            }

        }

    }

    /* report success */

    return 0;

}


int ff_mjpeg_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    MJpegDecodeContext *s = avctx->priv_data;

    const uint8_t *buf_end, *buf_ptr;

    const uint8_t *unescaped_buf_ptr;

    int unescaped_buf_size;

    int start_code;

    AVFrame *picture = data;

    s->got_picture = 0; // picture from previous image can not be reused

    buf_ptr = buf;

    buf_end = buf + buf_size;

    while (buf_ptr < buf_end) {

        /* find start next marker */

        start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end,

                                          &unescaped_buf_ptr, &unescaped_buf_size);

        {

            /* EOF */

            if (start_code < 0) {

                goto the_end;

            } else {

                av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", start_code, buf_end - buf_ptr);

                init_get_bits(&s->gb, unescaped_buf_ptr, unescaped_buf_size*8);

                s->start_code = start_code;

                if(s->avctx->debug & FF_DEBUG_STARTCODE){

                    av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);

                }

                /* process markers */

                if (start_code >= 0xd0 && start_code <= 0xd7) {

                    av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code&0x0f);

                    /* APP fields */

                } else if (start_code >= APP0 && start_code <= APP15) {

                    mjpeg_decode_app(s);

                    /* Comment */

                } else if (start_code == COM){

                    mjpeg_decode_com(s);

                }

                switch(start_code) {

                case SOI:

                    s->restart_interval = 0;

                    s->restart_count = 0;

                    /* nothing to do on SOI */

                    break;

                case DQT:

                    ff_mjpeg_decode_dqt(s);

                    break;

                case DHT:

                    if(ff_mjpeg_decode_dht(s) < 0){

                        av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");

                        return -1;

                    }

                    break;

                case SOF0:

                case SOF1:

                    s->lossless=0;

                    s->ls=0;

                    s->progressive=0;

                    if (ff_mjpeg_decode_sof(s) < 0)

                        return -1;

                    break;

                case SOF2:

                    s->lossless=0;

                    s->ls=0;

                    s->progressive=1;

                    if (ff_mjpeg_decode_sof(s) < 0)

                        return -1;

                    break;

                case SOF3:

                    s->lossless=1;

                    s->ls=0;

                    s->progressive=0;

                    if (ff_mjpeg_decode_sof(s) < 0)

                        return -1;

                    break;

                case SOF48:

                    s->lossless=1;

                    s->ls=1;

                    s->progressive=0;

                    if (ff_mjpeg_decode_sof(s) < 0)

                        return -1;

                    break;

                case LSE:

                    if (!CONFIG_JPEGLS_DECODER || ff_jpegls_decode_lse(s) < 0)

                        return -1;

                    break;

                case EOI:

                    if ((s->buggy_avid && !s->interlaced) || s->restart_interval)

                        break;

eoi_parser:

                    s->cur_scan = 0;

                    if (!s->got_picture) {

                        av_log(avctx, AV_LOG_WARNING, "Found EOI before any SOF, ignoring\n");

                        break;

                    }

                    if (s->interlaced) {

                        s->bottom_field ^= 1;

                        /* if not bottom field, do not output image yet */

                        if (s->bottom_field == !s->interlace_polarity)

                            break;

                    }

                    *picture = *s->picture_ptr;

                    *data_size = sizeof(AVFrame);

                    if(!s->lossless){

                        picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);

                        picture->qstride= 0;

                        picture->qscale_table= s->qscale_table;

                        memset(picture->qscale_table, picture->quality, (s->width+15)/16);

                        if(avctx->debug & FF_DEBUG_QP)

                            av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);

                        picture->quality*= FF_QP2LAMBDA;

                    }

                    goto the_end;

                case SOS:

                    if (!s->got_picture) {

                        av_log(avctx, AV_LOG_WARNING, "Can not process SOS before SOF, skipping\n");

                        break;

                    }

                    if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 &&

                        avctx->error_recognition >= FF_ER_EXPLODE)

                      return AVERROR_INVALIDDATA;

                    /* buggy avid puts EOI every 10-20th frame */

                    /* if restart period is over process EOI */

                    if ((s->buggy_avid && !s->interlaced) || s->restart_interval)

                        goto eoi_parser;

                    break;

                case DRI:

                    mjpeg_decode_dri(s);

                    break;

                case SOF5:

                case SOF6:

                case SOF7:

                case SOF9:

                case SOF10:

                case SOF11:

                case SOF13:

                case SOF14:

                case SOF15:

                case JPG:

                    av_log(avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code);

                    break;

//                default:

//                    printf("mjpeg: unsupported marker (%x)\n", start_code);

//                    break;

                }

                /* eof process start code */

                buf_ptr += (get_bits_count(&s->gb)+7)/8;

                av_log(avctx, AV_LOG_DEBUG, "marker parser used %d bytes (%d bits)\n",

                       (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));

            }

        }

    }

    if (s->got_picture) {

        av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");

        goto eoi_parser;

    }

    av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");

    return -1;

the_end:

    av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n", buf_end - buf_ptr);

//    return buf_end - buf_ptr;

    return buf_ptr - buf;

}


static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,

                                 struct image_info *info)

{

    abi_ulong stack_base, size, error;

    int i;

    /* Create enough stack to hold everything.  If we don't use

     * it for args, we'll use it for something else...

     */

    size = guest_stack_size;

    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)

        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;

    error = target_mmap(0,

                        size + qemu_host_page_size,

                        PROT_READ | PROT_WRITE,

                        MAP_PRIVATE | MAP_ANONYMOUS,

                        -1, 0);

    if (error == -1) {

        perror("stk mmap");

        exit(-1);

    }

    /* we reserve one extra page at the top of the stack as guard */

    target_mprotect(error + size, qemu_host_page_size, PROT_NONE);

    info->stack_limit = error;

    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE;

    p += stack_base;

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

        if (bprm->page[i]) {

            info->rss++;

            /* FIXME - check return value of memcpy_to_target() for failure */

            memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);

            free(bprm->page[i]);

        }

        stack_base += TARGET_PAGE_SIZE;

    }

    return p;

}


static size_t handle_aiocb_rw_vector(struct qemu_paiocb *aiocb)

{

    size_t offset = 0;

    ssize_t len;

    do {

        if (aiocb->aio_type == QEMU_PAIO_WRITE)

            len = qemu_pwritev(aiocb->aio_fildes,

                               aiocb->aio_iov,

                               aiocb->aio_niov,

                               aiocb->aio_offset + offset);

         else

            len = qemu_preadv(aiocb->aio_fildes,

                              aiocb->aio_iov,

                              aiocb->aio_niov,

                              aiocb->aio_offset + offset);

    } while (len == -1 && errno == EINTR);

    if (len == -1)

        return -errno;

    return len;

}


static VncClientInfo *qmp_query_vnc_client(const VncState *client)

{

    struct sockaddr_storage sa;

    socklen_t salen = sizeof(sa);

    char host[NI_MAXHOST];

    char serv[NI_MAXSERV];

    VncClientInfo *info;

    if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {

        return NULL;

    }

    if (getnameinfo((struct sockaddr *)&sa, salen,

                    host, sizeof(host),

                    serv, sizeof(serv),

                    NI_NUMERICHOST | NI_NUMERICSERV) < 0) {

        return NULL;

    }

    info = g_malloc0(sizeof(*info));

    info->base = g_malloc0(sizeof(*info->base));

    info->base->host = g_strdup(host);

    info->base->service = g_strdup(serv);

    info->base->family = inet_netfamily(sa.ss_family);

    info->base->websocket = client->websocket;

#ifdef CONFIG_VNC_TLS

    if (client->tls.session && client->tls.dname) {

        info->has_x509_dname = true;

        info->x509_dname = g_strdup(client->tls.dname);

    }

#endif

#ifdef CONFIG_VNC_SASL

    if (client->sasl.conn && client->sasl.username) {

        info->has_sasl_username = true;

        info->sasl_username = g_strdup(client->sasl.username);

    }

#endif

    return info;

}


int kvm_arch_put_registers(CPUState *env)

{

    struct kvm_regs regs;

    int ret;

    int i;

    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);

    if (ret < 0)

        return ret;

    regs.ctr = env->ctr;

    regs.lr  = env->lr;

    regs.xer = env->xer;

    regs.msr = env->msr;

    regs.pc = env->nip;

    regs.srr0 = env->spr[SPR_SRR0];

    regs.srr1 = env->spr[SPR_SRR1];

    regs.sprg0 = env->spr[SPR_SPRG0];

    regs.sprg1 = env->spr[SPR_SPRG1];

    regs.sprg2 = env->spr[SPR_SPRG2];

    regs.sprg3 = env->spr[SPR_SPRG3];

    regs.sprg4 = env->spr[SPR_SPRG4];

    regs.sprg5 = env->spr[SPR_SPRG5];

    regs.sprg6 = env->spr[SPR_SPRG6];

    regs.sprg7 = env->spr[SPR_SPRG7];

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

        regs.gpr[i] = env->gpr[i];

    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);

    if (ret < 0)

        return ret;

    return ret;

}


static int mp_decode_layer3(MPADecodeContext *s)

{

    int nb_granules, main_data_begin;

    int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;

    GranuleDef *g;

    int16_t exponents[576]; //FIXME try INTFLOAT

    /* read side info */

    if (s->lsf) {

        main_data_begin = get_bits(&s->gb, 8);

        skip_bits(&s->gb, s->nb_channels);

        nb_granules = 1;

    } else {

        main_data_begin = get_bits(&s->gb, 9);

        if (s->nb_channels == 2)

            skip_bits(&s->gb, 3);

        else

            skip_bits(&s->gb, 5);

        nb_granules = 2;

        for (ch = 0; ch < s->nb_channels; ch++) {

            s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */

            s->granules[ch][1].scfsi = get_bits(&s->gb, 4);

        }

    }

    for (gr = 0; gr < nb_granules; gr++) {

        for (ch = 0; ch < s->nb_channels; ch++) {

            av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);

            g = &s->granules[ch][gr];

            g->part2_3_length = get_bits(&s->gb, 12);

            g->big_values     = get_bits(&s->gb,  9);

            if (g->big_values > 288) {

                av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");

                return AVERROR_INVALIDDATA;

            }

            g->global_gain = get_bits(&s->gb, 8);

            /* if MS stereo only is selected, we precompute the

               1/sqrt(2) renormalization factor */

            if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==

                MODE_EXT_MS_STEREO)

                g->global_gain -= 2;

            if (s->lsf)

                g->scalefac_compress = get_bits(&s->gb, 9);

            else

                g->scalefac_compress = get_bits(&s->gb, 4);

            blocksplit_flag = get_bits1(&s->gb);

            if (blocksplit_flag) {

                g->block_type = get_bits(&s->gb, 2);

                if (g->block_type == 0) {

                    av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");

                    return AVERROR_INVALIDDATA;

                }

                g->switch_point = get_bits1(&s->gb);

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

                    g->table_select[i] = get_bits(&s->gb, 5);

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

                    g->subblock_gain[i] = get_bits(&s->gb, 3);

                ff_init_short_region(s, g);

            } else {

                int region_address1, region_address2;

                g->block_type = 0;

                g->switch_point = 0;

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

                    g->table_select[i] = get_bits(&s->gb, 5);

                /* compute huffman coded region sizes */

                region_address1 = get_bits(&s->gb, 4);

                region_address2 = get_bits(&s->gb, 3);

                av_dlog(s->avctx, "region1=%d region2=%d\n",

                        region_address1, region_address2);

                ff_init_long_region(s, g, region_address1, region_address2);

            }

            ff_region_offset2size(g);

            ff_compute_band_indexes(s, g);

            g->preflag = 0;

            if (!s->lsf)

                g->preflag = get_bits1(&s->gb);

            g->scalefac_scale     = get_bits1(&s->gb);

            g->count1table_select = get_bits1(&s->gb);

            av_dlog(s->avctx, "block_type=%d switch_point=%d\n",

                    g->block_type, g->switch_point);

        }

    }

    if (!s->adu_mode) {

        const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);

        int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);

        assert((get_bits_count(&s->gb) & 7) == 0);

        /* now we get bits from the main_data_begin offset */

        av_dlog(s->avctx, "seekback: %d\n", main_data_begin);

    //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);

        memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);

        s->in_gb = s->gb;

        init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);

#if !UNCHECKED_BITSTREAM_READER

        s->gb.size_in_bits_plus8 += FFMAX(extrasize, LAST_BUF_SIZE - s->last_buf_size) * 8;

#endif

        skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));

    }

    for (gr = 0; gr < nb_granules; gr++) {

        for (ch = 0; ch < s->nb_channels; ch++) {

            g = &s->granules[ch][gr];

            if (get_bits_count(&s->gb) < 0) {

                av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n",

                       main_data_begin, s->last_buf_size, gr);

                skip_bits_long(&s->gb, g->part2_3_length);

                memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));

                if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {

                    skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);

                    s->gb           = s->in_gb;

                    s->in_gb.buffer = NULL;

                }

                continue;

            }

            bits_pos = get_bits_count(&s->gb);

            if (!s->lsf) {

                uint8_t *sc;

                int slen, slen1, slen2;

                /* MPEG1 scale factors */

                slen1 = slen_table[0][g->scalefac_compress];

                slen2 = slen_table[1][g->scalefac_compress];

                av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);

                if (g->block_type == 2) {

                    n = g->switch_point ? 17 : 18;

                    j = 0;

                    if (slen1) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, slen1);

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                    if (slen2) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, slen2);

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

                            g->scale_factors[j++] = 0;

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                } else {

                    sc = s->granules[ch][0].scale_factors;

                    j = 0;

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

                        n = k == 0 ? 6 : 5;

                        if ((g->scfsi & (0x8 >> k)) == 0) {

                            slen = (k < 2) ? slen1 : slen2;

                            if (slen) {

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

                                    g->scale_factors[j++] = get_bits(&s->gb, slen);

                            } else {

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

                                    g->scale_factors[j++] = 0;

                            }

                        } else {

                            /* simply copy from last granule */

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

                                g->scale_factors[j] = sc[j];

                                j++;

                            }

                        }

                    }

                    g->scale_factors[j++] = 0;

                }

            } else {

                int tindex, tindex2, slen[4], sl, sf;

                /* LSF scale factors */

                if (g->block_type == 2)

                    tindex = g->switch_point ? 2 : 1;

                else

                    tindex = 0;

                sf = g->scalefac_compress;

                if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {

                    /* intensity stereo case */

                    sf >>= 1;

                    if (sf < 180) {

                        lsf_sf_expand(slen, sf, 6, 6, 0);

                        tindex2 = 3;

                    } else if (sf < 244) {

                        lsf_sf_expand(slen, sf - 180, 4, 4, 0);

                        tindex2 = 4;

                    } else {

                        lsf_sf_expand(slen, sf - 244, 3, 0, 0);

                        tindex2 = 5;

                    }

                } else {

                    /* normal case */

                    if (sf < 400) {

                        lsf_sf_expand(slen, sf, 5, 4, 4);

                        tindex2 = 0;

                    } else if (sf < 500) {

                        lsf_sf_expand(slen, sf - 400, 5, 4, 0);

                        tindex2 = 1;

                    } else {

                        lsf_sf_expand(slen, sf - 500, 3, 0, 0);

                        tindex2 = 2;

                        g->preflag = 1;

                    }

                }

                j = 0;

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

                    n  = lsf_nsf_table[tindex2][tindex][k];

                    sl = slen[k];

                    if (sl) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, sl);

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                }

                /* XXX: should compute exact size */

                for (; j < 40; j++)

                    g->scale_factors[j] = 0;

            }

            exponents_from_scale_factors(s, g, exponents);

            /* read Huffman coded residue */

            huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);

        } /* ch */

        if (s->nb_channels == 2)

            compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);

        for (ch = 0; ch < s->nb_channels; ch++) {

            g = &s->granules[ch][gr];

            reorder_block(s, g);

            compute_antialias(s, g);

            compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);

        }

    } /* gr */

    if (get_bits_count(&s->gb) < 0)

        skip_bits_long(&s->gb, -get_bits_count(&s->gb));

    return nb_granules * 18;

}


static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,

                             uint32_t val)

{

    PCIDevice *dev = opaque;

    unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;

    int vector = offset / MSIX_ENTRY_SIZE;

    pci_set_long(dev->msix_table_page + offset, val);

    if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) {

        msix_clr_pending(dev, vector);

        msix_notify(dev, vector);

    }

}


static void vhost_iommu_region_del(MemoryListener *listener,

                                   MemoryRegionSection *section)

{

    struct vhost_dev *dev = container_of(listener, struct vhost_dev,

                                         iommu_listener);

    struct vhost_iommu *iommu;

    if (!memory_region_is_iommu(section->mr)) {

        return;

    }

    QLIST_FOREACH(iommu, &dev->iommu_list, iommu_next) {

        if (iommu->mr == section->mr) {

            memory_region_unregister_iommu_notifier(iommu->mr,

                                                    &iommu->n);

            QLIST_REMOVE(iommu, iommu_next);

            g_free(iommu);

            break;

        }

    }

}


static void vfio_vga_quirk_teardown(VFIOPCIDevice *vdev)

{

    int i;

    for (i = 0; i < ARRAY_SIZE(vdev->vga.region); i++) {

        while (!QLIST_EMPTY(&vdev->vga.region[i].quirks)) {

            VFIOQuirk *quirk = QLIST_FIRST(&vdev->vga.region[i].quirks);

            memory_region_del_subregion(&vdev->vga.region[i].mem, &quirk->mem);

            object_unparent(OBJECT(&quirk->mem));

            QLIST_REMOVE(quirk, next);

            g_free(quirk);

        }

    }

}


int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)

{

    assert(len >= 14);

    if (!req->sense_len) {

        return 0;

    }

    return scsi_build_sense(req->sense, req->sense_len, buf, len, true);

}


uint64_t HELPER(popcnt)(uint64_t r2)

{

    uint64_t ret = 0;

    int i;

    for (i = 0; i < 64; i += 8) {

        uint64_t t = ctpop32((r2 >> i) & 0xff);

        ret |= t << i;

    }

    return ret;

}


static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,

                uint8_t *fb, int *miny, int *maxy)

{

    int y, src_width, dest_width, dirty[2];

    uint8_t *src, *dest;

    ram_addr_t x, addr, new_addr, start, end;

    drawfn fn = 0;

    if (s->dest_width)

        fn = s->line_fn[s->transp][s->bpp];

    if (!fn)

        return;

    src = fb;

    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */

    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)

        src_width *= 3;

    else if (s->bpp > pxa_lcdc_16bpp)

        src_width *= 4;

    else if (s->bpp > pxa_lcdc_8bpp)

        src_width *= 2;

    dest_width = s->yres * s->dest_width;

    dest = ds_get_data(s->ds) + dest_width * (s->xres - 1);

    addr = (ram_addr_t) (fb - phys_ram_base);

    start = addr + s->yres * src_width;

    end = addr;

    dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);

    for (y = 0; y < s->yres; y ++) {

        new_addr = addr + src_width;

        for (x = addr + TARGET_PAGE_SIZE; x < new_addr;

                        x += TARGET_PAGE_SIZE) {

            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);

            dirty[0] |= dirty[1];

        }

        if (dirty[0] || s->invalidated) {

            fn((uint32_t *) s->dma_ch[0].palette,

                            dest, src, s->xres, -dest_width);

            if (addr < start)

                start = addr;

            end = new_addr;

            if (y < *miny)

                *miny = y;

            if (y >= *maxy)

                *maxy = y + 1;

        }

        addr = new_addr;

        dirty[0] = dirty[1];

        src += src_width;

        dest += s->dest_width;

    }

    if (end > start)

        cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);

}


static void term_backspace(void)

{

    if (term_cmd_buf_index > 0) {

        term_backward_char();

        term_delete_char();

    }

}


static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {

    uint16_t *img_ptr;

    int index, x, y, c;

    int adjust[4];

    for (x = 0; x < image->numcomps; x++)

        adjust[x] = FFMAX(FFMIN(av_pix_fmt_desc_get(picture->format)->comp[x].depth_minus1 + 1 - image->comps[x].prec, 8), 0);

    for (y = 0; y < picture->height; y++) {

        index = y*picture->width;

        img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]);

        for (x = 0; x < picture->width; x++, index++) {

            for (c = 0; c < image->numcomps; c++) {

                *img_ptr++ = 0x8000 * image->comps[c].sgnd + (image->comps[c].data[index] << adjust[c]);

            }

        }

    }

}


int MPV_encode_picture(AVCodecContext *avctx,

                       unsigned char *buf, int buf_size, void *data)

{

    MpegEncContext *s = avctx->priv_data;

    AVFrame *pic_arg = data;

    int i, stuffing_count;

    for(i=0; i<avctx->thread_count; i++){

        int start_y= s->thread_context[i]->start_mb_y;

        int   end_y= s->thread_context[i]->  end_mb_y;

        int h= s->mb_height;

        uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h);

        uint8_t *end  = buf + (size_t)(((int64_t) buf_size)*  end_y/h);

        init_put_bits(&s->thread_context[i]->pb, start, end - start);

    }

    s->picture_in_gop_number++;

    if(load_input_picture(s, pic_arg) < 0)

        return -1;

    select_input_picture(s);

    /* output? */

    if(s->new_picture.data[0]){

        s->pict_type= s->new_picture.pict_type;

//emms_c();

//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale);

        MPV_frame_start(s, avctx);

        if (encode_picture(s, s->picture_number) < 0)

            return -1;

        avctx->real_pict_num  = s->picture_number;

        avctx->header_bits = s->header_bits;

        avctx->mv_bits     = s->mv_bits;

        avctx->misc_bits   = s->misc_bits;

        avctx->i_tex_bits  = s->i_tex_bits;

        avctx->p_tex_bits  = s->p_tex_bits;

        avctx->i_count     = s->i_count;

        avctx->p_count     = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx

        avctx->skip_count  = s->skip_count;

        MPV_frame_end(s);

        if (s->out_format == FMT_MJPEG)

            mjpeg_picture_trailer(s);

        if(s->flags&CODEC_FLAG_PASS1)

            ff_write_pass1_stats(s);

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

            s->current_picture_ptr->error[i]= s->current_picture.error[i];

            avctx->error[i] += s->current_picture_ptr->error[i];

        }

        if(s->flags&CODEC_FLAG_PASS1)

            assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb));

        flush_put_bits(&s->pb);

        s->frame_bits  = put_bits_count(&s->pb);

        stuffing_count= ff_vbv_update(s, s->frame_bits);

        if(stuffing_count){

            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){

                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");

                return -1;

            }

            switch(s->codec_id){

            case CODEC_ID_MPEG1VIDEO:

            case CODEC_ID_MPEG2VIDEO:

                while(stuffing_count--){

                    put_bits(&s->pb, 8, 0);

                }

            break;

            case CODEC_ID_MPEG4:

                put_bits(&s->pb, 16, 0);

                put_bits(&s->pb, 16, 0x1C3);

                stuffing_count -= 4;

                while(stuffing_count--){

                    put_bits(&s->pb, 8, 0xFF);

                }

            break;

            default:

                av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");

            }

            flush_put_bits(&s->pb);

            s->frame_bits  = put_bits_count(&s->pb);

        }

        /* update mpeg1/2 vbv_delay for CBR */

        if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1

           && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){

            int vbv_delay;

            assert(s->repeat_first_field==0);

            vbv_delay= lrintf(90000 * s->rc_context.buffer_index / s->avctx->rc_max_rate);

            assert(vbv_delay < 0xFFFF);

            s->vbv_delay_ptr[0] &= 0xF8;

            s->vbv_delay_ptr[0] |= vbv_delay>>13;

            s->vbv_delay_ptr[1]  = vbv_delay>>5;

            s->vbv_delay_ptr[2] &= 0x07;

            s->vbv_delay_ptr[2] |= vbv_delay<<3;

        }

        s->total_bits += s->frame_bits;

        avctx->frame_bits  = s->frame_bits;

    }else{

        assert((pbBufPtr(&s->pb) == s->pb.buf));

        s->frame_bits=0;

    }

    assert((s->frame_bits&7)==0);

    return s->frame_bits/8;

}


static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)

{

    int h, cy, i;

    int offset[AV_NUM_DATA_POINTERS];

    if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {

        int y_flipped = s->flipped_image ? s->avctx->height - y : y;

        /* At the end of the frame, report INT_MAX instead of the height of

         * the frame. This makes the other threads' ff_thread_await_progress()

         * calls cheaper, because they don't have to clip their values. */

        ff_thread_report_progress(&s->current_frame,

                                  y_flipped == s->avctx->height ? INT_MAX

                                                                : y_flipped - 1,

                                  0);

    }

    if (s->avctx->draw_horiz_band == NULL)

        return;

    h = y - s->last_slice_end;

    s->last_slice_end = y;

    y -= h;

    if (!s->flipped_image)

        y = s->avctx->height - y - h;

    cy        = y >> s->chroma_y_shift;

    offset[0] = s->current_frame.f->linesize[0] * y;

    offset[1] = s->current_frame.f->linesize[1] * cy;

    offset[2] = s->current_frame.f->linesize[2] * cy;

    for (i = 3; i < AV_NUM_DATA_POINTERS; i++)

        offset[i] = 0;

    emms_c();

    s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);

}


static int gif_write_header(AVFormatContext *s)

{

    GIFContext *gif = s->priv_data;

    AVIOContext *pb = s->pb;

    AVCodecContext *enc, *video_enc;

    int i, width, height, loop_count /*, rate*/;

/* XXX: do we reject audio streams or just ignore them ?

    if(s->nb_streams > 1)

        return -1;

*/

    gif->time = 0;

    gif->file_time = 0;

    video_enc = NULL;

    for(i=0;i<s->nb_streams;i++) {

        enc = s->streams[i]->codec;

        if (enc->codec_type != AVMEDIA_TYPE_AUDIO)

            video_enc = enc;

    }

    if (!video_enc) {

        av_free(gif);

        return -1;

    } else {

        width = video_enc->width;

        height = video_enc->height;

        loop_count = s->loop_output;

//        rate = video_enc->time_base.den;

    }

    if (video_enc->pix_fmt != PIX_FMT_RGB24) {

        av_log(s, AV_LOG_ERROR, "ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n");

        return AVERROR(EIO);

    }

    gif_image_write_header(pb, width, height, loop_count, NULL);

    avio_flush(s->pb);

    return 0;

}


fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,

                     uint8_t **buf)

{

    int i,offset, len, buf_len;

    unsigned char *ptr;

    len = priv->len[0] + priv->len[1] + priv->len[2];

    buf_len = len + len/255 + 64;

    ptr = *buf = av_realloc(NULL, buf_len);

    memset(*buf, '\0', buf_len);

    ptr[0] = 2;

    offset = 1;

    offset += av_xiphlacing(&ptr[offset], priv->len[0]);

    offset += av_xiphlacing(&ptr[offset], priv->len[1]);

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

        memcpy(&ptr[offset], priv->packet[i], priv->len[i]);

        offset += priv->len[i];

        av_freep(&priv->packet[i]);

    }

    *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);

    return offset;

}


static inline int small_diamond_search4MV(MpegEncContext * s, int *best, int dmin,

                                       UINT8 *new_pic, UINT8 *old_pic, int pic_stride,

                                       int pred_x, int pred_y, UINT16 *mv_penalty, int quant,

                                       int xmin, int ymin, int xmax, int ymax, int shift)

{

    int next_dir=-1;

    for(;;){

        int d;

        const int dir= next_dir;

        const int x= best[0];

        const int y= best[1];

        next_dir=-1;

//printf("%d", dir);

        if(dir!=2 && x>xmin) CHECK_MV4_DIR(x-1, y  , 0)

        if(dir!=3 && y>ymin) CHECK_MV4_DIR(x  , y-1, 1)

        if(dir!=0 && x<xmax) CHECK_MV4_DIR(x+1, y  , 2)

        if(dir!=1 && y<ymax) CHECK_MV4_DIR(x  , y+1, 3)

        if(next_dir==-1){

            return dmin;

        }

    }

}


void ff_h264_remove_all_refs(H264Context *h)

{

    int i;

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

        remove_long(h, i, 0);

    }

    assert(h->long_ref_count == 0);

    ff_h264_unref_picture(h, &h->last_pic_for_ec);

    if (h->short_ref_count)

        ff_h264_ref_picture(h, &h->last_pic_for_ec, h->short_ref[0]);

    for (i = 0; i < h->short_ref_count; i++) {

        unreference_pic(h, h->short_ref[i], 0);

        h->short_ref[i] = NULL;

    }

    h->short_ref_count = 0;

    memset(h->default_ref_list, 0, sizeof(h->default_ref_list));

    memset(h->ref_list, 0, sizeof(h->ref_list));

}


static int get_max_p_order(int max_porder, int n, int order)

{

    int porder, max_parts;

    porder = max_porder;

    while(porder > 0) {

        max_parts = (1 << porder);

        if(!(n % max_parts) && (n > max_parts*order)) {

            break;

        }

        porder--;

    }

    return porder;

}


TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)

{

    int idx;

    idx = tcg_global_reg_new_internal(TCG_TYPE_I64, reg, name);

    return MAKE_TCGV_I64(idx);

}


static void gen_window_check1(DisasContext *dc, unsigned r1)

{

    if (dc->tb->flags & XTENSA_TBFLAG_EXCM) {

        return;

    }

    if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&

            r1 / 4 > dc->used_window) {

        TCGv_i32 pc = tcg_const_i32(dc->pc);

        TCGv_i32 w = tcg_const_i32(r1 / 4);

        dc->used_window = r1 / 4;

        gen_advance_ccount(dc);

        gen_helper_window_check(cpu_env, pc, w);

        tcg_temp_free(w);

        tcg_temp_free(pc);

    }

}


void aio_notify(AioContext *ctx)

{

    /* Write e.g. bh->scheduled before reading ctx->notify_me.  Pairs

     * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll.

     */

    smp_mb();

    if (ctx->notify_me) {

        event_notifier_set(&ctx->notifier);

        atomic_mb_set(&ctx->notified, true);

    }

}


static void xlnx_zynqmp_qspips_reset(DeviceState *d)

{

    XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(d);

    int i;

    xilinx_spips_reset(d);

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

        s->regs[i] = 0;

    }

    fifo8_reset(&s->rx_fifo_g);

    fifo8_reset(&s->rx_fifo_g);

    fifo32_reset(&s->fifo_g);

    s->regs[R_INTR_STATUS] = R_INTR_STATUS_RESET;

    s->regs[R_GPIO] = 1;

    s->regs[R_LPBK_DLY_ADJ] = R_LPBK_DLY_ADJ_RESET;

    s->regs[R_GQSPI_GFIFO_THRESH] = 0x10;

    s->regs[R_MOD_ID] = 0x01090101;

    s->regs[R_GQSPI_IMR] = R_GQSPI_IMR_RESET;

    s->regs[R_GQSPI_TX_THRESH] = 1;

    s->regs[R_GQSPI_RX_THRESH] = 1;

    s->regs[R_GQSPI_GPIO] = 1;

    s->regs[R_GQSPI_LPBK_DLY_ADJ] = R_GQSPI_LPBK_DLY_ADJ_RESET;

    s->regs[R_GQSPI_MOD_ID] = R_GQSPI_MOD_ID_RESET;

    s->regs[R_QSPIDMA_DST_CTRL] = R_QSPIDMA_DST_CTRL_RESET;

    s->regs[R_QSPIDMA_DST_I_MASK] = R_QSPIDMA_DST_I_MASK_RESET;

    s->regs[R_QSPIDMA_DST_CTRL2] = R_QSPIDMA_DST_CTRL2_RESET;

    s->man_start_com_g = false;

    s->gqspi_irqline = 0;

    xlnx_zynqmp_qspips_update_ixr(s);

}


static void spapr_reset_htab(sPAPRMachineState *spapr)

{

    long shift;

    int index;

    shift = kvmppc_reset_htab(spapr->htab_shift);

    if (shift < 0) {

        error_setg(&error_abort, "Failed to reset HTAB");

    } else if (shift > 0) {

        if (shift != spapr->htab_shift) {

            error_setg(&error_abort, "Requested HTAB allocation failed during reset");

        }

        /* Tell readers to update their file descriptor */

        if (spapr->htab_fd >= 0) {

            spapr->htab_fd_stale = true;

        }

    } else {

        memset(spapr->htab, 0, HTAB_SIZE(spapr));

        for (index = 0; index < HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; index++) {

            DIRTY_HPTE(HPTE(spapr->htab, index));

        }

    }

    /* Update the RMA size if necessary */

    if (spapr->vrma_adjust) {

        spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),

                                          spapr->htab_shift);

    }

}


static void load_tco(const TestData *d)

{

    qpci_io_writew(d->dev, d->tco_io_base + TCO_RLD, 4);

}


target_ulong helper_srad(CPUPPCState *env, target_ulong value,

                         target_ulong shift)

{

    int64_t ret;

    if (likely(!(shift & 0x40))) {

        if (likely((uint64_t)shift != 0)) {

            shift &= 0x3f;

            ret = (int64_t)value >> shift;

            if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {

                env->ca = 0;

            } else {

                env->ca = 1;

            }

        } else {

            ret = (int64_t)value;

            env->ca = 0;

        }

    } else {

        ret = (int64_t)value >> 63;

        env->ca = (ret != 0);

    }

    return ret;

}


static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                             target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong avpn = args[2];

    RemoveResult ret;

    ret = remove_hpte(cpu, pte_index, avpn, flags,

                      &args[0], &args[1]);

    switch (ret) {

    case REMOVE_SUCCESS:

        check_tlb_flush(env);

        return H_SUCCESS;

    case REMOVE_NOT_FOUND:

        return H_NOT_FOUND;

    case REMOVE_PARM:

        return H_PARAMETER;

    case REMOVE_HW:

        return H_HARDWARE;

    }

    g_assert_not_reached();

}


static void qtrle_decode_16bpp(QtrleContext *s)

{

    int stream_ptr;

    int header;

    int start_line;

    int lines_to_change;

    signed char rle_code;

    int row_ptr, pixel_ptr;

    int row_inc = s->frame.linesize[0];

    unsigned short rgb16;

    unsigned char *rgb = s->frame.data[0];

    int pixel_limit = s->frame.linesize[0] * s->avctx->height;

    /* check if this frame is even supposed to change */

    if (s->size < 8)

        return;

    /* start after the chunk size */

    stream_ptr = 4;

    /* fetch the header */

    CHECK_STREAM_PTR(2);

    header = BE_16(&s->buf[stream_ptr]);

    stream_ptr += 2;

    /* if a header is present, fetch additional decoding parameters */

    if (header & 0x0008) {

        CHECK_STREAM_PTR(8);

        start_line = BE_16(&s->buf[stream_ptr]);

        stream_ptr += 4;

        lines_to_change = BE_16(&s->buf[stream_ptr]);

        stream_ptr += 4;

    } else {

        start_line = 0;

        lines_to_change = s->avctx->height;

    }

    row_ptr = row_inc * start_line;

    while (lines_to_change--) {

        CHECK_STREAM_PTR(2);

        pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2;

        while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {

            if (rle_code == 0) {

                /* there's another skip code in the stream */

                CHECK_STREAM_PTR(1);

                pixel_ptr += (s->buf[stream_ptr++] - 1) * 2;

                CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */

            } else if (rle_code < 0) {

                /* decode the run length code */

                rle_code = -rle_code;

                CHECK_STREAM_PTR(2);

                rgb16 = BE_16(&s->buf[stream_ptr]);

                stream_ptr += 2;

                CHECK_PIXEL_PTR(rle_code * 2);

                while (rle_code--) {

                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;

                    pixel_ptr += 2;

                }

            } else {

                CHECK_STREAM_PTR(rle_code * 2);

                CHECK_PIXEL_PTR(rle_code * 2);

                /* copy pixels directly to output */

                while (rle_code--) {

                    rgb16 = BE_16(&s->buf[stream_ptr]);

                    stream_ptr += 2;

                    *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;

                    pixel_ptr += 2;

                }

            }

        }

        row_ptr += row_inc;

    }

}


static inline void RENAME(palToY)(uint8_t *dst, uint8_t *src, int width, uint32_t *pal)

{

	int i;

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

	{

		int d= src[i];

		dst[i]= pal[d] & 0xFF;

	}

}


e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r)

{

    return core->mac[r->dh] == core->mac[r->dt];

}


void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)

{

    int i, rc;

    xen_pfn_t ioreq_pfn;

    xen_pfn_t bufioreq_pfn;

    evtchn_port_t bufioreq_evtchn;

    XenIOState *state;

    state = g_malloc0(sizeof (XenIOState));

    state->xce_handle = xenevtchn_open(NULL, 0);

    if (state->xce_handle == NULL) {

        perror("xen: event channel open");

        goto err;

    }

    state->xenstore = xs_daemon_open();

    if (state->xenstore == NULL) {

        perror("xen: xenstore open");

        goto err;

    }

    rc = xen_create_ioreq_server(xen_xc, xen_domid, &state->ioservid);

    if (rc < 0) {

        perror("xen: ioreq server create");

        goto err;

    }

    state->exit.notify = xen_exit_notifier;

    qemu_add_exit_notifier(&state->exit);

    state->suspend.notify = xen_suspend_notifier;

    qemu_register_suspend_notifier(&state->suspend);

    state->wakeup.notify = xen_wakeup_notifier;

    qemu_register_wakeup_notifier(&state->wakeup);

    rc = xen_get_ioreq_server_info(xen_xc, xen_domid, state->ioservid,

                                   &ioreq_pfn, &bufioreq_pfn,

                                   &bufioreq_evtchn);

    if (rc < 0) {

        error_report("failed to get ioreq server info: error %d handle=" XC_INTERFACE_FMT,

                     errno, xen_xc);

        goto err;

    }

    DPRINTF("shared page at pfn %lx\n", ioreq_pfn);

    DPRINTF("buffered io page at pfn %lx\n", bufioreq_pfn);

    DPRINTF("buffered io evtchn is %x\n", bufioreq_evtchn);

    state->shared_page = xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,

                                              PROT_READ|PROT_WRITE, ioreq_pfn);

    if (state->shared_page == NULL) {

        error_report("map shared IO page returned error %d handle=" XC_INTERFACE_FMT,

                     errno, xen_xc);

        goto err;

    }

    rc = xen_get_vmport_regs_pfn(xen_xc, xen_domid, &ioreq_pfn);

    if (!rc) {

        DPRINTF("shared vmport page at pfn %lx\n", ioreq_pfn);

        state->shared_vmport_page =

            xc_map_foreign_range(xen_xc, xen_domid, XC_PAGE_SIZE,

                                 PROT_READ|PROT_WRITE, ioreq_pfn);

        if (state->shared_vmport_page == NULL) {

            error_report("map shared vmport IO page returned error %d handle="

                         XC_INTERFACE_FMT, errno, xen_xc);

            goto err;

        }

    } else if (rc != -ENOSYS) {

        error_report("get vmport regs pfn returned error %d, rc=%d",

                     errno, rc);

        goto err;

    }

    state->buffered_io_page = xc_map_foreign_range(xen_xc, xen_domid,

                                                   XC_PAGE_SIZE,

                                                   PROT_READ|PROT_WRITE,

                                                   bufioreq_pfn);

    if (state->buffered_io_page == NULL) {

        error_report("map buffered IO page returned error %d", errno);

        goto err;

    }

    /* Note: cpus is empty at this point in init */

    state->cpu_by_vcpu_id = g_malloc0(max_cpus * sizeof(CPUState *));

    rc = xen_set_ioreq_server_state(xen_xc, xen_domid, state->ioservid, true);

    if (rc < 0) {

        error_report("failed to enable ioreq server info: error %d handle=" XC_INTERFACE_FMT,

                     errno, xen_xc);

        goto err;

    }

    state->ioreq_local_port = g_malloc0(max_cpus * sizeof (evtchn_port_t));

    /* FIXME: how about if we overflow the page here? */

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

        rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,

                                        xen_vcpu_eport(state->shared_page, i));

        if (rc == -1) {

            error_report("shared evtchn %d bind error %d", i, errno);

            goto err;

        }

        state->ioreq_local_port[i] = rc;

    }

    rc = xenevtchn_bind_interdomain(state->xce_handle, xen_domid,

                                    bufioreq_evtchn);

    if (rc == -1) {

        error_report("buffered evtchn bind error %d", errno);

        goto err;

    }

    state->bufioreq_local_port = rc;

    /* Init RAM management */

    xen_map_cache_init(xen_phys_offset_to_gaddr, state);

    xen_ram_init(pcms, ram_size, ram_memory);

    qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);

    state->memory_listener = xen_memory_listener;

    QLIST_INIT(&state->physmap);

    memory_listener_register(&state->memory_listener, &address_space_memory);

    state->log_for_dirtybit = NULL;

    state->io_listener = xen_io_listener;

    memory_listener_register(&state->io_listener, &address_space_io);

    state->device_listener = xen_device_listener;

    device_listener_register(&state->device_listener);

    /* Initialize backend core & drivers */

    if (xen_be_init() != 0) {

        error_report("xen backend core setup failed");

        goto err;

    }

    xen_be_register("console", &xen_console_ops);

    xen_be_register("vkbd", &xen_kbdmouse_ops);

    xen_be_register("qdisk", &xen_blkdev_ops);

    xen_read_physmap(state);

    return;

err:

    error_report("xen hardware virtual machine initialisation failed");

    exit(1);

}


void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)

{

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    c->add_pixels_clamped = ff_add_pixels_clamped_neon;

    c->put_pixels_clamped = ff_put_pixels_clamped_neon;

    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;

    c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;

    c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;

    c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon;

    c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon;

    c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon;

    c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon;

    c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon;

    c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon;

    c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon;

    c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon;

    c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon;

    c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon;

    c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon;

    c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon;

    c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon;

    c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon;

    c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon;

    c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon;

    c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon;

    c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon;

    c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon;

    c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon;

    c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon;

    c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon;

    c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon;

    c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon;

    c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon;

    c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon;

    c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon;

    c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon;

    c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon;

    c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon;

    c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon;

    c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon;

    c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon;

    c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon;

    c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon;

    c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon;

    c->h264_h_loop_filter_luma = ff_h264_h_loop_filter_luma_neon;

    c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon;

    c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon;

    c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16x16_neon;

    c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_16x8_neon;

    c->weight_h264_pixels_tab[2] = ff_weight_h264_pixels_8x16_neon;

    c->weight_h264_pixels_tab[3] = ff_weight_h264_pixels_8x8_neon;

    c->weight_h264_pixels_tab[4] = ff_weight_h264_pixels_8x4_neon;

    c->weight_h264_pixels_tab[5] = ff_weight_h264_pixels_4x8_neon;

    c->weight_h264_pixels_tab[6] = ff_weight_h264_pixels_4x4_neon;

    c->weight_h264_pixels_tab[7] = ff_weight_h264_pixels_4x2_neon;

    c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels_16x16_neon;

    c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels_16x8_neon;

    c->biweight_h264_pixels_tab[2] = ff_biweight_h264_pixels_8x16_neon;

    c->biweight_h264_pixels_tab[3] = ff_biweight_h264_pixels_8x8_neon;

    c->biweight_h264_pixels_tab[4] = ff_biweight_h264_pixels_8x4_neon;

    c->biweight_h264_pixels_tab[5] = ff_biweight_h264_pixels_4x8_neon;

    c->biweight_h264_pixels_tab[6] = ff_biweight_h264_pixels_4x4_neon;

    c->biweight_h264_pixels_tab[7] = ff_biweight_h264_pixels_4x2_neon;

    c->h264_idct_add = ff_h264_idct_add_neon;

    c->h264_idct_dc_add = ff_h264_idct_dc_add_neon;

    c->h264_idct_add16      = ff_h264_idct_add16_neon;

    c->h264_idct_add16intra = ff_h264_idct_add16intra_neon;

    c->h264_idct_add8       = ff_h264_idct_add8_neon;

    if (CONFIG_VP3_DECODER || CONFIG_THEORA_DECODER) {

        c->vp3_v_loop_filter = ff_vp3_v_loop_filter_neon;

        c->vp3_h_loop_filter = ff_vp3_h_loop_filter_neon;

    }

    c->vector_fmul = ff_vector_fmul_neon;

    c->vector_fmul_window = ff_vector_fmul_window_neon;

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

        c->float_to_int16 = ff_float_to_int16_neon;

        c->float_to_int16_interleave = ff_float_to_int16_interleave_neon;

    }

}


static void test_qemu_strtol_full_empty(void)

{

    const char *str = "";

    long res = 999L;

    int err;

    err =  qemu_strtol(str, NULL, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, 0);

}