static int ehci_process_itd(EHCIState *ehci,

                            EHCIitd *itd)

{

    USBDevice *dev;

    USBEndpoint *ep;

    int ret;

    uint32_t i, len, pid, dir, devaddr, endp;

    uint32_t pg, off, ptr1, ptr2, max, mult;

    dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION);

    devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR);

    endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP);

    max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT);

    mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT);

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

        if (itd->transact[i] & ITD_XACT_ACTIVE) {

            pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);

            off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;

            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);

            ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);

            len  = get_field(itd->transact[i], ITD_XACT_LENGTH);

            if (len > max * mult) {

                len = max * mult;

            }

            if (len > BUFF_SIZE) {

                return USB_RET_PROCERR;

            }

            pci_dma_sglist_init(&ehci->isgl, &ehci->dev, 2);

            if (off + len > 4096) {

                /* transfer crosses page border */

                uint32_t len2 = off + len - 4096;

                uint32_t len1 = len - len2;

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);

                qemu_sglist_add(&ehci->isgl, ptr2, len2);

            } else {

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len);

            }

            pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT;

            dev = ehci_find_device(ehci, devaddr);

            ep = usb_ep_get(dev, pid, endp);

            usb_packet_setup(&ehci->ipacket, pid, ep);

            usb_packet_map(&ehci->ipacket, &ehci->isgl);

            ret = usb_handle_packet(dev, &ehci->ipacket);

            usb_packet_unmap(&ehci->ipacket);

            qemu_sglist_destroy(&ehci->isgl);

#if 0

            /*  In isoch, there is no facility to indicate a NAK so let's

             *  instead just complete a zero-byte transaction.  Setting

             *  DBERR seems too draconian.

             */

            if (ret == USB_RET_NAK) {

                if (ehci->isoch_pause > 0) {

                    DPRINTF("ISOCH: received a NAK but paused so returning\n");

                    ehci->isoch_pause--;

                    return 0;

                } else if (ehci->isoch_pause == -1) {

                    DPRINTF("ISOCH: recv NAK & isoch pause inactive, setting\n");

                    // Pause frindex for up to 50 msec waiting for data from

                    // remote

                    ehci->isoch_pause = 50;

                    return 0;

                } else {

                    DPRINTF("ISOCH: isoch pause timeout! return 0\n");

                    ret = 0;

                }

            } else {

                DPRINTF("ISOCH: received ACK, clearing pause\n");

                ehci->isoch_pause = -1;

            }

#else

            if (ret == USB_RET_NAK) {

                ret = 0;

            }

#endif

            if (ret >= 0) {

                if (!dir) {

                    /* OUT */

                    set_field(&itd->transact[i], len - ret, ITD_XACT_LENGTH);

                } else {

                    /* IN */

                    set_field(&itd->transact[i], ret, ITD_XACT_LENGTH);

                }

                if (itd->transact[i] & ITD_XACT_IOC) {

                    ehci_record_interrupt(ehci, USBSTS_INT);

                }

            }

            itd->transact[i] &= ~ITD_XACT_ACTIVE;

        }

    }

    return 0;

}


static int swf_probe(AVProbeData *p)

{

    /* check file header */

    if (p->buf_size <= 16)

        return 0;

    if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&

        p->buf[2] == 'S')

        return AVPROBE_SCORE_MAX;

    else

        return 0;

}


static int16_t *precalc_coefs(double dist25, int depth)

{

    int i;

    double gamma, simil, C;

    int16_t *ct = av_malloc((512<<LUT_BITS)*sizeof(int16_t));

    if (!ct)

        return NULL;

    gamma = log(0.25) / log(1.0 - FFMIN(dist25,252.0)/255.0 - 0.00001);

    for (i = -255<<LUT_BITS; i <= 255<<LUT_BITS; i++) {

        double f = ((i<<(9-LUT_BITS)) + (1<<(8-LUT_BITS)) - 1) / 512.0; // midpoint of the bin

        simil = 1.0 - FFABS(f) / 255.0;

        C = pow(simil, gamma) * 256.0 * f;

        ct[(256<<LUT_BITS)+i] = lrint(C);

    }

    ct[0] = !!dist25;

    return ct;

}


static void avc_biwgt_4x2_msa(uint8_t *src,

                              int32_t src_stride,

                              uint8_t *dst,

                              int32_t dst_stride,

                              int32_t log2_denom,

                              int32_t src_weight,

                              int32_t dst_weight,

                              int32_t offset_in)

{

    uint32_t load0, load1, out0, out1;

    v16i8 src_wgt, dst_wgt, wgt;

    v16i8 src0, src1, dst0, dst1;

    v8i16 temp0, temp1, denom, offset, add_val;

    int32_t val = 128 * (src_weight + dst_weight);

    offset_in = ((offset_in + 1) | 1) << log2_denom;

    src_wgt = __msa_fill_b(src_weight);

    dst_wgt = __msa_fill_b(dst_weight);

    offset = __msa_fill_h(offset_in);

    denom = __msa_fill_h(log2_denom + 1);

    add_val = __msa_fill_h(val);

    offset += add_val;

    wgt = __msa_ilvev_b(dst_wgt, src_wgt);

    load0 = LOAD_WORD(src);

    src += src_stride;

    load1 = LOAD_WORD(src);

    src0 = (v16i8) __msa_fill_w(load0);

    src1 = (v16i8) __msa_fill_w(load1);

    load0 = LOAD_WORD(dst);

    load1 = LOAD_WORD(dst + dst_stride);

    dst0 = (v16i8) __msa_fill_w(load0);

    dst1 = (v16i8) __msa_fill_w(load1);

    XORI_B_4VECS_SB(src0, src1, dst0, dst1, src0, src1, dst0, dst1, 128);

    ILVR_B_2VECS_SH(src0, src1, dst0, dst1, temp0, temp1);

    temp0 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp0);

    temp1 = __msa_dpadd_s_h(offset, wgt, (v16i8) temp1);

    temp0 >>= denom;

    temp1 >>= denom;

    temp0 = CLIP_UNSIGNED_CHAR_H(temp0);

    temp1 = CLIP_UNSIGNED_CHAR_H(temp1);

    dst0 = __msa_pckev_b((v16i8) temp0, (v16i8) temp0);

    dst1 = __msa_pckev_b((v16i8) temp1, (v16i8) temp1);

    out0 = __msa_copy_u_w((v4i32) dst0, 0);

    out1 = __msa_copy_u_w((v4i32) dst1, 0);

    STORE_WORD(dst, out0);

    dst += dst_stride;

    STORE_WORD(dst, out1);

}


static int asf_read_value(AVFormatContext *s, uint8_t *name, uint16_t name_len,

                          uint16_t val_len, int type, AVDictionary **met)

{

    int ret;

    uint8_t *value;

    uint16_t buflen = 2 * val_len + 1;

    AVIOContext *pb = s->pb;

    value = av_malloc(buflen);

    if (!value)

        return AVERROR(ENOMEM);

    if (type == ASF_UNICODE) {

        // get_asf_string reads UTF-16 and converts it to UTF-8 which needs longer buffer

        if ((ret = get_asf_string(pb, val_len, value, buflen)) < 0)

            goto failed;

        if (av_dict_set(met, name, value, 0) < 0)

            av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");

    } else {

        char buf[256];

        if (val_len > sizeof(buf)) {

            ret = AVERROR_INVALIDDATA;

            goto failed;

        }

        if ((ret = avio_read(pb, value, val_len)) < 0)

            goto failed;

        if (ret < 2 * val_len)

            value[ret] = '\0';

        else

            value[2 * val_len - 1] = '\0';

        snprintf(buf, sizeof(buf), "%s", value);

        if (av_dict_set(met, name, buf, 0) < 0)

            av_log(s, AV_LOG_WARNING, "av_dict_set failed.\n");

    }

    av_freep(&value);

    return 0;

failed:

    av_freep(&value);

    return ret;

}


static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res,

                     BdrvCheckMode fix)

{

    /* TODO: additional checks possible. */

    BDRVVdiState *s = (BDRVVdiState *)bs->opaque;

    uint32_t blocks_allocated = 0;

    uint32_t block;

    uint32_t *bmap;

    logout("\n");

    if (fix) {

        return -ENOTSUP;

    }

    bmap = g_try_malloc(s->header.blocks_in_image * sizeof(uint32_t));

    if (s->header.blocks_in_image && bmap == NULL) {

        res->check_errors++;

        return -ENOMEM;

    }

    memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t));

    /* Check block map and value of blocks_allocated. */

    for (block = 0; block < s->header.blocks_in_image; block++) {

        uint32_t bmap_entry = le32_to_cpu(s->bmap[block]);

        if (VDI_IS_ALLOCATED(bmap_entry)) {

            if (bmap_entry < s->header.blocks_in_image) {

                blocks_allocated++;

                if (!VDI_IS_ALLOCATED(bmap[bmap_entry])) {

                    bmap[bmap_entry] = bmap_entry;

                } else {

                    fprintf(stderr, "ERROR: block index %" PRIu32

                            " also used by %" PRIu32 "\n", bmap[bmap_entry], bmap_entry);

                    res->corruptions++;

                }

            } else {

                fprintf(stderr, "ERROR: block index %" PRIu32

                        " too large, is %" PRIu32 "\n", block, bmap_entry);

                res->corruptions++;

            }

        }

    }

    if (blocks_allocated != s->header.blocks_allocated) {

        fprintf(stderr, "ERROR: allocated blocks mismatch, is %" PRIu32

               ", should be %" PRIu32 "\n",

               blocks_allocated, s->header.blocks_allocated);

        res->corruptions++;

    }

    g_free(bmap);

    return 0;

}


static void uart_write(void *opaque, hwaddr addr,

                       uint64_t value, unsigned size)

{

    LM32UartState *s = opaque;

    unsigned char ch = value;

    trace_lm32_uart_memory_write(addr, value);

    addr >>= 2;

    switch (addr) {

    case R_RXTX:

        if (s->chr) {

            qemu_chr_fe_write_all(s->chr, &ch, 1);

        }

        break;

    case R_IER:

    case R_LCR:

    case R_MCR:

    case R_DIV:

        s->regs[addr] = value;

        break;

    case R_IIR:

    case R_LSR:

    case R_MSR:

        error_report("lm32_uart: write access to read only register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    default:

        error_report("lm32_uart: write access to unknown register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    }

    uart_update_irq(s);

}


static void test_opts_parse_size(void)

{

    Error *err = NULL;

    QemuOpts *opts;

    /* Lower limit zero */

    opts = qemu_opts_parse(&opts_list_02, "size1=0", false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 1);

    g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);

    /* Note: precision is 53 bits since we're parsing with strtod() */

    /* Around limit of precision: 2^53-1, 2^53, 2^54 */

    opts = qemu_opts_parse(&opts_list_02,

                           "size1=9007199254740991,"

                           "size2=9007199254740992,"

                           "size3=9007199254740993",

                           false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 3);

    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),

                     ==, 0x1fffffffffffff);

    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),

                     ==, 0x20000000000000);

    g_assert_cmphex(qemu_opt_get_size(opts, "size3", 1),

                     ==, 0x20000000000000);

    /* Close to signed upper limit 0x7ffffffffffffc00 (53 msbs set) */

    opts = qemu_opts_parse(&opts_list_02,

                           "size1=9223372036854774784," /* 7ffffffffffffc00 */

                           "size2=9223372036854775295", /* 7ffffffffffffdff */

                           false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 2);

    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),

                     ==, 0x7ffffffffffffc00);

    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),

                     ==, 0x7ffffffffffffc00);

    /* Close to actual upper limit 0xfffffffffffff800 (53 msbs set) */

    opts = qemu_opts_parse(&opts_list_02,

                           "size1=18446744073709549568," /* fffffffffffff800 */

                           "size2=18446744073709550591", /* fffffffffffffbff */

                           false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 2);

    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 1),

                     ==, 0xfffffffffffff800);

    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 1),

                     ==, 0xfffffffffffff800);

    /* Beyond limits */

    opts = qemu_opts_parse(&opts_list_02, "size1=-1", false, &err);

    error_free_or_abort(&err);

    g_assert(!opts);

    opts = qemu_opts_parse(&opts_list_02,

                           "size1=18446744073709550592", /* fffffffffffffc00 */

                           false, &error_abort);

    /* BUG: should reject */

    g_assert_cmpuint(opts_count(opts), ==, 1);

    g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);

    /* Suffixes */

    opts = qemu_opts_parse(&opts_list_02, "size1=8b,size2=1.5k,size3=2M",

                           false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 3);

    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, 8);

    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0), ==, 1536);

    g_assert_cmphex(qemu_opt_get_size(opts, "size3", 0), ==, 2 * M_BYTE);

    opts = qemu_opts_parse(&opts_list_02, "size1=0.1G,size2=16777215T",

                           false, &error_abort);

    g_assert_cmpuint(opts_count(opts), ==, 2);

    g_assert_cmphex(qemu_opt_get_size(opts, "size1", 0), ==, G_BYTE / 10);

    g_assert_cmphex(qemu_opt_get_size(opts, "size2", 0),

                     ==, 16777215 * T_BYTE);

    /* Beyond limit with suffix */

    opts = qemu_opts_parse(&opts_list_02, "size1=16777216T",

                           false, &error_abort);

    /* BUG: should reject */

    g_assert_cmpuint(opts_count(opts), ==, 1);

    g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 0);

    /* Trailing crap */

    opts = qemu_opts_parse(&opts_list_02, "size1=16E", false, &err);

    error_free_or_abort(&err);

    g_assert(!opts);

    opts = qemu_opts_parse(&opts_list_02, "size1=16Gi", false, &error_abort);

    /* BUG: should reject */

    g_assert_cmpuint(opts_count(opts), ==, 1);

    g_assert_cmpuint(qemu_opt_get_size(opts, "size1", 1), ==, 16 * G_BYTE);

    qemu_opts_reset(&opts_list_02);

}


static int usbredir_post_load(void *priv, int version_id)
{
    USBRedirDevice *dev = priv;
    switch (dev->device_info.speed) {
    case usb_redir_speed_low:
        dev->dev.speed = USB_SPEED_LOW;
        break;
    case usb_redir_speed_full:
        dev->dev.speed = USB_SPEED_FULL;
        break;
    case usb_redir_speed_high:
        dev->dev.speed = USB_SPEED_HIGH;
        break;
    case usb_redir_speed_super:
        dev->dev.speed = USB_SPEED_SUPER;
        break;
    default:
        dev->dev.speed = USB_SPEED_FULL;
    dev->dev.speedmask = (1 << dev->dev.speed);
    usbredir_setup_usb_eps(dev);
    usbredir_check_bulk_receiving(dev);


static void smc_decode_stream(SmcContext *s)

{

    int width = s->avctx->width;

    int height = s->avctx->height;

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

    int i;

    int stream_ptr = 0;

    int chunk_size;

    unsigned char opcode;

    int n_blocks;

    unsigned int color_flags;

    unsigned int color_flags_a;

    unsigned int color_flags_b;

    unsigned int flag_mask;

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

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

    int row_ptr = 0;

    int pixel_ptr = 0;

    int pixel_x, pixel_y;

    int row_inc = stride - 4;

    int block_ptr;

    int prev_block_ptr;

    int prev_block_ptr1, prev_block_ptr2;

    int prev_block_flag;

    int total_blocks;

    int color_table_index;  /* indexes to color pair, quad, or octet tables */

    int pixel;

    int color_pair_index = 0;

    int color_quad_index = 0;

    int color_octet_index = 0;

    /* make the palette available */

    memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);

    chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF;

    stream_ptr += 4;

    if (chunk_size != s->size)

        av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n",

            chunk_size, s->size);

    chunk_size = s->size;

    total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);

    /* traverse through the blocks */

    while (total_blocks) {

        /* sanity checks */

        /* make sure stream ptr hasn't gone out of bounds */

        if (stream_ptr > chunk_size) {

            av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)\n",

                stream_ptr, chunk_size);

            return;

        }

        /* make sure the row pointer hasn't gone wild */

        if (row_ptr >= image_size) {

            av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n",

                row_ptr, image_size);

            return;

        }

        opcode = s->buf[stream_ptr++];

        switch (opcode & 0xF0) {

        /* skip n blocks */

        case 0x00:

        case 0x10:

            n_blocks = GET_BLOCK_COUNT();

            while (n_blocks--) {

                ADVANCE_BLOCK();

            }

            break;

        /* repeat last block n times */

        case 0x20:

        case 0x30:

            n_blocks = GET_BLOCK_COUNT();

            /* sanity check */

            if ((row_ptr == 0) && (pixel_ptr == 0)) {

                av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n",

                    opcode & 0xF0);

                break;

            }

            /* figure out where the previous block started */

            if (pixel_ptr == 0)

                prev_block_ptr1 =

                    (row_ptr - s->avctx->width * 4) + s->avctx->width - 4;

            else

                prev_block_ptr1 = row_ptr + pixel_ptr - 4;

            while (n_blocks--) {

                block_ptr = row_ptr + pixel_ptr;

                prev_block_ptr = prev_block_ptr1;

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

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

                        pixels[block_ptr++] = pixels[prev_block_ptr++];

                    }

                    block_ptr += row_inc;

                    prev_block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* repeat previous pair of blocks n times */

        case 0x40:

        case 0x50:

            n_blocks = GET_BLOCK_COUNT();

            n_blocks *= 2;

            /* sanity check */

            if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) {

                av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n",

                    opcode & 0xF0);

                break;

            }

            /* figure out where the previous 2 blocks started */

            if (pixel_ptr == 0)

                prev_block_ptr1 = (row_ptr - s->avctx->width * 4) +

                    s->avctx->width - 4 * 2;

            else if (pixel_ptr == 4)

                prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc;

            else

                prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2;

            if (pixel_ptr == 0)

                prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc;

            else

                prev_block_ptr2 = row_ptr + pixel_ptr - 4;

            prev_block_flag = 0;

            while (n_blocks--) {

                block_ptr = row_ptr + pixel_ptr;

                if (prev_block_flag)

                    prev_block_ptr = prev_block_ptr2;

                else

                    prev_block_ptr = prev_block_ptr1;

                prev_block_flag = !prev_block_flag;

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

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

                        pixels[block_ptr++] = pixels[prev_block_ptr++];

                    }

                    block_ptr += row_inc;

                    prev_block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* 1-color block encoding */

        case 0x60:

        case 0x70:

            n_blocks = GET_BLOCK_COUNT();

            pixel = s->buf[stream_ptr++];

            while (n_blocks--) {

                block_ptr = row_ptr + pixel_ptr;

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

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

                        pixels[block_ptr++] = pixel;

                    }

                    block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* 2-color block encoding */

        case 0x80:

        case 0x90:

            n_blocks = (opcode & 0x0F) + 1;

            /* figure out which color pair to use to paint the 2-color block */

            if ((opcode & 0xF0) == 0x80) {

                /* fetch the next 2 colors from bytestream and store in next

                 * available entry in the color pair table */

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

                    pixel = s->buf[stream_ptr++];

                    color_table_index = CPAIR * color_pair_index + i;

                    s->color_pairs[color_table_index] = pixel;

                }

                /* this is the base index to use for this block */

                color_table_index = CPAIR * color_pair_index;

                color_pair_index++;

                /* wraparound */

                if (color_pair_index == COLORS_PER_TABLE)

                    color_pair_index = 0;

            } else

                color_table_index = CPAIR * s->buf[stream_ptr++];

            while (n_blocks--) {

                color_flags = AV_RB16(&s->buf[stream_ptr]);

                stream_ptr += 2;

                flag_mask = 0x8000;

                block_ptr = row_ptr + pixel_ptr;

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

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

                        if (color_flags & flag_mask)

                            pixel = color_table_index + 1;

                        else

                            pixel = color_table_index;

                        flag_mask >>= 1;

                        pixels[block_ptr++] = s->color_pairs[pixel];

                    }

                    block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* 4-color block encoding */

        case 0xA0:

        case 0xB0:

            n_blocks = (opcode & 0x0F) + 1;

            /* figure out which color quad to use to paint the 4-color block */

            if ((opcode & 0xF0) == 0xA0) {

                /* fetch the next 4 colors from bytestream and store in next

                 * available entry in the color quad table */

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

                    pixel = s->buf[stream_ptr++];

                    color_table_index = CQUAD * color_quad_index + i;

                    s->color_quads[color_table_index] = pixel;

                }

                /* this is the base index to use for this block */

                color_table_index = CQUAD * color_quad_index;

                color_quad_index++;

                /* wraparound */

                if (color_quad_index == COLORS_PER_TABLE)

                    color_quad_index = 0;

            } else

                color_table_index = CQUAD * s->buf[stream_ptr++];

            while (n_blocks--) {

                color_flags = AV_RB32(&s->buf[stream_ptr]);

                stream_ptr += 4;

                /* flag mask actually acts as a bit shift count here */

                flag_mask = 30;

                block_ptr = row_ptr + pixel_ptr;

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

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

                        pixel = color_table_index +

                            ((color_flags >> flag_mask) & 0x03);

                        flag_mask -= 2;

                        pixels[block_ptr++] = s->color_quads[pixel];

                    }

                    block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* 8-color block encoding */

        case 0xC0:

        case 0xD0:

            n_blocks = (opcode & 0x0F) + 1;

            /* figure out which color octet to use to paint the 8-color block */

            if ((opcode & 0xF0) == 0xC0) {

                /* fetch the next 8 colors from bytestream and store in next

                 * available entry in the color octet table */

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

                    pixel = s->buf[stream_ptr++];

                    color_table_index = COCTET * color_octet_index + i;

                    s->color_octets[color_table_index] = pixel;

                }

                /* this is the base index to use for this block */

                color_table_index = COCTET * color_octet_index;

                color_octet_index++;

                /* wraparound */

                if (color_octet_index == COLORS_PER_TABLE)

                    color_octet_index = 0;

            } else

                color_table_index = COCTET * s->buf[stream_ptr++];

            while (n_blocks--) {

                /*

                  For this input of 6 hex bytes:

                    01 23 45 67 89 AB

                  Mangle it to this output:

                    flags_a = xx012456, flags_b = xx89A37B

                */

                /* build the color flags */

                color_flags_a =

                    ((AV_RB16(s->buf + stream_ptr    ) & 0xFFF0) << 8) |

                     (AV_RB16(s->buf + stream_ptr + 2) >> 4);

                color_flags_b =

                    ((AV_RB16(s->buf + stream_ptr + 4) & 0xFFF0) << 8) |

                    ((s->buf[stream_ptr + 1] & 0x0F) << 8) |

                    ((s->buf[stream_ptr + 3] & 0x0F) << 4) |

                    (s->buf[stream_ptr + 5] & 0x0F);

                stream_ptr += 6;

                color_flags = color_flags_a;

                /* flag mask actually acts as a bit shift count here */

                flag_mask = 21;

                block_ptr = row_ptr + pixel_ptr;

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

                    /* reload flags at third row (iteration pixel_y == 2) */

                    if (pixel_y == 2) {

                        color_flags = color_flags_b;

                        flag_mask = 21;

                    }

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

                        pixel = color_table_index +

                            ((color_flags >> flag_mask) & 0x07);

                        flag_mask -= 3;

                        pixels[block_ptr++] = s->color_octets[pixel];

                    }

                    block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        /* 16-color block encoding (every pixel is a different color) */

        case 0xE0:

            n_blocks = (opcode & 0x0F) + 1;

            while (n_blocks--) {

                block_ptr = row_ptr + pixel_ptr;

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

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

                        pixels[block_ptr++] = s->buf[stream_ptr++];

                    }

                    block_ptr += row_inc;

                }

                ADVANCE_BLOCK();

            }

            break;

        case 0xF0:

            av_log(s->avctx, AV_LOG_INFO, "0xF0 opcode seen in SMC chunk (contact the developers)\n");

            break;

        }

    }

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->exit = vhost_scsi_exit;

    dc->props = vhost_scsi_properties;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

    vdc->init = vhost_scsi_init;

    vdc->get_features = vhost_scsi_get_features;

    vdc->set_config = vhost_scsi_set_config;

    vdc->set_status = vhost_scsi_set_status;

}


ivshmem_client_parse_args(IvshmemClientArgs *args, int argc, char *argv[])

{

    int c;

    while ((c = getopt(argc, argv,

                       "h"  /* help */

                       "v"  /* verbose */

                       "S:" /* unix_sock_path */

                      )) != -1) {

        switch (c) {

        case 'h': /* help */

            ivshmem_client_usage(argv[0], 0);

            break;

        case 'v': /* verbose */

            args->verbose = 1;

            break;

        case 'S': /* unix_sock_path */

            args->unix_sock_path = strdup(optarg);

            break;

        default:

            ivshmem_client_usage(argv[0], 1);

            break;

        }

    }

}


static int estimate_sid_gain(G723_1_Context *p)

{

    int i, shift, seg, seg2, t, val, val_add, x, y;

    shift = 16 - p->cur_gain * 2;

    if (shift > 0)

        t = p->sid_gain << shift;

    else

        t = p->sid_gain >> -shift;

    x = av_clipl_int32(t * (int64_t)cng_filt[0] >> 16);

    if (x >= cng_bseg[2])

        return 0x3F;

    if (x >= cng_bseg[1]) {

        shift = 4;

        seg   = 3;

    } else {

        shift = 3;

        seg   = (x >= cng_bseg[0]);

    }

    seg2 = FFMIN(seg, 3);

    val     = 1 << shift;

    val_add = val >> 1;

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

        t = seg * 32 + (val << seg2);

        t *= t;

        if (x >= t)

            val += val_add;

        else

            val -= val_add;

        val_add >>= 1;

    }

    t = seg * 32 + (val << seg2);

    y = t * t - x;

    if (y <= 0) {

        t = seg * 32 + (val + 1 << seg2);

        t = t * t - x;

        val = (seg2 - 1 << 4) + val;

        if (t >= y)

            val++;

    } else {

        t = seg * 32 + (val - 1 << seg2);

        t = t * t - x;

        val = (seg2 - 1 << 4) + val;

        if (t >= y)

            val--;

    }

    return val;

}


static int decode_exp_vlc(WMACodecContext *s, int ch)

{

    int last_exp, n, code;

    const uint16_t *ptr;

    float v, max_scale;

    uint32_t *q, *q_end, iv;

    const float *ptab = pow_tab + 60;

    const uint32_t *iptab = (const uint32_t*)ptab;

    ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits];

    q = (uint32_t *)s->exponents[ch];

    q_end = q + s->block_len;

    max_scale = 0;

    if (s->version == 1) {

        last_exp = get_bits(&s->gb, 5) + 10;

        v = ptab[last_exp];

        iv = iptab[last_exp];

        max_scale = v;

        n = *ptr++;

        switch (n & 3) do {

        case 0: *q++ = iv;

        case 3: *q++ = iv;

        case 2: *q++ = iv;

        case 1: *q++ = iv;

        } while ((n -= 4) > 0);

    }else

        last_exp = 36;

    while (q < q_end) {

        code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX);

        if (code < 0){

            av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n");

            return -1;

        }

        /* NOTE: this offset is the same as MPEG4 AAC ! */

        last_exp += code - 60;

        if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) {

            av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n",

                   last_exp);

            return -1;

        }

        v = ptab[last_exp];

        iv = iptab[last_exp];

        if (v > max_scale)

            max_scale = v;

        n = *ptr++;

        switch (n & 3) do {

        case 0: *q++ = iv;

        case 3: *q++ = iv;

        case 2: *q++ = iv;

        case 1: *q++ = iv;

        } while ((n -= 4) > 0);

    }

    s->max_exponent[ch] = max_scale;

    return 0;

}


static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)

{

    BC_STATUS ret;

    BC_DTS_STATUS decoder_status;

    CopyRet rec_ret;

    CHDContext *priv   = avctx->priv_data;

    HANDLE dev         = priv->dev;

    int len            = avpkt->size;

    uint8_t pic_type   = 0;

    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");

    if (len) {

        int32_t tx_free = (int32_t)DtsTxFreeSize(dev);

        if (priv->parser) {

            uint8_t *pout;

            int psize = len;

            H264Context *h = priv->parser->priv_data;

            while (psize)

                ret = av_parser_parse2(priv->parser, avctx, &pout, &psize,

                                       avpkt->data, len, avctx->pkt->pts,

                                       avctx->pkt->dts, len - psize);

            av_log(avctx, AV_LOG_VERBOSE,

                   "CrystalHD: parser picture type %d\n",

                   h->s.picture_structure);

            pic_type = h->s.picture_structure;

        }

        if (len < tx_free - 1024) {

            /*

             * Despite being notionally opaque, either libcrystalhd or

             * the hardware itself will mangle pts values that are too

             * small or too large. The docs claim it should be in units

             * of 100ns. Given that we're nominally dealing with a black

             * box on both sides, any transform we do has no guarantee of

             * avoiding mangling so we need to build a mapping to values

             * we know will not be mangled.

             */

            uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type);

            if (!pts) {

                return AVERROR(ENOMEM);

            }

            av_log(priv->avctx, AV_LOG_VERBOSE,

                   "input \"pts\": %"PRIu64"\n", pts);

            ret = DtsProcInput(dev, avpkt->data, len, pts, 0);

            if (ret == BC_STS_BUSY) {

                av_log(avctx, AV_LOG_WARNING,

                       "CrystalHD: ProcInput returned busy\n");

                usleep(BASE_WAIT);

                return AVERROR(EBUSY);

            } else if (ret != BC_STS_SUCCESS) {

                av_log(avctx, AV_LOG_ERROR,

                       "CrystalHD: ProcInput failed: %u\n", ret);

                return -1;

            }

            avctx->has_b_frames++;

        } else {

            av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n");

            len = 0; // We didn't consume any bytes.

        }

    } else {

        av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");

    }

    if (priv->skip_next_output) {

        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n");

        priv->skip_next_output = 0;

        avctx->has_b_frames--;

        return len;

    }

    ret = DtsGetDriverStatus(dev, &decoder_status);

    if (ret != BC_STS_SUCCESS) {

        av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");

        return -1;

    }

    /*

     * No frames ready. Don't try to extract.

     *

     * Empirical testing shows that ReadyListCount can be a damn lie,

     * and ProcOut still fails when count > 0. The same testing showed

     * that two more iterations were needed before ProcOutput would

     * succeed.

     */

    if (priv->output_ready < 2) {

        if (decoder_status.ReadyListCount != 0)

            priv->output_ready++;

        usleep(BASE_WAIT);

        av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n");

        return len;

    } else if (decoder_status.ReadyListCount == 0) {

        /*

         * After the pipeline is established, if we encounter a lack of frames

         * that probably means we're not giving the hardware enough time to

         * decode them, so start increasing the wait time at the end of a

         * decode call.

         */

        usleep(BASE_WAIT);

        priv->decode_wait += WAIT_UNIT;

        av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n");

        return len;

    }

    do {

        rec_ret = receive_frame(avctx, data, data_size, 0);

        if (rec_ret == RET_OK && *data_size == 0) {

            /*

             * This case is for when the encoded fields are stored

             * separately and we get a separate avpkt for each one. To keep

             * the pipeline stable, we should return nothing and wait for

             * the next time round to grab the second field.

             * H.264 PAFF is an example of this.

             */

            av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n");

            avctx->has_b_frames--;

        } else if (rec_ret == RET_COPY_NEXT_FIELD) {

            /*

             * This case is for when the encoded fields are stored in a

             * single avpkt but the hardware returns then separately. Unless

             * we grab the second field before returning, we'll slip another

             * frame in the pipeline and if that happens a lot, we're sunk.

             * So we have to get that second field now.

             * Interlaced mpeg2 and vc1 are examples of this.

             */

            av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n");

            while (1) {

                usleep(priv->decode_wait);

                ret = DtsGetDriverStatus(dev, &decoder_status);

                if (ret == BC_STS_SUCCESS &&

                    decoder_status.ReadyListCount > 0) {

                    rec_ret = receive_frame(avctx, data, data_size, 1);

                    if ((rec_ret == RET_OK && *data_size > 0) ||

                        rec_ret == RET_ERROR)

                        break;

                }

            }

            av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n");

        } else if (rec_ret == RET_SKIP_NEXT_COPY) {

            /*

             * Two input packets got turned into a field pair. Gawd.

             */

            av_log(avctx, AV_LOG_VERBOSE,

                   "Don't output on next decode call.\n");

            priv->skip_next_output = 1;

        }

        /*

         * If rec_ret == RET_COPY_AGAIN, that means that either we just handled

         * a FMT_CHANGE event and need to go around again for the actual frame,

         * we got a busy status and need to try again, or we're dealing with

         * packed b-frames, where the hardware strangely returns the packed

         * p-frame twice. We choose to keep the second copy as it carries the

         * valid pts.

         */

    } while (rec_ret == RET_COPY_AGAIN);

    usleep(priv->decode_wait);

    return len;

}


static int au_read_packet(AVFormatContext *s,

                          AVPacket *pkt)

{

    int ret;

    ret= av_get_packet(s->pb, pkt, BLOCK_SIZE *

                       s->streams[0]->codec->channels *

                       av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3);

    if (ret < 0)

        return ret;

    pkt->stream_index = 0;

    /* note: we need to modify the packet size here to handle the last

       packet */

    pkt->size = ret;

    return 0;

}


static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)

{

    int tag = track->enc->codec_tag;

    if (track->mode == MODE_MP4 || track->mode == MODE_PSP) {

        if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))

            return 0;

        if      (track->enc->codec_id == CODEC_ID_H264)      tag = MKTAG('a','v','c','1');

        else if (track->enc->codec_id == CODEC_ID_AC3)       tag = MKTAG('a','c','-','3');

        else if (track->enc->codec_id == CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');

        else if (track->enc->codec_id == CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');

        else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v');

        else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a');

    } else if (track->mode == MODE_IPOD) {

        if (track->enc->codec_type == CODEC_TYPE_SUBTITLE &&

            (tag == MKTAG('t','x','3','g') ||

             tag == MKTAG('t','e','x','t')))

            track->tag = tag; // keep original tag

        else

            tag = codec_get_tag(codec_ipod_tags, track->enc->codec_id);

        if (!match_ext(s->filename, "m4a") && !match_ext(s->filename, "m4v"))

            av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "

                   "Quicktime/Ipod might not play the file\n");

    } else if (track->mode & MODE_3GP) {

        tag = codec_get_tag(codec_3gp_tags, track->enc->codec_id);

    } else if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&

                        (tag == MKTAG('d','v','c','p') ||

                         track->enc->codec_id == CODEC_ID_RAWVIDEO))) {

        if (track->enc->codec_id == CODEC_ID_DVVIDEO) {

            if (track->enc->height == 480) /* NTSC */

                if  (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');

                else                                         tag = MKTAG('d','v','c',' ');

            else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');

            else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');

            else                                             tag = MKTAG('d','v','p','p');

        } else if (track->enc->codec_id == CODEC_ID_RAWVIDEO) {

            tag = codec_get_tag(mov_pix_fmt_tags, track->enc->pix_fmt);

            if (!tag) // restore tag

                tag = track->enc->codec_tag;

        } else {

            if (track->enc->codec_type == CODEC_TYPE_VIDEO) {

                tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);

                if (!tag) { // if no mac fcc found, try with Microsoft tags

                    tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);

                    if (tag)

                        av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "

                               "the file may be unplayable!\n");

                }

            } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {

                tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);

                if (!tag) { // if no mac fcc found, try with Microsoft tags

                    int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id);

                    if (ms_tag) {

                        tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));

                        av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "

                               "the file may be unplayable!\n");

                    }

                }

            } else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE) {

                tag = codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id);

            }

        }

    }

    return tag;

}


static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx)

{

    NvencContext *ctx = avctx->priv_data;

    if (avctx->bit_rate > 0) {

        ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate;

    } else if (ctx->encode_config.rcParams.averageBitRate > 0) {

        ctx->encode_config.rcParams.maxBitRate = ctx->encode_config.rcParams.averageBitRate;

    }

    if (avctx->rc_max_rate > 0)

        ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate;

    if (ctx->rc < 0) {

        if (ctx->flags & NVENC_ONE_PASS)

            ctx->twopass = 0;

        if (ctx->flags & NVENC_TWO_PASSES)

            ctx->twopass = 1;

        if (ctx->twopass < 0)

            ctx->twopass = (ctx->flags & NVENC_LOWLATENCY) != 0;

        if (ctx->cbr) {

            if (ctx->twopass) {

                ctx->rc = NV_ENC_PARAMS_RC_2_PASS_QUALITY;

            } else {

                ctx->rc = NV_ENC_PARAMS_RC_CBR;

            }

        } else if (avctx->global_quality > 0) {

            ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;

        } else if (ctx->twopass) {

            ctx->rc = NV_ENC_PARAMS_RC_2_PASS_VBR;

        } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {

            ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;

        }

    }

    if (ctx->flags & NVENC_LOSSLESS) {

        set_lossless(avctx);

    } else if (ctx->rc >= 0) {

        nvenc_override_rate_control(avctx);

    } else {

        ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR;

        set_vbr(avctx);

    }

    if (avctx->rc_buffer_size > 0) {

        ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size;

    } else if (ctx->encode_config.rcParams.averageBitRate > 0) {

        ctx->encode_config.rcParams.vbvBufferSize = 2 * ctx->encode_config.rcParams.averageBitRate;

    }

    if (ctx->aq) {

        ctx->encode_config.rcParams.enableAQ   = 1;

        ctx->encode_config.rcParams.aqStrength = ctx->aq_strength;

        av_log(avctx, AV_LOG_VERBOSE, "AQ enabled.\n");

    }

    if (ctx->temporal_aq) {

        ctx->encode_config.rcParams.enableTemporalAQ = 1;

        av_log(avctx, AV_LOG_VERBOSE, "Temporal AQ enabled.\n");

    }

    if (ctx->rc_lookahead) {

        int lkd_bound = FFMIN(ctx->nb_surfaces, ctx->async_depth) -

                        ctx->encode_config.frameIntervalP - 4;

        if (lkd_bound < 0) {

            av_log(avctx, AV_LOG_WARNING,

                   "Lookahead not enabled. Increase buffer delay (-delay).\n");

        } else {

            ctx->encode_config.rcParams.enableLookahead = 1;

            ctx->encode_config.rcParams.lookaheadDepth  = av_clip(ctx->rc_lookahead, 0, lkd_bound);

            ctx->encode_config.rcParams.disableIadapt   = ctx->no_scenecut;

            ctx->encode_config.rcParams.disableBadapt   = !ctx->b_adapt;

            av_log(avctx, AV_LOG_VERBOSE,

                   "Lookahead enabled: depth %d, scenecut %s, B-adapt %s.\n",

                   ctx->encode_config.rcParams.lookaheadDepth,

                   ctx->encode_config.rcParams.disableIadapt ? "disabled" : "enabled",

                   ctx->encode_config.rcParams.disableBadapt ? "disabled" : "enabled");

        }

    }

    if (ctx->strict_gop) {

        ctx->encode_config.rcParams.strictGOPTarget = 1;

        av_log(avctx, AV_LOG_VERBOSE, "Strict GOP target enabled.\n");

    }

    if (ctx->nonref_p)

        ctx->encode_config.rcParams.enableNonRefP = 1;

    if (ctx->zerolatency)

        ctx->encode_config.rcParams.zeroReorderDelay = 1;

    if (ctx->quality)

        ctx->encode_config.rcParams.targetQuality = ctx->quality;

}


int ff_rv34_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            uint8_t *buf, int buf_size)

{

    RV34DecContext *r = avctx->priv_data;

    MpegEncContext *s = &r->s;

    AVFrame *pict = data;

    SliceInfo si;

    int i;

    int slice_count;

    uint8_t *slices_hdr = NULL;

    int last = 0;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict= *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr= NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(!avctx->slice_count){

        slice_count = (*buf++) + 1;

        slices_hdr = buf + 4;

        buf += 8 * slice_count;

    }else

        slice_count = avctx->slice_count;

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

        int offset= get_slice_offset(avctx, slices_hdr, i);

        int size;

        if(i+1 == slice_count)

            size= buf_size - offset;

        else

            size= get_slice_offset(avctx, slices_hdr, i+1) - offset;

        r->si.end = s->mb_width * s->mb_height;

        if(i+1 < slice_count){

            init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);

            if(r->parse_slice_header(r, &r->s.gb, &si) < 0){

                if(i+2 < slice_count)

                    size = get_slice_offset(avctx, slices_hdr, i+2) - offset;

                else

                    size = buf_size - offset;

            }else

                r->si.end = si.start;

        }

        last = rv34_decode_slice(r, r->si.end, buf + offset, size);

        s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;

        if(last)

            break;

    }

    if(last){

        if(r->loop_filter)

            r->loop_filter(r);

        ff_er_frame_end(s);

        MPV_frame_end(s);

        if (s->pict_type == FF_B_TYPE || s->low_delay) {

            *pict= *(AVFrame*)s->current_picture_ptr;

        } else if (s->last_picture_ptr != NULL) {

            *pict= *(AVFrame*)s->last_picture_ptr;

        }

        if(s->last_picture_ptr || s->low_delay){

            *data_size = sizeof(AVFrame);

            ff_print_debug_info(s, pict);

        }

        s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)

    }

    return buf_size;

}


static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)

{

    int x, y, Y, U, V, A;

    uint8_t *lum, *cb, *cr;

    int dstx, dsty, dstw, dsth;

    const AVPicture *src = &rect->pict;

    dstw = av_clip(rect->w, 0, imgw);

    dsth = av_clip(rect->h, 0, imgh);

    dstx = av_clip(rect->x, 0, imgw - dstw);

    dsty = av_clip(rect->y, 0, imgh - dsth);

    lum = dst->data[0] + dstx + dsty * dst->linesize[0];

    cb  = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];

    cr  = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];

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

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

            Y = src->data[0][x + y*src->linesize[0]];

            A = src->data[3][x + y*src->linesize[3]];

            lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);

            lum++;

        }

        lum += dst->linesize[0] - dstw;

    }

    for (y = 0; y<dsth/2; y++) {

        for (x = 0; x<dstw/2; x++) {

            U = src->data[1][x + y*src->linesize[1]];

            V = src->data[2][x + y*src->linesize[2]];

            A = src->data[3][2*x     +  2*y   *src->linesize[3]]

              + src->data[3][2*x + 1 +  2*y   *src->linesize[3]]

              + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]

              + src->data[3][2*x     + (2*y+1)*src->linesize[3]];

            cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);

            cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);

            cb++;

            cr++;

        }

        cb += dst->linesize[1] - dstw/2;

        cr += dst->linesize[2] - dstw/2;

    }

}


int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)

{

    int len;

    if (size < 0)

        return -1;

    if (s->read_packet && s->write_flag) {

        len = s->read_packet(s->opaque, buf, size);

        if (len > 0)

            s->pos += len;

        return len;

    }

    len = s->buf_end - s->buf_ptr;

    if (len == 0) {

        /* Reset the buf_end pointer to the start of the buffer, to make sure

         * the fill_buffer call tries to read as much data as fits into the

         * full buffer, instead of just what space is left after buf_end.

         * This avoids returning partial packets at the end of the buffer,

         * for packet based inputs.

         */

        s->buf_end = s->buf_ptr = s->buffer;

        fill_buffer(s);

        len = s->buf_end - s->buf_ptr;

    }

    if (len > size)

        len = size;

    memcpy(buf, s->buf_ptr, len);

    s->buf_ptr += len;

    if (!len) {

        if (s->error)      return s->error;

        if (avio_feof(s))  return AVERROR_EOF;

    }

    return len;

}


static int sp5x_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              uint8_t *buf, int buf_size)

{

#if 0

    MJpegDecodeContext *s = avctx->priv_data;

#endif

    const int qscale = 5;

    uint8_t *buf_ptr, *buf_end, *recoded;

    int i = 0, j = 0;

    /* no supplementary picture */

    if (buf_size == 0)

        return 0;

    if (!avctx->width || !avctx->height)

	return -1;

    buf_ptr = buf;

    buf_end = buf + buf_size;

#if 1

    recoded = av_mallocz(buf_size + 1024);

    if (!recoded)

	return -1;

    /* SOI */

    recoded[j++] = 0xFF;

    recoded[j++] = 0xD8;

    memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt));

    memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64);

    memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64);

    j += sizeof(sp5x_data_dqt);

    memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht));

    j += sizeof(sp5x_data_dht);

    memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof));

    recoded[j+5] = (avctx->coded_height >> 8) & 0xFF;

    recoded[j+6] = avctx->coded_height & 0xFF;

    recoded[j+7] = (avctx->coded_width >> 8) & 0xFF;

    recoded[j+8] = avctx->coded_width & 0xFF;

    j += sizeof(sp5x_data_sof);

    memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos));

    j += sizeof(sp5x_data_sos);

    for (i = 14; i < buf_size && j < buf_size+1024-2; i++)

    {

	recoded[j++] = buf[i];

	if (buf[i] == 0xff)

	    recoded[j++] = 0;

    }

    /* EOI */

    recoded[j++] = 0xFF;

    recoded[j++] = 0xD9;

    i = mjpeg_decode_frame(avctx, data, data_size, recoded, j);

    av_free(recoded);

#else

    /* SOF */

    s->bits = 8;

    s->width  = avctx->coded_width;

    s->height = avctx->coded_height;

    s->nb_components = 3;

    s->component_id[0] = 0;

    s->h_count[0] = 2;

    s->v_count[0] = 2;

    s->quant_index[0] = 0;

    s->component_id[1] = 1;

    s->h_count[1] = 1;

    s->v_count[1] = 1;

    s->quant_index[1] = 1;

    s->component_id[2] = 2;

    s->h_count[2] = 1;

    s->v_count[2] = 1;

    s->quant_index[2] = 1;

    s->h_max = 2;

    s->v_max = 2;

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

    avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420;

    s->interlaced = 0;

    s->picture.reference = 0;

    if (avctx->get_buffer(avctx, &s->picture) < 0)

    {

	fprintf(stderr, "get_buffer() failed\n");

	return -1;

    }

    s->picture.pict_type = I_TYPE;

    s->picture.key_frame = 1;

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

	s->linesize[i] = s->picture.linesize[i] << s->interlaced;

    /* DQT */

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

    {

	j = s->scantable.permutated[i];

	s->quant_matrixes[0][j] = sp5x_quant_table[(qscale * 2) + i];

    }

    s->qscale[0] = FFMAX(

	s->quant_matrixes[0][s->scantable.permutated[1]],

	s->quant_matrixes[0][s->scantable.permutated[8]]) >> 1;

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

    {

	j = s->scantable.permutated[i];

	s->quant_matrixes[1][j] = sp5x_quant_table[(qscale * 2) + 1 + i];

    }

    s->qscale[1] = FFMAX(

	s->quant_matrixes[1][s->scantable.permutated[1]],

	s->quant_matrixes[1][s->scantable.permutated[8]]) >> 1;

    /* DHT */

    /* SOS */

    s->comp_index[0] = 0;

    s->nb_blocks[0] = s->h_count[0] * s->v_count[0];

    s->h_scount[0] = s->h_count[0];

    s->v_scount[0] = s->v_count[0];

    s->dc_index[0] = 0;

    s->ac_index[0] = 0;

    s->comp_index[1] = 1;

    s->nb_blocks[1] = s->h_count[1] * s->v_count[1];

    s->h_scount[1] = s->h_count[1];

    s->v_scount[1] = s->v_count[1];

    s->dc_index[1] = 1;

    s->ac_index[1] = 1;

    s->comp_index[2] = 2;

    s->nb_blocks[2] = s->h_count[2] * s->v_count[2];

    s->h_scount[2] = s->h_count[2];

    s->v_scount[2] = s->v_count[2];

    s->dc_index[2] = 1;

    s->ac_index[2] = 1;

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

	s->last_dc[i] = 1024;

    s->mb_width = (s->width * s->h_max * 8 -1) / (s->h_max * 8);

    s->mb_height = (s->height * s->v_max * 8 -1) / (s->v_max * 8);

    init_get_bits(&s->gb, buf+14, (buf_size-14)*8);

    return mjpeg_decode_scan(s);

#endif

    return i;

}


float32 helper_fdtos(CPUSPARCState *env, float64 src)

{

    float32 ret;

    clear_float_exceptions(env);

    ret = float64_to_float32(src, &env->fp_status);

    check_ieee_exceptions(env);

    return ret;

}


static void icp_control_init(target_phys_addr_t base)

{

    MemoryRegion *io;

    io = (MemoryRegion *)g_malloc0(sizeof(MemoryRegion));

    memory_region_init_io(io, &icp_control_ops, NULL,

                          "control", 0x00800000);

    memory_region_add_subregion(get_system_memory(), base, io);

    /* ??? Save/restore.  */

}


gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,

                               bool search_pc)

{

    CPUState *cs = CPU(cpu);

    DisasContext ctx;

    target_ulong pc_start;

    uint16_t *gen_opc_end;

    CPUBreakpoint *bp;

    int j, lj = -1;

    CPUMoxieState *env = &cpu->env;

    int num_insns;

    pc_start = tb->pc;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    ctx.pc = pc_start;

    ctx.saved_pc = -1;

    ctx.tb = tb;

    ctx.memidx = 0;

    ctx.singlestep_enabled = 0;

    ctx.bstate = BS_NONE;

    num_insns = 0;

    gen_tb_start();

    do {

        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {

            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {

                if (ctx.pc == bp->pc) {

                    tcg_gen_movi_i32(cpu_pc, ctx.pc);

                    gen_helper_debug(cpu_env);

                    ctx.bstate = BS_EXCP;

                    goto done_generating;

                }

            }

        }

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j) {

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

                }

            }

            tcg_ctx.gen_opc_pc[lj] = ctx.pc;

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = num_insns;

        }

        ctx.opcode = cpu_lduw_code(env, ctx.pc);

        ctx.pc += decode_opc(cpu, &ctx);

        num_insns++;

        if (cs->singlestep_enabled) {

            break;

        }

        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {

            break;

        }

    } while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end);

    if (cs->singlestep_enabled) {

        tcg_gen_movi_tl(cpu_pc, ctx.pc);

        gen_helper_debug(cpu_env);

    } else {

        switch (ctx.bstate) {

        case BS_STOP:

        case BS_NONE:

            gen_goto_tb(env, &ctx, 0, ctx.pc);

            break;

        case BS_EXCP:

            tcg_gen_exit_tb(0);

            break;

        case BS_BRANCH:

        default:

            break;

        }

    }

 done_generating:

    gen_tb_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        lj++;

        while (lj <= j) {

            tcg_ctx.gen_opc_instr_start[lj++] = 0;

        }

    } else {

        tb->size = ctx.pc - pc_start;

        tb->icount = num_insns;

    }

}


USBBus *usb_bus_find(int busnr)

{

    USBBus *bus;

    if (-1 == busnr)

        return TAILQ_FIRST(&busses);

    TAILQ_FOREACH(bus, &busses, next) {

        if (bus->busnr == busnr)

            return bus;

    }

    return NULL;

}


vreader_copy_list(VReaderList *list)

{

    VReaderList *new_list = NULL;

    VReaderListEntry *current_entry = NULL;

    new_list = vreader_list_new();

    if (new_list == NULL) {

        return NULL;

    }

    for (current_entry = vreader_list_get_first(list); current_entry;

         current_entry = vreader_list_get_next(current_entry)) {

        VReader *reader = vreader_list_get_reader(current_entry);

        VReaderListEntry *new_entry = vreader_list_entry_new(reader);

        vreader_free(reader);

        vreader_queue(new_list, new_entry);

    }

    return new_list;

}


static int cow_find_streak(const uint8_t *bitmap, int value, int start, int nb_sectors)

{

    int streak_value = value ? 0xFF : 0;

    int last = MIN(start + nb_sectors, BITS_PER_BITMAP_SECTOR);

    int bitnum = start;

    while (bitnum < last) {

        if ((bitnum & 7) == 0 && bitmap[bitnum / 8] == streak_value) {

            bitnum += 8;

            continue;

        }

        if (cow_test_bit(bitnum, bitmap) == value) {

            bitnum++;

            continue;

        }

        break;

    }

    return MIN(bitnum, last) - start;

}


static int raw_read_options(QDict *options, BlockDriverState *bs,

    BDRVRawState *s, Error **errp)

{

    Error *local_err = NULL;

    QemuOpts *opts = NULL;

    int64_t real_size = 0;

    int ret;

    real_size = bdrv_getlength(bs->file->bs);

    if (real_size < 0) {

        error_setg_errno(errp, -real_size, "Could not get image size");

        return real_size;

    }

    opts = qemu_opts_create(&raw_runtime_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto end;

    }

    s->offset = qemu_opt_get_size(opts, "offset", 0);

    if (s->offset > real_size) {

        error_setg(errp, "Offset (%" PRIu64 ") cannot be greater than "

            "size of the containing file (%" PRId64 ")",

            s->offset, real_size);

        ret = -EINVAL;

        goto end;

    }

    if (qemu_opt_find(opts, "size") != NULL) {

        s->size = qemu_opt_get_size(opts, "size", 0);

        s->has_size = true;

    } else {

        s->has_size = false;

        s->size = real_size - s->offset;

    }

    /* Check size and offset */

    if ((real_size - s->offset) < s->size) {

        error_setg(errp, "The sum of offset (%" PRIu64 ") and size "

            "(%" PRIu64 ") has to be smaller or equal to the "

            " actual size of the containing file (%" PRId64 ")",

            s->offset, s->size, real_size);

        ret = -EINVAL;

        goto end;

    }

    /* Make sure size is multiple of BDRV_SECTOR_SIZE to prevent rounding

     * up and leaking out of the specified area. */

    if (s->has_size && !QEMU_IS_ALIGNED(s->size, BDRV_SECTOR_SIZE)) {

        error_setg(errp, "Specified size is not multiple of %llu",

            BDRV_SECTOR_SIZE);

        ret = -EINVAL;

        goto end;

    }

    ret = 0;

end:

    qemu_opts_del(opts);

    return ret;

}


static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,

                                        long dstWidth, const uint8_t *src, int srcW,

                                        int xInc)

{

#if ARCH_X86

#if COMPILE_TEMPLATE_MMX2

    int32_t *filterPos = c->hLumFilterPos;

    int16_t *filter    = c->hLumFilter;

    int     canMMX2BeUsed  = c->canMMX2BeUsed;

    void    *mmx2FilterCode= c->lumMmx2FilterCode;

    int i;

#if defined(PIC)

    DECLARE_ALIGNED(8, uint64_t, ebxsave);

#endif

    if (canMMX2BeUsed) {

        __asm__ volatile(

#if defined(PIC)

            "mov               %%"REG_b", %5        \n\t"

#endif

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

            "mov                      %0, %%"REG_c" \n\t"

            "mov                      %1, %%"REG_D" \n\t"

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

            "mov                      %3, %%"REG_b" \n\t"

            "xor               %%"REG_a", %%"REG_a" \n\t" // i

            PREFETCH"        (%%"REG_c")            \n\t"

            PREFETCH"      32(%%"REG_c")            \n\t"

            PREFETCH"      64(%%"REG_c")            \n\t"

#if ARCH_X86_64

#define CALL_MMX2_FILTER_CODE \

            "movl            (%%"REG_b"), %%esi     \n\t"\

            "call                    *%4            \n\t"\

            "movl (%%"REG_b", %%"REG_a"), %%esi     \n\t"\

            "add               %%"REG_S", %%"REG_c" \n\t"\

            "add               %%"REG_a", %%"REG_D" \n\t"\

            "xor               %%"REG_a", %%"REG_a" \n\t"\

#else

#define CALL_MMX2_FILTER_CODE \

            "movl (%%"REG_b"), %%esi        \n\t"\

            "call         *%4                       \n\t"\

            "addl (%%"REG_b", %%"REG_a"), %%"REG_c" \n\t"\

            "add               %%"REG_a", %%"REG_D" \n\t"\

            "xor               %%"REG_a", %%"REG_a" \n\t"\

#endif /* ARCH_X86_64 */

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

            CALL_MMX2_FILTER_CODE

#if defined(PIC)

            "mov                      %5, %%"REG_b" \n\t"

#endif

            :: "m" (src), "m" (dst), "m" (filter), "m" (filterPos),

            "m" (mmx2FilterCode)

#if defined(PIC)

            ,"m" (ebxsave)

#endif

            : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

            ,"%"REG_b

#endif

        );

        for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;

    } else {

#endif /* COMPILE_TEMPLATE_MMX2 */

    x86_reg xInc_shr16 = xInc >> 16;

    uint16_t xInc_mask = xInc & 0xffff;

    x86_reg dstWidth_reg = dstWidth;

    //NO MMX just normal asm ...

    __asm__ volatile(

        "xor %%"REG_a", %%"REG_a"            \n\t" // i

        "xor %%"REG_d", %%"REG_d"            \n\t" // xx

        "xorl    %%ecx, %%ecx                \n\t" // xalpha

        ".p2align    4                       \n\t"

        "1:                                  \n\t"

        "movzbl    (%0, %%"REG_d"), %%edi    \n\t" //src[xx]

        "movzbl   1(%0, %%"REG_d"), %%esi    \n\t" //src[xx+1]

        FAST_BILINEAR_X86

        "movw     %%si, (%%"REG_D", %%"REG_a", 2)   \n\t"

        "addw       %4, %%cx                 \n\t" //xalpha += xInc&0xFFFF

        "adc        %3, %%"REG_d"            \n\t" //xx+= xInc>>16 + carry

        "movzbl    (%0, %%"REG_d"), %%edi    \n\t" //src[xx]

        "movzbl   1(%0, %%"REG_d"), %%esi    \n\t" //src[xx+1]

        FAST_BILINEAR_X86

        "movw     %%si, 2(%%"REG_D", %%"REG_a", 2)  \n\t"

        "addw       %4, %%cx                 \n\t" //xalpha += xInc&0xFFFF

        "adc        %3, %%"REG_d"            \n\t" //xx+= xInc>>16 + carry

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

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

        " jb        1b                       \n\t"

        :: "r" (src), "m" (dst), "m" (dstWidth_reg), "m" (xInc_shr16), "m" (xInc_mask)

        : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"

    );

#if COMPILE_TEMPLATE_MMX2

    } //if MMX2 can't be used

#endif

#else

    int i;

    unsigned int xpos=0;

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

        register unsigned int xx=xpos>>16;

        register unsigned int xalpha=(xpos&0xFFFF)>>9;

        dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;

        xpos+=xInc;

    }

#endif /* ARCH_X86 */

}


bool memory_region_is_skip_dump(MemoryRegion *mr)

{

    return mr->skip_dump;

}


static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply)

{

    uint8_t buf[4 + 4 + 8];

    /* Reply

       [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)

       [ 4 ..  7]    error   (0 == no error)

       [ 7 .. 15]    handle

     */

    cpu_to_be32w((uint32_t*)buf, NBD_REPLY_MAGIC);

    cpu_to_be32w((uint32_t*)(buf + 4), reply->error);

    cpu_to_be64w((uint64_t*)(buf + 8), reply->handle);

    TRACE("Sending response to client");

    if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {

        LOG("writing to socket failed");

        errno = EINVAL;

        return -1;

    }

    return 0;

}


static void switch_tss(CPUX86State *env, int tss_selector,

                       uint32_t e1, uint32_t e2, int source,

                       uint32_t next_eip)

{

    int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i;

    target_ulong tss_base;

    uint32_t new_regs[8], new_segs[6];

    uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap;

    uint32_t old_eflags, eflags_mask;

    SegmentCache *dt;

    int index;

    target_ulong ptr;

    type = (e2 >> DESC_TYPE_SHIFT) & 0xf;

    LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type,

              source);

    /* if task gate, we read the TSS segment and we load it */

    if (type == 5) {

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc);

        }

        tss_selector = e1 >> 16;

        if (tss_selector & 4) {

            raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);

        }

        if (load_segment(env, &e1, &e2, tss_selector) != 0) {

            raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);

        }

        if (e2 & DESC_S_MASK) {

            raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);

        }

        type = (e2 >> DESC_TYPE_SHIFT) & 0xf;

        if ((type & 7) != 1) {

            raise_exception_err(env, EXCP0D_GPF, tss_selector & 0xfffc);

        }

    }

    if (!(e2 & DESC_P_MASK)) {

        raise_exception_err(env, EXCP0B_NOSEG, tss_selector & 0xfffc);

    }

    if (type & 8) {

        tss_limit_max = 103;

    } else {

        tss_limit_max = 43;

    }

    tss_limit = get_seg_limit(e1, e2);

    tss_base = get_seg_base(e1, e2);

    if ((tss_selector & 4) != 0 ||

        tss_limit < tss_limit_max) {

        raise_exception_err(env, EXCP0A_TSS, tss_selector & 0xfffc);

    }

    old_type = (env->tr.flags >> DESC_TYPE_SHIFT) & 0xf;

    if (old_type & 8) {

        old_tss_limit_max = 103;

    } else {

        old_tss_limit_max = 43;

    }

    /* read all the registers from the new TSS */

    if (type & 8) {

        /* 32 bit */

        new_cr3 = cpu_ldl_kernel(env, tss_base + 0x1c);

        new_eip = cpu_ldl_kernel(env, tss_base + 0x20);

        new_eflags = cpu_ldl_kernel(env, tss_base + 0x24);

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

            new_regs[i] = cpu_ldl_kernel(env, tss_base + (0x28 + i * 4));

        }

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

            new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x48 + i * 4));

        }

        new_ldt = cpu_lduw_kernel(env, tss_base + 0x60);

        new_trap = cpu_ldl_kernel(env, tss_base + 0x64);

    } else {

        /* 16 bit */

        new_cr3 = 0;

        new_eip = cpu_lduw_kernel(env, tss_base + 0x0e);

        new_eflags = cpu_lduw_kernel(env, tss_base + 0x10);

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

            new_regs[i] = cpu_lduw_kernel(env, tss_base + (0x12 + i * 2)) |

                0xffff0000;

        }

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

            new_segs[i] = cpu_lduw_kernel(env, tss_base + (0x22 + i * 4));

        }

        new_ldt = cpu_lduw_kernel(env, tss_base + 0x2a);

        new_segs[R_FS] = 0;

        new_segs[R_GS] = 0;

        new_trap = 0;

    }

    /* XXX: avoid a compiler warning, see

     http://support.amd.com/us/Processor_TechDocs/24593.pdf

     chapters 12.2.5 and 13.2.4 on how to implement TSS Trap bit */

    (void)new_trap;

    /* NOTE: we must avoid memory exceptions during the task switch,

       so we make dummy accesses before */

    /* XXX: it can still fail in some cases, so a bigger hack is

       necessary to valid the TLB after having done the accesses */

    v1 = cpu_ldub_kernel(env, env->tr.base);

    v2 = cpu_ldub_kernel(env, env->tr.base + old_tss_limit_max);

    cpu_stb_kernel(env, env->tr.base, v1);

    cpu_stb_kernel(env, env->tr.base + old_tss_limit_max, v2);

    /* clear busy bit (it is restartable) */

    if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) {

        target_ulong ptr;

        uint32_t e2;

        ptr = env->gdt.base + (env->tr.selector & ~7);

        e2 = cpu_ldl_kernel(env, ptr + 4);

        e2 &= ~DESC_TSS_BUSY_MASK;

        cpu_stl_kernel(env, ptr + 4, e2);

    }

    old_eflags = cpu_compute_eflags(env);

    if (source == SWITCH_TSS_IRET) {

        old_eflags &= ~NT_MASK;

    }

    /* save the current state in the old TSS */

    if (type & 8) {

        /* 32 bit */

        cpu_stl_kernel(env, env->tr.base + 0x20, next_eip);

        cpu_stl_kernel(env, env->tr.base + 0x24, old_eflags);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]);

        cpu_stl_kernel(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]);

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

            cpu_stw_kernel(env, env->tr.base + (0x48 + i * 4),

                           env->segs[i].selector);

        }

    } else {

        /* 16 bit */

        cpu_stw_kernel(env, env->tr.base + 0x0e, next_eip);

        cpu_stw_kernel(env, env->tr.base + 0x10, old_eflags);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]);

        cpu_stw_kernel(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]);

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

            cpu_stw_kernel(env, env->tr.base + (0x22 + i * 4),

                           env->segs[i].selector);

        }

    }

    /* now if an exception occurs, it will occurs in the next task

       context */

    if (source == SWITCH_TSS_CALL) {

        cpu_stw_kernel(env, tss_base, env->tr.selector);

        new_eflags |= NT_MASK;

    }

    /* set busy bit */

    if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_CALL) {

        target_ulong ptr;

        uint32_t e2;

        ptr = env->gdt.base + (tss_selector & ~7);

        e2 = cpu_ldl_kernel(env, ptr + 4);

        e2 |= DESC_TSS_BUSY_MASK;

        cpu_stl_kernel(env, ptr + 4, e2);

    }

    /* set the new CPU state */

    /* from this point, any exception which occurs can give problems */

    env->cr[0] |= CR0_TS_MASK;

    env->hflags |= HF_TS_MASK;

    env->tr.selector = tss_selector;

    env->tr.base = tss_base;

    env->tr.limit = tss_limit;

    env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK;

    if ((type & 8) && (env->cr[0] & CR0_PG_MASK)) {

        cpu_x86_update_cr3(env, new_cr3);

    }

    /* load all registers without an exception, then reload them with

       possible exception */

    env->eip = new_eip;

    eflags_mask = TF_MASK | AC_MASK | ID_MASK |

        IF_MASK | IOPL_MASK | VM_MASK | RF_MASK | NT_MASK;

    if (!(type & 8)) {

        eflags_mask &= 0xffff;

    }

    cpu_load_eflags(env, new_eflags, eflags_mask);

    /* XXX: what to do in 16 bit case? */

    env->regs[R_EAX] = new_regs[0];

    env->regs[R_ECX] = new_regs[1];

    env->regs[R_EDX] = new_regs[2];

    env->regs[R_EBX] = new_regs[3];

    env->regs[R_ESP] = new_regs[4];

    env->regs[R_EBP] = new_regs[5];

    env->regs[R_ESI] = new_regs[6];

    env->regs[R_EDI] = new_regs[7];

    if (new_eflags & VM_MASK) {

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

            load_seg_vm(env, i, new_segs[i]);

        }

        /* in vm86, CPL is always 3 */

        cpu_x86_set_cpl(env, 3);

    } else {

        /* CPL is set the RPL of CS */

        cpu_x86_set_cpl(env, new_segs[R_CS] & 3);

        /* first just selectors as the rest may trigger exceptions */

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

            cpu_x86_load_seg_cache(env, i, new_segs[i], 0, 0, 0);

        }

    }

    env->ldt.selector = new_ldt & ~4;

    env->ldt.base = 0;

    env->ldt.limit = 0;

    env->ldt.flags = 0;

    /* load the LDT */

    if (new_ldt & 4) {

        raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);

    }

    if ((new_ldt & 0xfffc) != 0) {

        dt = &env->gdt;

        index = new_ldt & ~7;

        if ((index + 7) > dt->limit) {

            raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);

        }

        ptr = dt->base + index;

        e1 = cpu_ldl_kernel(env, ptr);

        e2 = cpu_ldl_kernel(env, ptr + 4);

        if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) {

            raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);

        }

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, new_ldt & 0xfffc);

        }

        load_seg_cache_raw_dt(&env->ldt, e1, e2);

    }

    /* load the segments */

    if (!(new_eflags & VM_MASK)) {

        tss_load_seg(env, R_CS, new_segs[R_CS]);

        tss_load_seg(env, R_SS, new_segs[R_SS]);

        tss_load_seg(env, R_ES, new_segs[R_ES]);

        tss_load_seg(env, R_DS, new_segs[R_DS]);

        tss_load_seg(env, R_FS, new_segs[R_FS]);

        tss_load_seg(env, R_GS, new_segs[R_GS]);

    }

    /* check that env->eip is in the CS segment limits */

    if (new_eip > env->segs[R_CS].limit) {

        /* XXX: different exception if CALL? */

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

#ifndef CONFIG_USER_ONLY

    /* reset local breakpoints */

    if (env->dr[7] & DR7_LOCAL_BP_MASK) {

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

            if (hw_local_breakpoint_enabled(env->dr[7], i) &&

                !hw_global_breakpoint_enabled(env->dr[7], i)) {

                hw_breakpoint_remove(env, i);

            }

        }

        env->dr[7] &= ~DR7_LOCAL_BP_MASK;

    }

#endif

}


void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n)

{

    int fd, rc;

    int i;

    fd = kvmppc_get_htab_fd(false, ptex, &error_abort);

    i = 0;

    while (i < n) {

        struct kvm_get_htab_header *hdr;

        int m = n < HPTES_PER_GROUP ? n : HPTES_PER_GROUP;

        char buf[sizeof(*hdr) + m * HASH_PTE_SIZE_64];

        rc = read(fd, buf, sizeof(buf));

        if (rc < 0) {

            hw_error("kvmppc_read_hptes: Unable to read HPTEs");

        }

        hdr = (struct kvm_get_htab_header *)buf;

        while ((i < n) && ((char *)hdr < (buf + rc))) {

            int invalid = hdr->n_invalid;

            if (hdr->index != (ptex + i)) {

                hw_error("kvmppc_read_hptes: Unexpected HPTE index %"PRIu32

                         " != (%"HWADDR_PRIu" + %d", hdr->index, ptex, i);

            }

            memcpy(hptes + i, hdr + 1, HASH_PTE_SIZE_64 * hdr->n_valid);

            i += hdr->n_valid;

            if ((n - i) < invalid) {

                invalid = n - i;

            }

            memset(hptes + i, 0, invalid * HASH_PTE_SIZE_64);

            i += hdr->n_invalid;

            hdr = (struct kvm_get_htab_header *)

                ((char *)(hdr + 1) + HASH_PTE_SIZE_64 * hdr->n_valid);

        }

    }

    close(fd);

}


void qmp_output_visitor_cleanup(QmpOutputVisitor *v)

{

    QStackEntry *e, *tmp;

    QTAILQ_FOREACH_SAFE(e, &v->stack, node, tmp) {

        QTAILQ_REMOVE(&v->stack, e, node);

        g_free(e);

    }

    qobject_decref(v->root);

    g_free(v);

}


static int check_host_key(BDRVSSHState *s, const char *host, int port,

                          const char *host_key_check)

{

    /* host_key_check=no */

    if (strcmp(host_key_check, "no") == 0) {

        return 0;

    }

    /* host_key_check=md5:xx:yy:zz:... */

    if (strncmp(host_key_check, "md5:", 4) == 0) {

        return check_host_key_hash(s, &host_key_check[4],

                                   LIBSSH2_HOSTKEY_HASH_MD5, 16);

    }

    /* host_key_check=sha1:xx:yy:zz:... */

    if (strncmp(host_key_check, "sha1:", 5) == 0) {

        return check_host_key_hash(s, &host_key_check[5],

                                   LIBSSH2_HOSTKEY_HASH_SHA1, 20);

    }

    /* host_key_check=yes */

    if (strcmp(host_key_check, "yes") == 0) {

        return check_host_key_knownhosts(s, host, port);

    }

    error_report("unknown host_key_check setting (%s)", host_key_check);

    return -EINVAL;

}


void memory_region_notify_iommu(MemoryRegion *mr,

                                IOMMUTLBEntry entry)

{

    IOMMUNotifier *iommu_notifier;

    IOMMUNotifierFlag request_flags;

    assert(memory_region_is_iommu(mr));

    if (entry.perm & IOMMU_RW) {

        request_flags = IOMMU_NOTIFIER_MAP;

    } else {

        request_flags = IOMMU_NOTIFIER_UNMAP;

    }

    IOMMU_NOTIFIER_FOREACH(iommu_notifier, mr) {

        /*

         * Skip the notification if the notification does not overlap

         * with registered range.

         */

        if (iommu_notifier->start > entry.iova + entry.addr_mask + 1 ||

            iommu_notifier->end < entry.iova) {

            continue;

        }

        if (iommu_notifier->notifier_flags & request_flags) {

            iommu_notifier->notify(iommu_notifier, &entry);

        }

    }

}


static IOWatchPoll *io_watch_poll_from_source(GSource *source)

{

    IOWatchPoll *i;

    QTAILQ_FOREACH(i, &io_watch_poll_list, node) {

        if (i->src == source) {

            return i;

        }

    }

    return NULL;

}


void memory_region_init_io(MemoryRegion *mr,

                           Object *owner,

                           const MemoryRegionOps *ops,

                           void *opaque,

                           const char *name,

                           uint64_t size)

{

    memory_region_init(mr, owner, name, size);

    mr->ops = ops;

    mr->opaque = opaque;

    mr->terminates = true;

    mr->ram_addr = ~(ram_addr_t)0;

}


static void filter_mb( H264Context *h, int mb_x, int mb_y ) {

    MpegEncContext * const s = &h->s;

    const int mb_xy= mb_x + mb_y*s->mb_stride;

    uint8_t *img_y  = s->current_picture.data[0] + (mb_y * 16* s->linesize  ) + mb_x * 16;

    uint8_t *img_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;

    uint8_t *img_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;

    int linesize, uvlinesize;

    int dir;

#if 0

    /* FIXME what's that ? */

    if( !s->decode )

        return;

#endif

    /* FIXME Implement deblocking filter for field MB */

    if( h->sps.mb_aff ) {

        return;

    }

    linesize = s->linesize;

    uvlinesize = s->uvlinesize;

    /* dir : 0 -> vertical edge, 1 -> horizontal edge */

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

    {

        int start = 0;

        int edge;

        /* test picture boundary */

        if( ( dir == 0 && mb_x == 0 ) || ( dir == 1 && mb_y == 0 ) ) {

            start = 1;

        }

        /* FIXME test slice boundary */

        if( h->disable_deblocking_filter_idc == 2 ) {

        }

        /* Calculate bS */

        for( edge = start; edge < 4; edge++ ) {

            /* mbn_xy: neighbour macroblock (how that works for field ?) */

            int mbn_xy = edge > 0 ? mb_xy : ( dir == 0 ? mb_xy -1 : mb_xy - s->mb_stride );

            int bS[4];

            int qp;

            if( IS_INTRA( s->current_picture.mb_type[mb_xy] ) ||

                IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) {

                bS[0] = bS[1] = bS[2] = bS[3] = ( edge == 0 ? 4 : 3 );

            } else {

                int i;

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

                    static const uint8_t block_idx_xy[4][4] = {

                        { 0, 2, 8,  10}, { 1, 3, 9,  11},

                        { 4, 6, 12, 14}, { 5, 7, 13, 15}

                    };

                    int x = dir == 0 ? edge : i;

                    int y = dir == 0 ? i    : edge;

                    int xn = (x - (dir == 0 ? 1 : 0 ))&0x03;

                    int yn = (y - (dir == 0 ? 0 : 1 ))&0x03;

                    if( h->non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||

                        h->non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 ) {

                        bS[i] = 2;

                    }

                    else if( h->slice_type == P_TYPE ) {

                        const int b8_xy = h->mb2b8_xy[mb_xy]+(y>>1)*h->b8_stride+(x>>1);

                        const int b8n_xy= h->mb2b8_xy[mbn_xy]+(yn>>1)*h->b8_stride+(xn>>1);

                        const int b_xy  = h->mb2b_xy[mb_xy]+y*h->b_stride+x;

                        const int bn_xy = h->mb2b_xy[mbn_xy]+yn*h->b_stride+xn;

                        if( s->current_picture.ref_index[0][b8_xy] != s->current_picture.ref_index[0][b8n_xy] ||

                            ABS( s->current_picture.motion_val[0][b_xy][0] - s->current_picture.motion_val[0][bn_xy][0] ) >= 4 ||

                            ABS( s->current_picture.motion_val[0][b_xy][1] - s->current_picture.motion_val[0][bn_xy][1] ) >= 4 )

                            bS[i] = 1;

                        else

                            bS[i] = 0;

                    }

                    else {

                        /* FIXME Add support for B frame */

                        return;

                    }

                }

            }

            /* Filter edge */

            qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;

            if( dir == 0 ) {

                filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp );

                if( (edge&1) == 0 ) {

                    int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) +

                                      get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;

                    filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, chroma_qp );

                    filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, chroma_qp );

                }

            } else {

                filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp );

                if( (edge&1) == 0 ) {

                    int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) +

                                      get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;

                    filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, chroma_qp );

                    filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, chroma_qp );

                }

            }

        }

    }

}


void mpeg_motion_internal(MpegEncContext *s,

                          uint8_t *dest_y,

                          uint8_t *dest_cb,

                          uint8_t *dest_cr,

                          int field_based,

                          int bottom_field,

                          int field_select,

                          uint8_t **ref_picture,

                          op_pixels_func (*pix_op)[4],

                          int motion_x,

                          int motion_y,

                          int h,

                          int is_mpeg12,

                          int mb_y)

{

    uint8_t *ptr_y, *ptr_cb, *ptr_cr;

    int dxy, uvdxy, mx, my, src_x, src_y,

        uvsrc_x, uvsrc_y, v_edge_pos;

    ptrdiff_t uvlinesize, linesize;

#if 0

    if (s->quarter_sample) {

        motion_x >>= 1;

        motion_y >>= 1;

    }

#endif

    v_edge_pos = s->v_edge_pos >> field_based;

    linesize   = s->current_picture.f.linesize[0] << field_based;

    uvlinesize = s->current_picture.f.linesize[1] << field_based;

    dxy   = ((motion_y & 1) << 1) | (motion_x & 1);

    src_x = s->mb_x * 16 + (motion_x >> 1);

    src_y = (mb_y << (4 - field_based)) + (motion_y >> 1);

    if (!is_mpeg12 && s->out_format == FMT_H263) {

        if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {

            mx      = (motion_x >> 1) | (motion_x & 1);

            my      = motion_y >> 1;

            uvdxy   = ((my & 1) << 1) | (mx & 1);

            uvsrc_x = s->mb_x * 8 + (mx >> 1);

            uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);

        } else {

            uvdxy   = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);

            uvsrc_x = src_x >> 1;

            uvsrc_y = src_y >> 1;

        }

    // Even chroma mv's are full pel in H261

    } else if (!is_mpeg12 && s->out_format == FMT_H261) {

        mx      = motion_x / 4;

        my      = motion_y / 4;

        uvdxy   = 0;

        uvsrc_x = s->mb_x * 8 + mx;

        uvsrc_y = mb_y * 8 + my;

    } else {

        if (s->chroma_y_shift) {

            mx      = motion_x / 2;

            my      = motion_y / 2;

            uvdxy   = ((my & 1) << 1) | (mx & 1);

            uvsrc_x = s->mb_x * 8 + (mx >> 1);

            uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);

        } else {

            if (s->chroma_x_shift) {

                // Chroma422

                mx      = motion_x / 2;

                uvdxy   = ((motion_y & 1) << 1) | (mx & 1);

                uvsrc_x = s->mb_x * 8 + (mx >> 1);

                uvsrc_y = src_y;

            } else {

                // Chroma444

                uvdxy   = dxy;

                uvsrc_x = src_x;

                uvsrc_y = src_y;

            }

        }

    }

    ptr_y  = ref_picture[0] + src_y * linesize + src_x;

    ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;

    ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;

    if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) ||

        (unsigned)src_y > FFMAX(v_edge_pos - (motion_y & 1) - h, 0)) {

        if (is_mpeg12 ||

            s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||

            s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {

            av_log(s->avctx, AV_LOG_DEBUG,

                   "MPEG motion vector out of boundary (%d %d)\n", src_x,

                   src_y);

            return;

        }

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,

                                 s->linesize, s->linesize,

                                 17, 17 + field_based,

                                 src_x, src_y << field_based,

                                 s->h_edge_pos, s->v_edge_pos);

        ptr_y = s->edge_emu_buffer;

        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {

            uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;

            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb,

                                     s->uvlinesize, s->uvlinesize,

                                     9, 9 + field_based,

                                     uvsrc_x, uvsrc_y << field_based,

                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);

            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,

                                     s->uvlinesize, s->uvlinesize,

                                     9, 9 + field_based,

                                     uvsrc_x, uvsrc_y << field_based,

                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);

            ptr_cb = uvbuf;

            ptr_cr = uvbuf + 16;

        }

    }

    /* FIXME use this for field pix too instead of the obnoxious hack which

     * changes picture.data */

    if (bottom_field) {

        dest_y  += s->linesize;

        dest_cb += s->uvlinesize;

        dest_cr += s->uvlinesize;

    }

    if (field_select) {

        ptr_y  += s->linesize;

        ptr_cb += s->uvlinesize;

        ptr_cr += s->uvlinesize;

    }

    pix_op[0][dxy](dest_y, ptr_y, linesize, h);

    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {

        pix_op[s->chroma_x_shift][uvdxy]

            (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);

        pix_op[s->chroma_x_shift][uvdxy]

            (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);

    }

    if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&

        s->out_format == FMT_H261) {

        ff_h261_loop_filter(s);

    }

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->config_read = i6300esb_config_read;

    k->config_write = i6300esb_config_write;

    k->realize = i6300esb_realize;

    k->vendor_id = PCI_VENDOR_ID_INTEL;

    k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;

    k->class_id = PCI_CLASS_SYSTEM_OTHER;

    dc->reset = i6300esb_reset;

    dc->vmsd = &vmstate_i6300esb;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

}


BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,

        QEMUWin32AIOState *aio, HANDLE hfile,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockDriverCompletionFunc *cb, void *opaque, int type)

{

    struct QEMUWin32AIOCB *waiocb;

    uint64_t offset = sector_num * 512;

    DWORD rc;

    waiocb = qemu_aio_get(&win32_aiocb_info, bs, cb, opaque);

    waiocb->nbytes = nb_sectors * 512;

    waiocb->qiov = qiov;

    waiocb->is_read = (type == QEMU_AIO_READ);

    if (qiov->niov > 1) {

        waiocb->buf = qemu_blockalign(bs, qiov->size);

        if (type & QEMU_AIO_WRITE) {

            iov_to_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);

        }

        waiocb->is_linear = false;

    } else {

        waiocb->buf = qiov->iov[0].iov_base;

        waiocb->is_linear = true;

    }

    memset(&waiocb->ov, 0, sizeof(waiocb->ov));

    waiocb->ov.Offset = (DWORD)offset;

    waiocb->ov.OffsetHigh = (DWORD)(offset >> 32);

    waiocb->ov.hEvent = event_notifier_get_handle(&aio->e);

    aio->count++;

    if (type & QEMU_AIO_READ) {

        rc = ReadFile(hfile, waiocb->buf, waiocb->nbytes, NULL, &waiocb->ov);

    } else {

        rc = WriteFile(hfile, waiocb->buf, waiocb->nbytes, NULL, &waiocb->ov);

    }

    if(rc == 0 && GetLastError() != ERROR_IO_PENDING) {

        goto out_dec_count;

    }

    return &waiocb->common;

out_dec_count:

    aio->count--;

    qemu_aio_release(waiocb);

    return NULL;

}


static av_cold int vp9_decode_free(AVCodecContext *ctx)

{

    VP9Context *s = ctx->priv_data;

    int i;

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

        if (s->frames[i].tf.f->data[0])

            vp9_unref_frame(ctx, &s->frames[i]);

        av_frame_free(&s->frames[i].tf.f);

    }

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

        if (s->refs[i].f->data[0])

            ff_thread_release_buffer(ctx, &s->refs[i]);

        av_frame_free(&s->refs[i].f);

        if (s->next_refs[i].f->data[0])

            ff_thread_release_buffer(ctx, &s->next_refs[i]);

        av_frame_free(&s->next_refs[i].f);

    }

    av_freep(&s->above_partition_ctx);

    av_freep(&s->c_b);

    s->c_b_size = 0;

    av_freep(&s->b_base);

    av_freep(&s->block_base);

    return 0;

}


static int sd_create(const char *filename, QemuOpts *opts,

                     Error **errp)

{

    int ret = 0;

    uint32_t vid = 0;

    char *backing_file = NULL;

    char *buf = NULL;

    BDRVSheepdogState *s;

    char tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    bool prealloc = false;

    s = g_malloc0(sizeof(BDRVSheepdogState));

    memset(tag, 0, sizeof(tag));

    if (strstr(filename, "://")) {

        ret = sd_parse_uri(s, filename, s->name, &snapid, tag);

    } else {

        ret = parse_vdiname(s, filename, s->name, &snapid, tag);

    }

    if (ret < 0) {

        error_setg(errp, "Can't parse filename");

        goto out;

    }

    s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);

    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);

    if (!buf || !strcmp(buf, "off")) {

        prealloc = false;

    } else if (!strcmp(buf, "full")) {

        prealloc = true;

    } else {

        error_setg(errp, "Invalid preallocation mode: '%s'", buf);

        ret = -EINVAL;

        goto out;

    }

    g_free(buf);

    buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);

    if (buf) {

        ret = parse_redundancy(s, buf);

        if (ret < 0) {

            error_setg(errp, "Invalid redundancy mode: '%s'", buf);

            goto out;

        }

    }

    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {

        error_setg(errp, "too big image size");

        ret = -EINVAL;

        goto out;

    }

    if (backing_file) {

        BlockDriverState *bs;

        BDRVSheepdogState *base;

        BlockDriver *drv;

        /* Currently, only Sheepdog backing image is supported. */

        drv = bdrv_find_protocol(backing_file, true);

        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {

            error_setg(errp, "backing_file must be a sheepdog image");

            ret = -EINVAL;

            goto out;

        }

        bs = NULL;

        ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL,

                        errp);

        if (ret < 0) {

            goto out;

        }

        base = bs->opaque;

        if (!is_snapshot(&base->inode)) {

            error_setg(errp, "cannot clone from a non snapshot vdi");

            bdrv_unref(bs);

            ret = -EINVAL;

            goto out;

        }

        s->inode.vdi_id = base->inode.vdi_id;

        bdrv_unref(bs);

    }

    s->aio_context = qemu_get_aio_context();

    ret = do_sd_create(s, &vid, 0, errp);

    if (ret) {

        goto out;

    }

    if (prealloc) {

        ret = sd_prealloc(filename, errp);

    }

out:

    g_free(backing_file);

    g_free(buf);

    g_free(s);

    return ret;

}


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

{

    ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev);

    ICSState *ics = ICS_BASE(dev);

    Object *obj;

    Error *err = NULL;

    obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);

    if (!obj) {

        error_setg(errp, "%s: required link '" ICS_PROP_XICS "' not found: %s",

                   __func__, error_get_pretty(err));

        return;

    }

    ics->xics = XICS_FABRIC(obj);

    if (icsc->realize) {

        icsc->realize(ics, errp);

    }

}