static void vga_draw_graphic(VGACommonState *s, int full_update)

{

    DisplaySurface *surface = qemu_console_surface(s->con);

    int y1, y, update, linesize, y_start, double_scan, mask, depth;

    int width, height, shift_control, line_offset, bwidth, bits;

    ram_addr_t page0, page1;

    DirtyBitmapSnapshot *snap = NULL;

    int disp_width, multi_scan, multi_run;

    uint8_t *d;

    uint32_t v, addr1, addr;

    vga_draw_line_func *vga_draw_line = NULL;

    bool share_surface;

    pixman_format_code_t format;

#ifdef HOST_WORDS_BIGENDIAN

    bool byteswap = !s->big_endian_fb;

#else

    bool byteswap = s->big_endian_fb;

#endif

    full_update |= update_basic_params(s);

    s->get_resolution(s, &width, &height);

    disp_width = width;

    shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3;

    double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7);

    if (shift_control != 1) {

        multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan)

            - 1;

    } else {

        /* in CGA modes, multi_scan is ignored */

        /* XXX: is it correct ? */

        multi_scan = double_scan;

    }

    multi_run = multi_scan;

    if (shift_control != s->shift_control ||

        double_scan != s->double_scan) {

        full_update = 1;

        s->shift_control = shift_control;

        s->double_scan = double_scan;

    }

    if (shift_control == 0) {

        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {

            disp_width <<= 1;

        }

    } else if (shift_control == 1) {

        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {

            disp_width <<= 1;

        }

    }

    depth = s->get_bpp(s);

    /*

     * Check whether we can share the surface with the backend

     * or whether we need a shadow surface. We share native

     * endian surfaces for 15bpp and above and byteswapped

     * surfaces for 24bpp and above.

     */

    format = qemu_default_pixman_format(depth, !byteswap);

    if (format) {

        share_surface = dpy_gfx_check_format(s->con, format)

            && !s->force_shadow;

    } else {

        share_surface = false;

    }

    if (s->line_offset != s->last_line_offset ||

        disp_width != s->last_width ||

        height != s->last_height ||

        s->last_depth != depth ||

        s->last_byteswap != byteswap ||

        share_surface != is_buffer_shared(surface)) {

        if (share_surface) {

            surface = qemu_create_displaysurface_from(disp_width,

                    height, format, s->line_offset,

                    s->vram_ptr + (s->start_addr * 4));

            dpy_gfx_replace_surface(s->con, surface);

        } else {

            qemu_console_resize(s->con, disp_width, height);

            surface = qemu_console_surface(s->con);

        }

        s->last_scr_width = disp_width;

        s->last_scr_height = height;

        s->last_width = disp_width;

        s->last_height = height;

        s->last_line_offset = s->line_offset;

        s->last_depth = depth;

        s->last_byteswap = byteswap;

        full_update = 1;

    } else if (is_buffer_shared(surface) &&

               (full_update || surface_data(surface) != s->vram_ptr

                + (s->start_addr * 4))) {

        pixman_format_code_t format =

            qemu_default_pixman_format(depth, !byteswap);

        surface = qemu_create_displaysurface_from(disp_width,

                height, format, s->line_offset,

                s->vram_ptr + (s->start_addr * 4));

        dpy_gfx_replace_surface(s->con, surface);

    }

    if (shift_control == 0) {

        full_update |= update_palette16(s);

        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {

            v = VGA_DRAW_LINE4D2;

        } else {

            v = VGA_DRAW_LINE4;

        }

        bits = 4;

    } else if (shift_control == 1) {

        full_update |= update_palette16(s);

        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {

            v = VGA_DRAW_LINE2D2;

        } else {

            v = VGA_DRAW_LINE2;

        }

        bits = 4;

    } else {

        switch(s->get_bpp(s)) {

        default:

        case 0:

            full_update |= update_palette256(s);

            v = VGA_DRAW_LINE8D2;

            bits = 4;

            break;

        case 8:

            full_update |= update_palette256(s);

            v = VGA_DRAW_LINE8;

            bits = 8;

            break;

        case 15:

            v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;

            bits = 16;

            break;

        case 16:

            v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;

            bits = 16;

            break;

        case 24:

            v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;

            bits = 24;

            break;

        case 32:

            v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;

            bits = 32;

            break;

        }

    }

    vga_draw_line = vga_draw_line_table[v];

    if (!is_buffer_shared(surface) && s->cursor_invalidate) {

        s->cursor_invalidate(s);

    }

    line_offset = s->line_offset;

#if 0

    printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",

           width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],

           s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));

#endif

    addr1 = (s->start_addr * 4);

    bwidth = DIV_ROUND_UP(width * bits, 8);

    y_start = -1;

    d = surface_data(surface);

    linesize = surface_stride(surface);

    y1 = 0;

    if (!full_update) {

        ram_addr_t region_start = addr1;

        ram_addr_t region_end = addr1 + line_offset * height;

        vga_sync_dirty_bitmap(s);

        if (s->line_compare < height) {

            /* split screen mode */

            region_start = 0;

        }

        snap = memory_region_snapshot_and_clear_dirty(&s->vram, region_start,

                                                      region_end - region_start,

                                                      DIRTY_MEMORY_VGA);

    }

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

        addr = addr1;

        if (!(s->cr[VGA_CRTC_MODE] & 1)) {

            int shift;

            /* CGA compatibility handling */

            shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1);

            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);

        }

        if (!(s->cr[VGA_CRTC_MODE] & 2)) {

            addr = (addr & ~0x8000) | ((y1 & 2) << 14);

        }

        update = full_update;

        page0 = addr;

        page1 = addr + bwidth - 1;

        if (full_update) {

            update = 1;

        } else {

            update = memory_region_snapshot_get_dirty(&s->vram, snap,

                                                      page0, page1 - page0);

        }

        /* explicit invalidation for the hardware cursor (cirrus only) */

        update |= vga_scanline_invalidated(s, y);

        if (update) {

            if (y_start < 0)

                y_start = y;

            if (!(is_buffer_shared(surface))) {

                vga_draw_line(s, d, s->vram_ptr + addr, width);

                if (s->cursor_draw_line)

                    s->cursor_draw_line(s, d, y);

            }

        } else {

            if (y_start >= 0) {

                /* flush to display */

                dpy_gfx_update(s->con, 0, y_start,

                               disp_width, y - y_start);

                y_start = -1;

            }

        }

        if (!multi_run) {

            mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;

            if ((y1 & mask) == mask)

                addr1 += line_offset;

            y1++;

            multi_run = multi_scan;

        } else {

            multi_run--;

        }

        /* line compare acts on the displayed lines */

        if (y == s->line_compare)

            addr1 = 0;

        d += linesize;

    }

    if (y_start >= 0) {

        /* flush to display */

        dpy_gfx_update(s->con, 0, y_start,

                       disp_width, y - y_start);

    }

    g_free(snap);

    memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));

}


static int filter_frame(AVFilterLink *link, AVFrame *frame)

{

    AVFilterContext *ctx = link->dst;

    AudioFIRContext *s = ctx->priv;

    AVFilterLink *outlink = ctx->outputs[0];

    int ret = 0;

    av_audio_fifo_write(s->fifo[0], (void **)frame->extended_data,

                        frame->nb_samples);

    if (s->pts == AV_NOPTS_VALUE)

        s->pts = frame->pts;

    av_frame_free(&frame);

    if (!s->have_coeffs && s->eof_coeffs) {

        ret = convert_coeffs(ctx);

        if (ret < 0)

            return ret;

    }

    if (s->have_coeffs) {

        while (av_audio_fifo_size(s->fifo[0]) >= s->part_size) {

            ret = fir_frame(s, outlink);

            if (ret < 0)

                break;

        }

    }

    return ret;

}


static int dnxhd_encode_init(AVCodecContext *avctx)

{

    DNXHDEncContext *ctx = avctx->priv_data;

    int i, index, bit_depth;

    switch (avctx->pix_fmt) {

    case AV_PIX_FMT_YUV422P:

        bit_depth = 8;

        break;

    case AV_PIX_FMT_YUV422P10:

        bit_depth = 10;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "pixel format is incompatible with DNxHD\n");

        return -1;

    }

    ctx->cid = ff_dnxhd_find_cid(avctx, bit_depth);

    if (!ctx->cid) {

        av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");

        return -1;

    }

    av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);

    index = ff_dnxhd_get_cid_table(ctx->cid);

    av_assert0(index >= 0);

    ctx->cid_table = &ff_dnxhd_cid_table[index];

    ctx->m.avctx = avctx;

    ctx->m.mb_intra = 1;

    ctx->m.h263_aic = 1;

    avctx->bits_per_raw_sample = ctx->cid_table->bit_depth;

    ff_dct_common_init(&ctx->m);

    ff_dct_encode_init(&ctx->m);

    if (!ctx->m.dct_quantize)

        ctx->m.dct_quantize = ff_dct_quantize_c;

    if (ctx->cid_table->bit_depth == 10) {

       ctx->m.dct_quantize = dnxhd_10bit_dct_quantize;

       ctx->get_pixels_8x4_sym = dnxhd_10bit_get_pixels_8x4_sym;

       ctx->block_width_l2 = 4;

    } else {

       ctx->get_pixels_8x4_sym = dnxhd_8bit_get_pixels_8x4_sym;

       ctx->block_width_l2 = 3;

    }

    if (ARCH_X86)

        ff_dnxhdenc_init_x86(ctx);

    ctx->m.mb_height = (avctx->height + 15) / 16;

    ctx->m.mb_width  = (avctx->width  + 15) / 16;

    if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {

        ctx->interlaced = 1;

        ctx->m.mb_height /= 2;

    }

    ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;

    if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)

        ctx->m.intra_quant_bias = avctx->intra_quant_bias;

    if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias

        return -1;

    // Avid Nitris hardware decoder requires a minimum amount of padding in the coding unit payload

    if (ctx->nitris_compat)

        ctx->min_padding = 1600;

    if (dnxhd_init_vlc(ctx) < 0)

        return -1;

    if (dnxhd_init_rc(ctx) < 0)

        return -1;

    FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t), fail);

    FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, ctx->m.mb_height*sizeof(uint32_t), fail);

    FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits,    ctx->m.mb_num   *sizeof(uint16_t), fail);

    FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale,  ctx->m.mb_num   *sizeof(uint8_t),  fail);

    ctx->frame.key_frame = 1;

    ctx->frame.pict_type = AV_PICTURE_TYPE_I;

    ctx->m.avctx->coded_frame = &ctx->frame;

    if (avctx->thread_count > MAX_THREADS) {

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

        return -1;

    }

    ctx->thread[0] = ctx;

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

        ctx->thread[i] =  av_malloc(sizeof(DNXHDEncContext));

        memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));

    }

    return 0;

 fail: //for FF_ALLOCZ_OR_GOTO

    return -1;

}


static int nbd_co_readv(BlockDriverState *bs, int64_t sector_num,

                        int nb_sectors, QEMUIOVector *qiov)

{

    BDRVNBDState *s = bs->opaque;

    return nbd_client_session_co_readv(&s->client, sector_num,

                                       nb_sectors, qiov);

}


static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,

                              int n, int coded)

{

    int level, i, last, run, run_diff;

    int dc_pred_dir;

    RLTable *rl;

    RL_VLC_ELEM *rl_vlc;

    const UINT8 *scan_table;

    int qmul, qadd;

    if (s->mb_intra) {

        qmul=1;

        qadd=0;

	/* DC coef */

        set_stat(ST_DC);

        level = msmpeg4_decode_dc(s, n, &dc_pred_dir);

#ifdef PRINT_MB

{

    static int c;

    if(n==0) c=0;

    if(n==4) printf("%X", c);

    c+= c +dc_pred_dir;

}

#endif

        if (level < 0){

            fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);

            if(s->inter_intra_pred) level=0;

            else                    return -1;

        }

        if (n < 4) {

            rl = &rl_table[s->rl_table_index];

            if(level > 256*s->y_dc_scale){

                fprintf(stderr, "dc overflow+ L qscale: %d//\n", s->qscale);

                if(!s->inter_intra_pred) return -1;

            }

        } else {

            rl = &rl_table[3 + s->rl_chroma_table_index];

            if(level > 256*s->c_dc_scale){

                fprintf(stderr, "dc overflow+ C qscale: %d//\n", s->qscale);

                if(!s->inter_intra_pred) return -1;

            }

        }

        block[0] = level;

        run_diff = 0;

        i = 0;

        if (!coded) {

            goto not_coded;

        }

        if (s->ac_pred) {

            if (dc_pred_dir == 0)

                scan_table = s->intra_v_scantable; /* left */

            else

                scan_table = s->intra_h_scantable; /* top */

        } else {

            scan_table = s->intra_scantable;

        }

        set_stat(ST_INTRA_AC);

        rl_vlc= rl->rl_vlc[0];

    } else {

        qmul = s->qscale << 1;

        qadd = (s->qscale - 1) | 1;

        i = -1;

        rl = &rl_table[3 + s->rl_table_index];

        if(s->msmpeg4_version==2)

            run_diff = 0;

        else

            run_diff = 1;

        if (!coded) {

            s->block_last_index[n] = i;

            return 0;

        }

        scan_table = s->inter_scantable;

        set_stat(ST_INTER_AC);

        rl_vlc= rl->rl_vlc[s->qscale];

    }

  {

    OPEN_READER(re, &s->gb);

    for(;;) {

        UPDATE_CACHE(re, &s->gb);

        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);

        if (level==0) {

            int cache;

            cache= GET_CACHE(re, &s->gb);

            /* escape */

            if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {

                if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {

                    /* third escape */

                    if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);

                    UPDATE_CACHE(re, &s->gb);

                    if(s->msmpeg4_version<=3){

                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);

                        run=   SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);

                        level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8);

                        SKIP_COUNTER(re, &s->gb, 1+6+8);

                    }else{

                        int sign;

                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);

                        if(!s->esc3_level_length){

                            int ll;

                            //printf("ESC-3 %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y);

                            if(s->qscale<8){

                                ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);

                                if(ll==0){

                                    if(SHOW_UBITS(re, &s->gb, 1)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n");

                                    SKIP_BITS(re, &s->gb, 1);

                                    ll=8;

                                }

                            }else{

                                ll=2;

                                while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){

                                    ll++;

                                    SKIP_BITS(re, &s->gb, 1);

                                }

                                if(ll<8) SKIP_BITS(re, &s->gb, 1);

                            }

                            s->esc3_level_length= ll;

                            s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);

//printf("level length:%d, run length: %d\n", ll, s->esc3_run_length);

                            UPDATE_CACHE(re, &s->gb);

                        }

                        run=   SHOW_UBITS(re, &s->gb, s->esc3_run_length);

                        SKIP_BITS(re, &s->gb, s->esc3_run_length);

                        sign=  SHOW_UBITS(re, &s->gb, 1);

                        SKIP_BITS(re, &s->gb, 1);

                        level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);

                        SKIP_BITS(re, &s->gb, s->esc3_level_length);

                        if(sign) level= -level;

                    }

//printf("level: %d, run: %d at %d %d\n", level, run, s->mb_x, s->mb_y);

#if 0 // waste of time / this will detect very few errors

                    {

                        const int abs_level= ABS(level);

                        const int run1= run - rl->max_run[last][abs_level] - run_diff;

                        if(abs_level<=MAX_LEVEL && run<=MAX_RUN){

                            if(abs_level <= rl->max_level[last][run]){

                                fprintf(stderr, "illegal 3. esc, vlc encoding possible\n");

                                return DECODING_AC_LOST;

                            }

                            if(abs_level <= rl->max_level[last][run]*2){

                                fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n");

                                return DECODING_AC_LOST;

                            }

                            if(run1>=0 && abs_level <= rl->max_level[last][run1]){

                                fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n");

                                return DECODING_AC_LOST;

                            }

                        }

                    }

#endif

		    //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;

		    if (level>0) level= level * qmul + qadd;

                    else         level= level * qmul - qadd;

#if 0 // waste of time too :(

                    if(level>2048 || level<-2048){

                        fprintf(stderr, "|level| overflow in 3. esc\n");

                        return DECODING_AC_LOST;

                    }

#endif

                    i+= run + 1;

                    if(last) i+=192;

#ifdef ERROR_DETAILS

                if(run==66)

                    fprintf(stderr, "illegal vlc code in ESC3 level=%d\n", level);

                else if((i>62 && i<192) || i>192+63)

                    fprintf(stderr, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);

#endif

                } else {

                    /* second escape */

#if MIN_CACHE_BITS < 23

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

                    UPDATE_CACHE(re, &s->gb);

#else

                    SKIP_BITS(re, &s->gb, 2);

#endif

                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);

                    i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing

                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);

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

#ifdef ERROR_DETAILS

                if(run==66)

                    fprintf(stderr, "illegal vlc code in ESC2 level=%d\n", level);

                else if((i>62 && i<192) || i>192+63)

                    fprintf(stderr, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);

#endif

                }

            } else {

                /* first escape */

#if MIN_CACHE_BITS < 22

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

                UPDATE_CACHE(re, &s->gb);

#else

                SKIP_BITS(re, &s->gb, 1);

#endif

                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2);

                i+= run;

                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing

                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);

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

#ifdef ERROR_DETAILS

                if(run==66)

                    fprintf(stderr, "illegal vlc code in ESC1 level=%d\n", level);

                else if((i>62 && i<192) || i>192+63)

                    fprintf(stderr, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);

#endif

            }

        } else {

            i+= run;

            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);

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

#ifdef ERROR_DETAILS

                if(run==66)

                    fprintf(stderr, "illegal vlc code level=%d\n", level);

                else if((i>62 && i<192) || i>192+63)

                    fprintf(stderr, "run overflow i=%d run=%d level=%d\n", i, run, level);

#endif

        }

        if (i > 62){

            i-= 192;

            if(i&(~63)){

                if(i+192 == 64 && level/qmul==-1){

                    fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);

                    break;

                }else{

                    fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);

                    return -1;

                }

            }

            block[scan_table[i]] = level;

            break;

        }

        block[scan_table[i]] = level;

    }

    CLOSE_READER(re, &s->gb);

  }

 not_coded:

    if (s->mb_intra) {

        mpeg4_pred_ac(s, block, n, dc_pred_dir);

        if (s->ac_pred) {

            i = 63; /* XXX: not optimal */

        }

    }

    if(s->msmpeg4_version==4 && i>0) i=63; //FIXME/XXX optimize

    s->block_last_index[n] = i;

    return 0;

}


static void revert_acfilter(WmallDecodeCtx *s, int tile_size)

{

    int ich, pred, i, j;

    int16_t *filter_coeffs = s->acfilter_coeffs;

    int scaling            = s->acfilter_scaling;

    int order              = s->acfilter_order;

    for (ich = 0; ich < s->num_channels; ich++) {

        int *prevvalues = s->acfilter_prevvalues[ich];

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

            pred = 0;

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

                if (i <= j)

                    pred += filter_coeffs[j] * prevvalues[j - i];

                else

                    pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j];

            }

            pred >>= scaling;

            s->channel_residues[ich][i] += pred;

        }

        for (i = order; i < tile_size; i++) {

            pred = 0;

            for (j = 0; j < order; j++)

                pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j];

            pred >>= scaling;

            s->channel_residues[ich][i] += pred;

        }

        for (j = 0; j < order; j++)

            prevvalues[j] = s->channel_residues[ich][tile_size - j - 1];

    }

}


int bdrv_snapshot_list(BlockDriverState *bs,

                       QEMUSnapshotInfo **psn_info)

{

    BlockDriver *drv = bs->drv;

    if (!drv)

        return -ENOMEDIUM;

    if (drv->bdrv_snapshot_list)

        return drv->bdrv_snapshot_list(bs, psn_info);

    if (bs->file)

        return bdrv_snapshot_list(bs->file, psn_info);

    return -ENOTSUP;

}


static int mp3_write_xing(AVFormatContext *s)

{

    MP3Context       *mp3 = s->priv_data;

    AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;

    AVDictionaryEntry *enc = av_dict_get(s->streams[mp3->audio_stream_idx]->metadata, "encoder", NULL, 0);

    AVIOContext *dyn_ctx;

    int32_t        header;

    MPADecodeHeader  mpah;

    int srate_idx, i, channels;

    int bitrate_idx;

    int best_bitrate_idx = -1;

    int best_bitrate_error = INT_MAX;

    int ret;

    int ver = 0;

    int bytes_needed;

    if (!s->pb->seekable || !mp3->write_xing)

        return 0;

    for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {

        const uint16_t base_freq = avpriv_mpa_freq_tab[i];

        if      (codec->sample_rate == base_freq)     ver = 0x3; // MPEG 1

        else if (codec->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2

        else if (codec->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5

        else continue;

        srate_idx = i;

        break;

    }

    if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {

        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing header.\n");

        return -1;

    }

    switch (codec->channels) {

    case 1:  channels = MPA_MONO;                                          break;

    case 2:  channels = MPA_STEREO;                                        break;

    default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "

                    "not writing Xing header.\n");

             return -1;

    }

    /* dummy MPEG audio header */

    header  =  0xffU                                 << 24; // sync

    header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/

    header |= (srate_idx << 2) << 8;

    header |= channels << 6;

    for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) {

        int bit_rate = 1000 * avpriv_mpa_bitrate_tab[ver != 3][3 - 1][bitrate_idx];

        int error    = FFABS(bit_rate - codec->bit_rate);

        if (error < best_bitrate_error) {

            best_bitrate_error = error;

            best_bitrate_idx   = bitrate_idx;

        }

    }

    av_assert0(best_bitrate_idx >= 0);

    for (bitrate_idx = best_bitrate_idx; ; bitrate_idx++) {

        int32_t mask = bitrate_idx << (4 + 8);

        if (15 == bitrate_idx)

            return -1;

        header |= mask;

        avpriv_mpegaudio_decode_header(&mpah, header);

        mp3->xing_offset = xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1] + 4;

        bytes_needed     = mp3->xing_offset + XING_SIZE;

        if (bytes_needed <= mpah.frame_size)

            break;

        header &= ~mask;

    }

    ret = avio_open_dyn_buf(&dyn_ctx);

    if (ret < 0)

        return ret;

    avio_wb32(dyn_ctx, header);

    ffio_fill(dyn_ctx, 0, mp3->xing_offset - 4);

    ffio_wfourcc(dyn_ctx, "Xing");

    avio_wb32(dyn_ctx, 0x01 | 0x02 | 0x04 | 0x08);  // frames / size / TOC / vbr scale

    mp3->size = mpah.frame_size;

    mp3->want=1;

    mp3->seen=0;

    mp3->pos=0;

    avio_wb32(dyn_ctx, 0);  // frames

    avio_wb32(dyn_ctx, 0);  // size

    // TOC

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

        avio_w8(dyn_ctx, (uint8_t)(255 * i / XING_TOC_SIZE));

    // vbr quality

    // we write it, because some (broken) tools always expect it to be present

    avio_wb32(dyn_ctx, 0);

    // encoder short version string

    if (enc) {

        uint8_t encoder_str[9] = { 0 };

        if (   strlen(enc->value) > sizeof(encoder_str)

            && !strcmp("Lavc libmp3lame", enc->value)) {

            memcpy(encoder_str, "Lavf lame", 9);

        } else

            memcpy(encoder_str, enc->value, FFMIN(strlen(enc->value), sizeof(encoder_str)));

        avio_write(dyn_ctx, encoder_str, sizeof(encoder_str));

    } else

        avio_write(dyn_ctx, "Lavf\0\0\0\0\0", 9);

    avio_w8(dyn_ctx, 0);      // tag revision 0 / unknown vbr method

    avio_w8(dyn_ctx, 0);      // unknown lowpass filter value

    ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields

    avio_w8(dyn_ctx, 0);      // unknown encoding flags

    avio_w8(dyn_ctx, 0);      // unknown abr/minimal bitrate

    // encoder delay

    if (codec->initial_padding - 528 - 1 >= 1 << 12) {

        av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n");

    }

    avio_wb24(dyn_ctx, FFMAX(codec->initial_padding - 528 - 1, 0)<<12);

    avio_w8(dyn_ctx,   0); // misc

    avio_w8(dyn_ctx,   0); // mp3gain

    avio_wb16(dyn_ctx, 0); // preset

    // audio length and CRCs (will be updated later)

    avio_wb32(dyn_ctx, 0); // music length

    avio_wb16(dyn_ctx, 0); // music crc

    avio_wb16(dyn_ctx, 0); // tag crc

    ffio_fill(dyn_ctx, 0, mpah.frame_size - bytes_needed);

    mp3->xing_frame_size   = avio_close_dyn_buf(dyn_ctx, &mp3->xing_frame);

    mp3->xing_frame_offset = avio_tell(s->pb);

    avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size);

    mp3->audio_size = mp3->xing_frame_size;

    return 0;

}


static void dec_store(DisasContext *dc)

{

    TCGv t, *addr;

    unsigned int size;

    size = 1 << (dc->opcode & 3);

    if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)

          && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {

        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);

        t_gen_raise_exception(dc, EXCP_HW_EXCP);

        return;

    }

    LOG_DIS("s%d%s\n", size, dc->type_b ? "i" : "");

    t_sync_flags(dc);

    /* If we get a fault on a dslot, the jmpstate better be in sync.  */

    sync_jmpstate(dc);

    addr = compute_ldst_addr(dc, &t);

    /* Verify alignment if needed.  */

    if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {

        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),

                            tcg_const_tl(1), tcg_const_tl(size - 1));

    }

    gen_store(dc, *addr, cpu_R[dc->rd], size);

    if (addr == &t)

        tcg_temp_free(t);

}


static void qpci_spapr_io_writew(QPCIBus *bus, void *addr, uint16_t value)

{

    QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);

    uint64_t port = (uintptr_t)addr;

    value = bswap16(value);

    if (port < s->pio.size) {

        writew(s->pio_cpu_base + port, value);

    } else {

        writew(s->mmio_cpu_base + port, value);

    }

}


static void dwt_decode97_int(DWTContext *s, int32_t *t)

{

    int lev;

    int w       = s->linelen[s->ndeclevels - 1][0];

    int h       = s->linelen[s->ndeclevels - 1][1];

    int i;

    int32_t *line = s->i_linebuf;

    int32_t *data = t;

    /* position at index O of line range [0-5,w+5] cf. extend function */

    line += 5;

    for (i = 0; i < w * h; i++)

        data[i] *= 1 << I_PRESHIFT;

    for (lev = 0; lev < s->ndeclevels; lev++) {

        int lh = s->linelen[lev][0],

            lv = s->linelen[lev][1],

            mh = s->mod[lev][0],

            mv = s->mod[lev][1],

            lp;

        int32_t *l;

        // HOR_SD

        l = line + mh;

        for (lp = 0; lp < lv; lp++) {

            int i, j = 0;

            // rescale with interleaving

            for (i = mh; i < lh; i += 2, j++)

                l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;

            for (i = 1 - mh; i < lh; i += 2, j++)

                l[i] = data[w * lp + j];

            sr_1d97_int(line, mh, mh + lh);

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

                data[w * lp + i] = l[i];

        }

        // VER_SD

        l = line + mv;

        for (lp = 0; lp < lh; lp++) {

            int i, j = 0;

            // rescale with interleaving

            for (i = mv; i < lv; i += 2, j++)

                l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;

            for (i = 1 - mv; i < lv; i += 2, j++)

                l[i] = data[w * j + lp];

            sr_1d97_int(line, mv, mv + lv);

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

                data[w * i + lp] = l[i];

        }

    }

    for (i = 0; i < w * h; i++)

        data[i] = (data[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT;

}


int kvm_arch_get_registers(CPUState *env)

{

    struct kvm_regs regs;

    struct kvm_sregs sregs;

    uint32_t cr;

    int i, ret;

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

    if (ret < 0)

        return ret;

    cr = regs.cr;

    for (i = 7; i >= 0; i--) {

        env->crf[i] = cr & 15;

        cr >>= 4;

    }

    env->ctr = regs.ctr;

    env->lr = regs.lr;

    env->xer = regs.xer;

    env->msr = regs.msr;

    env->nip = regs.pc;

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

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

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

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

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

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

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

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

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

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

    env->spr[SPR_BOOKE_PID] = regs.pid;

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

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

#ifdef KVM_CAP_PPC_BOOKE_SREGS

    if (cap_booke_sregs) {

        ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);

        if (ret < 0) {

            return ret;

        }

        if (sregs.u.e.features & KVM_SREGS_E_BASE) {

            env->spr[SPR_BOOKE_CSRR0] = sregs.u.e.csrr0;

            env->spr[SPR_BOOKE_CSRR1] = sregs.u.e.csrr1;

            env->spr[SPR_BOOKE_ESR] = sregs.u.e.esr;

            env->spr[SPR_BOOKE_DEAR] = sregs.u.e.dear;

            env->spr[SPR_BOOKE_MCSR] = sregs.u.e.mcsr;

            env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;

            env->spr[SPR_BOOKE_TCR] = sregs.u.e.tcr;

            env->spr[SPR_DECR] = sregs.u.e.dec;

            env->spr[SPR_TBL] = sregs.u.e.tb & 0xffffffff;

            env->spr[SPR_TBU] = sregs.u.e.tb >> 32;

            env->spr[SPR_VRSAVE] = sregs.u.e.vrsave;

        }

        if (sregs.u.e.features & KVM_SREGS_E_ARCH206) {

            env->spr[SPR_BOOKE_PIR] = sregs.u.e.pir;

            env->spr[SPR_BOOKE_MCSRR0] = sregs.u.e.mcsrr0;

            env->spr[SPR_BOOKE_MCSRR1] = sregs.u.e.mcsrr1;

            env->spr[SPR_BOOKE_DECAR] = sregs.u.e.decar;

            env->spr[SPR_BOOKE_IVPR] = sregs.u.e.ivpr;

        }

        if (sregs.u.e.features & KVM_SREGS_E_64) {

            env->spr[SPR_BOOKE_EPCR] = sregs.u.e.epcr;

        }

        if (sregs.u.e.features & KVM_SREGS_E_SPRG8) {

            env->spr[SPR_BOOKE_SPRG8] = sregs.u.e.sprg8;

        }

        if (sregs.u.e.features & KVM_SREGS_E_IVOR) {

            env->spr[SPR_BOOKE_IVOR0] = sregs.u.e.ivor_low[0];

            env->spr[SPR_BOOKE_IVOR1] = sregs.u.e.ivor_low[1];

            env->spr[SPR_BOOKE_IVOR2] = sregs.u.e.ivor_low[2];

            env->spr[SPR_BOOKE_IVOR3] = sregs.u.e.ivor_low[3];

            env->spr[SPR_BOOKE_IVOR4] = sregs.u.e.ivor_low[4];

            env->spr[SPR_BOOKE_IVOR5] = sregs.u.e.ivor_low[5];

            env->spr[SPR_BOOKE_IVOR6] = sregs.u.e.ivor_low[6];

            env->spr[SPR_BOOKE_IVOR7] = sregs.u.e.ivor_low[7];

            env->spr[SPR_BOOKE_IVOR8] = sregs.u.e.ivor_low[8];

            env->spr[SPR_BOOKE_IVOR9] = sregs.u.e.ivor_low[9];

            env->spr[SPR_BOOKE_IVOR10] = sregs.u.e.ivor_low[10];

            env->spr[SPR_BOOKE_IVOR11] = sregs.u.e.ivor_low[11];

            env->spr[SPR_BOOKE_IVOR12] = sregs.u.e.ivor_low[12];

            env->spr[SPR_BOOKE_IVOR13] = sregs.u.e.ivor_low[13];

            env->spr[SPR_BOOKE_IVOR14] = sregs.u.e.ivor_low[14];

            env->spr[SPR_BOOKE_IVOR15] = sregs.u.e.ivor_low[15];

            if (sregs.u.e.features & KVM_SREGS_E_SPE) {

                env->spr[SPR_BOOKE_IVOR32] = sregs.u.e.ivor_high[0];

                env->spr[SPR_BOOKE_IVOR33] = sregs.u.e.ivor_high[1];

                env->spr[SPR_BOOKE_IVOR34] = sregs.u.e.ivor_high[2];

            }

            if (sregs.u.e.features & KVM_SREGS_E_PM) {

                env->spr[SPR_BOOKE_IVOR35] = sregs.u.e.ivor_high[3];

            }

            if (sregs.u.e.features & KVM_SREGS_E_PC) {

                env->spr[SPR_BOOKE_IVOR36] = sregs.u.e.ivor_high[4];

                env->spr[SPR_BOOKE_IVOR37] = sregs.u.e.ivor_high[5];

            }

        }

        if (sregs.u.e.features & KVM_SREGS_E_ARCH206_MMU) {

            env->spr[SPR_BOOKE_MAS0] = sregs.u.e.mas0;

            env->spr[SPR_BOOKE_MAS1] = sregs.u.e.mas1;

            env->spr[SPR_BOOKE_MAS2] = sregs.u.e.mas2;

            env->spr[SPR_BOOKE_MAS3] = sregs.u.e.mas7_3 & 0xffffffff;

            env->spr[SPR_BOOKE_MAS4] = sregs.u.e.mas4;

            env->spr[SPR_BOOKE_MAS6] = sregs.u.e.mas6;

            env->spr[SPR_BOOKE_MAS7] = sregs.u.e.mas7_3 >> 32;

            env->spr[SPR_MMUCFG] = sregs.u.e.mmucfg;

            env->spr[SPR_BOOKE_TLB0CFG] = sregs.u.e.tlbcfg[0];

            env->spr[SPR_BOOKE_TLB1CFG] = sregs.u.e.tlbcfg[1];

        }

        if (sregs.u.e.features & KVM_SREGS_EXP) {

            env->spr[SPR_BOOKE_EPR] = sregs.u.e.epr;

        }

        if (sregs.u.e.features & KVM_SREGS_E_PD) {

            env->spr[SPR_BOOKE_EPLC] = sregs.u.e.eplc;

            env->spr[SPR_BOOKE_EPSC] = sregs.u.e.epsc;

        }

        if (sregs.u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {

            env->spr[SPR_E500_SVR] = sregs.u.e.impl.fsl.svr;

            env->spr[SPR_Exxx_MCAR] = sregs.u.e.impl.fsl.mcar;

            env->spr[SPR_HID0] = sregs.u.e.impl.fsl.hid0;

            if (sregs.u.e.impl.fsl.features & KVM_SREGS_E_FSL_PIDn) {

                env->spr[SPR_BOOKE_PID1] = sregs.u.e.impl.fsl.pid1;

                env->spr[SPR_BOOKE_PID2] = sregs.u.e.impl.fsl.pid2;

            }

        }

    }

#endif

#ifdef KVM_CAP_PPC_SEGSTATE

    if (cap_segstate) {

        ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);

        if (ret < 0) {

            return ret;

        }

        ppc_store_sdr1(env, sregs.u.s.sdr1);

        /* Sync SLB */

#ifdef TARGET_PPC64

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

            ppc_store_slb(env, sregs.u.s.ppc64.slb[i].slbe,

                               sregs.u.s.ppc64.slb[i].slbv);

        }

#endif

        /* Sync SRs */

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

            env->sr[i] = sregs.u.s.ppc32.sr[i];

        }

        /* Sync BATs */

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

            env->DBAT[0][i] = sregs.u.s.ppc32.dbat[i] & 0xffffffff;

            env->DBAT[1][i] = sregs.u.s.ppc32.dbat[i] >> 32;

            env->IBAT[0][i] = sregs.u.s.ppc32.ibat[i] & 0xffffffff;

            env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32;

        }

    }

#endif

    return 0;

}


static int cdrom_probe_device(const char *filename)

{

    if (strstart(filename, "/dev/cd", NULL))

        return 100;

    return 0;

}


static int qio_channel_socket_listen_worker(QIOTask *task,

                                            Error **errp,

                                            gpointer opaque)

{

    QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));

    SocketAddress *addr = opaque;

    int ret;

    ret = qio_channel_socket_listen_sync(ioc,

                                         addr,

                                         errp);

    object_unref(OBJECT(ioc));

    return ret;

}


static int get_http_header_data(MMSHContext *mmsh)

{

    MMSContext *mms = &mmsh->mms;

    int res, len;

    ChunkType chunk_type;

    for (;;) {

        len = 0;

        res = chunk_type = get_chunk_header(mmsh, &len);

        if (res < 0) {

            return res;

        } else if (chunk_type == CHUNK_TYPE_ASF_HEADER){

            // get asf header and stored it

            if (!mms->header_parsed) {

                if (mms->asf_header) {

                    if (len != mms->asf_header_size) {

                        mms->asf_header_size = len;

                        av_dlog(NULL, "Header len changed from %d to %d\n",

                                mms->asf_header_size, len);

                        av_freep(&mms->asf_header);

                    }

                }

                mms->asf_header = av_mallocz(len);

                if (!mms->asf_header) {

                    return AVERROR(ENOMEM);

                }

                mms->asf_header_size = len;

            }

            if (len > mms->asf_header_size) {

                av_log(NULL, AV_LOG_ERROR,

                       "Asf header packet len = %d exceed the asf header buf size %d\n",

                       len, mms->asf_header_size);

                return AVERROR(EIO);

            }

            res = ffurl_read_complete(mms->mms_hd, mms->asf_header, len);

            if (res != len) {

                av_log(NULL, AV_LOG_ERROR,

                       "Recv asf header data len %d != expected len %d\n", res, len);

                return AVERROR(EIO);

            }

            mms->asf_header_size = len;

            if (!mms->header_parsed) {

                res = ff_mms_asf_header_parser(mms);

                mms->header_parsed = 1;

                return res;

            }

        } else if (chunk_type == CHUNK_TYPE_DATA) {

            // read data packet and do padding

            return read_data_packet(mmsh, len);

        } else {

            if (len) {

                if (len > sizeof(mms->in_buffer)) {

                    av_log(NULL, AV_LOG_ERROR,

                           "Other packet len = %d exceed the in_buffer size %zu\n",

                           len, sizeof(mms->in_buffer));

                    return AVERROR(EIO);

                }

                res = ffurl_read_complete(mms->mms_hd, mms->in_buffer, len);

                if (res != len) {

                    av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n");

                    return AVERROR(EIO);

                } else {

                    av_dlog(NULL, "Skip chunk type %d \n", chunk_type);

                    continue;

                }

            }

        }

    }

    return 0;

}


static USBPort *xhci_lookup_uport(XHCIState *xhci, uint32_t *slot_ctx)

{

    USBPort *uport;

    char path[32];

    int i, pos, port;

    port = (slot_ctx[1]>>16) & 0xFF;

    port = xhci->ports[port-1].uport->index+1;

    pos = snprintf(path, sizeof(path), "%d", port);

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

        port = (slot_ctx[0] >> 4*i) & 0x0f;

        if (!port) {

            break;

        pos += snprintf(path + pos, sizeof(path) - pos, ".%d", port);

    QTAILQ_FOREACH(uport, &xhci->bus.used, next) {

        if (strcmp(uport->path, path) == 0) {

            return uport;


static void io_watch_poll_finalize(GSource *source)

{

    IOWatchPoll *iwp = io_watch_poll_from_source(source);

    if (iwp->src) {

        g_source_destroy(iwp->src);

        g_source_unref(iwp->src);

        iwp->src = NULL;

    }

}


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

                            int *data_size, AVPacket *avpkt)

{

    const uint8_t *buf   = avpkt->data;

    int buf_size         = avpkt->size;

    PNMContext * const s = avctx->priv_data;

    AVFrame *picture     = data;

    AVFrame * const p    = (AVFrame*)&s->picture;

    int i, j, n, linesize, h, upgrade = 0;

    unsigned char *ptr;

    int components, sample_len;

    s->bytestream_start =

    s->bytestream       = buf;

    s->bytestream_end   = buf + buf_size;

    if (ff_pnm_decode_header(avctx, s) < 0)

        return -1;

    if (p->data[0])

        avctx->release_buffer(avctx, p);

    p->reference = 0;

    if (avctx->get_buffer(avctx, p) < 0) {

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

        return -1;

    }

    p->pict_type = AV_PICTURE_TYPE_I;

    p->key_frame = 1;

    switch (avctx->pix_fmt) {

    default:

        return -1;

    case PIX_FMT_RGB48BE:

        n = avctx->width * 6;

        components=3;

        sample_len=16;

        goto do_read;

    case PIX_FMT_RGB24:

        n = avctx->width * 3;

        components=3;

        sample_len=8;

        goto do_read;

    case PIX_FMT_GRAY8:

        n = avctx->width;

        components=1;

        sample_len=8;

        if (s->maxval < 255)

            upgrade = 1;

        goto do_read;

    case PIX_FMT_GRAY16BE:

    case PIX_FMT_GRAY16LE:

        n = avctx->width * 2;

        components=1;

        sample_len=16;

        if (s->maxval < 65535)

            upgrade = 2;

        goto do_read;

    case PIX_FMT_MONOWHITE:

    case PIX_FMT_MONOBLACK:

        n = (avctx->width + 7) >> 3;

        components=1;

        sample_len=1;

    do_read:

        ptr      = p->data[0];

        linesize = p->linesize[0];

        if (s->bytestream + n * avctx->height > s->bytestream_end)

            return -1;

        if(s->type < 4){

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

                PutBitContext pb;

                init_put_bits(&pb, ptr, linesize);

                for(j=0; j<avctx->width * components; j++){

                    unsigned int c=0;

                    int v=0;

                    while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))

                        s->bytestream++;

                    if(s->bytestream >= s->bytestream_end)

                        return -1;

                    do{

                        v= 10*v + c;

                        c= (*s->bytestream++) - '0';

                    }while(c <= 9);

                    put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);

                }

                flush_put_bits(&pb);

                ptr+= linesize;

            }

        }else{

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

            if (!upgrade)

                memcpy(ptr, s->bytestream, n);

            else if (upgrade == 1) {

                unsigned int j, f = (255 * 128 + s->maxval / 2) / s->maxval;

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

                    ptr[j] = (s->bytestream[j] * f + 64) >> 7;

            } else if (upgrade == 2) {

                unsigned int j, v, f = (65535 * 32768 + s->maxval / 2) / s->maxval;

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

                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);

                    ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;

                }

            }

            s->bytestream += n;

            ptr           += linesize;

        }

        }

        break;

    case PIX_FMT_YUV420P:

        {

            unsigned char *ptr1, *ptr2;

            n        = avctx->width;

            ptr      = p->data[0];

            linesize = p->linesize[0];

            if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)

                return -1;

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

                memcpy(ptr, s->bytestream, n);

                s->bytestream += n;

                ptr           += linesize;

            }

            ptr1 = p->data[1];

            ptr2 = p->data[2];

            n >>= 1;

            h = avctx->height >> 1;

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

                memcpy(ptr1, s->bytestream, n);

                s->bytestream += n;

                memcpy(ptr2, s->bytestream, n);

                s->bytestream += n;

                ptr1 += p->linesize[1];

                ptr2 += p->linesize[2];

            }

        }

        break;

    case PIX_FMT_RGB32:

        ptr      = p->data[0];

        linesize = p->linesize[0];

        if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end)

            return -1;

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

            int j, r, g, b, a;

            for (j = 0; j < avctx->width; j++) {

                r = *s->bytestream++;

                g = *s->bytestream++;

                b = *s->bytestream++;

                a = *s->bytestream++;

                ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b;

            }

            ptr += linesize;

        }

        break;

    }

    *picture   = *(AVFrame*)&s->picture;

    *data_size = sizeof(AVPicture);

    return s->bytestream - s->bytestream_start;

}


static int estimate_best_b_count(MpegEncContext *s)

{

    AVCodec *codec    = avcodec_find_encoder(s->avctx->codec_id);

    AVCodecContext *c = avcodec_alloc_context3(NULL);

    const int scale = s->avctx->brd_scale;

    int i, j, out_size, p_lambda, b_lambda, lambda2;

    int64_t best_rd  = INT64_MAX;

    int best_b_count = -1;

    assert(scale >= 0 && scale <= 3);

    //emms_c();

    //s->next_picture_ptr->quality;

    p_lambda = s->last_lambda_for[AV_PICTURE_TYPE_P];

    //p_lambda * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;

    b_lambda = s->last_lambda_for[AV_PICTURE_TYPE_B];

    if (!b_lambda) // FIXME we should do this somewhere else

        b_lambda = p_lambda;

    lambda2  = (b_lambda * b_lambda + (1 << FF_LAMBDA_SHIFT) / 2) >>

               FF_LAMBDA_SHIFT;

    c->width        = s->width  >> scale;

    c->height       = s->height >> scale;

    c->flags        = CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR |

                      CODEC_FLAG_INPUT_PRESERVED;

    c->flags       |= s->avctx->flags & CODEC_FLAG_QPEL;

    c->mb_decision  = s->avctx->mb_decision;

    c->me_cmp       = s->avctx->me_cmp;

    c->mb_cmp       = s->avctx->mb_cmp;

    c->me_sub_cmp   = s->avctx->me_sub_cmp;

    c->pix_fmt      = AV_PIX_FMT_YUV420P;

    c->time_base    = s->avctx->time_base;

    c->max_b_frames = s->max_b_frames;

    if (avcodec_open2(c, codec, NULL) < 0)

        return -1;

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

        Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] :

                                                s->next_picture_ptr;

        if (pre_input_ptr && (!i || s->input_picture[i - 1])) {

            pre_input = *pre_input_ptr;

            if (!pre_input.shared && i) {

                pre_input.f.data[0] += INPLACE_OFFSET;

                pre_input.f.data[1] += INPLACE_OFFSET;

                pre_input.f.data[2] += INPLACE_OFFSET;

            }

            s->dsp.shrink[scale](s->tmp_frames[i]->data[0], s->tmp_frames[i]->linesize[0],

                                 pre_input.f.data[0], pre_input.f.linesize[0],

                                 c->width,      c->height);

            s->dsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[i]->linesize[1],

                                 pre_input.f.data[1], pre_input.f.linesize[1],

                                 c->width >> 1, c->height >> 1);

            s->dsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2],

                                 pre_input.f.data[2], pre_input.f.linesize[2],

                                 c->width >> 1, c->height >> 1);

        }

    }

    for (j = 0; j < s->max_b_frames + 1; j++) {

        int64_t rd = 0;

        if (!s->input_picture[j])

            break;

        c->error[0] = c->error[1] = c->error[2] = 0;

        s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I;

        s->tmp_frames[0]->quality   = 1 * FF_QP2LAMBDA;

        out_size = encode_frame(c, s->tmp_frames[0]);

        //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;

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

            int is_p = i % (j + 1) == j || i == s->max_b_frames;

            s->tmp_frames[i + 1]->pict_type = is_p ?

                                     AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;

            s->tmp_frames[i + 1]->quality   = is_p ? p_lambda : b_lambda;

            out_size = encode_frame(c, s->tmp_frames[i + 1]);

            rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);

        }

        /* get the delayed frames */

        while (out_size) {

            out_size = encode_frame(c, NULL);

            rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);

        }

        rd += c->error[0] + c->error[1] + c->error[2];

        if (rd < best_rd) {

            best_rd = rd;

            best_b_count = j;

        }

    }

    avcodec_close(c);

    av_freep(&c);

    return best_b_count;

}


static int str_read_packet(AVFormatContext *s,

                           AVPacket *ret_pkt)

{

    ByteIOContext *pb = s->pb;

    StrDemuxContext *str = s->priv_data;

    unsigned char sector[RAW_CD_SECTOR_SIZE];

    int channel;

    AVPacket *pkt;

    AVStream *st;

    while (1) {

        if (get_buffer(pb, sector, RAW_CD_SECTOR_SIZE) != RAW_CD_SECTOR_SIZE)

            return AVERROR(EIO);

        channel = sector[0x11];

        if (channel >= 32)

            return AVERROR_INVALIDDATA;

        switch (sector[0x12] & CDXA_TYPE_MASK) {

        case CDXA_TYPE_DATA:

        case CDXA_TYPE_VIDEO:

            {

                int current_sector = AV_RL16(&sector[0x1C]);

                int sector_count   = AV_RL16(&sector[0x1E]);

                int frame_size = AV_RL32(&sector[0x24]);

                if(!(   frame_size>=0

                     && current_sector < sector_count

                     && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){

                    av_log(s, AV_LOG_ERROR, "Invalid parameters %d %d %d\n", current_sector, sector_count, frame_size);

                    return AVERROR_INVALIDDATA;

                }

                if(str->channels[channel].video_stream_index < 0){

                    /* allocate a new AVStream */

                    st = av_new_stream(s, 0);

                    if (!st)

                        return AVERROR(ENOMEM);

                    av_set_pts_info(st, 64, 1, 15);

                    str->channels[channel].video_stream_index = st->index;

                    st->codec->codec_type = CODEC_TYPE_VIDEO;

                    st->codec->codec_id   = CODEC_ID_MDEC;

                    st->codec->codec_tag  = 0;  /* no fourcc */

                    st->codec->width      = AV_RL16(&sector[0x28]);

                    st->codec->height     = AV_RL16(&sector[0x2A]);

                }

                /* if this is the first sector of the frame, allocate a pkt */

                pkt = &str->channels[channel].tmp_pkt;

                if(pkt->size != sector_count*VIDEO_DATA_CHUNK_SIZE){

                    if(pkt->data)

                        av_log(s, AV_LOG_ERROR, "missmatching sector_count\n");

                    av_free_packet(pkt);

                    if (av_new_packet(pkt, sector_count*VIDEO_DATA_CHUNK_SIZE))

                        return AVERROR(EIO);

                    pkt->pos= url_ftell(pb) - RAW_CD_SECTOR_SIZE;

                    pkt->stream_index =

                        str->channels[channel].video_stream_index;

                }

                memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE,

                       sector + VIDEO_DATA_HEADER_SIZE,

                       VIDEO_DATA_CHUNK_SIZE);

                if (current_sector == sector_count-1) {

                    pkt->size= frame_size;

                    *ret_pkt = *pkt;

                    pkt->data= NULL;

                    pkt->size= -1;

                    return 0;

                }

            }

            break;

        case CDXA_TYPE_AUDIO:

            if(str->channels[channel].audio_stream_index < 0){

                int fmt = sector[0x13];

                /* allocate a new AVStream */

                st = av_new_stream(s, 0);

                if (!st)

                    return AVERROR(ENOMEM);

                str->channels[channel].audio_stream_index = st->index;

                st->codec->codec_type  = CODEC_TYPE_AUDIO;

                st->codec->codec_id    = CODEC_ID_ADPCM_XA;

                st->codec->codec_tag   = 0;  /* no fourcc */

                st->codec->channels    = (fmt&1)?2:1;

                st->codec->sample_rate = (fmt&4)?18900:37800;

            //    st->codec->bit_rate = 0; //FIXME;

                st->codec->block_align = 128;

                av_set_pts_info(st, 64, 128, st->codec->sample_rate);

            }

                pkt = ret_pkt;

                if (av_new_packet(pkt, 2304))

                    return AVERROR(EIO);

                memcpy(pkt->data,sector+24,2304);

                pkt->stream_index =

                    str->channels[channel].audio_stream_index;

                return 0;

            break;

        default:

            /* drop the sector and move on */

            break;

        }

        if (url_feof(pb))

            return AVERROR(EIO);

    }

}


static inline void RENAME(rgb32tobgr24)(const uint8_t *src, uint8_t *dst, long src_size)

{

    uint8_t *dest = dst;

    const uint8_t *s = src;

    const uint8_t *end;

#if COMPILE_TEMPLATE_MMX

    const uint8_t *mm_end;

#endif

    end = s + src_size;

#if COMPILE_TEMPLATE_MMX

    __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");

    mm_end = end - 31;

    while (s < mm_end) {

        __asm__ volatile(

            PREFETCH"    32%1           \n\t"

            "movq          %1, %%mm0    \n\t"

            "movq         8%1, %%mm1    \n\t"

            "movq        16%1, %%mm4    \n\t"

            "movq        24%1, %%mm5    \n\t"

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

            "movq       %%mm1, %%mm3    \n\t"

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

            "movq       %%mm5, %%mm7    \n\t"

            STORE_BGR24_MMX

            :"=m"(*dest)

            :"m"(*s)

            :"memory");

        dest += 24;

        s += 32;

    }

    __asm__ volatile(SFENCE:::"memory");

    __asm__ volatile(EMMS:::"memory");

#endif

    while (s < end) {

#if HAVE_BIGENDIAN

        /* RGB32 (= A,B,G,R) -> RGB24 (= R,G,B) */

        s++;

        dest[2] = *s++;

        dest[1] = *s++;

        dest[0] = *s++;

        dest += 3;

#else

        *dest++ = *s++;

        *dest++ = *s++;

        *dest++ = *s++;

        s++;

#endif

    }

}


static void bmdma_addr_write(void *opaque, target_phys_addr_t addr,

                             uint64_t data, unsigned width)

{

    BMDMAState *bm = opaque;

    int shift = addr * 8;

    uint32_t mask = (1ULL << (width * 8)) - 1;

#ifdef DEBUG_IDE

    printf("%s: 0x%08x\n", __func__, (unsigned)data);

#endif

    bm->addr &= ~(mask << shift);

    bm->addr |= ((data & mask) << shift) & ~3;

}


int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,

                          GIOFunc func, void *user_data)

{

    GSource *src;

    guint tag;

    if (s->chr_add_watch == NULL) {

        return -ENOSYS;

    }

    src = s->chr_add_watch(s, cond);

    if (!src) {

        return -EINVAL;

    }

    g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);

    tag = g_source_attach(src, NULL);

    g_source_unref(src);

    return tag;

}


uint64_t ldq_phys(target_phys_addr_t addr)

{

    return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);

}


static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,

                                const char *name, void *value, size_t size)

{

    char *buffer;

    ssize_t ret;

    buffer = rpath(ctx, path);

    ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);

    g_free(buffer);

    return ret;

}


static void search_for_ms_mips(AACEncContext *s, ChannelElement *cpe)

{

    int start = 0, i, w, w2, g;

    float M[128], S[128];

    float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3;

    const float lambda = s->lambda;

    SingleChannelElement *sce0 = &cpe->ch[0];

    SingleChannelElement *sce1 = &cpe->ch[1];

    if (!cpe->common_window)

        return;

    for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {

        start = 0;

        for (g = 0;  g < sce0->ics.num_swb; g++) {

            if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {

                float dist1 = 0.0f, dist2 = 0.0f;

                for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {

                    FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];

                    FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];

                    float minthr = FFMIN(band0->threshold, band1->threshold);

                    float maxthr = FFMAX(band0->threshold, band1->threshold);

                    for (i = 0; i < sce0->ics.swb_sizes[g]; i+=4) {

                        M[i  ] = (sce0->coeffs[start+w2*128+i  ]

                                + sce1->coeffs[start+w2*128+i  ]) * 0.5;

                        M[i+1] = (sce0->coeffs[start+w2*128+i+1]

                                + sce1->coeffs[start+w2*128+i+1]) * 0.5;

                        M[i+2] = (sce0->coeffs[start+w2*128+i+2]

                                + sce1->coeffs[start+w2*128+i+2]) * 0.5;

                        M[i+3] = (sce0->coeffs[start+w2*128+i+3]

                                + sce1->coeffs[start+w2*128+i+3]) * 0.5;

                        S[i  ] =  M[i  ]

                                - sce1->coeffs[start+w2*128+i  ];

                        S[i+1] =  M[i+1]

                                - sce1->coeffs[start+w2*128+i+1];

                        S[i+2] =  M[i+2]

                                - sce1->coeffs[start+w2*128+i+2];

                        S[i+3] =  M[i+3]

                                - sce1->coeffs[start+w2*128+i+3];

                   }

                    abs_pow34_v(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);

                    abs_pow34_v(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]);

                    abs_pow34_v(M34, M,                         sce0->ics.swb_sizes[g]);

                    abs_pow34_v(S34, S,                         sce0->ics.swb_sizes[g]);

                    dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128],

                                                L34,

                                                sce0->ics.swb_sizes[g],

                                                sce0->sf_idx[(w+w2)*16+g],

                                                sce0->band_type[(w+w2)*16+g],

                                                lambda / band0->threshold, INFINITY, NULL, NULL, 0);

                    dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128],

                                                R34,

                                                sce1->ics.swb_sizes[g],

                                                sce1->sf_idx[(w+w2)*16+g],

                                                sce1->band_type[(w+w2)*16+g],

                                                lambda / band1->threshold, INFINITY, NULL, NULL, 0);

                    dist2 += quantize_band_cost(s, M,

                                                M34,

                                                sce0->ics.swb_sizes[g],

                                                sce0->sf_idx[(w+w2)*16+g],

                                                sce0->band_type[(w+w2)*16+g],

                                                lambda / maxthr, INFINITY, NULL, NULL, 0);

                    dist2 += quantize_band_cost(s, S,

                                                S34,

                                                sce1->ics.swb_sizes[g],

                                                sce1->sf_idx[(w+w2)*16+g],

                                                sce1->band_type[(w+w2)*16+g],

                                                lambda / minthr, INFINITY, NULL, NULL, 0);

                }

                cpe->ms_mask[w*16+g] = dist2 < dist1;

            }

            start += sce0->ics.swb_sizes[g];

        }

    }

}


static void fw_cfg_realize(DeviceState *dev, Error **errp)

{

    FWCfgState *s = FW_CFG(dev);

    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    if (s->ctl_iobase + 1 == s->data_iobase) {

        sysbus_add_io(sbd, s->ctl_iobase, &s->comb_iomem);

    } else {

        if (s->ctl_iobase) {

            sysbus_add_io(sbd, s->ctl_iobase, &s->ctl_iomem);

        }

        if (s->data_iobase) {

            sysbus_add_io(sbd, s->data_iobase, &s->data_iomem);

        }

    }

}


static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)

{

    vscsi_req *req;

    int done;

    req = vscsi_get_req(s);

    if (req == NULL) {

        fprintf(stderr, "VSCSI: Failed to get a request !\n");

        return;

    }

    /* We only support a limited number of descriptors, we know

     * the ibmvscsi driver uses up to 10 max, so it should fit

     * in our 256 bytes IUs. If not we'll have to increase the size

     * of the structure.

     */

    if (crq->s.IU_length > sizeof(union viosrp_iu)) {

        fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n",

                crq->s.IU_length);

        return;

    }

    /* XXX Handle failure differently ? */

    if (spapr_tce_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,

                           crq->s.IU_length)) {

        fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");

        g_free(req);

    }

    memcpy(&req->crq, crq, sizeof(vscsi_crq));

    if (crq->s.format == VIOSRP_MAD_FORMAT) {

        done = vscsi_handle_mad_req(s, req);

    } else {

        done = vscsi_handle_srp_req(s, req);

    }

    if (done) {

        vscsi_put_req(req);

    }

}


static MTPData *usb_mtp_get_object_info(MTPState *s, MTPControl *c,

                                        MTPObject *o)

{

    MTPData *d = usb_mtp_data_alloc(c);

    trace_usb_mtp_op_get_object_info(s->dev.addr, o->handle, o->path);

    usb_mtp_add_u32(d, QEMU_STORAGE_ID);

    usb_mtp_add_u16(d, o->format);

    usb_mtp_add_u16(d, 0);

    usb_mtp_add_u32(d, o->stat.st_size);

    usb_mtp_add_u16(d, 0);

    usb_mtp_add_u32(d, 0);

    usb_mtp_add_u32(d, 0);

    usb_mtp_add_u32(d, 0);

    usb_mtp_add_u32(d, 0);

    usb_mtp_add_u32(d, 0);

    usb_mtp_add_u32(d, 0);

    if (o->parent) {

        usb_mtp_add_u32(d, o->parent->handle);

    } else {

        usb_mtp_add_u32(d, 0);

    }

    if (o->format == FMT_ASSOCIATION) {

        usb_mtp_add_u16(d, 0x0001);

        usb_mtp_add_u32(d, 0x00000001);

        usb_mtp_add_u32(d, 0);

    } else {

        usb_mtp_add_u16(d, 0);

        usb_mtp_add_u32(d, 0);

        usb_mtp_add_u32(d, 0);

    }

    usb_mtp_add_str(d, o->name);

    usb_mtp_add_time(d, o->stat.st_ctime);

    usb_mtp_add_time(d, o->stat.st_mtime);

    usb_mtp_add_wstr(d, L"");

    return d;

}


static inline bool rom_order_compare(Rom *rom, Rom *item)

{

    return (rom->as > item->as) ||

           (rom->as == item->as && rom->addr >= item->addr);

}


static int slb_lookup (CPUState *env, target_ulong eaddr,

                       target_ulong *vsid, target_ulong *page_mask, int *attr)

{

    target_phys_addr_t sr_base;

    target_ulong mask;

    uint64_t tmp64;

    uint32_t tmp;

    int n, ret;

    int slb_nr;

    ret = -5;

    sr_base = env->spr[SPR_ASR];

    mask = 0x0000000000000000ULL; /* Avoid gcc warning */

#if 0 /* XXX: Fix this */

    slb_nr = env->slb_nr;

#else

    slb_nr = 32;

#endif

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

        tmp64 = ldq_phys(sr_base);

        if (tmp64 & 0x0000000008000000ULL) {

            /* SLB entry is valid */

            switch (tmp64 & 0x0000000006000000ULL) {

            case 0x0000000000000000ULL:

                /* 256 MB segment */

                mask = 0xFFFFFFFFF0000000ULL;

                break;

            case 0x0000000002000000ULL:

                /* 1 TB segment */

                mask = 0xFFFF000000000000ULL;

                break;

            case 0x0000000004000000ULL:

            case 0x0000000006000000ULL:

                /* Reserved => segment is invalid */

                continue;

            }

            if ((eaddr & mask) == (tmp64 & mask)) {

                /* SLB match */

                tmp = ldl_phys(sr_base + 8);

                *vsid = ((tmp64 << 24) | (tmp >> 8)) & 0x0003FFFFFFFFFFFFULL;

                *page_mask = ~mask;

                *attr = tmp & 0xFF;

                ret = 0;

                break;

            }

        }

        sr_base += 12;

    }

    return ret;

}


static uint8_t fw_cfg_read(FWCfgState *s)

{

    int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL);

    FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL :

                    &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK];

    uint8_t ret;

    if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)

        ret = 0;

    else {

        ret = e->data[s->cur_offset++];

    }

    trace_fw_cfg_read(s, ret);

    return ret;

}


void qmp_block_resize(bool has_device, const char *device,

                      bool has_node_name, const char *node_name,

                      int64_t size, Error **errp)

{

    Error *local_err = NULL;

    BlockBackend *blk = NULL;

    BlockDriverState *bs;

    AioContext *aio_context;

    int ret;

    bs = bdrv_lookup_bs(has_device ? device : NULL,

                        has_node_name ? node_name : NULL,

                        &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    aio_context = bdrv_get_aio_context(bs);

    aio_context_acquire(aio_context);

    if (!bdrv_is_first_non_filter(bs)) {

        error_setg(errp, QERR_FEATURE_DISABLED, "resize");

        goto out;

    }

    if (size < 0) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");

        goto out;

    }

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_RESIZE, NULL)) {

        error_setg(errp, QERR_DEVICE_IN_USE, device);

        goto out;

    }

    blk = blk_new(BLK_PERM_RESIZE, BLK_PERM_ALL);

    ret = blk_insert_bs(blk, bs, errp);

    if (ret < 0) {

        goto out;

    }

    /* complete all in-flight operations before resizing the device */

    bdrv_drain_all();

    ret = blk_truncate(blk, size, errp);

out:

    blk_unref(blk);

    aio_context_release(aio_context);

}


static void clear_context(MpegEncContext *s)

{

    int i, j, k;

    memset(&s->next_picture, 0, sizeof(s->next_picture));

    memset(&s->last_picture, 0, sizeof(s->last_picture));

    memset(&s->current_picture, 0, sizeof(s->current_picture));

    memset(&s->new_picture, 0, sizeof(s->new_picture));

    memset(s->thread_context, 0, sizeof(s->thread_context));

    s->me.map = NULL;

    s->me.score_map = NULL;

    s->dct_error_sum = NULL;

    s->block = NULL;

    s->blocks = NULL;

    memset(s->pblocks, 0, sizeof(s->pblocks));

    s->ac_val_base = NULL;

    s->ac_val[0] =

    s->ac_val[1] =

    s->ac_val[2] =NULL;

    s->sc.edge_emu_buffer = NULL;

    s->me.scratchpad = NULL;

    s->me.temp =

    s->sc.rd_scratchpad =

    s->sc.b_scratchpad =

    s->sc.obmc_scratchpad = NULL;

    s->parse_context.buffer = NULL;

    s->parse_context.buffer_size = 0;

    s->bitstream_buffer = NULL;

    s->allocated_bitstream_buffer_size = 0;

    s->picture          = NULL;

    s->mb_type          = NULL;

    s->p_mv_table_base  = NULL;

    s->b_forw_mv_table_base = NULL;

    s->b_back_mv_table_base = NULL;

    s->b_bidir_forw_mv_table_base = NULL;

    s->b_bidir_back_mv_table_base = NULL;

    s->b_direct_mv_table_base = NULL;

    s->p_mv_table            = NULL;

    s->b_forw_mv_table       = NULL;

    s->b_back_mv_table       = NULL;

    s->b_bidir_forw_mv_table = NULL;

    s->b_bidir_back_mv_table = NULL;

    s->b_direct_mv_table     = NULL;

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

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

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

                s->b_field_mv_table_base[i][j][k] = NULL;

                s->b_field_mv_table[i][j][k] = NULL;

            }

            s->b_field_select_table[i][j] = NULL;

            s->p_field_mv_table_base[i][j] = NULL;

            s->p_field_mv_table[i][j] = NULL;

        }

        s->p_field_select_table[i] = NULL;

    }

    s->dc_val_base = NULL;

    s->coded_block_base = NULL;

    s->mbintra_table = NULL;

    s->cbp_table = NULL;

    s->pred_dir_table = NULL;

    s->mbskip_table = NULL;

    s->er.error_status_table = NULL;

    s->er.er_temp_buffer = NULL;

    s->mb_index2xy = NULL;

    s->lambda_table = NULL;

    s->cplx_tab = NULL;

    s->bits_tab = NULL;

}


static int rac_get_model256_sym(RangeCoder *c, Model256 *m)

{

    int prob, prob2, helper, val;

    int start, end;

    int ssym;

    prob2      = c->range;

    c->range >>= MODEL_SCALE;

    helper     = c->low / c->range;

    ssym       = helper >> MODEL256_SEC_SCALE;

    val        = m->secondary[ssym];

    end = start = m->secondary[ssym + 1] + 1;

    while (end > val + 1) {

        ssym = (end + val) >> 1;

        if (m->freqs[ssym] <= helper) {

            end = start;

            val = ssym;

        } else {

            end   = (end + val) >> 1;

            start = ssym;

        }

    }

    prob = m->freqs[val] * c->range;

    if (val != 255)

        prob2 = m->freqs[val + 1] * c->range;

    c->low  -= prob;

    c->range = prob2 - prob;

    if (c->range < RAC_BOTTOM)

        rac_normalise(c);

    model256_update(m, val);

    return val;

}


int ff_replaygain_export(AVStream *st, AVDictionary *metadata)

{

    const AVDictionaryEntry *tg, *tp, *ag, *ap;

    tg = av_dict_get(metadata, "REPLAYGAIN_TRACK_GAIN", NULL, 0);

    tp = av_dict_get(metadata, "REPLAYGAIN_TRACK_PEAK", NULL, 0);

    ag = av_dict_get(metadata, "REPLAYGAIN_ALBUM_GAIN", NULL, 0);

    ap = av_dict_get(metadata, "REPLAYGAIN_ALBUM_PEAK", NULL, 0);

    return replaygain_export(st,

                             tg ? tg->value : NULL,

                             tp ? tp->value : NULL,

                             ag ? ag->value : NULL,

                             ap ? ap->value : NULL);

}


static int decode_end(AVCodecContext * avctx)

{

    KmvcContext *const c = (KmvcContext *) avctx->priv_data;

    if (c->frm0)

        av_free(c->frm0);

    if (c->frm1)

        av_free(c->frm1);

    if (c->pic.data[0])

        avctx->release_buffer(avctx, &c->pic);

    return 0;

}


static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,

        int nb_sectors)

{

    int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8;

    uint64_t offset = (bitnum / 8) & -BDRV_SECTOR_SIZE;

    bool first = true;

    int sector_bits;

    for ( ; nb_sectors;

            bitnum += sector_bits,

            nb_sectors -= sector_bits,

            offset += BDRV_SECTOR_SIZE) {

        int ret, set;

        uint8_t bitmap[BDRV_SECTOR_SIZE];

        bitnum &= BITS_PER_BITMAP_SECTOR - 1;

        sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum);

        ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));

        if (ret < 0) {

            return ret;

        }

        /* Skip over any already set bits */

        set = cow_find_streak(bitmap, 1, bitnum, sector_bits);

        bitnum += set;

        sector_bits -= set;

        nb_sectors -= set;

        if (!sector_bits) {

            continue;

        }

        if (first) {

            ret = bdrv_flush(bs->file);

            if (ret < 0) {

                return ret;

            }

            first = false;

        }

        cow_set_bits(bitmap, bitnum, sector_bits);

        ret = bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap));

        if (ret < 0) {

            return ret;

        }

    }

    return 0;

}


static void ff_h264_idct_add16_mmx2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){

    int i;

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

        int nnz = nnzc[ scan8[i] ];

        if(nnz){

            if(nnz==1 && block[i*16]) ff_h264_idct_dc_add_mmx2(dst + block_offset[i], block + i*16, stride);

            else                      ff_h264_idct_add_mmx    (dst + block_offset[i], block + i*16, stride);

        }

    }

}


void op_mtc0_ebase (void)

{

    /* vectored interrupts not implemented */

    /* Multi-CPU not implemented */

    env->CP0_EBase = (int32_t)0x80000000 | (T0 & 0x3FFFF000);

    RETURN();

}


static void check_cpu_flag(const char *name, int flag)

{

    int old_cpu_flag = state.cpu_flag;

    flag |= old_cpu_flag;

    av_set_cpu_flags_mask(flag);

    state.cpu_flag = av_get_cpu_flags();

    if (!flag || state.cpu_flag != old_cpu_flag) {

        int i;

        state.cpu_flag_name = name;

        for (i = 0; tests[i].func; i++) {

            state.current_test_name = tests[i].name;

            tests[i].func();

        }

    }

}


bool replay_checkpoint(ReplayCheckpoint checkpoint)

{

    bool res = false;

    assert(EVENT_CHECKPOINT + checkpoint <= EVENT_CHECKPOINT_LAST);

    replay_save_instructions();

    if (!replay_file) {

        return true;

    }

    replay_mutex_lock();

    if (replay_mode == REPLAY_MODE_PLAY) {

        if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {

            replay_finish_event();

        } else if (replay_data_kind != EVENT_ASYNC) {

            res = false;

            goto out;

        }

        replay_read_events(checkpoint);

        /* replay_read_events may leave some unread events.

           Return false if not all of the events associated with

           checkpoint were processed */

        res = replay_data_kind != EVENT_ASYNC;

    } else if (replay_mode == REPLAY_MODE_RECORD) {

        replay_put_event(EVENT_CHECKPOINT + checkpoint);

        replay_save_events(checkpoint);

        res = true;

    }

out:

    replay_mutex_unlock();

    return res;

}


static void openrisc_sim_machine_init(MachineClass *mc)

{

    mc->desc = "or1k simulation";

    mc->init = openrisc_sim_init;

    mc->max_cpus = 1;

    mc->is_default = 1;

}


static int coroutine_fn qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset,

                                              size_t len)

{

    /* Allocate buffer for zero writes */

    if (acb->flags & QED_AIOCB_ZERO) {

        struct iovec *iov = acb->qiov->iov;

        if (!iov->iov_base) {

            iov->iov_base = qemu_try_blockalign(acb->bs, iov->iov_len);

            if (iov->iov_base == NULL) {

                return -ENOMEM;

            }

            memset(iov->iov_base, 0, iov->iov_len);

        }

    }

    /* Calculate the I/O vector */

    acb->cur_cluster = offset;

    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);

    /* Do the actual write */

    return qed_aio_write_main(acb);

}


Aml *aml_add(Aml *arg1, Aml *arg2)

{

    Aml *var = aml_opcode(0x72 /* AddOp */);

    aml_append(var, arg1);

    aml_append(var, arg2);

    build_append_byte(var->buf, 0x00 /* NullNameOp */);

    return var;

}


static int menelaus_load(QEMUFile *f, void *opaque, int version_id)

{

    MenelausState *s = (MenelausState *) opaque;

    s->firstbyte = qemu_get_be32(f);

    qemu_get_8s(f, &s->reg);

    if (s->rtc.ctrl & 1)					/* RTC_EN */

        menelaus_rtc_stop(s);

    qemu_get_8s(f, &s->vcore[0]);

    qemu_get_8s(f, &s->vcore[1]);

    qemu_get_8s(f, &s->vcore[2]);

    qemu_get_8s(f, &s->vcore[3]);

    qemu_get_8s(f, &s->vcore[4]);

    qemu_get_8s(f, &s->dcdc[0]);

    qemu_get_8s(f, &s->dcdc[1]);

    qemu_get_8s(f, &s->dcdc[2]);

    qemu_get_8s(f, &s->ldo[0]);

    qemu_get_8s(f, &s->ldo[1]);

    qemu_get_8s(f, &s->ldo[2]);

    qemu_get_8s(f, &s->ldo[3]);

    qemu_get_8s(f, &s->ldo[4]);

    qemu_get_8s(f, &s->ldo[5]);

    qemu_get_8s(f, &s->ldo[6]);

    qemu_get_8s(f, &s->ldo[7]);

    qemu_get_8s(f, &s->sleep[0]);

    qemu_get_8s(f, &s->sleep[1]);

    qemu_get_8s(f, &s->osc);

    qemu_get_8s(f, &s->detect);

    qemu_get_be16s(f, &s->mask);

    qemu_get_be16s(f, &s->status);

    qemu_get_8s(f, &s->dir);

    qemu_get_8s(f, &s->inputs);

    qemu_get_8s(f, &s->outputs);

    qemu_get_8s(f, &s->bbsms);

    qemu_get_8s(f, &s->pull[0]);

    qemu_get_8s(f, &s->pull[1]);

    qemu_get_8s(f, &s->pull[2]);

    qemu_get_8s(f, &s->pull[3]);

    qemu_get_8s(f, &s->mmc_ctrl[0]);

    qemu_get_8s(f, &s->mmc_ctrl[1]);

    qemu_get_8s(f, &s->mmc_ctrl[2]);

    qemu_get_8s(f, &s->mmc_debounce);

    qemu_get_8s(f, &s->rtc.ctrl);

    qemu_get_be16s(f, &s->rtc.comp);

    s->rtc.next = qemu_get_be16(f);

    tm_get(f, &s->rtc.new);

    tm_get(f, &s->rtc.alm);

    s->pwrbtn_state = qemu_get_byte(f);

    menelaus_alm_update(s);

    menelaus_update(s);

    if (s->rtc.ctrl & 1)					/* RTC_EN */

        menelaus_rtc_start(s);

    i2c_slave_load(f, &s->i2c);

    return 0;

}


static void find_completion(const char *cmdline)

{

    const char *cmdname;

    char *args[MAX_ARGS];

    int nb_args, i, len;

    const char *ptype, *str;

    term_cmd_t *cmd;

    parse_cmdline(cmdline, &nb_args, args);

#ifdef DEBUG_COMPLETION

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

        term_printf("arg%d = '%s'\n", i, (char *)args[i]);

    }

#endif

    /* if the line ends with a space, it means we want to complete the

       next arg */

    len = strlen(cmdline);

    if (len > 0 && isspace(cmdline[len - 1])) {

        if (nb_args >= MAX_ARGS)

            return;

        args[nb_args++] = qemu_strdup("");

    }

    if (nb_args <= 1) {

        /* command completion */

        if (nb_args == 0)

            cmdname = "";

        else

            cmdname = args[0];

        completion_index = strlen(cmdname);

        for(cmd = term_cmds; cmd->name != NULL; cmd++) {

            cmd_completion(cmdname, cmd->name);

        }

    } else {

        /* find the command */

        for(cmd = term_cmds; cmd->name != NULL; cmd++) {

            if (compare_cmd(args[0], cmd->name))

                goto found;

        }

        return;

    found:

        ptype = cmd->args_type;

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

            if (*ptype != '\0') {

                ptype++;

                while (*ptype == '?')

                    ptype++;

            }

        }

        str = args[nb_args - 1];

        switch(*ptype) {

        case 'F':

            /* file completion */

            completion_index = strlen(str);

            file_completion(str);

            break;

        case 'B':

            /* block device name completion */

            completion_index = strlen(str);

            bdrv_iterate(block_completion_it, (void *)str);

            break;

        default:

            break;

        }

    }

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

        qemu_free(args[i]);

}


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

                         int *got_frame_ptr, AVPacket* avpkt)

{

    WMAProDecodeCtx *s = avctx->priv_data;

    GetBitContext* gb  = &s->pgb;

    const uint8_t* buf = avpkt->data;

    int buf_size       = avpkt->size;

    int num_bits_prev_frame;

    int packet_sequence_number;

    *got_frame_ptr = 0;

    if (s->packet_done || s->packet_loss) {

        s->packet_done = 0;

        /** sanity check for the buffer length */

        if (buf_size < avctx->block_align)

            return 0;

        s->next_packet_start = buf_size - avctx->block_align;

        buf_size = avctx->block_align;

        s->buf_bit_size = buf_size << 3;

        /** parse packet header */

        init_get_bits(gb, buf, s->buf_bit_size);

        packet_sequence_number = get_bits(gb, 4);

        skip_bits(gb, 2);

        /** get number of bits that need to be added to the previous frame */

        num_bits_prev_frame = get_bits(gb, s->log2_frame_size);

        av_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,

                num_bits_prev_frame);

        /** check for packet loss */

        if (!s->packet_loss &&

            ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) {

            s->packet_loss = 1;

            av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",

                   s->packet_sequence_number, packet_sequence_number);

        }

        s->packet_sequence_number = packet_sequence_number;

        if (num_bits_prev_frame > 0) {

            int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);

            if (num_bits_prev_frame >= remaining_packet_bits) {

                num_bits_prev_frame = remaining_packet_bits;

                s->packet_done = 1;

            }

            /** append the previous frame data to the remaining data from the

                previous packet to create a full frame */

            save_bits(s, gb, num_bits_prev_frame, 1);

            av_dlog(avctx, "accumulated %x bits of frame data\n",

                    s->num_saved_bits - s->frame_offset);

            /** decode the cross packet frame if it is valid */

            if (!s->packet_loss)

                decode_frame(s, data, got_frame_ptr);

        } else if (s->num_saved_bits - s->frame_offset) {

            av_dlog(avctx, "ignoring %x previously saved bits\n",

                    s->num_saved_bits - s->frame_offset);

        }

        if (s->packet_loss) {

            /** reset number of saved bits so that the decoder

                does not start to decode incomplete frames in the

                s->len_prefix == 0 case */

            s->num_saved_bits = 0;

            s->packet_loss = 0;

        }

    } else {

        int frame_size;

        s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3;

        init_get_bits(gb, avpkt->data, s->buf_bit_size);

        skip_bits(gb, s->packet_offset);

        if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size &&

            (frame_size = show_bits(gb, s->log2_frame_size)) &&

            frame_size <= remaining_bits(s, gb)) {

            save_bits(s, gb, frame_size, 0);

            s->packet_done = !decode_frame(s, data, got_frame_ptr);

        } else if (!s->len_prefix

                   && s->num_saved_bits > get_bits_count(&s->gb)) {

            /** when the frames do not have a length prefix, we don't know

                the compressed length of the individual frames

                however, we know what part of a new packet belongs to the

                previous frame

                therefore we save the incoming packet first, then we append

                the "previous frame" data from the next packet so that

                we get a buffer that only contains full frames */

            s->packet_done = !decode_frame(s, data, got_frame_ptr);

        } else

            s->packet_done = 1;

    }

    if (s->packet_done && !s->packet_loss &&

        remaining_bits(s, gb) > 0) {

        /** save the rest of the data so that it can be decoded

            with the next packet */

        save_bits(s, gb, remaining_bits(s, gb), 0);

    }

    s->packet_offset = get_bits_count(gb) & 7;

    if (s->packet_loss)

        return AVERROR_INVALIDDATA;

    return get_bits_count(gb) >> 3;

}


static int pci_cirrus_vga_initfn(PCIDevice *dev)

{

     PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);

     CirrusVGAState *s = &d->cirrus_vga;

     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);

     int16_t device_id = pc->device_id;

     /* setup VGA */

     vga_common_init(&s->vga);

     cirrus_init_common(s, device_id, 1, pci_address_space(dev),

                        pci_address_space_io(dev));

     s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,

                                       s->vga.screen_dump, s->vga.text_update,

                                       &s->vga);

     /* setup PCI */

    memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);

    /* XXX: add byte swapping apertures */

    memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);

    memory_region_add_subregion(&s->pci_bar, 0x1000000,

                                &s->cirrus_linear_bitblt_io);

     /* setup memory space */

     /* memory #0 LFB */

     /* memory #1 memory-mapped I/O */

     /* XXX: s->vga.vram_size must be a power of two */

     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);

     if (device_id == CIRRUS_ID_CLGD5446) {

         pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);

     }

     return 0;

}


static int acpi_pcihp_get_bsel(PCIBus *bus)

{

    QObject *o = object_property_get_qobject(OBJECT(bus),

                                             ACPI_PCIHP_PROP_BSEL, NULL);

    int64_t bsel = -1;

    if (o) {

        bsel = qint_get_int(qobject_to_qint(o));

    }

    if (bsel < 0) {

        return -1;

    }

    return bsel;

}


void vnc_client_write(void *opaque)

{

    long ret;

    VncState *vs = opaque;

#ifdef CONFIG_VNC_TLS

    if (vs->tls.session) {

	ret = gnutls_write(vs->tls.session, vs->output.buffer, vs->output.offset);

	if (ret < 0) {

	    if (ret == GNUTLS_E_AGAIN)

		errno = EAGAIN;

	    else

		errno = EIO;

	    ret = -1;

	}

    } else

#endif /* CONFIG_VNC_TLS */

	ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);

    ret = vnc_client_io_error(vs, ret, socket_error());

    if (!ret)

	return;

    memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));

    vs->output.offset -= ret;

    if (vs->output.offset == 0) {

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

    }

}


static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    AVIContext *avi = s->priv_data;

    ByteIOContext *pb = &s->pb;

    int n, d[8], size;

    offset_t i;

    void* dstr;

    memset(d, -1, sizeof(int)*8);

    if (avi->dv_demux) {

        size = dv_get_packet(avi->dv_demux, pkt);

	if (size >= 0)

	    return size;

    }

    for(i=url_ftell(pb); !url_feof(pb); i++) {

        int j;

	if (i >= avi->movi_end) {

	    if (avi->is_odml) {

		url_fskip(pb, avi->riff_end - i);

	        avi->riff_end = avi->movi_end = url_filesize(url_fileno(pb));

	    } else

	        break;

	}

        for(j=0; j<7; j++)

            d[j]= d[j+1];

        d[7]= get_byte(pb);

        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);

        //parse ix##

        n= (d[2] - '0') * 10 + (d[3] - '0');

        if(    d[2] >= '0' && d[2] <= '9'

            && d[3] >= '0' && d[3] <= '9'

            && d[0] == 'i' && d[1] == 'x'

            && n < s->nb_streams

            && i + size <= avi->movi_end){

            url_fskip(pb, size);

        }

	//parse JUNK

        if(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K' &&

           i + size <= avi->movi_end) {

            url_fskip(pb, size);

        }

        //parse ##dc/##wb

        n= (d[0] - '0') * 10 + (d[1] - '0');

        if(    d[0] >= '0' && d[0] <= '9'

            && d[1] >= '0' && d[1] <= '9'

            && ((d[2] == 'd' && d[3] == 'c') ||

	        (d[2] == 'w' && d[3] == 'b') ||

		(d[2] == 'd' && d[3] == 'b') ||

		(d[2] == '_' && d[3] == '_'))

            && n < s->nb_streams

            && i + size <= avi->movi_end) {

            av_new_packet(pkt, size);

            get_buffer(pb, pkt->data, size);

            if (size & 1) {

                get_byte(pb);

		size++;

	    }

	    if (avi->dv_demux) {

	        dstr = pkt->destruct;

	        size = dv_produce_packet(avi->dv_demux, pkt,

		                         pkt->data, pkt->size);

		pkt->destruct = dstr;

                pkt->flags |= PKT_FLAG_KEY;

	    } else {

                AVStream *st;

                AVIStream *ast;

                st = s->streams[n];

                ast = st->priv_data;

                /* XXX: how to handle B frames in avi ? */

                pkt->dts = ast->frame_offset;

//                pkt->dts += ast->start;

                if(ast->sample_size)

                    pkt->dts /= ast->sample_size;

//av_log(NULL, AV_LOG_DEBUG, "dts:%Ld offset:%d %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, n, size);

                pkt->stream_index = n;

                /* FIXME: We really should read index for that */

                if (st->codec.codec_type == CODEC_TYPE_VIDEO) {

                    if (ast->frame_offset < ast->nb_index_entries) {

                        if (ast->index_entries[ast->frame_offset].flags & AVIIF_INDEX)

                            pkt->flags |= PKT_FLAG_KEY;

                    } else {

                        /* if no index, better to say that all frames

                           are key frames */

                        pkt->flags |= PKT_FLAG_KEY;

                    }

                } else {

                    pkt->flags |= PKT_FLAG_KEY;

                }

                if(ast->sample_size)

                    ast->frame_offset += pkt->size;

                else

                    ast->frame_offset++;

	    }

            return size;

        }

    }

    return -1;

}