int avfilter_config_links(AVFilterContext *filter)

{

    int (*config_link)(AVFilterLink *);

    unsigned i;

    int ret;

    for (i = 0; i < filter->nb_inputs; i ++) {

        AVFilterLink *link = filter->inputs[i];

        AVFilterLink *inlink = link->src->nb_inputs ?

            link->src->inputs[0] : NULL;

        if (!link) continue;

        link->current_pts = AV_NOPTS_VALUE;

        switch (link->init_state) {

        case AVLINK_INIT:

            continue;

        case AVLINK_STARTINIT:

            av_log(filter, AV_LOG_INFO, "circular filter chain detected\n");

            return 0;

        case AVLINK_UNINIT:

            link->init_state = AVLINK_STARTINIT;

            if ((ret = avfilter_config_links(link->src)) < 0)

                return ret;

            if (!(config_link = link->srcpad->config_props)) {

                if (link->src->nb_inputs != 1) {

                    av_log(link->src, AV_LOG_ERROR, "Source filters and filters "

                                                    "with more than one input "

                                                    "must set config_props() "

                                                    "callbacks on all outputs\n");

                    return AVERROR(EINVAL);

                }

            } else if ((ret = config_link(link)) < 0) {

                av_log(link->src, AV_LOG_ERROR,

                       "Failed to configure output pad on %s\n",

                       link->src->name);

                return ret;

            }

            switch (link->type) {

            case AVMEDIA_TYPE_VIDEO:

                if (!link->time_base.num && !link->time_base.den)

                    link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;

                if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)

                    link->sample_aspect_ratio = inlink ?

                        inlink->sample_aspect_ratio : (AVRational){1,1};

                if (inlink && !link->frame_rate.num && !link->frame_rate.den)

                    link->frame_rate = inlink->frame_rate;

                if (inlink) {

                    if (!link->w)

                        link->w = inlink->w;

                    if (!link->h)

                        link->h = inlink->h;

                } else if (!link->w || !link->h) {

                    av_log(link->src, AV_LOG_ERROR,

                           "Video source filters must set their output link's "

                           "width and height\n");

                    return AVERROR(EINVAL);

                }

                break;

            case AVMEDIA_TYPE_AUDIO:

                if (inlink) {

                    if (!link->sample_rate)

                        link->sample_rate = inlink->sample_rate;

                    if (!link->time_base.num && !link->time_base.den)

                        link->time_base = inlink->time_base;

                    if (!link->channel_layout)

                        link->channel_layout = inlink->channel_layout;

                } else if (!link->sample_rate) {

                    av_log(link->src, AV_LOG_ERROR,

                           "Audio source filters must set their output link's "

                           "sample_rate\n");

                    return AVERROR(EINVAL);

                }

                if (!link->time_base.num && !link->time_base.den)

                    link->time_base = (AVRational) {1, link->sample_rate};

            }

            if ((config_link = link->dstpad->config_props))

                if ((ret = config_link(link)) < 0) {

                    av_log(link->src, AV_LOG_ERROR,

                           "Failed to configure input pad on %s\n",

                           link->dst->name);

                    return ret;

                }

            link->init_state = AVLINK_INIT;

        }

    }

    return 0;

}


static inline void RENAME(bgr24ToY)(uint8_t *dst, uint8_t *src, long width)

{

#ifdef HAVE_MMX

	asm volatile(

		"mov %2, %%"REG_a"		\n\t"

		"movq "MANGLE(bgr2YCoeff)", %%mm6		\n\t"

		"movq "MANGLE(w1111)", %%mm5		\n\t"

		"pxor %%mm7, %%mm7		\n\t"

		"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"\n\t"

		ASMALIGN16

		"1:				\n\t"

		PREFETCH" 64(%0, %%"REG_b")	\n\t"

		"movd (%0, %%"REG_b"), %%mm0	\n\t"

		"movd 3(%0, %%"REG_b"), %%mm1	\n\t"

		"punpcklbw %%mm7, %%mm0		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"movd 6(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 9(%0, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm0		\n\t"

		"pmaddwd %%mm6, %%mm1		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

		"pmaddwd %%mm6, %%mm3		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm0		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm1, %%mm0		\n\t"

		"packssdw %%mm3, %%mm2		\n\t"

		"pmaddwd %%mm5, %%mm0		\n\t"

		"pmaddwd %%mm5, %%mm2		\n\t"

		"packssdw %%mm2, %%mm0		\n\t"

		"psraw $7, %%mm0		\n\t"

		"movd 12(%0, %%"REG_b"), %%mm4	\n\t"

		"movd 15(%0, %%"REG_b"), %%mm1	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"movd 18(%0, %%"REG_b"), %%mm2	\n\t"

		"movd 21(%0, %%"REG_b"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm4		\n\t"

		"pmaddwd %%mm6, %%mm1		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

		"pmaddwd %%mm6, %%mm3		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm4		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm1, %%mm4		\n\t"

		"packssdw %%mm3, %%mm2		\n\t"

		"pmaddwd %%mm5, %%mm4		\n\t"

		"pmaddwd %%mm5, %%mm2		\n\t"

		"add $24, %%"REG_b"		\n\t"

		"packssdw %%mm2, %%mm4		\n\t"

		"psraw $7, %%mm4		\n\t"

		"packuswb %%mm4, %%mm0		\n\t"

		"paddusb "MANGLE(bgr2YOffset)", %%mm0	\n\t"

		"movq %%mm0, (%1, %%"REG_a")	\n\t"

		"add $8, %%"REG_a"		\n\t"

		" js 1b				\n\t"

		: : "r" (src+width*3), "r" (dst+width), "g" (-width)

		: "%"REG_a, "%"REG_b

	);

#else

	int i;

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

	{

		int b= src[i*3+0];

		int g= src[i*3+1];

		int r= src[i*3+2];

		dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);

	}

#endif

}


static inline int decode_subframe(FLACContext *s, int channel)

{

    int type, wasted = 0;

    int i, tmp;

    s->curr_bps = s->bps;

    if (channel == 0) {

        if (s->decorrelation == RIGHT_SIDE)

            s->curr_bps++;

    } else {

        if (s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE)

            s->curr_bps++;

    }

    if (s->curr_bps > 32) {

        ff_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0);

        return -1;

    }

    if (get_bits1(&s->gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");

        return -1;

    }

    type = get_bits(&s->gb, 6);

    if (get_bits1(&s->gb)) {

        wasted = 1;

        while (!get_bits1(&s->gb))

            wasted++;

        s->curr_bps -= wasted;

    }

//FIXME use av_log2 for types

    if (type == 0) {

        tmp = get_sbits_long(&s->gb, s->curr_bps);

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

            s->decoded[channel][i] = tmp;

    } else if (type == 1) {

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

            s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps);

    } else if ((type >= 8) && (type <= 12)) {

        if (decode_subframe_fixed(s, channel, type & ~0x8) < 0)

            return -1;

    } else if (type >= 32) {

        if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0)

            return -1;

    } else {

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

        return -1;

    }

    if (wasted) {

        int i;

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

            s->decoded[channel][i] <<= wasted;

    }

    return 0;

}


static void unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)

{

    int bit = 0;

    int current_superblock = 0;

    int current_run = 0;

    int decode_fully_flags = 0;

    int decode_partial_blocks = 0;

    int i, j;

    int current_fragment;

    debug_vp3("  vp3: unpacking superblock coding\n");

    if (s->keyframe) {

        debug_vp3("    keyframe-- all superblocks are fully coded\n");

        memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);

    } else {

        /* unpack the list of partially-coded superblocks */

        bit = get_bits(gb, 1);

        /* toggle the bit because as soon as the first run length is

         * fetched the bit will be toggled again */

        bit ^= 1;

        while (current_superblock < s->superblock_count) {

            if (current_run == 0) {

                bit ^= 1;

                current_run = get_superblock_run_length(gb);

                debug_block_coding("      setting superblocks %d..%d to %s\n",

                    current_superblock,

                    current_superblock + current_run - 1,

                    (bit) ? "partially coded" : "not coded");

                /* if any of the superblocks are not partially coded, flag

                 * a boolean to decode the list of fully-coded superblocks */

                if (bit == 0)

                    decode_fully_flags = 1;

            } else {

                /* make a note of the fact that there are partially coded

                 * superblocks */

                decode_partial_blocks = 1;

            }

            s->superblock_coding[current_superblock++] =

                (bit) ? SB_PARTIALLY_CODED : SB_NOT_CODED;

            current_run--;

        }

        /* unpack the list of fully coded superblocks if any of the blocks were

         * not marked as partially coded in the previous step */

        if (decode_fully_flags) {

            current_superblock = 0;

            current_run = 0;

            bit = get_bits(gb, 1);

            /* toggle the bit because as soon as the first run length is

             * fetched the bit will be toggled again */

            bit ^= 1;

            while (current_superblock < s->superblock_count) {

                /* skip any superblocks already marked as partially coded */

                if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {

                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_superblock_run_length(gb);

                    }

                    debug_block_coding("      setting superblock %d to %s\n",

                        current_superblock,

                        (bit) ? "fully coded" : "not coded");

                    s->superblock_coding[current_superblock] =

                        (bit) ? SB_FULLY_CODED : SB_NOT_CODED;

                    current_run--;

                }

                current_superblock++;

            }

        }

        /* if there were partial blocks, initialize bitstream for

         * unpacking fragment codings */

        if (decode_partial_blocks) {

            current_run = 0;

            bit = get_bits(gb, 1);

            /* toggle the bit because as soon as the first run length is

             * fetched the bit will be toggled again */

            bit ^= 1;

        }

    }

    /* figure out which fragments are coded; iterate through each

     * superblock (all planes) */

    s->coded_fragment_list_index = 0;

    s->first_coded_y_fragment = s->first_coded_c_fragment = 0;

    s->last_coded_y_fragment = s->last_coded_c_fragment = -1;

    memset(s->macroblock_coded, 0, s->macroblock_count);

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

        /* iterate through all 16 fragments in a superblock */

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

            /* if the fragment is in bounds, check its coding status */

            current_fragment = s->superblock_fragments[i * 16 + j];

            if (current_fragment != -1) {

                if (s->superblock_coding[i] == SB_NOT_CODED) {

                    /* copy all the fragments from the prior frame */

                    s->all_fragments[current_fragment].coding_method =

                        MODE_COPY;

                } else if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {

                    /* fragment may or may not be coded; this is the case

                     * that cares about the fragment coding runs */

                    if (current_run == 0) {

                        bit ^= 1;

                        current_run = get_fragment_run_length(gb);

                    }

                    if (bit) {

                        /* mode will be decoded in the next phase */

                        s->all_fragments[current_fragment].coding_method =

                            MODE_INTER_NO_MV;

                        s->coded_fragment_list[s->coded_fragment_list_index] =

                            current_fragment;

                        if ((current_fragment >= s->u_fragment_start) &&

                            (s->last_coded_y_fragment == -1)) {

                            s->first_coded_c_fragment = s->coded_fragment_list_index;

                            s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                        }

                        s->coded_fragment_list_index++;

                        s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is coded\n",

                            i, current_fragment);

                    } else {

                        /* not coded; copy this fragment from the prior frame */

                        s->all_fragments[current_fragment].coding_method =

                            MODE_COPY;

                        debug_block_coding("      superblock %d is partially coded, fragment %d is not coded\n",

                            i, current_fragment);

                    }

                    current_run--;

                } else {

                    /* fragments are fully coded in this superblock; actual

                     * coding will be determined in next step */

                    s->all_fragments[current_fragment].coding_method =

                        MODE_INTER_NO_MV;

                    s->coded_fragment_list[s->coded_fragment_list_index] =

                        current_fragment;

                    if ((current_fragment >= s->u_fragment_start) &&

                        (s->last_coded_y_fragment == -1)) {

                        s->first_coded_c_fragment = s->coded_fragment_list_index;

                        s->last_coded_y_fragment = s->first_coded_c_fragment - 1;

                    }

                    s->coded_fragment_list_index++;

                    s->macroblock_coded[s->all_fragments[current_fragment].macroblock] = 1;

                    debug_block_coding("      superblock %d is fully coded, fragment %d is coded\n",

                        i, current_fragment);

                }

            }

        }

    }

    if (s->first_coded_c_fragment == 0)

        /* no C fragments coded */

        s->last_coded_y_fragment = s->coded_fragment_list_index - 1;

    else

        s->last_coded_c_fragment = s->coded_fragment_list_index - 1;

    debug_block_coding("    %d total coded fragments, y: %d -> %d, c: %d -> %d\n",

        s->coded_fragment_list_index,

        s->first_coded_y_fragment,

        s->last_coded_y_fragment,

        s->first_coded_c_fragment,

        s->last_coded_c_fragment);

}


static int svq1_decode_delta_block(MpegEncContext *s, GetBitContext *bitbuf,

                                   uint8_t *current, uint8_t *previous,

                                   int pitch, svq1_pmv *motion, int x, int y)

{

    uint32_t block_type;

    int result = 0;

    /* get block type */

    block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2);

    /* reset motion vectors */

    if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) {

        motion[0].x         =

        motion[0].y         =

        motion[x / 8 + 2].x =

        motion[x / 8 + 2].y =

        motion[x / 8 + 3].x =

        motion[x / 8 + 3].y = 0;

    }

    switch (block_type) {

    case SVQ1_BLOCK_SKIP:

        svq1_skip_block(current, previous, pitch, x, y);

        break;

    case SVQ1_BLOCK_INTER:

        result = svq1_motion_inter_block(s, bitbuf, current, previous,

                                         pitch, motion, x, y);

        if (result != 0) {

            av_dlog(s->avctx, "Error in svq1_motion_inter_block %i\n", result);

            break;

        }

        result = svq1_decode_block_non_intra(bitbuf, current, pitch);

        break;

    case SVQ1_BLOCK_INTER_4V:

        result = svq1_motion_inter_4v_block(s, bitbuf, current, previous,

                                            pitch, motion, x, y);

        if (result != 0) {

            av_dlog(s->avctx,

                    "Error in svq1_motion_inter_4v_block %i\n", result);

            break;

        }

        result = svq1_decode_block_non_intra(bitbuf, current, pitch);

        break;

    case SVQ1_BLOCK_INTRA:

        result = svq1_decode_block_intra(bitbuf, current, pitch);

        break;

    }

    return result;

}


int ff_h263_decode_mb(MpegEncContext *s,

                      DCTELEM block[6][64])

{

    int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;

    INT16 *mot_val;

    static INT8 quant_tab[4] = { -1, -2, 1, 2 };

    s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;

    if(s->mb_x==0) PRINT_MB_TYPE("\n");

    if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) {

        if (get_bits1(&s->gb)) {

            /* skip mb */

            s->mb_intra = 0;

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

                s->block_last_index[i] = -1;

            s->mv_dir = MV_DIR_FORWARD;

            s->mv_type = MV_TYPE_16X16;

            if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){

                PRINT_MB_TYPE("G");

                s->mcsel=1;

                s->mv[0][0][0]= get_amv(s, 0);

                s->mv[0][0][1]= get_amv(s, 1);

                s->mb_skiped = 0;

            }else{

                PRINT_MB_TYPE("S");

                s->mcsel=0;

                s->mv[0][0][0] = 0;

                s->mv[0][0][1] = 0;

                s->mb_skiped = 1;

            }

            goto end;

        }

        cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);

        //fprintf(stderr, "\tCBPC: %d", cbpc);

        if (cbpc < 0)

            return -1;

        if (cbpc > 20)

            cbpc+=3;

        else if (cbpc == 20)

            fprintf(stderr, "Stuffing !");

        dquant = cbpc & 8;

        s->mb_intra = ((cbpc & 4) != 0);

        if (s->mb_intra) goto intra;

        if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)

            s->mcsel= get_bits1(&s->gb);

        else s->mcsel= 0;

        cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);

        cbp = (cbpc & 3) | ((cbpy ^ 0xf) << 2);

        if (dquant) {

            change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);

        }

        if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE)))

            s->interlaced_dct= get_bits1(&s->gb);

        s->mv_dir = MV_DIR_FORWARD;

        if ((cbpc & 16) == 0) {

            if(s->mcsel){

                PRINT_MB_TYPE("G");

                /* 16x16 global motion prediction */

                s->mv_type = MV_TYPE_16X16;

                mx= get_amv(s, 0);

                my= get_amv(s, 1);

                s->mv[0][0][0] = mx;

                s->mv[0][0][1] = my;

            }else if((!s->progressive_sequence) && get_bits1(&s->gb)){

                PRINT_MB_TYPE("f");

                /* 16x8 field motion prediction */

                s->mv_type= MV_TYPE_FIELD;

                s->field_select[0][0]= get_bits1(&s->gb);

                s->field_select[0][1]= get_bits1(&s->gb);

                h263_pred_motion(s, 0, &pred_x, &pred_y);

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

                    mx = h263_decode_motion(s, pred_x, s->f_code);

                    if (mx >= 0xffff)

                        return -1;

                    my = h263_decode_motion(s, pred_y/2, s->f_code);

                    if (my >= 0xffff)

                        return -1;

                    s->mv[0][i][0] = mx;

                    s->mv[0][i][1] = my;

                }

            }else{

                PRINT_MB_TYPE("P");

                /* 16x16 motion prediction */

                s->mv_type = MV_TYPE_16X16;

                h263_pred_motion(s, 0, &pred_x, &pred_y);

                if (s->umvplus_dec)

                   mx = h263p_decode_umotion(s, pred_x);

                else

                   mx = h263_decode_motion(s, pred_x, s->f_code);

                if (mx >= 0xffff)

                    return -1;

                if (s->umvplus_dec)

                   my = h263p_decode_umotion(s, pred_y);

                else

                   my = h263_decode_motion(s, pred_y, s->f_code);

                if (my >= 0xffff)

                    return -1;

                s->mv[0][0][0] = mx;

                s->mv[0][0][1] = my;

                if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1)

                   skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */

            }

        } else {

            PRINT_MB_TYPE("4");

            s->mv_type = MV_TYPE_8X8;

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

                mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);

                if (s->umvplus_dec)

                  mx = h263p_decode_umotion(s, pred_x);

                else

                  mx = h263_decode_motion(s, pred_x, s->f_code);

                if (mx >= 0xffff)

                    return -1;

                if (s->umvplus_dec)

                  my = h263p_decode_umotion(s, pred_y);

                else

                  my = h263_decode_motion(s, pred_y, s->f_code);

                if (my >= 0xffff)

                    return -1;

                s->mv[0][i][0] = mx;

                s->mv[0][i][1] = my;

                if (s->umvplus_dec && (mx - pred_x) == 1 && (my - pred_y) == 1)

                  skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */

                mot_val[0] = mx;

                mot_val[1] = my;

            }

        }

    } else if(s->pict_type==B_TYPE) {

        int modb1; // first bit of modb

        int modb2; // second bit of modb

        int mb_type;

        int xy;

        s->mb_intra = 0; //B-frames never contain intra blocks

        s->mcsel=0;      //     ...               true gmc blocks

        if(s->mb_x==0){

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

                s->last_mv[i][0][0]=

                s->last_mv[i][0][1]=

                s->last_mv[i][1][0]=

                s->last_mv[i][1][1]= 0;

            }

        }

        /* if we skipped it in the future P Frame than skip it now too */

        s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC

        if(s->mb_skiped){

                /* skip mb */

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

                s->block_last_index[i] = -1;

            s->mv_dir = MV_DIR_FORWARD;

            s->mv_type = MV_TYPE_16X16;

            s->mv[0][0][0] = 0;

            s->mv[0][0][1] = 0;

            s->mv[1][0][0] = 0;

            s->mv[1][0][1] = 0;

            PRINT_MB_TYPE("s");

            goto end;

        }

        modb1= get_bits1(&s->gb);

        if(modb1){

            mb_type=4; //like MB_TYPE_B_DIRECT but no vectors coded

            cbp=0;

        }else{

            int field_mv;

            modb2= get_bits1(&s->gb);

            mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);

            if(modb2) cbp= 0;

            else      cbp= get_bits(&s->gb, 6);

            if (mb_type!=MB_TYPE_B_DIRECT && cbp) {

                if(get_bits1(&s->gb)){

                    change_qscale(s, get_bits1(&s->gb)*4 - 2);

                }

            }

            field_mv=0;

            if(!s->progressive_sequence){

                if(cbp)

                    s->interlaced_dct= get_bits1(&s->gb);

                if(mb_type!=MB_TYPE_B_DIRECT && get_bits1(&s->gb)){

                    field_mv=1;

                    if(mb_type!=MB_TYPE_B_BACKW){

                        s->field_select[0][0]= get_bits1(&s->gb);

                        s->field_select[0][1]= get_bits1(&s->gb);

                    }

                    if(mb_type!=MB_TYPE_B_FORW){

                        s->field_select[1][0]= get_bits1(&s->gb);

                        s->field_select[1][1]= get_bits1(&s->gb);

                    }

                }

            }

            s->mv_dir = 0;

            if(mb_type!=MB_TYPE_B_DIRECT && !field_mv){

                s->mv_type= MV_TYPE_16X16;

                if(mb_type!=MB_TYPE_B_BACKW){

                    s->mv_dir = MV_DIR_FORWARD;

                    mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);

                    my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);

                    s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx;

                    s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my;

                }

                if(mb_type!=MB_TYPE_B_FORW){

                    s->mv_dir |= MV_DIR_BACKWARD;

                    mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);

                    my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);

                    s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx;

                    s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my;

                }

                if(mb_type!=MB_TYPE_B_DIRECT)

                    PRINT_MB_TYPE(mb_type==MB_TYPE_B_FORW ? "F" : (mb_type==MB_TYPE_B_BACKW ? "B" : "T"));

            }else if(mb_type!=MB_TYPE_B_DIRECT){

                s->mv_type= MV_TYPE_FIELD;

                if(mb_type!=MB_TYPE_B_BACKW){

                    s->mv_dir = MV_DIR_FORWARD;

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

                        mx = h263_decode_motion(s, s->last_mv[0][i][0]  , s->f_code);

                        my = h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code);

                        s->last_mv[0][i][0]=  s->mv[0][i][0] = mx;

                        s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2;

                    }

                }

                if(mb_type!=MB_TYPE_B_FORW){

                    s->mv_dir |= MV_DIR_BACKWARD;

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

                        mx = h263_decode_motion(s, s->last_mv[1][i][0]  , s->b_code);

                        my = h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code);

                        s->last_mv[1][i][0]=  s->mv[1][i][0] = mx;

                        s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2;

                    }

                }

                if(mb_type!=MB_TYPE_B_DIRECT)

                    PRINT_MB_TYPE(mb_type==MB_TYPE_B_FORW ? "f" : (mb_type==MB_TYPE_B_BACKW ? "b" : "t"));

            }

        }

        if(mb_type==4 || mb_type==MB_TYPE_B_DIRECT){

            if(mb_type==4)

                mx=my=0;

            else{

                mx = h263_decode_motion(s, 0, 1);

                my = h263_decode_motion(s, 0, 1);

            }

            s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;

            ff_mpeg4_set_direct_mv(s, mx, my);

        }

        if(mb_type<0 || mb_type>4){

            printf("illegal MB_type\n");

            return -1;

        }

    } else { /* I-Frame */

        cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1);

        if (cbpc < 0)

            return -1;

        dquant = cbpc & 4;

        s->mb_intra = 1;

intra:

        s->ac_pred = 0;

        if (s->h263_pred || s->h263_aic) {

            s->ac_pred = get_bits1(&s->gb);

            if (s->ac_pred && s->h263_aic)

                s->h263_aic_dir = get_bits1(&s->gb);

        }

        PRINT_MB_TYPE(s->ac_pred ? "A" : "I");

        cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);

        if(cbpy<0) return -1;

        cbp = (cbpc & 3) | (cbpy << 2);

        if (dquant) {

            change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);

        }

        if(!s->progressive_sequence)

            s->interlaced_dct= get_bits1(&s->gb);

        /* decode each block */

        if (s->h263_pred) {

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

                if (mpeg4_decode_block(s, block[i], i, cbp&32, 1) < 0)

                    return -1;

                cbp+=cbp;

            }

        } else {

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

                if (h263_decode_block(s, block[i], i, cbp&32) < 0)

                    return -1;

                cbp+=cbp;

            }

        }

        goto end;

    }

    /* decode each block */

    if (s->h263_pred) {

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

            if (mpeg4_decode_block(s, block[i], i, cbp&32, 0) < 0)

                return -1;

            cbp+=cbp;

        }

    } else {

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

            if (h263_decode_block(s, block[i], i, cbp&32) < 0)

                return -1;

            cbp+=cbp;

        }

    }

end:

        /* per-MB end of slice check */

    if(s->codec_id==CODEC_ID_MPEG4){

        if(mpeg4_is_resync(s)){

            if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x+1])

                return SLICE_OK;

            return SLICE_END;

        }

    }else{

        int v= show_bits(&s->gb, 16);

        if(get_bits_count(&s->gb) + 16 > s->gb.size*8){

            v>>= get_bits_count(&s->gb) + 16 - s->gb.size*8;

        }

        if(v==0)

            return SLICE_END;

    }

    return SLICE_OK;

}


void qemu_mutex_init(QemuMutex *mutex)

{

    int err;

    pthread_mutexattr_t mutexattr;

    pthread_mutexattr_init(&mutexattr);

    pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);

    err = pthread_mutex_init(&mutex->lock, &mutexattr);

    pthread_mutexattr_destroy(&mutexattr);

    if (err)

        error_exit(err, __func__);

}


static int old_codec47(SANMVideoContext *ctx, int top,
                       int left, int width, int height)
{
    int i, j, seq, compr, new_rot, tbl_pos, skip;
    int stride     = ctx->pitch;
    uint8_t *dst   = ((uint8_t*)ctx->frm0) + left + top * stride;
    uint8_t *prev1 = (uint8_t*)ctx->frm1;
    uint8_t *prev2 = (uint8_t*)ctx->frm2;
    uint32_t decoded_size;
    tbl_pos = bytestream2_tell(&ctx->gb);
    seq     = bytestream2_get_le16(&ctx->gb);
    compr   = bytestream2_get_byte(&ctx->gb);
    new_rot = bytestream2_get_byte(&ctx->gb);
    skip    = bytestream2_get_byte(&ctx->gb);
    bytestream2_skip(&ctx->gb, 9);
    decoded_size = bytestream2_get_le32(&ctx->gb);
    bytestream2_skip(&ctx->gb, 8);
    if (skip & 1)
        bytestream2_skip(&ctx->gb, 0x8080);
    if (!seq) {
        ctx->prev_seq = -1;
        memset(prev1, 0, ctx->height * stride);
        memset(prev2, 0, ctx->height * stride);
    av_dlog(ctx->avctx, "compression %d\n", compr);
    switch (compr) {
    case 0:
        if (bytestream2_get_bytes_left(&ctx->gb) < width * height)
            return AVERROR_INVALIDDATA;
        for (j = 0; j < height; j++) {
            bytestream2_get_bufferu(&ctx->gb, dst, width);
            dst += stride;
        break;
    case 1:
        if (bytestream2_get_bytes_left(&ctx->gb) < ((width + 1) >> 1) * ((height + 1) >> 1))
            return AVERROR_INVALIDDATA;
        for (j = 0; j < height; j += 2) {
            for (i = 0; i < width; i += 2) {
                dst[i] = dst[i + 1] =
                dst[stride + i] = dst[stride + i + 1] = bytestream2_get_byteu(&ctx->gb);
            dst += stride * 2;
        break;
    case 2:
        if (seq == ctx->prev_seq + 1) {
            for (j = 0; j < height; j += 8) {
                for (i = 0; i < width; i += 8) {
                    if (process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
                                      tbl_pos + 8, 8))
                        return AVERROR_INVALIDDATA;
                dst   += stride * 8;
                prev1 += stride * 8;
                prev2 += stride * 8;
        break;
    case 3:
        memcpy(ctx->frm0, ctx->frm2, ctx->pitch * ctx->height);
        break;
    case 4:
        memcpy(ctx->frm0, ctx->frm1, ctx->pitch * ctx->height);
        break;
    case 5:
        if (rle_decode(ctx, dst, decoded_size))
            return AVERROR_INVALIDDATA;
        break;
    default:
        av_log(ctx->avctx, AV_LOG_ERROR,
               "subcodec 47 compression %d not implemented\n", compr);
        return AVERROR_PATCHWELCOME;
    if (seq == ctx->prev_seq + 1)
        ctx->rotate_code = new_rot;
    else
        ctx->rotate_code = 0;
    ctx->prev_seq = seq;
    return 0;


static av_cold int cinvideo_decode_end(AVCodecContext *avctx)

{

    CinVideoContext *cin = avctx->priv_data;

    int i;

    if (cin->frame.data[0])

        avctx->release_buffer(avctx, &cin->frame);

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

        av_free(cin->bitmap_table[i]);

    return 0;

}


static int vhost_virtqueue_start(struct vhost_dev *dev,

                                struct VirtIODevice *vdev,

                                struct vhost_virtqueue *vq,

                                unsigned idx)

{

    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));

    VirtioBusState *vbus = VIRTIO_BUS(qbus);

    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);

    hwaddr s, l, a;

    int r;

    int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx);

    struct vhost_vring_file file = {

        .index = vhost_vq_index

    };

    struct vhost_vring_state state = {

        .index = vhost_vq_index

    };

    struct VirtQueue *vvq = virtio_get_queue(vdev, idx);

    vq->num = state.num = virtio_queue_get_num(vdev, idx);

    r = dev->vhost_ops->vhost_set_vring_num(dev, &state);

    if (r) {

        VHOST_OPS_DEBUG("vhost_set_vring_num failed");

        return -errno;

    }

    state.num = virtio_queue_get_last_avail_idx(vdev, idx);

    r = dev->vhost_ops->vhost_set_vring_base(dev, &state);

    if (r) {

        VHOST_OPS_DEBUG("vhost_set_vring_base failed");

        return -errno;

    }

    if (vhost_needs_vring_endian(vdev)) {

        r = vhost_virtqueue_set_vring_endian_legacy(dev,

                                                    virtio_is_big_endian(vdev),

                                                    vhost_vq_index);

        if (r) {

            return -errno;

        }

    }

    s = l = virtio_queue_get_desc_size(vdev, idx);

    a = virtio_queue_get_desc_addr(vdev, idx);

    vq->desc = cpu_physical_memory_map(a, &l, 0);

    if (!vq->desc || l != s) {

        r = -ENOMEM;

        goto fail_alloc_desc;

    }

    s = l = virtio_queue_get_avail_size(vdev, idx);

    a = virtio_queue_get_avail_addr(vdev, idx);

    vq->avail = cpu_physical_memory_map(a, &l, 0);

    if (!vq->avail || l != s) {

        r = -ENOMEM;

        goto fail_alloc_avail;

    }

    vq->used_size = s = l = virtio_queue_get_used_size(vdev, idx);

    vq->used_phys = a = virtio_queue_get_used_addr(vdev, idx);

    vq->used = cpu_physical_memory_map(a, &l, 1);

    if (!vq->used || l != s) {

        r = -ENOMEM;

        goto fail_alloc_used;

    }

    vq->ring_size = s = l = virtio_queue_get_ring_size(vdev, idx);

    vq->ring_phys = a = virtio_queue_get_ring_addr(vdev, idx);

    vq->ring = cpu_physical_memory_map(a, &l, 1);

    if (!vq->ring || l != s) {

        r = -ENOMEM;

        goto fail_alloc_ring;

    }

    r = vhost_virtqueue_set_addr(dev, vq, vhost_vq_index, dev->log_enabled);

    if (r < 0) {

        r = -errno;

        goto fail_alloc;

    }

    file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));

    r = dev->vhost_ops->vhost_set_vring_kick(dev, &file);

    if (r) {

        VHOST_OPS_DEBUG("vhost_set_vring_kick failed");

        r = -errno;

        goto fail_kick;

    }

    /* Clear and discard previous events if any. */

    event_notifier_test_and_clear(&vq->masked_notifier);

    /* Init vring in unmasked state, unless guest_notifier_mask

     * will do it later.

     */

    if (!vdev->use_guest_notifier_mask) {

        /* TODO: check and handle errors. */

        vhost_virtqueue_mask(dev, vdev, idx, false);

    }

    if (k->query_guest_notifiers &&

        k->query_guest_notifiers(qbus->parent) &&

        virtio_queue_vector(vdev, idx) == VIRTIO_NO_VECTOR) {

        file.fd = -1;

        r = dev->vhost_ops->vhost_set_vring_call(dev, &file);

        if (r) {

            goto fail_vector;

        }

    }

    return 0;

fail_vector:

fail_kick:

fail_alloc:

    cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),

                              0, 0);

fail_alloc_ring:

    cpu_physical_memory_unmap(vq->used, virtio_queue_get_used_size(vdev, idx),

                              0, 0);

fail_alloc_used:

    cpu_physical_memory_unmap(vq->avail, virtio_queue_get_avail_size(vdev, idx),

                              0, 0);

fail_alloc_avail:

    cpu_physical_memory_unmap(vq->desc, virtio_queue_get_desc_size(vdev, idx),

                              0, 0);

fail_alloc_desc:

    return r;

}


int qemu_v9fs_synth_add_file(V9fsSynthNode *parent, int mode,

                             const char *name, v9fs_synth_read read,

                             v9fs_synth_write write, void *arg)

{

    int ret;

    V9fsSynthNode *node, *tmp;

    if (!v9fs_synth_fs) {

        return EAGAIN;

    }

    if (!name || (strlen(name) >= NAME_MAX)) {

        return EINVAL;

    }

    if (!parent) {

        parent = &v9fs_synth_root;

    }

    qemu_mutex_lock(&v9fs_synth_mutex);

    QLIST_FOREACH(tmp, &parent->child, sibling) {

        if (!strcmp(tmp->name, name)) {

            ret = EEXIST;

            goto err_out;

        }

    }

    /* Add file type and remove write bits */

    mode = ((mode & 0777) | S_IFREG);

    node = g_malloc0(sizeof(V9fsSynthNode));

    node->attr         = &node->actual_attr;

    node->attr->inode  = v9fs_synth_node_count++;

    node->attr->nlink  = 1;

    node->attr->read   = read;

    node->attr->write  = write;

    node->attr->mode   = mode;

    node->private      = arg;

    strncpy(node->name, name, sizeof(node->name));

    QLIST_INSERT_HEAD_RCU(&parent->child, node, sibling);

    ret = 0;

err_out:

    qemu_mutex_unlock(&v9fs_synth_mutex);

    return ret;

}


PPC_OP(extsb)

{

    T0 = (int32_t)((int8_t)(Ts0));

    RETURN();

}


static int qemu_rdma_broken_ipv6_kernel(Error **errp, struct ibv_context *verbs)

{

    struct ibv_port_attr port_attr;

    /* This bug only exists in linux, to our knowledge. */

#ifdef CONFIG_LINUX

    /*

     * Verbs are only NULL if management has bound to '[::]'.

     *

     * Let's iterate through all the devices and see if there any pure IB

     * devices (non-ethernet).

     *

     * If not, then we can safely proceed with the migration.

     * Otherwise, there are no guarantees until the bug is fixed in linux.

     */

        int num_devices, x;

        struct ibv_device ** dev_list = ibv_get_device_list(&num_devices);

        bool roce_found = false;

        bool ib_found = false;

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

            verbs = ibv_open_device(dev_list[x]);

            if (ibv_query_port(verbs, 1, &port_attr)) {

                ibv_close_device(verbs);

                ERROR(errp, "Could not query initial IB port");

            if (port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) {

                ib_found = true;

            } else if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET) {

                roce_found = true;

            ibv_close_device(verbs);

        if (roce_found) {

            if (ib_found) {

                fprintf(stderr, "WARN: migrations may fail:"

                                " IPv6 over RoCE / iWARP in linux"

                                " is broken. But since you appear to have a"

                                " mixed RoCE / IB environment, be sure to only"

                                " migrate over the IB fabric until the kernel "

                                " fixes the bug.\n");

                ERROR(errp, "You only have RoCE / iWARP devices in your systems"

                            " and your management software has specified '[::]'"

                            ", but IPv6 over RoCE / iWARP is not supported in Linux.");

                return -ENONET;

        return 0;

    /*

     * If we have a verbs context, that means that some other than '[::]' was

     * used by the management software for binding. In which case we can

     * actually warn the user about a potentially broken kernel.

     */

    /* IB ports start with 1, not 0 */

    if (ibv_query_port(verbs, 1, &port_attr)) {

        ERROR(errp, "Could not query initial IB port");

    if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET) {

        ERROR(errp, "Linux kernel's RoCE / iWARP does not support IPv6 "

                    "(but patches on linux-rdma in progress)");

        return -ENONET;

#endif

    return 0;


static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,

                         unsigned int epid, unsigned int streamid)

{

    XHCIStreamContext *stctx;

    XHCIEPContext *epctx;

    XHCIRing *ring;

    USBEndpoint *ep = NULL;

    uint64_t mfindex;

    int length;

    int i;

    trace_usb_xhci_ep_kick(slotid, epid, streamid);

    assert(slotid >= 1 && slotid <= xhci->numslots);

    assert(epid >= 1 && epid <= 31);

    if (!xhci->slots[slotid-1].enabled) {

        fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid);

        return;

    }

    epctx = xhci->slots[slotid-1].eps[epid-1];

    if (!epctx) {

        fprintf(stderr, "xhci: xhci_kick_ep for disabled endpoint %d,%d\n",

                epid, slotid);

        return;

    }

    if (epctx->retry) {

        XHCITransfer *xfer = epctx->retry;

        trace_usb_xhci_xfer_retry(xfer);

        assert(xfer->running_retry);

        if (xfer->iso_xfer) {

            /* retry delayed iso transfer */

            mfindex = xhci_mfindex_get(xhci);

            xhci_check_iso_kick(xhci, xfer, epctx, mfindex);

            if (xfer->running_retry) {

                return;

            }

            if (xhci_setup_packet(xfer) < 0) {

                return;

            }

            usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);

            assert(xfer->packet.status != USB_RET_NAK);

            xhci_complete_packet(xfer);

        } else {

            /* retry nak'ed transfer */

            if (xhci_setup_packet(xfer) < 0) {

                return;

            }

            usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);

            if (xfer->packet.status == USB_RET_NAK) {

                return;

            }

            xhci_complete_packet(xfer);

        }

        assert(!xfer->running_retry);

        epctx->retry = NULL;

    }

    if (epctx->state == EP_HALTED) {

        DPRINTF("xhci: ep halted, not running schedule\n");

        return;

    }

    if (epctx->nr_pstreams) {

        uint32_t err;

        stctx = xhci_find_stream(epctx, streamid, &err);

        if (stctx == NULL) {

            return;

        }

        ring = &stctx->ring;

        xhci_set_ep_state(xhci, epctx, stctx, EP_RUNNING);

    } else {

        ring = &epctx->ring;

        streamid = 0;

        xhci_set_ep_state(xhci, epctx, NULL, EP_RUNNING);

    }

    assert(ring->dequeue != 0);

    while (1) {

        XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer];

        if (xfer->running_async || xfer->running_retry) {

            break;

        }

        length = xhci_ring_chain_length(xhci, ring);

        if (length < 0) {

            break;

        } else if (length == 0) {

            break;

        }

        if (xfer->trbs && xfer->trb_alloced < length) {

            xfer->trb_count = 0;

            xfer->trb_alloced = 0;

            g_free(xfer->trbs);

            xfer->trbs = NULL;

        }

        if (!xfer->trbs) {

            xfer->trbs = g_malloc(sizeof(XHCITRB) * length);

            xfer->trb_alloced = length;

        }

        xfer->trb_count = length;

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

            assert(xhci_ring_fetch(xhci, ring, &xfer->trbs[i], NULL));

        }

        xfer->xhci = xhci;

        xfer->epid = epid;

        xfer->slotid = slotid;

        xfer->streamid = streamid;

        if (epid == 1) {

            if (xhci_fire_ctl_transfer(xhci, xfer) >= 0) {

                epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;

                ep = xfer->packet.ep;

            } else {

                fprintf(stderr, "xhci: error firing CTL transfer\n");

            }

        } else {

            if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) {

                epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;

                ep = xfer->packet.ep;

            } else {

                if (!xfer->iso_xfer) {

                    fprintf(stderr, "xhci: error firing data transfer\n");

                }

            }

        }

        if (epctx->state == EP_HALTED) {

            break;

        }

        if (xfer->running_retry) {

            DPRINTF("xhci: xfer nacked, stopping schedule\n");

            epctx->retry = xfer;

            break;

        }

    }

    if (ep) {

        usb_device_flush_ep_queue(ep->dev, ep);

    }

}


static int rv10_decode_init(AVCodecContext *avctx)

{

    MpegEncContext *s = avctx->priv_data;

    static int done=0;

    MPV_decode_defaults(s);

    s->avctx= avctx;

    s->out_format = FMT_H263;

    s->codec_id= avctx->codec_id;

    s->width = avctx->width;

    s->height = avctx->height;

    switch(avctx->sub_id){

    case 0x10000000:

        s->rv10_version= 0;

        s->h263_long_vectors=0;

        s->low_delay=1;

        break;

    case 0x10002000:

        s->rv10_version= 3;

        s->h263_long_vectors=1;

        s->low_delay=1;

        s->obmc=1;

        break;

    case 0x10003000:

        s->rv10_version= 3;

        s->h263_long_vectors=1;

        s->low_delay=1;

        break;

    case 0x10003001:

        s->rv10_version= 3;

        s->h263_long_vectors=0;

        s->low_delay=1;

        break;

    case 0x20001000:

    case 0x20100001:

    case 0x20101001:

    case 0x20103001:

        s->low_delay=1;

        break;

    case 0x20200002:

    case 0x20201002:

    case 0x30202002:

    case 0x30203002:

        s->low_delay=0;

        s->avctx->has_b_frames=1;

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id);

    }

//av_log(avctx, AV_LOG_DEBUG, "ver:%X\n", avctx->sub_id);

    if (MPV_common_init(s) < 0)

        return -1;

    h263_decode_init_vlc(s);

    /* init rv vlc */

    if (!done) {

        init_vlc(&rv_dc_lum, DC_VLC_BITS, 256,

                 rv_lum_bits, 1, 1,

                 rv_lum_code, 2, 2);

        init_vlc(&rv_dc_chrom, DC_VLC_BITS, 256,

                 rv_chrom_bits, 1, 1,

                 rv_chrom_code, 2, 2);

        done = 1;

    }

    avctx->pix_fmt = PIX_FMT_YUV420P;

    return 0;

}


static uint64_t get_vb(ByteIOContext *bc){

    uint64_t val=0;

    int i= get_v(bc);

    if(i>8)

        return UINT64_MAX;

    while(i--)

        val = (val<<8) + get_byte(bc);

//av_log(NULL, AV_LOG_DEBUG, "get_vb()= %lld\n", val);

    return val;

}


static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)

{

    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;

    qpci_io_writew(dev->pdev, dev->addr + VIRTIO_PCI_QUEUE_NOTIFY, vq->index);

}


static av_always_inline void decode_bgr_1(HYuvContext *s, int count,

                                          int decorrelate, int alpha)

{

    int i;

    OPEN_READER(re, &s->gb);

    for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {

        unsigned int index;

        int code, n;

        UPDATE_CACHE(re, &s->gb);

        index = SHOW_UBITS(re, &s->gb, VLC_BITS);

        n     = s->vlc[4].table[index][1];

        if (n>0) {

            code  = s->vlc[4].table[index][0];

            *(uint32_t*)&s->temp[0][4 * i] = s->pix_bgr_map[code];

            LAST_SKIP_BITS(re, &s->gb, n);

        } else {

            int nb_bits;

            if(decorrelate) {

                VLC_INTERN(s->temp[0][4 * i + G], s->vlc[1].table,

                           &s->gb, re, VLC_BITS, 3);

                UPDATE_CACHE(re, &s->gb);

                index = SHOW_UBITS(re, &s->gb, VLC_BITS);

                VLC_INTERN(code, s->vlc[0].table, &s->gb, re, VLC_BITS, 3);

                s->temp[0][4 * i + B] = code + s->temp[0][4 * i + G];

                UPDATE_CACHE(re, &s->gb);

                index = SHOW_UBITS(re, &s->gb, VLC_BITS);

                VLC_INTERN(code, s->vlc[2].table, &s->gb, re, VLC_BITS, 3);

                s->temp[0][4 * i + R] = code + s->temp[0][4 * i + G];

            } else {

                VLC_INTERN(s->temp[0][4 * i + B], s->vlc[0].table,

                           &s->gb, re, VLC_BITS, 3);

                UPDATE_CACHE(re, &s->gb);

                index = SHOW_UBITS(re, &s->gb, VLC_BITS);

                VLC_INTERN(s->temp[0][4 * i + G], s->vlc[1].table,

                           &s->gb, re, VLC_BITS, 3);

                UPDATE_CACHE(re, &s->gb);

                index = SHOW_UBITS(re, &s->gb, VLC_BITS);

                VLC_INTERN(s->temp[0][4 * i + R], s->vlc[2].table,

                           &s->gb, re, VLC_BITS, 3);

            }

            if (alpha) {

                UPDATE_CACHE(re, &s->gb);

                index = SHOW_UBITS(re, &s->gb, VLC_BITS);

                VLC_INTERN(s->temp[0][4 * i + A], s->vlc[2].table,

                           &s->gb, re, VLC_BITS, 3);

            }

        }

    }

    CLOSE_READER(re, &s->gb);

}


static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)

{

    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);

    VirtQueueElement *elem;

    VirtIOBalloonStat stat;

    size_t offset = 0;

    qemu_timeval tv;

    s->stats_vq_elem = elem = virtqueue_pop(vq, sizeof(VirtQueueElement));

    if (!elem) {

        goto out;

    }

    /* Initialize the stats to get rid of any stale values.  This is only

     * needed to handle the case where a guest supports fewer stats than it

     * used to (ie. it has booted into an old kernel).

     */

    reset_stats(s);

    while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat))

           == sizeof(stat)) {

        uint16_t tag = virtio_tswap16(vdev, stat.tag);

        uint64_t val = virtio_tswap64(vdev, stat.val);

        offset += sizeof(stat);

        if (tag < VIRTIO_BALLOON_S_NR)

            s->stats[tag] = val;

    }

    s->stats_vq_offset = offset;

    if (qemu_gettimeofday(&tv) < 0) {

        fprintf(stderr, "warning: %s: failed to get time of day\n", __func__);

        goto out;

    }

    s->stats_last_update = tv.tv_sec;

out:

    if (balloon_stats_enabled(s)) {

        balloon_stats_change_timer(s, s->stats_poll_interval);

    }

}


static int vmdk_write(BlockDriverState *bs, int64_t sector_num,

                     const uint8_t *buf, int nb_sectors)

{

    BDRVVmdkState *s = bs->opaque;

    VmdkExtent *extent = NULL;

    int n, ret;

    int64_t index_in_cluster;

    uint64_t cluster_offset;

    VmdkMetaData m_data;

    if (sector_num > bs->total_sectors) {

        fprintf(stderr,

                "(VMDK) Wrong offset: sector_num=0x%" PRIx64

                " total_sectors=0x%" PRIx64 "\n",

                sector_num, bs->total_sectors);

        return -EIO;

    }

    while (nb_sectors > 0) {

        extent = find_extent(s, sector_num, extent);

        if (!extent) {

            return -EIO;

        }

        ret = get_cluster_offset(

                                bs,

                                extent,

                                &m_data,

                                sector_num << 9, !extent->compressed,

                                &cluster_offset);

        if (extent->compressed) {

            if (ret == 0) {

                /* Refuse write to allocated cluster for streamOptimized */

                fprintf(stderr,

                        "VMDK: can't write to allocated cluster"

                        " for streamOptimized\n");

                return -EIO;

            } else {

                /* allocate */

                ret = get_cluster_offset(

                                        bs,

                                        extent,

                                        &m_data,

                                        sector_num << 9, 1,

                                        &cluster_offset);

            }

        }

        if (ret) {

            return -EINVAL;

        }

        index_in_cluster = sector_num % extent->cluster_sectors;

        n = extent->cluster_sectors - index_in_cluster;

        if (n > nb_sectors) {

            n = nb_sectors;

        }

        ret = vmdk_write_extent(extent,

                        cluster_offset, index_in_cluster * 512,

                        buf, n, sector_num);

        if (ret) {

            return ret;

        }

        if (m_data.valid) {

            /* update L2 tables */

            if (vmdk_L2update(extent, &m_data) == -1) {

                return -EIO;

            }

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

        /* update CID on the first write every time the virtual disk is

         * opened */

        if (!s->cid_updated) {

            ret = vmdk_write_cid(bs, time(NULL));

            if (ret < 0) {

                return ret;

            }

            s->cid_updated = true;

        }

    }

    return 0;

}


av_cold void ff_fft_init_mmx(FFTContext *s)

{

#if HAVE_YASM

    int has_vectors = av_get_cpu_flags();

#if ARCH_X86_32

    if (has_vectors & AV_CPU_FLAG_3DNOW && HAVE_AMD3DNOW) {

        /* 3DNow! for K6-2/3 */

        s->imdct_calc = ff_imdct_calc_3dnow;

        s->imdct_half = ff_imdct_half_3dnow;

        s->fft_calc   = ff_fft_calc_3dnow;

    }

    if (has_vectors & AV_CPU_FLAG_3DNOWEXT && HAVE_AMD3DNOWEXT) {

        /* 3DNowEx for K7 */

        s->imdct_calc = ff_imdct_calc_3dnowext;

        s->imdct_half = ff_imdct_half_3dnowext;

        s->fft_calc   = ff_fft_calc_3dnowext;

    }

#endif

    if (has_vectors & AV_CPU_FLAG_SSE && HAVE_SSE) {

        /* SSE for P3/P4/K8 */

        s->imdct_calc  = ff_imdct_calc_sse;

        s->imdct_half  = ff_imdct_half_sse;

        s->fft_permute = ff_fft_permute_sse;

        s->fft_calc    = ff_fft_calc_sse;

        s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;

    }

    if (has_vectors & AV_CPU_FLAG_AVX && HAVE_AVX && s->nbits >= 5) {

        /* AVX for SB */

        s->imdct_half      = ff_imdct_half_avx;

        s->fft_calc        = ff_fft_calc_avx;

        s->fft_permutation = FF_FFT_PERM_AVX;

    }

#endif

}


void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)

{

POWERPC_TBL_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1);

#ifdef ALTIVEC_USE_REFERENCE_C_CODE

    int j;

POWERPC_TBL_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);

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

      int i;

      const uint32_t a = (((const struct unaligned_32 *) (pixels))->l);

      const uint32_t b =

        (((const struct unaligned_32 *) (pixels + 1))->l);

      uint32_t l0 =

        (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;

      uint32_t h0 =

        ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);

      uint32_t l1, h1;

      pixels += line_size;

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

        uint32_t a = (((const struct unaligned_32 *) (pixels))->l);

        uint32_t b = (((const struct unaligned_32 *) (pixels + 1))->l);

        l1 = (a & 0x03030303UL) + (b & 0x03030303UL);

        h1 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);

        *((uint32_t *) block) =

          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);

        pixels += line_size;

        block += line_size;

        a = (((const struct unaligned_32 *) (pixels))->l);

        b = (((const struct unaligned_32 *) (pixels + 1))->l);

        l0 = (a & 0x03030303UL) + (b & 0x03030303UL) + 0x01010101UL;

        h0 = ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2);

        *((uint32_t *) block) =

          h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL);

        pixels += line_size;

        block += line_size;

      } pixels += 4 - line_size * (h + 1);

      block += 4 - line_size * h;

    }

POWERPC_TBL_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);

#else /* ALTIVEC_USE_REFERENCE_C_CODE */

   register int i;

   register vector unsigned char

     pixelsv1, pixelsv2,

     pixelsavg;

   register vector unsigned char

     blockv, temp1, temp2;

   register vector unsigned short

     pixelssum1, pixelssum2, temp3;

   register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);

   register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);

   register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);

   temp1 = vec_ld(0, pixels);

   temp2 = vec_ld(16, pixels);

   pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));

   if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F)

   {

     pixelsv2 = temp2;

   }

   else

   {

     pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));

   }

   pixelsv1 = vec_mergeh(vczero, pixelsv1);

   pixelsv2 = vec_mergeh(vczero, pixelsv2);

   pixelssum1 = vec_add((vector unsigned short)pixelsv1,

                        (vector unsigned short)pixelsv2);

   pixelssum1 = vec_add(pixelssum1, vcone);

POWERPC_TBL_START_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);

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

     int rightside = ((unsigned long)block & 0x0000000F);

     blockv = vec_ld(0, block);

     temp1 = vec_ld(line_size, pixels);

     temp2 = vec_ld(line_size + 16, pixels);

     pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));

     if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F)

     {

       pixelsv2 = temp2;

     }

     else

     {

       pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));

     }

     pixelsv1 = vec_mergeh(vczero, pixelsv1);

     pixelsv2 = vec_mergeh(vczero, pixelsv2);

     pixelssum2 = vec_add((vector unsigned short)pixelsv1,

                          (vector unsigned short)pixelsv2);

     temp3 = vec_add(pixelssum1, pixelssum2);

     temp3 = vec_sra(temp3, vctwo);

     pixelssum1 = vec_add(pixelssum2, vcone);

     pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);

     if (rightside)

     {

       blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));

     }

     else

     {

       blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));

     }

     vec_st(blockv, 0, block);

     block += line_size;

     pixels += line_size;

   }

POWERPC_TBL_STOP_COUNT(altivec_put_no_rnd_pixels8_xy2_num, 1);

#endif /* ALTIVEC_USE_REFERENCE_C_CODE */

}


static void put_subframe_samples(DCAEncContext *c, int ss, int band, int ch)

{

    if (c->abits[band][ch] <= 7) {

        int sum, i, j;

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

            sum = 0;

            for (j = 3; j >= 0; j--) {

                sum *= ff_dca_quant_levels[c->abits[band][ch]];

                sum += c->quantized[ss * 8 + i + j][band][ch];

                sum += (ff_dca_quant_levels[c->abits[band][ch]] - 1) / 2;

            }

            put_bits(&c->pb, bit_consumption[c->abits[band][ch]] / 4, sum);

        }

    } else {

        int i;

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

            int bits = bit_consumption[c->abits[band][ch]] / 16;

            put_sbits(&c->pb, bits, c->quantized[ss * 8 + i][band][ch]);

        }

    }

}


static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,

                             SpectrumParameters *spectrum)

{

    unsigned int temp, max_qmf_subbands = 0;

    unsigned int start_min, stop_min;

    int k;

    const int8_t *sbr_offset_ptr;

    int16_t stop_dk[13];

    if (sbr->sample_rate < 32000) {

        temp = 3000;

    } else if (sbr->sample_rate < 64000) {

        temp = 4000;

    } else

        temp = 5000;

    start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;

    stop_min  = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;

    switch (sbr->sample_rate) {

    case 16000:

        sbr_offset_ptr = sbr_offset[0];

        break;

    case 22050:

        sbr_offset_ptr = sbr_offset[1];

        break;

    case 24000:

        sbr_offset_ptr = sbr_offset[2];

        break;

    case 32000:

        sbr_offset_ptr = sbr_offset[3];

        break;

    case 44100: case 48000: case 64000:

        sbr_offset_ptr = sbr_offset[4];

        break;

    case 88200: case 96000: case 128000: case 176400: case 192000:

        sbr_offset_ptr = sbr_offset[5];

        break;

    default:

        av_log(ac->avctx, AV_LOG_ERROR,

               "Unsupported sample rate for SBR: %d\n", sbr->sample_rate);

        return -1;

    }

    sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];

    if (spectrum->bs_stop_freq < 14) {

        sbr->k[2] = stop_min;

        make_bands(stop_dk, stop_min, 64, 13);

        qsort(stop_dk, 13, sizeof(stop_dk[0]), qsort_comparison_function_int16);

        for (k = 0; k < spectrum->bs_stop_freq; k++)

            sbr->k[2] += stop_dk[k];

    } else if (spectrum->bs_stop_freq == 14) {

        sbr->k[2] = 2*sbr->k[0];

    } else if (spectrum->bs_stop_freq == 15) {

        sbr->k[2] = 3*sbr->k[0];

    } else {

        av_log(ac->avctx, AV_LOG_ERROR,

               "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq);

        return -1;

    }

    sbr->k[2] = FFMIN(64, sbr->k[2]);

    // Requirements (14496-3 sp04 p205)

    if (sbr->sample_rate <= 32000) {

        max_qmf_subbands = 48;

    } else if (sbr->sample_rate == 44100) {

        max_qmf_subbands = 35;

    } else if (sbr->sample_rate >= 48000)

        max_qmf_subbands = 32;

    if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {

        av_log(ac->avctx, AV_LOG_ERROR,

               "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]);

        return -1;

    }

    if (!spectrum->bs_freq_scale) {

        int dk, k2diff;

        dk = spectrum->bs_alter_scale + 1;

        sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1;

        if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))

            return -1;

        for (k = 1; k <= sbr->n_master; k++)

            sbr->f_master[k] = dk;

        k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk;

        if (k2diff < 0) {

            sbr->f_master[1]--;

            sbr->f_master[2]-= (k2diff < -1);

        } else if (k2diff) {

            sbr->f_master[sbr->n_master]++;

        }

        sbr->f_master[0] = sbr->k[0];

        for (k = 1; k <= sbr->n_master; k++)

            sbr->f_master[k] += sbr->f_master[k - 1];

    } else {

        int half_bands = 7 - spectrum->bs_freq_scale;      // bs_freq_scale  = {1,2,3}

        int two_regions, num_bands_0;

        int vdk0_max, vdk1_min;

        int16_t vk0[49];

        if (49 * sbr->k[2] > 110 * sbr->k[0]) {

            two_regions = 1;

            sbr->k[1] = 2 * sbr->k[0];

        } else {

            two_regions = 0;

            sbr->k[1] = sbr->k[2];

        }

        num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;

        if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)

            av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);

            return -1;

        }

        vk0[0] = 0;

        make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0);

        qsort(vk0 + 1, num_bands_0, sizeof(vk0[1]), qsort_comparison_function_int16);

        vdk0_max = vk0[num_bands_0];

        vk0[0] = sbr->k[0];

        for (k = 1; k <= num_bands_0; k++) {

            if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205)

                av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);

                return -1;

            }

            vk0[k] += vk0[k-1];

        }

        if (two_regions) {

            int16_t vk1[49];

            float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f

                                                     : 1.0f; // bs_alter_scale = {0,1}

            int num_bands_1 = lrintf(half_bands * invwarp *

                                     log2f(sbr->k[2] / (float)sbr->k[1])) * 2;

            make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1);

            vdk1_min = array_min_int16(vk1 + 1, num_bands_1);

            if (vdk1_min < vdk0_max) {

                int change;

                qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);

                change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1);

                vk1[1]           += change;

                vk1[num_bands_1] -= change;

            }

            qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);

            vk1[0] = sbr->k[1];

            for (k = 1; k <= num_bands_1; k++) {

                if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205)

                    av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);

                    return -1;

                }

                vk1[k] += vk1[k-1];

            }

            sbr->n_master = num_bands_0 + num_bands_1;

            if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))

                return -1;

            memcpy(&sbr->f_master[0],               vk0,

                   (num_bands_0 + 1) * sizeof(sbr->f_master[0]));

            memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1,

                    num_bands_1      * sizeof(sbr->f_master[0]));

        } else {

            sbr->n_master = num_bands_0;

            if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))

                return -1;

            memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0]));

        }

    }

    return 0;

}


BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,

                                 const uint8_t *buf, int nb_sectors,

                                 BlockDriverCompletionFunc *cb, void *opaque)

{

    BlockDriver *drv = bs->drv;

    BlockDriverAIOCB *ret;

    if (!drv)

        return NULL;

    if (bs->read_only)

        return NULL;

    if (bdrv_wr_badreq_sectors(bs, sector_num, nb_sectors))

        return NULL;

    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {

        memcpy(bs->boot_sector_data, buf, 512);

    }

    ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);

    if (ret) {

	/* Update stats even though technically transfer has not happened. */

	bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;

	bs->wr_ops ++;

    }

    return ret;

}


target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,

                                target_ulong r2, target_ulong r3)

{

    uint64_t t1 = extract64(r1, 0, 32);

    uint64_t t2 = extract64(r2, 0, 32);

    uint64_t t3 = extract64(r3, 0, 32);

    int64_t result;

    result = t2 + (t1 * t3);

    return suov32(env, result);

}


void do_addmeo (void)

{

    T1 = T0;

    T0 += xer_ca + (-1);

    if (likely(!((uint32_t)T1 &

                 ((uint32_t)T1 ^ (uint32_t)T0) & (1UL << 31)))) {

        xer_ov = 0;

    } else {

        xer_ov = 1;

        xer_so = 1;

    }

    if (likely(T1 != 0))

        xer_ca = 1;

}


static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
{
    CPUState *cs = CPU(dev);
    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
    cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
    xcc->parent_realize(dev, errp);
}


static void mov_build_index(MOVContext *mov, AVStream *st)

{

    MOVStreamContext *sc = st->priv_data;

    int64_t current_offset;

    int64_t current_dts = 0;

    unsigned int stts_index = 0;

    unsigned int stsc_index = 0;

    unsigned int stss_index = 0;

    unsigned int stps_index = 0;

    unsigned int i, j;

    uint64_t stream_size = 0;

    /* adjust first dts according to edit list */

    if (sc->time_offset && mov->time_scale > 0) {

        if (sc->time_offset < 0)

            sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);

        current_dts = -sc->time_offset;

        if (sc->ctts_data && sc->stts_data &&

            sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {

            /* more than 16 frames delay, dts are likely wrong

               this happens with files created by iMovie */

            sc->wrong_dts = 1;

            st->codec->has_b_frames = 1;

        }

    }

    /* only use old uncompressed audio chunk demuxing when stts specifies it */

    if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&

          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {

        unsigned int current_sample = 0;

        unsigned int stts_sample = 0;

        unsigned int sample_size;

        unsigned int distance = 0;

        int key_off = sc->keyframes && sc->keyframes[0] == 1;

        current_dts -= sc->dts_shift;

        if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries))

            return;

        st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries));

        if (!st->index_entries)

            return;

        st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries);

        for (i = 0; i < sc->chunk_count; i++) {

            current_offset = sc->chunk_offsets[i];

            while (stsc_index + 1 < sc->stsc_count &&

                i + 1 == sc->stsc_data[stsc_index + 1].first)

                stsc_index++;

            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {

                int keyframe = 0;

                if (current_sample >= sc->sample_count) {

                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");

                    return;

                }

                if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) {

                    keyframe = 1;

                    if (stss_index + 1 < sc->keyframe_count)

                        stss_index++;

                } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {

                    keyframe = 1;

                    if (stps_index + 1 < sc->stps_count)

                        stps_index++;

                }

                if (keyframe)

                    distance = 0;

                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];

                if (sc->pseudo_stream_id == -1 ||

                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {

                    AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];

                    e->pos = current_offset;

                    e->timestamp = current_dts;

                    e->size = sample_size;

                    e->min_distance = distance;

                    e->flags = keyframe ? AVINDEX_KEYFRAME : 0;

                    av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "

                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,

                            current_offset, current_dts, sample_size, distance, keyframe);

                }

                current_offset += sample_size;

                stream_size += sample_size;

                current_dts += sc->stts_data[stts_index].duration;

                distance++;

                stts_sample++;

                current_sample++;

                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {

                    stts_sample = 0;

                    stts_index++;

                }

            }

        }

        if (st->duration > 0)

            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;

    } else {

        unsigned chunk_samples, total = 0;

        // compute total chunk count

        for (i = 0; i < sc->stsc_count; i++) {

            unsigned count, chunk_count;

            chunk_samples = sc->stsc_data[i].count;

            if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {

                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");

                return;

            }

            if (sc->samples_per_frame >= 160) { // gsm

                count = chunk_samples / sc->samples_per_frame;

            } else if (sc->samples_per_frame > 1) {

                unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;

                count = (chunk_samples+samples-1) / samples;

            } else {

                count = (chunk_samples+1023) / 1024;

            }

            if (i < sc->stsc_count - 1)

                chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;

            else

                chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);

            total += chunk_count * count;

        }

        av_dlog(mov->fc, "chunk count %d\n", total);

        if (total >= UINT_MAX / sizeof(*st->index_entries))

            return;

        st->index_entries = av_malloc(total*sizeof(*st->index_entries));

        if (!st->index_entries)

            return;

        st->index_entries_allocated_size = total*sizeof(*st->index_entries);

        // populate index

        for (i = 0; i < sc->chunk_count; i++) {

            current_offset = sc->chunk_offsets[i];

            if (stsc_index + 1 < sc->stsc_count &&

                i + 1 == sc->stsc_data[stsc_index + 1].first)

                stsc_index++;

            chunk_samples = sc->stsc_data[stsc_index].count;

            while (chunk_samples > 0) {

                AVIndexEntry *e;

                unsigned size, samples;

                if (sc->samples_per_frame >= 160) { // gsm

                    samples = sc->samples_per_frame;

                    size = sc->bytes_per_frame;

                } else {

                    if (sc->samples_per_frame > 1) {

                        samples = FFMIN((1024 / sc->samples_per_frame)*

                                        sc->samples_per_frame, chunk_samples);

                        size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;

                    } else {

                        samples = FFMIN(1024, chunk_samples);

                        size = samples * sc->sample_size;

                    }

                }

                if (st->nb_index_entries >= total) {

                    av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total);

                    return;

                }

                e = &st->index_entries[st->nb_index_entries++];

                e->pos = current_offset;

                e->timestamp = current_dts;

                e->size = size;

                e->min_distance = 0;

                e->flags = AVINDEX_KEYFRAME;

                av_dlog(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "

                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,

                        size, samples);

                current_offset += size;

                current_dts += samples;

                chunk_samples -= samples;

            }

        }

    }

}


int MPV_common_init(MpegEncContext *s)

{

    int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, threads;

    s->mb_height = (s->height + 15) / 16;

    if(s->avctx->thread_count > MAX_THREADS || (s->avctx->thread_count > s->mb_height && s->mb_height)){

        av_log(s->avctx, AV_LOG_ERROR, "too many threads\n");

        return -1;

    }

    if((s->width || s->height) && avcodec_check_dimensions(s->avctx, s->width, s->height))

        return -1;

    dsputil_init(&s->dsp, s->avctx);

    ff_dct_common_init(s);

    s->flags= s->avctx->flags;

    s->flags2= s->avctx->flags2;

    s->mb_width  = (s->width  + 15) / 16;

    s->mb_stride = s->mb_width + 1;

    s->b8_stride = s->mb_width*2 + 1;

    s->b4_stride = s->mb_width*4 + 1;

    mb_array_size= s->mb_height * s->mb_stride;

    mv_table_size= (s->mb_height+2) * s->mb_stride + 1;

    /* set chroma shifts */

    avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,&(s->chroma_x_shift),

                                                    &(s->chroma_y_shift) );

    /* set default edge pos, will be overriden in decode_header if needed */

    s->h_edge_pos= s->mb_width*16;

    s->v_edge_pos= s->mb_height*16;

    s->mb_num = s->mb_width * s->mb_height;

    s->block_wrap[0]=

    s->block_wrap[1]=

    s->block_wrap[2]=

    s->block_wrap[3]= s->b8_stride;

    s->block_wrap[4]=

    s->block_wrap[5]= s->mb_stride;

    y_size = s->b8_stride * (2 * s->mb_height + 1);

    c_size = s->mb_stride * (s->mb_height + 1);

    yc_size = y_size + 2 * c_size;

    /* convert fourcc to upper case */

    s->codec_tag=          toupper( s->avctx->codec_tag     &0xFF)

                        + (toupper((s->avctx->codec_tag>>8 )&0xFF)<<8 )

                        + (toupper((s->avctx->codec_tag>>16)&0xFF)<<16)

                        + (toupper((s->avctx->codec_tag>>24)&0xFF)<<24);

    s->stream_codec_tag=          toupper( s->avctx->stream_codec_tag     &0xFF)

                               + (toupper((s->avctx->stream_codec_tag>>8 )&0xFF)<<8 )

                               + (toupper((s->avctx->stream_codec_tag>>16)&0xFF)<<16)

                               + (toupper((s->avctx->stream_codec_tag>>24)&0xFF)<<24);

    s->avctx->coded_frame= (AVFrame*)&s->current_picture;

    CHECKED_ALLOCZ(s->mb_index2xy, (s->mb_num+1)*sizeof(int)) //error ressilience code looks cleaner with this

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

        for(x=0; x<s->mb_width; x++){

            s->mb_index2xy[ x + y*s->mb_width ] = x + y*s->mb_stride;

        }

    }

    s->mb_index2xy[ s->mb_height*s->mb_width ] = (s->mb_height-1)*s->mb_stride + s->mb_width; //FIXME really needed?

    if (s->encoding) {

        /* Allocate MV tables */

        CHECKED_ALLOCZ(s->p_mv_table_base            , mv_table_size * 2 * sizeof(int16_t))

        CHECKED_ALLOCZ(s->b_forw_mv_table_base       , mv_table_size * 2 * sizeof(int16_t))

        CHECKED_ALLOCZ(s->b_back_mv_table_base       , mv_table_size * 2 * sizeof(int16_t))

        CHECKED_ALLOCZ(s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t))

        CHECKED_ALLOCZ(s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t))

        CHECKED_ALLOCZ(s->b_direct_mv_table_base     , mv_table_size * 2 * sizeof(int16_t))

        s->p_mv_table           = s->p_mv_table_base            + s->mb_stride + 1;

        s->b_forw_mv_table      = s->b_forw_mv_table_base       + s->mb_stride + 1;

        s->b_back_mv_table      = s->b_back_mv_table_base       + s->mb_stride + 1;

        s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1;

        s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1;

        s->b_direct_mv_table    = s->b_direct_mv_table_base     + s->mb_stride + 1;

        if(s->msmpeg4_version){

            CHECKED_ALLOCZ(s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int));

        }

        CHECKED_ALLOCZ(s->avctx->stats_out, 256);

        /* Allocate MB type table */

        CHECKED_ALLOCZ(s->mb_type  , mb_array_size * sizeof(uint16_t)) //needed for encoding

        CHECKED_ALLOCZ(s->lambda_table, mb_array_size * sizeof(int))

        CHECKED_ALLOCZ(s->q_intra_matrix, 64*32 * sizeof(int))

        CHECKED_ALLOCZ(s->q_inter_matrix, 64*32 * sizeof(int))

        CHECKED_ALLOCZ(s->q_intra_matrix16, 64*32*2 * sizeof(uint16_t))

        CHECKED_ALLOCZ(s->q_inter_matrix16, 64*32*2 * sizeof(uint16_t))

        CHECKED_ALLOCZ(s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))

        CHECKED_ALLOCZ(s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*))

        if(s->avctx->noise_reduction){

            CHECKED_ALLOCZ(s->dct_offset, 2 * 64 * sizeof(uint16_t))

        }

    }

    CHECKED_ALLOCZ(s->picture, MAX_PICTURE_COUNT * sizeof(Picture))

    CHECKED_ALLOCZ(s->error_status_table, mb_array_size*sizeof(uint8_t))

    if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){

        /* interlaced direct mode decoding tables */

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

                int j, k;

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

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

                        CHECKED_ALLOCZ(s->b_field_mv_table_base[i][j][k]     , mv_table_size * 2 * sizeof(int16_t))

                        s->b_field_mv_table[i][j][k]    = s->b_field_mv_table_base[i][j][k]     + s->mb_stride + 1;

                    }

                    CHECKED_ALLOCZ(s->b_field_select_table[i][j]     , mb_array_size * 2 * sizeof(uint8_t))

                    CHECKED_ALLOCZ(s->p_field_mv_table_base[i][j]     , mv_table_size * 2 * sizeof(int16_t))

                    s->p_field_mv_table[i][j]    = s->p_field_mv_table_base[i][j]     + s->mb_stride + 1;

                }

                CHECKED_ALLOCZ(s->p_field_select_table[i]      , mb_array_size * 2 * sizeof(uint8_t))

            }

    }

    if (s->out_format == FMT_H263) {

        /* ac values */

        CHECKED_ALLOCZ(s->ac_val_base, yc_size * sizeof(int16_t) * 16);

        s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;

        s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;

        s->ac_val[2] = s->ac_val[1] + c_size;

        /* cbp values */

        CHECKED_ALLOCZ(s->coded_block_base, y_size);

        s->coded_block= s->coded_block_base + s->b8_stride + 1;

        /* cbp, ac_pred, pred_dir */

        CHECKED_ALLOCZ(s->cbp_table  , mb_array_size * sizeof(uint8_t))

        CHECKED_ALLOCZ(s->pred_dir_table, mb_array_size * sizeof(uint8_t))

    }

    if (s->h263_pred || s->h263_plus || !s->encoding) {

        /* dc values */

        //MN: we need these for error resilience of intra-frames

        CHECKED_ALLOCZ(s->dc_val_base, yc_size * sizeof(int16_t));

        s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;

        s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;

        s->dc_val[2] = s->dc_val[1] + c_size;

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

            s->dc_val_base[i] = 1024;

    }

    /* which mb is a intra block */

    CHECKED_ALLOCZ(s->mbintra_table, mb_array_size);

    memset(s->mbintra_table, 1, mb_array_size);

    /* init macroblock skip table */

    CHECKED_ALLOCZ(s->mbskip_table, mb_array_size+2);

    //Note the +1 is for a quicker mpeg4 slice_end detection

    CHECKED_ALLOCZ(s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE);

    s->parse_context.state= -1;

    if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){

       s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH);

       s->visualization_buffer[1] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);

       s->visualization_buffer[2] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH);

    }

    s->context_initialized = 1;

    s->thread_context[0]= s;

    /* h264 does thread context setup itself, but it needs context[0]

     * to be fully initialized for the error resilience code */

    threads = s->codec_id == CODEC_ID_H264 ? 1 : s->avctx->thread_count;

    for(i=1; i<threads; i++){

        s->thread_context[i]= av_malloc(sizeof(MpegEncContext));

        memcpy(s->thread_context[i], s, sizeof(MpegEncContext));

    }

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

        if(init_duplicate_context(s->thread_context[i], s) < 0)

           goto fail;

        s->thread_context[i]->start_mb_y= (s->mb_height*(i  ) + s->avctx->thread_count/2) / s->avctx->thread_count;

        s->thread_context[i]->end_mb_y  = (s->mb_height*(i+1) + s->avctx->thread_count/2) / s->avctx->thread_count;

    }

    return 0;

 fail:

    MPV_common_end(s);

    return -1;

}


static void read_const_block_data(ALSDecContext *ctx, ALSBlockData *bd)

{

    ALSSpecificConfig *sconf = &ctx->sconf;

    AVCodecContext *avctx    = ctx->avctx;

    GetBitContext *gb        = &ctx->gb;

    *bd->raw_samples = 0;

    *bd->const_block = get_bits1(gb);    // 1 = constant value, 0 = zero block (silence)

    bd->js_blocks    = get_bits1(gb);

    // skip 5 reserved bits

    skip_bits(gb, 5);

    if (*bd->const_block) {

        unsigned int const_val_bits = sconf->floating ? 24 : avctx->bits_per_raw_sample;

        *bd->raw_samples = get_sbits_long(gb, const_val_bits);

    }

    // ensure constant block decoding by reusing this field

    *bd->const_block = 1;

}


static int MP3lame_encode_frame(AVCodecContext *avctx,

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

{

    Mp3AudioContext *s = avctx->priv_data;

    int len;

    int lame_result;

    /* lame 3.91 dies on '1-channel interleaved' data */

    if(data){

        if (s->stereo) {

            lame_result = lame_encode_buffer_interleaved(

                s->gfp,

                data,

                avctx->frame_size,

                s->buffer + s->buffer_index,

                BUFFER_SIZE - s->buffer_index

                );

        } else {

            lame_result = lame_encode_buffer(

                s->gfp,

                data,

                data,

                avctx->frame_size,

                s->buffer + s->buffer_index,

                BUFFER_SIZE - s->buffer_index

                );

        }

    }else{

        lame_result= lame_encode_flush(

                s->gfp,

                s->buffer + s->buffer_index,

                BUFFER_SIZE - s->buffer_index

                );

    }

    if(lame_result==-1) {

        /* output buffer too small */

        av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index);

        return 0;

    }

    s->buffer_index += lame_result;

    if(s->buffer_index<4)

        return 0;

        len= mp3len(s->buffer, NULL, NULL);

//av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index);

        if(len <= s->buffer_index){

            memcpy(frame, s->buffer, len);

            s->buffer_index -= len;

            memmove(s->buffer, s->buffer+len, s->buffer_index);

            //FIXME fix the audio codec API, so we do not need the memcpy()

/*for(i=0; i<len; i++){

    av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);

}*/

            return len;

        }else

            return 0;

}


static void lx_init(const LxBoardDesc *board, MachineState *machine)

{

#ifdef TARGET_WORDS_BIGENDIAN

    int be = 1;

#else

    int be = 0;

#endif

    MemoryRegion *system_memory = get_system_memory();

    XtensaCPU *cpu = NULL;

    CPUXtensaState *env = NULL;

    MemoryRegion *ram, *rom, *system_io;

    DriveInfo *dinfo;

    pflash_t *flash = NULL;

    QemuOpts *machine_opts = qemu_get_machine_opts();

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");

    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");

    const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");

    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");

    int n;

    if (!cpu_model) {

        cpu_model = XTENSA_DEFAULT_CPU_MODEL;

    }

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

        cpu = cpu_xtensa_init(cpu_model);

        if (cpu == NULL) {

            error_report("unable to find CPU definition '%s'",

                         cpu_model);

            exit(EXIT_FAILURE);

        }

        env = &cpu->env;

        env->sregs[PRID] = n;

        qemu_register_reset(lx60_reset, cpu);

        /* Need MMU initialized prior to ELF loading,

         * so that ELF gets loaded into virtual addresses

         */

        cpu_reset(CPU(cpu));

    }

    ram = g_malloc(sizeof(*ram));

    memory_region_init_ram(ram, NULL, "lx60.dram", machine->ram_size,

                           &error_abort);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(system_memory, 0, ram);

    system_io = g_malloc(sizeof(*system_io));

    memory_region_init_io(system_io, NULL, &lx60_io_ops, NULL, "lx60.io",

                          224 * 1024 * 1024);

    memory_region_add_subregion(system_memory, 0xf0000000, system_io);

    lx60_fpga_init(system_io, 0x0d020000);

    if (nd_table[0].used) {

        lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,

                xtensa_get_extint(env, 1), nd_table);

    }

    if (!serial_hds[0]) {

        serial_hds[0] = qemu_chr_new("serial0", "null", NULL);

    }

    serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0),

            115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    dinfo = drive_get(IF_PFLASH, 0, 0);

    if (dinfo) {

        flash = pflash_cfi01_register(board->flash_base,

                NULL, "lx60.io.flash", board->flash_size,

                blk_by_legacy_dinfo(dinfo),

                board->flash_sector_size,

                board->flash_size / board->flash_sector_size,

                4, 0x0000, 0x0000, 0x0000, 0x0000, be);

        if (flash == NULL) {

            error_report("unable to mount pflash");

            exit(EXIT_FAILURE);

        }

    }

    /* Use presence of kernel file name as 'boot from SRAM' switch. */

    if (kernel_filename) {

        uint32_t entry_point = env->pc;

        size_t bp_size = 3 * get_tag_size(0); /* first/last and memory tags */

        uint32_t tagptr = 0xfe000000 + board->sram_size;

        uint32_t cur_tagptr;

        BpMemInfo memory_location = {

            .type = tswap32(MEMORY_TYPE_CONVENTIONAL),

            .start = tswap32(0),

            .end = tswap32(machine->ram_size),

        };

        uint32_t lowmem_end = machine->ram_size < 0x08000000 ?

            machine->ram_size : 0x08000000;

        uint32_t cur_lowmem = QEMU_ALIGN_UP(lowmem_end / 2, 4096);

        rom = g_malloc(sizeof(*rom));

        memory_region_init_ram(rom, NULL, "lx60.sram", board->sram_size,

                               &error_abort);

        vmstate_register_ram_global(rom);

        memory_region_add_subregion(system_memory, 0xfe000000, rom);

        if (kernel_cmdline) {

            bp_size += get_tag_size(strlen(kernel_cmdline) + 1);

        }

        if (dtb_filename) {

            bp_size += get_tag_size(sizeof(uint32_t));

        }

        if (initrd_filename) {

            bp_size += get_tag_size(sizeof(BpMemInfo));

        }

        /* Put kernel bootparameters to the end of that SRAM */

        tagptr = (tagptr - bp_size) & ~0xff;

        cur_tagptr = put_tag(tagptr, BP_TAG_FIRST, 0, NULL);

        cur_tagptr = put_tag(cur_tagptr, BP_TAG_MEMORY,

                             sizeof(memory_location), &memory_location);

        if (kernel_cmdline) {

            cur_tagptr = put_tag(cur_tagptr, BP_TAG_COMMAND_LINE,

                                 strlen(kernel_cmdline) + 1, kernel_cmdline);

        }

        if (dtb_filename) {

            int fdt_size;

            void *fdt = load_device_tree(dtb_filename, &fdt_size);

            uint32_t dtb_addr = tswap32(cur_lowmem);

            if (!fdt) {

                error_report("could not load DTB '%s'", dtb_filename);

                exit(EXIT_FAILURE);

            }

            cpu_physical_memory_write(cur_lowmem, fdt, fdt_size);

            cur_tagptr = put_tag(cur_tagptr, BP_TAG_FDT,

                                 sizeof(dtb_addr), &dtb_addr);

            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + fdt_size, 4096);

        }

        if (initrd_filename) {

            BpMemInfo initrd_location = { 0 };

            int initrd_size = load_ramdisk(initrd_filename, cur_lowmem,

                                           lowmem_end - cur_lowmem);

            if (initrd_size < 0) {

                initrd_size = load_image_targphys(initrd_filename,

                                                  cur_lowmem,

                                                  lowmem_end - cur_lowmem);

            }

            if (initrd_size < 0) {

                error_report("could not load initrd '%s'", initrd_filename);

                exit(EXIT_FAILURE);

            }

            initrd_location.start = tswap32(cur_lowmem);

            initrd_location.end = tswap32(cur_lowmem + initrd_size);

            cur_tagptr = put_tag(cur_tagptr, BP_TAG_INITRD,

                                 sizeof(initrd_location), &initrd_location);

            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + initrd_size, 4096);

        }

        cur_tagptr = put_tag(cur_tagptr, BP_TAG_LAST, 0, NULL);

        env->regs[2] = tagptr;

        uint64_t elf_entry;

        uint64_t elf_lowaddr;

        int success = load_elf(kernel_filename, translate_phys_addr, cpu,

                &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);

        if (success > 0) {

            entry_point = elf_entry;

        } else {

            hwaddr ep;

            int is_linux;

            success = load_uimage(kernel_filename, &ep, NULL, &is_linux,

                                  translate_phys_addr, cpu);

            if (success > 0 && is_linux) {

                entry_point = ep;

            } else {

                error_report("could not load kernel '%s'",

                             kernel_filename);

                exit(EXIT_FAILURE);

            }

        }

        if (entry_point != env->pc) {

            static const uint8_t jx_a0[] = {

#ifdef TARGET_WORDS_BIGENDIAN

                0x0a, 0, 0,

#else

                0xa0, 0, 0,

#endif

            };

            env->regs[0] = entry_point;

            cpu_physical_memory_write(env->pc, jx_a0, sizeof(jx_a0));

        }

    } else {

        if (flash) {

            MemoryRegion *flash_mr = pflash_cfi01_get_memory(flash);

            MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));

            memory_region_init_alias(flash_io, NULL, "lx60.flash",

                    flash_mr, board->flash_boot_base,

                    board->flash_size - board->flash_boot_base < 0x02000000 ?

                    board->flash_size - board->flash_boot_base : 0x02000000);

            memory_region_add_subregion(system_memory, 0xfe000000,

                    flash_io);

        }

    }

}


USBDevice *usb_bt_init(HCIInfo *hci)

{

    USBDevice *dev;

    struct USBBtState *s;

    if (!hci)

    dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle");

    s = DO_UPCAST(struct USBBtState, dev, dev);

    s->dev.opaque = s;

    s->hci = hci;

    s->hci->opaque = s;

    s->hci->evt_recv = usb_bt_out_hci_packet_event;

    s->hci->acl_recv = usb_bt_out_hci_packet_acl;

    usb_bt_handle_reset(&s->dev);

    return dev;


static void term_up_char(void)

{

    int idx;

    if (term_hist_entry == 0)

	return;

    if (term_hist_entry == -1) {

	/* Find latest entry */

	for (idx = 0; idx < TERM_MAX_CMDS; idx++) {

	    if (term_history[idx] == NULL)

		break;

	}

	term_hist_entry = idx;

    }

    term_hist_entry--;

    if (term_hist_entry >= 0) {

	strcpy(term_cmd_buf, term_history[term_hist_entry]);

	term_printf("\n");

	term_print_cmdline(term_cmd_buf);

	term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);

    }

}


static int vf_open(vf_instance_t *vf, char *args)

{

        vf->config=config;

        vf->query_format=query_format;

        vf->put_image=put_image;

        vf->uninit=uninit;

        vf->priv = calloc(1, sizeof (struct vf_priv_s));

        vf->priv->skipline = 0;

        vf->priv->scalew = 1;

        vf->priv->scaleh = 2;

        if (args) sscanf(args, "%d:%d:%d", &vf->priv->skipline, &vf->priv->scalew, &vf->priv->scaleh);

        return 1;

}


static void coroutine_fn v9fs_link(void *opaque)

{

    V9fsPDU *pdu = opaque;

    int32_t dfid, oldfid;

    V9fsFidState *dfidp, *oldfidp;

    V9fsString name;

    size_t offset = 7;

    int err = 0;

    v9fs_string_init(&name);

    err = pdu_unmarshal(pdu, offset, "dds", &dfid, &oldfid, &name);

    if (err < 0) {

        goto out_nofid;

    }

    trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);

    if (name_is_illegal(name.data)) {

        err = -ENOENT;

        goto out_nofid;

    }

    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {

        err = -EEXIST;

        goto out_nofid;

    }

    dfidp = get_fid(pdu, dfid);

    if (dfidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    oldfidp = get_fid(pdu, oldfid);

    if (oldfidp == NULL) {

        err = -ENOENT;

        goto out;

    }

    err = v9fs_co_link(pdu, oldfidp, dfidp, &name);

    if (!err) {

        err = offset;

    }

out:

    put_fid(pdu, dfidp);

out_nofid:

    v9fs_string_free(&name);

    pdu_complete(pdu, err);

}


static void port92_class_initfn(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->no_user = 1;

    dc->realize = port92_realizefn;

    dc->reset = port92_reset;

    dc->vmsd = &vmstate_port92_isa;

}