int h263_decode_picture_header(MpegEncContext *s)

{

    int format, width, height, i;

    uint32_t startcode;

    align_get_bits(&s->gb);

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

    for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=8) {

        startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF;

        if(startcode == 0x20)

            break;

    }

    if (startcode != 0x20) {

        av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");

        return -1;

    }

    /* temporal reference */

    s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */

    /* PTYPE starts here */

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

        /* marker */

        av_log(s->avctx, AV_LOG_ERROR, "Bad marker\n");

        return -1;

    }

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

        av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n");

        return -1;	/* h263 id */

    }

    skip_bits1(&s->gb);	/* split screen off */

    skip_bits1(&s->gb);	/* camera  off */

    skip_bits1(&s->gb);	/* freeze picture release off */

    /* Reset GOB number */

    s->gob_number = 0;

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

    /*

        0    forbidden

        1    sub-QCIF

        10   QCIF

        7	extended PTYPE (PLUSPTYPE)

    */

    if (format != 7 && format != 6) {

        s->h263_plus = 0;

        /* H.263v1 */

        width = h263_format[format][0];

        height = h263_format[format][1];

        if (!width)

            return -1;

        s->pict_type = I_TYPE + get_bits1(&s->gb);

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

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

            av_log(s->avctx, AV_LOG_ERROR, "H263 SAC not supported\n");

            return -1;	/* SAC: off */

        }

        s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */

        s->unrestricted_mv = s->h263_long_vectors || s->obmc;

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

            av_log(s->avctx, AV_LOG_ERROR, "H263 PB frame not supported\n");

            return -1;	/* not PB frame */

        }

        s->qscale = get_bits(&s->gb, 5);

        skip_bits1(&s->gb);	/* Continuous Presence Multipoint mode: off */

        s->width = width;

        s->height = height;

    } else {

        int ufep;

        /* H.263v2 */

        s->h263_plus = 1;

        ufep = get_bits(&s->gb, 3); /* Update Full Extended PTYPE */

        /* ufep other than 0 and 1 are reserved */

        if (ufep == 1) {

            /* OPPTYPE */

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

            dprintf("ufep=1, format: %d\n", format);

            skip_bits(&s->gb,1); /* Custom PCF */

            s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */

            skip_bits1(&s->gb); /* Syntax-based Arithmetic Coding (SAC) */

            s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */

            s->unrestricted_mv = s->umvplus || s->obmc;

            s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */

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

                av_log(s->avctx, AV_LOG_ERROR, "Deblocking Filter not supported\n");

            }

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

                av_log(s->avctx, AV_LOG_ERROR, "Slice Structured not supported\n");

            }

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

                av_log(s->avctx, AV_LOG_ERROR, "Reference Picture Selection not supported\n");

            }

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

                av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n");

            }

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

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

            skip_bits(&s->gb, 1); /* Prevent start code emulation */

            skip_bits(&s->gb, 3); /* Reserved */

        } else if (ufep != 0) {

            av_log(s->avctx, AV_LOG_ERROR, "Bad UFEP type (%d)\n", ufep);

            return -1;

        }

        /* MPPTYPE */

        s->pict_type = get_bits(&s->gb, 3) + I_TYPE;

	if (s->pict_type == 8 && s->avctx->codec_tag == ff_get_fourcc("ZYGO"))

	    s->pict_type = I_TYPE;

        if (s->pict_type != I_TYPE &&

            s->pict_type != P_TYPE)

            return -1;

        skip_bits(&s->gb, 2);

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

        skip_bits(&s->gb, 4);

        /* Get the picture dimensions */

        if (ufep) {

            if (format == 6) {

                /* Custom Picture Format (CPFMT) */

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

                dprintf("aspect: %d\n", s->aspect_ratio_info);

                /* aspect ratios:

                0 - forbidden

                1 - 1:1

                2 - 12:11 (CIF 4:3)

                3 - 10:11 (525-type 4:3)

                4 - 16:11 (CIF 16:9)

                5 - 40:33 (525-type 16:9)

                6-14 - reserved

                */

                width = (get_bits(&s->gb, 9) + 1) * 4;

                skip_bits1(&s->gb);

                height = get_bits(&s->gb, 9) * 4;

                dprintf("\nH.263+ Custom picture: %dx%d\n",width,height);

                if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {

                    /* aspected dimensions */

                    s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 8);

                    s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 8);

                }else{

                    s->avctx->sample_aspect_ratio= pixel_aspect[s->aspect_ratio_info];

                }

            } else {

                width = h263_format[format][0];

                height = h263_format[format][1];

            }

            if ((width == 0) || (height == 0))

                return -1;

            s->width = width;

            s->height = height;

            if (s->umvplus) {

                if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */

                    skip_bits1(&s->gb);

            }

        }

        s->qscale = get_bits(&s->gb, 5);

    }

    /* PEI */

    while (get_bits1(&s->gb) != 0) {

        skip_bits(&s->gb, 8);

    }

    s->f_code = 1;

    if(s->h263_aic){

         s->y_dc_scale_table=

         s->c_dc_scale_table= ff_aic_dc_scale_table;

    }else{

        s->y_dc_scale_table=

        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;

    }

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

         av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s\n",

         s->qscale, av_get_pict_type_char(s->pict_type),

         s->gb.size_in_bits, 1-s->no_rounding,

         s->obmc ? " AP" : "",

         s->umvplus ? " UMV" : "",

         s->h263_long_vectors ? " LONG" : "",

         s->h263_plus ? " +" : "",

         s->h263_aic ? " AIC" : "",

         s->alt_inter_vlc ? " AIV" : "",

         s->modified_quant ? " MQ" : ""

         );

     }

#if 1

    if (s->pict_type == I_TYPE && s->avctx->codec_tag == ff_get_fourcc("ZYGO")){

        int i,j;

        for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));

        av_log(s->avctx, AV_LOG_DEBUG, "\n");

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

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

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

                v |= get_sbits(&s->gb, 8)<<8;

                av_log(s->avctx, AV_LOG_DEBUG, " %5d", v);

            }

            av_log(s->avctx, AV_LOG_DEBUG, "\n");

        }

        for(i=0; i<50; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));

    }

#endif

    return 0;

}


static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,

                          Error **errp)

{

    X86CPU *cpu = NULL;

    Error *local_err = NULL;

    cpu = cpu_x86_create(cpu_model, &local_err);

    if (local_err != NULL) {

        goto out;

    }

    object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);

    object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);

out:

    if (local_err) {

        error_propagate(errp, local_err);

        object_unref(OBJECT(cpu));

        cpu = NULL;

    }

    return cpu;

}


static int find_pte64 (mmu_ctx_t *ctx, int h, int rw)

{

    return _find_pte(ctx, 1, h, rw);

}


void pc_basic_device_init(qemu_irq *isa_irq,

                          ISADevice **rtc_state)

{

    int i;

    DriveInfo *fd[MAX_FD];

    PITState *pit;

    qemu_irq rtc_irq = NULL;

    qemu_irq *a20_line;

    ISADevice *i8042, *port92, *vmmouse;

    qemu_irq *cpu_exit_irq;

    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);

    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);

    if (!no_hpet) {

        DeviceState *hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);

        if (hpet) {

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

                sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]);

            }

            rtc_irq = qdev_get_gpio_in(hpet, 0);

        }

    }

    *rtc_state = rtc_init(2000, rtc_irq);

    qemu_register_boot_set(pc_boot_set, *rtc_state);

    pit = pit_init(0x40, isa_reserve_irq(0));

    pcspk_init(pit);

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

        if (serial_hds[i]) {

            serial_isa_init(i, serial_hds[i]);

        }

    }

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

        if (parallel_hds[i]) {

            parallel_init(i, parallel_hds[i]);

        }

    }

    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);

    i8042 = isa_create_simple("i8042");

    i8042_setup_a20_line(i8042, &a20_line[0]);

    vmport_init();

    vmmouse = isa_try_create("vmmouse");

    if (vmmouse) {

        qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);

    }

    port92 = isa_create_simple("port92");

    port92_init(port92, &a20_line[1]);

    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);

    DMA_init(0, cpu_exit_irq);

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

        fd[i] = drive_get(IF_FLOPPY, 0, i);

    }

    fdctrl_init_isa(fd);

}


static JSONTokenType token_get_type(QObject *obj)

{

    return qdict_get_int(qobject_to_qdict(obj), "type");

}


void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,

                  const char *boot_device,

                  BusState *idebus0, BusState *idebus1,

                  ISADevice *s)

{

    int val, nb, nb_heads, max_track, last_sect, i;

    FDriveType fd_type[2];

    DriveInfo *fd[2];

    static pc_cmos_init_late_arg arg;

    /* various important CMOS locations needed by PC/Bochs bios */

    /* memory size */

    val = 640; /* base memory in K */

    rtc_set_memory(s, 0x15, val);

    rtc_set_memory(s, 0x16, val >> 8);

    val = (ram_size / 1024) - 1024;

    if (val > 65535)

        val = 65535;

    rtc_set_memory(s, 0x17, val);

    rtc_set_memory(s, 0x18, val >> 8);

    rtc_set_memory(s, 0x30, val);

    rtc_set_memory(s, 0x31, val >> 8);

    if (above_4g_mem_size) {

        rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16);

        rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24);

        rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32);

    }

    if (ram_size > (16 * 1024 * 1024))

        val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);

    else

        val = 0;

    if (val > 65535)

        val = 65535;

    rtc_set_memory(s, 0x34, val);

    rtc_set_memory(s, 0x35, val >> 8);

    /* set the number of CPU */

    rtc_set_memory(s, 0x5f, smp_cpus - 1);

    /* set boot devices, and disable floppy signature check if requested */

    if (set_boot_dev(s, boot_device, fd_bootchk)) {

        exit(1);

    }

    /* floppy type */

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

        fd[i] = drive_get(IF_FLOPPY, 0, i);

        if (fd[i]) {

            bdrv_get_floppy_geometry_hint(fd[i]->bdrv, &nb_heads, &max_track,

                                          &last_sect, FDRIVE_DRV_NONE,

                                          &fd_type[i]);

        } else {

            fd_type[i] = FDRIVE_DRV_NONE;

        }

    }

    val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |

        cmos_get_fd_drive_type(fd_type[1]);

    rtc_set_memory(s, 0x10, val);

    val = 0;

    nb = 0;

    if (fd_type[0] < FDRIVE_DRV_NONE) {

        nb++;

    }

    if (fd_type[1] < FDRIVE_DRV_NONE) {

        nb++;

    }

    switch (nb) {

    case 0:

        break;

    case 1:

        val |= 0x01; /* 1 drive, ready for boot */

        break;

    case 2:

        val |= 0x41; /* 2 drives, ready for boot */

        break;

    }

    val |= 0x02; /* FPU is there */

    val |= 0x04; /* PS/2 mouse installed */

    rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);

    /* hard drives */

    arg.rtc_state = s;

    arg.idebus0 = idebus0;

    arg.idebus1 = idebus1;

    qemu_register_reset(pc_cmos_init_late, &arg);

}


static uint32_t slow_bar_readw(void *opaque, target_phys_addr_t addr)

{

    AssignedDevRegion *d = opaque;

    uint16_t *in = (uint16_t *)(d->u.r_virtbase + addr);

    uint32_t r;

    r = *in;

    DEBUG("slow_bar_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r);

    return r;

}


static void simple_dict(void)

{

    int i;

    struct {

        const char *encoded;

        LiteralQObject decoded;

    } test_cases[] = {

        {

            .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}",

            .decoded = QLIT_QDICT(((LiteralQDictEntry[]){

                        { "foo", QLIT_QINT(42) },

                        { "bar", QLIT_QSTR("hello world") },

                        { }

                    })),

        }, {

            .encoded = "{}",

            .decoded = QLIT_QDICT(((LiteralQDictEntry[]){

                        { }

                    })),

        }, {

            .encoded = "{\"foo\": 43}",

            .decoded = QLIT_QDICT(((LiteralQDictEntry[]){

                        { "foo", QLIT_QINT(43) },

                        { }

                    })),

        },

        { }

    };

    for (i = 0; test_cases[i].encoded; i++) {

        QObject *obj;

        QString *str;

        obj = qobject_from_json(test_cases[i].encoded, NULL);

        g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);

        str = qobject_to_json(obj);

        qobject_decref(obj);

        obj = qobject_from_json(qstring_get_str(str), NULL);

        g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);

        qobject_decref(obj);

        QDECREF(str);

    }

}


static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type)

{

    int16_t *ip = input;

    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;

    int Ed, Gd, Add, Bdd, Fd, Hd;

    int i;

    /* Inverse DCT on the rows now */

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

        /* Check for non-zero values */

        if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {

            A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);

            B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);

            C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);

            D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);

            Ad = M(xC4S4, (A - C));

            Bd = M(xC4S4, (B - D));

            Cd = A + C;

            Dd = B + D;

            E = M(xC4S4, (ip[0] + ip[4]));

            F = M(xC4S4, (ip[0] - ip[4]));

            G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);

            H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);

            Ed = E - G;

            Gd = E + G;

            Add = F + Ad;

            Bdd = Bd - H;

            Fd = F - Ad;

            Hd = Bd + H;

            /*  Final sequence of operations over-write original inputs. */

            ip[0] = Gd + Cd ;

            ip[7] = Gd - Cd ;

            ip[1] = Add + Hd;

            ip[2] = Add - Hd;

            ip[3] = Ed + Dd ;

            ip[4] = Ed - Dd ;

            ip[5] = Fd + Bdd;

            ip[6] = Fd - Bdd;

        }

        ip += 8;            /* next row */

    }

    ip = input;

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

        /* Check for non-zero values (bitwise or faster than ||) */

        if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |

             ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {

            A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]);

            B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]);

            C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]);

            D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]);

            Ad = M(xC4S4, (A - C));

            Bd = M(xC4S4, (B - D));

            Cd = A + C;

            Dd = B + D;

            E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8;

            F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8;

            if(type==1){  //HACK

                E += 16*128;

                F += 16*128;

            }

            G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]);

            H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]);

            Ed = E - G;

            Gd = E + G;

            Add = F + Ad;

            Bdd = Bd - H;

            Fd = F - Ad;

            Hd = Bd + H;

            /* Final sequence of operations over-write original inputs. */

            if(type==0){

                ip[0*8] = (Gd + Cd )  >> 4;

                ip[7*8] = (Gd - Cd )  >> 4;

                ip[1*8] = (Add + Hd ) >> 4;

                ip[2*8] = (Add - Hd ) >> 4;

                ip[3*8] = (Ed + Dd )  >> 4;

                ip[4*8] = (Ed - Dd )  >> 4;

                ip[5*8] = (Fd + Bdd ) >> 4;

                ip[6*8] = (Fd - Bdd ) >> 4;

            }else if(type==1){

                dst[0*stride] = cm[(Gd + Cd )  >> 4];

                dst[7*stride] = cm[(Gd - Cd )  >> 4];

                dst[1*stride] = cm[(Add + Hd ) >> 4];

                dst[2*stride] = cm[(Add - Hd ) >> 4];

                dst[3*stride] = cm[(Ed + Dd )  >> 4];

                dst[4*stride] = cm[(Ed - Dd )  >> 4];

                dst[5*stride] = cm[(Fd + Bdd ) >> 4];

                dst[6*stride] = cm[(Fd - Bdd ) >> 4];

            }else{

                dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd )  >> 4)];

                dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd )  >> 4)];

                dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)];

                dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)];

                dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd )  >> 4)];

                dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd )  >> 4)];

                dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)];

                dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)];

            }

        } else {

            if(type==0){

                ip[0*8] =

                ip[1*8] =

                ip[2*8] =

                ip[3*8] =

                ip[4*8] =

                ip[5*8] =

                ip[6*8] =

                ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);

            }else if(type==1){

                dst[0*stride]=

                dst[1*stride]=

                dst[2*stride]=

                dst[3*stride]=

                dst[4*stride]=

                dst[5*stride]=

                dst[6*stride]=

                dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)];

            }else{

                if(ip[0*8]){

                    int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);

                    dst[0*stride] = cm[dst[0*stride] + v];

                    dst[1*stride] = cm[dst[1*stride] + v];

                    dst[2*stride] = cm[dst[2*stride] + v];

                    dst[3*stride] = cm[dst[3*stride] + v];

                    dst[4*stride] = cm[dst[4*stride] + v];

                    dst[5*stride] = cm[dst[5*stride] + v];

                    dst[6*stride] = cm[dst[6*stride] + v];

                    dst[7*stride] = cm[dst[7*stride] + v];

                }

            }

        }

        ip++;            /* next column */

        dst++;

    }

}


static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    const uint8_t *buf_end = avpkt->data + avpkt->size;
    int buf_size = avpkt->size;
    QdrawContext * const a = avctx->priv_data;
    AVFrame * const p= (AVFrame*)&a->pic;
    uint8_t* outdata;
    int colors;
    int i;
    uint32_t *pal;
    int r, g, b;
    if(p->data[0])
        avctx->release_buffer(avctx, p);
    p->reference= 0;
    if(avctx->get_buffer(avctx, p) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
    p->pict_type= AV_PICTURE_TYPE_I;
    p->key_frame= 1;
    outdata = a->pic.data[0];
    if (buf_end - buf < 0x68 + 4)
    buf += 0x68; /* jump to palette */
    colors = AV_RB32(buf);
    buf += 4;
    if(colors < 0 || colors > 256) {
        av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
        return -1;
    }
    if (buf_end - buf < (colors + 1) * 8)
    pal = (uint32_t*)p->data[1];
    for (i = 0; i <= colors; i++) {
        unsigned int idx;
        idx = AV_RB16(buf); /* color index */
        buf += 2;
        if (idx > 255) {
            av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx);
            buf += 6;
            continue;
        }
        r = *buf++;
        buf++;
        g = *buf++;
        buf++;
        b = *buf++;
        buf++;
        pal[idx] = (r << 16) | (g << 8) | b;
    }
    p->palette_has_changed = 1;
    if (buf_end - buf < 18)
    buf += 18; /* skip unneeded data */
    for (i = 0; i < avctx->height; i++) {
        int size, left, code, pix;
        const uint8_t *next;
        uint8_t *out;
        int tsize = 0;
        /* decode line */
        out = outdata;
        size = AV_RB16(buf); /* size of packed line */
        buf += 2;
        left = size;
        next = buf + size;
        while (left > 0) {
            code = *buf++;
            if (code & 0x80 ) { /* run */
                pix = *buf++;
                if ((out + (257 - code)) > (outdata +  a->pic.linesize[0]))
                    break;
                memset(out, pix, 257 - code);
                out += 257 - code;
                tsize += 257 - code;
                left -= 2;
            } else { /* copy */
                if ((out + code) > (outdata +  a->pic.linesize[0]))
                    break;
                if (buf_end - buf < code + 1)
                memcpy(out, buf, code + 1);
                out += code + 1;
                buf += code + 1;
                left -= 2 + code;
                tsize += code + 1;
            }
        }
        buf = next;
        outdata += a->pic.linesize[0];
    }
    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = a->pic;
    return buf_size;
}


static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,

                          const char *name, int restricted,

                          const char *vnetwork, const char *vhost,

                          const char *vhostname, const char *tftp_export,

                          const char *bootfile, const char *vdhcp_start,

                          const char *vnameserver, const char *smb_export,

                          const char *vsmbserver)

{

    /* default settings according to historic slirp */

    struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */

    struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */

    struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */

    struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */

    struct in_addr dns  = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */

#ifndef _WIN32

    struct in_addr smbsrv = { .s_addr = 0 };

#endif

    SlirpState *s;

    char buf[20];

    uint32_t addr;

    int shift;

    char *end;

    struct slirp_config_str *config;

    if (!tftp_export) {

        tftp_export = legacy_tftp_prefix;

    }

    if (!bootfile) {

        bootfile = legacy_bootp_filename;

    }

    if (vnetwork) {

        if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) {

            if (!inet_aton(vnetwork, &net)) {

                return -1;

            }

            addr = ntohl(net.s_addr);

            if (!(addr & 0x80000000)) {

                mask.s_addr = htonl(0xff000000); /* class A */

            } else if ((addr & 0xfff00000) == 0xac100000) {

                mask.s_addr = htonl(0xfff00000); /* priv. 172.16.0.0/12 */

            } else if ((addr & 0xc0000000) == 0x80000000) {

                mask.s_addr = htonl(0xffff0000); /* class B */

            } else if ((addr & 0xffff0000) == 0xc0a80000) {

                mask.s_addr = htonl(0xffff0000); /* priv. 192.168.0.0/16 */

            } else if ((addr & 0xffff0000) == 0xc6120000) {

                mask.s_addr = htonl(0xfffe0000); /* tests 198.18.0.0/15 */

            } else if ((addr & 0xe0000000) == 0xe0000000) {

                mask.s_addr = htonl(0xffffff00); /* class C */

            } else {

                mask.s_addr = htonl(0xfffffff0); /* multicast/reserved */

            }

        } else {

            if (!inet_aton(buf, &net)) {

                return -1;

            }

            shift = strtol(vnetwork, &end, 10);

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

                if (!inet_aton(vnetwork, &mask)) {

                    return -1;

                }

            } else if (shift < 4 || shift > 32) {

                return -1;

            } else {

                mask.s_addr = htonl(0xffffffff << (32 - shift));

            }

        }

        net.s_addr &= mask.s_addr;

        host.s_addr = net.s_addr | (htonl(0x0202) & ~mask.s_addr);

        dhcp.s_addr = net.s_addr | (htonl(0x020f) & ~mask.s_addr);

        dns.s_addr  = net.s_addr | (htonl(0x0203) & ~mask.s_addr);

    }

    if (vhost && !inet_aton(vhost, &host)) {

        return -1;

    }

    if ((host.s_addr & mask.s_addr) != net.s_addr) {

        return -1;

    }

    if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) {

        return -1;

    }

    if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||

        dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {

        return -1;

    }

    if (vnameserver && !inet_aton(vnameserver, &dns)) {

        return -1;

    }

    if ((dns.s_addr & mask.s_addr) != net.s_addr ||

        dns.s_addr == host.s_addr) {

        return -1;

    }

#ifndef _WIN32

    if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {

        return -1;

    }

#endif

    s = qemu_mallocz(sizeof(SlirpState));

    s->slirp = slirp_init(restricted, net, mask, host, vhostname,

                          tftp_export, bootfile, dhcp, dns, s);

    QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);

    for (config = slirp_configs; config; config = config->next) {

        if (config->flags & SLIRP_CFG_HOSTFWD) {

            slirp_hostfwd(s, mon, config->str,

                          config->flags & SLIRP_CFG_LEGACY);

        } else {

            slirp_guestfwd(s, mon, config->str,

                           config->flags & SLIRP_CFG_LEGACY);

        }

    }

#ifndef _WIN32

    if (!smb_export) {

        smb_export = legacy_smb_export;

    }

    if (smb_export) {

        slirp_smb(s, mon, smb_export, smbsrv);

    }

#endif

    s->vc = qemu_new_vlan_client(vlan, model, name, NULL, slirp_receive, NULL,

                                 net_slirp_cleanup, s);

    snprintf(s->vc->info_str, sizeof(s->vc->info_str),

             "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');

    return 0;

}


void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp)

{

    QIOChannel *ioc;

    const char *argv[] = { "/bin/sh", "-c", command, NULL };

    trace_migration_exec_outgoing(command);

    ioc = QIO_CHANNEL(qio_channel_command_new_spawn(argv,

                                                    O_WRONLY,

                                                    errp));

    if (!ioc) {

        return;

    }

    migration_set_outgoing_channel(s, ioc);

    object_unref(OBJECT(ioc));

}


static int nsv_probe(AVProbeData *p)

{

    int i;

    av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size);

    /* check file header */

    /* streamed files might not have any header */

    if (p->buf[0] == 'N' && p->buf[1] == 'S' &&

        p->buf[2] == 'V' && (p->buf[3] == 'f' || p->buf[3] == 's'))

        return AVPROBE_SCORE_MAX;

    /* XXX: do streamed files always start at chunk boundary ?? */

    /* or do we need to search NSVs in the byte stream ? */

    /* seems the servers don't bother starting clean chunks... */

    /* sometimes even the first header is at 9KB or something :^) */

    for (i = 1; i < p->buf_size - 3; i++) {

        if (p->buf[i+0] == 'N' && p->buf[i+1] == 'S' &&

            p->buf[i+2] == 'V' && p->buf[i+3] == 's')

            return AVPROBE_SCORE_MAX-20;

    }

    /* so we'll have more luck on extension... */

    if (av_match_ext(p->filename, "nsv"))

        return AVPROBE_SCORE_MAX/2;

    /* FIXME: add mime-type check */

    return 0;

}


static int nvdec_hevc_decode_init(AVCodecContext *avctx)

{

    const HEVCContext *s = avctx->priv_data;

    const HEVCSPS *sps = s->ps.sps;

    return ff_nvdec_decode_init(avctx, sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + 1);

}


qemu_irq sh7750_irl(SH7750State *s)

{

    sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */

    return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),

                               1)[0];

}


static uint64_t ivshmem_io_read(void *opaque, hwaddr addr,

                                unsigned size)

{

    IVShmemState *s = opaque;

    uint32_t ret;

    switch (addr)

    {

        case INTRMASK:

            ret = ivshmem_IntrMask_read(s);

            break;

        case INTRSTATUS:

            ret = ivshmem_IntrStatus_read(s);

            break;

        case IVPOSITION:

            /* return my VM ID if the memory is mapped */

            if (s->shm_fd >= 0) {

                ret = s->vm_id;

            } else {

                ret = -1;

            }

            break;

        default:

            IVSHMEM_DPRINTF("why are we reading " TARGET_FMT_plx "\n", addr);

            ret = 0;

    }

    return ret;

}


static void mcf_fec_enable_rx(mcf_fec_state *s)

{

    mcf_fec_bd bd;

    mcf_fec_read_bd(&bd, s->rx_descriptor);

    s->rx_enabled = ((bd.flags & FEC_BD_E) != 0);

    if (!s->rx_enabled)

        DPRINTF("RX buffer full\n");

}


void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id,

                      bool short_not_ok, bool int_req)

{

    assert(!usb_packet_is_inflight(p));

    assert(p->iov.iov != NULL);

    p->id = id;

    p->pid = pid;

    p->ep = ep;

    p->result = 0;

    p->parameter = 0;

    p->short_not_ok = short_not_ok;

    p->int_req = int_req;

    qemu_iovec_reset(&p->iov);

    usb_packet_set_state(p, USB_PACKET_SETUP);

}


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

{

    VirtIODevice *vdev = VIRTIO_DEVICE(dev);

    VirtIOSCSI *s = VIRTIO_SCSI(dev);

    static int virtio_scsi_id;

    Error *err = NULL;

    virtio_scsi_common_realize(dev, &err);

    if (err != NULL) {

        error_propagate(errp, err);

        return;

    }

    scsi_bus_new(&s->bus, sizeof(s->bus), dev,

                 &virtio_scsi_scsi_info, vdev->bus_name);

    if (!dev->hotplugged) {

        scsi_bus_legacy_handle_cmdline(&s->bus, &err);

        if (err != NULL) {

            error_propagate(errp, err);

            return;

        }

    }

    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,

                    virtio_scsi_save, virtio_scsi_load, s);

}


void qemu_mutex_lock(QemuMutex *mutex)

{

    EnterCriticalSection(&mutex->lock);

    /* Win32 CRITICAL_SECTIONs are recursive.  Assert that we're not

     * using them as such.

     */

    assert(mutex->owner == 0);

    mutex->owner = GetCurrentThreadId();

}


void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)

{

    /* We're passed bits [11..0] of the instruction; extract

     * SYSm and the mask bits.

     * Invalid combinations of SYSm and mask are UNPREDICTABLE;

     * we choose to treat them as if the mask bits were valid.

     * NB that the pseudocode 'mask' variable is bits [11..10],

     * whereas ours is [11..8].

     */

    uint32_t mask = extract32(maskreg, 8, 4);

    uint32_t reg = extract32(maskreg, 0, 8);

    if (arm_current_el(env) == 0 && reg > 7) {

        /* only xPSR sub-fields may be written by unprivileged */

        return;

    }

    switch (reg) {

    case 0 ... 7: /* xPSR sub-fields */

        /* only APSR is actually writable */

        if (!(reg & 4)) {

            uint32_t apsrmask = 0;

            if (mask & 8) {

                apsrmask |= 0xf8000000; /* APSR NZCVQ */

            }

            if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) {

                apsrmask |= 0x000f0000; /* APSR GE[3:0] */

            }

            xpsr_write(env, val, apsrmask);

        }

        break;

    case 8: /* MSP */

        if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {

            env->v7m.other_sp = val;

        } else {

            env->regs[13] = val;

        }

        break;

    case 9: /* PSP */

        if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {

            env->regs[13] = val;

        } else {

            env->v7m.other_sp = val;

        }

        break;

    case 16: /* PRIMASK */

        if (val & 1) {

            env->daif |= PSTATE_I;

        } else {

            env->daif &= ~PSTATE_I;

        }

        break;

    case 17: /* BASEPRI */

        env->v7m.basepri = val & 0xff;

        break;

    case 18: /* BASEPRI_MAX */

        val &= 0xff;

        if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))

            env->v7m.basepri = val;

        break;

    case 19: /* FAULTMASK */

        if (val & 1) {

            env->daif |= PSTATE_F;

        } else {

            env->daif &= ~PSTATE_F;

        }

        break;

    case 20: /* CONTROL */

        switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);

        env->v7m.control = val & (R_V7M_CONTROL_SPSEL_MASK |

                                  R_V7M_CONTROL_NPRIV_MASK);

        break;

    default:

        qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"

                                       " register %d\n", reg);

        return;

    }

}


static int parse_h264_sdp_line(AVFormatContext *s, int st_index,

                               PayloadContext *h264_data, const char *line)

{

    AVStream *stream;

    AVCodecContext *codec;

    const char *p = line;

    if (st_index < 0)

        return 0;

    stream = s->streams[st_index];

    codec = stream->codec;

    assert(h264_data->cookie == MAGIC_COOKIE);

    if (av_strstart(p, "framesize:", &p)) {

        char buf1[50];

        char *dst = buf1;

        // remove the protocol identifier..

        while (*p && *p == ' ') p++; // strip spaces.

        while (*p && *p != ' ') p++; // eat protocol identifier

        while (*p && *p == ' ') p++; // strip trailing spaces.

        while (*p && *p != '-' && (dst - buf1) < sizeof(buf1) - 1) {

            *dst++ = *p++;

        }

        *dst = '\0';

        // a='framesize:96 320-240'

        // set our parameters..

        codec->width = atoi(buf1);

        codec->height = atoi(p + 1); // skip the -

        codec->pix_fmt = PIX_FMT_YUV420P;

    } else if (av_strstart(p, "fmtp:", &p)) {

        return ff_parse_fmtp(stream, h264_data, p, sdp_parse_fmtp_config_h264);

    } else if (av_strstart(p, "cliprect:", &p)) {

        // could use this if we wanted.

    }

    return 0;                   // keep processing it the normal way...

}


PPC_OP(icbi)

{

    do_icbi();

    RETURN();

}


void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){

    idct(dest, line_size, block, 1);

}


static bool is_iso_bc_entry_compatible(IsoBcSection *s)

{

    return true;

}


int64_t bdrv_get_block_status(BlockDriverState *bs,

                              int64_t sector_num,

                              int nb_sectors, int *pnum)

{

    return bdrv_get_block_status_above(bs, backing_bs(bs),

                                       sector_num, nb_sectors, pnum);

}


static inline void gen_op_eval_fbe(TCGv dst, TCGv src,

                                    unsigned int fcc_offset)

{

    gen_mov_reg_FCC0(dst, src, fcc_offset);

    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);

    tcg_gen_or_tl(dst, dst, cpu_tmp0);

    tcg_gen_xori_tl(dst, dst, 0x1);

}


static int blk_free(struct XenDevice *xendev)

{

    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    struct ioreq *ioreq;

    while (!LIST_EMPTY(&blkdev->freelist)) {

	ioreq = LIST_FIRST(&blkdev->freelist);

        LIST_REMOVE(ioreq, list);

        qemu_iovec_destroy(&ioreq->v);

	qemu_free(ioreq);

    }

    qemu_free(blkdev->params);

    qemu_free(blkdev->mode);

    qemu_free(blkdev->type);

    qemu_free(blkdev->dev);

    qemu_free(blkdev->devtype);

    qemu_bh_delete(blkdev->bh);

    return 0;

}


static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)

{

    IDEState *ide_if = opaque;

    IDEState *s = ide_if->cur_drive;

    uint32_t addr;

    int ret, hob;

    addr = addr1 & 7;

    /* FIXME: HOB readback uses bit 7, but it's always set right now */

    //hob = s->select & (1 << 7);

    hob = 0;

    switch(addr) {

    case 0:

        ret = 0xff;

        break;

    case 1:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->error;

	else

	    ret = s->hob_feature;

        break;

    case 2:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->nsector & 0xff;

	else

	    ret = s->hob_nsector;

        break;

    case 3:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->sector;

	else

	    ret = s->hob_sector;

        break;

    case 4:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->lcyl;

	else

	    ret = s->hob_lcyl;

        break;

    case 5:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->hcyl;

	else

	    ret = s->hob_hcyl;

        break;

    case 6:

        if (!ide_if[0].bs && !ide_if[1].bs)

            ret = 0;

        else

            ret = s->select;

        break;

    default:

    case 7:

        if ((!ide_if[0].bs && !ide_if[1].bs) ||

            (s != ide_if && !s->bs))

            ret = 0;

        else

            ret = s->status;

        qemu_irq_lower(s->irq);

        break;

    }

#ifdef DEBUG_IDE

    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);

#endif

    return ret;

}


void qmp_block_dirty_bitmap_add(const char *node, const char *name,

                                bool has_granularity, uint32_t granularity,

                                Error **errp)

{

    AioContext *aio_context;

    BlockDriverState *bs;

    if (!name || name[0] == '\0') {

        error_setg(errp, "Bitmap name cannot be empty");

        return;

    }

    bs = bdrv_lookup_bs(node, node, errp);

    if (!bs) {

        return;

    }

    aio_context = bdrv_get_aio_context(bs);

    aio_context_acquire(aio_context);

    if (has_granularity) {

        if (granularity < 512 || !is_power_of_2(granularity)) {

            error_setg(errp, "Granularity must be power of 2 "

                             "and at least 512");

            goto out;

        }

    } else {

        /* Default to cluster size, if available: */

        granularity = bdrv_get_default_bitmap_granularity(bs);

    }

    bdrv_create_dirty_bitmap(bs, granularity, name, errp);

 out:

    aio_context_release(aio_context);

}


static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp)

{

    uint16_t nodenr;

    uint16List *cpus = NULL;

    if (node->has_nodeid) {

        nodenr = node->nodeid;

    } else {

        nodenr = nb_numa_nodes;

    }

    if (nodenr >= MAX_NODES) {

        error_setg(errp, "Max number of NUMA nodes reached: %"

                   PRIu16 "", nodenr);

        return;

    }

    if (numa_info[nodenr].present) {

        error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr);

        return;

    }

    for (cpus = node->cpus; cpus; cpus = cpus->next) {

        if (cpus->value >= MAX_CPUMASK_BITS) {

            error_setg(errp, "CPU number %" PRIu16 " is bigger than %d",

                       cpus->value, MAX_CPUMASK_BITS - 1);

            return;

        }

        bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);

    }

    if (node->has_mem && node->has_memdev) {

        error_setg(errp, "qemu: cannot specify both mem= and memdev=");

        return;

    }

    if (have_memdevs == -1) {

        have_memdevs = node->has_memdev;

    }

    if (node->has_memdev != have_memdevs) {

        error_setg(errp, "qemu: memdev option must be specified for either "

                   "all or no nodes");

        return;

    }

    if (node->has_mem) {

        uint64_t mem_size = node->mem;

        const char *mem_str = qemu_opt_get(opts, "mem");

        /* Fix up legacy suffix-less format */

        if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {

            mem_size <<= 20;

        }

        numa_info[nodenr].node_mem = mem_size;

    }

    if (node->has_memdev) {

        Object *o;

        o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);

        if (!o) {

            error_setg(errp, "memdev=%s is ambiguous", node->memdev);

            return;

        }

        object_ref(o);

        numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);

        numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);

    }

    numa_info[nodenr].present = true;

    max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);

}


static int create_filtergraph(AVFilterContext *ctx,

                              const AVFrame *in, const AVFrame *out)

{

    ColorSpaceContext *s = ctx->priv;

    const AVPixFmtDescriptor *in_desc  = av_pix_fmt_desc_get(in->format);

    const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(out->format);

    int emms = 0, m, n, o, res, fmt_identical, redo_yuv2rgb = 0, redo_rgb2yuv = 0;

#define supported_depth(d) ((d) == 8 || (d) == 10 || (d) == 12)

#define supported_subsampling(lcw, lch) \

    (((lcw) == 0 && (lch) == 0) || ((lcw) == 1 && (lch) == 0) || ((lcw) == 1 && (lch) == 1))

#define supported_format(d) \

    ((d) != NULL && (d)->nb_components == 3 && \

     !((d)->flags & AV_PIX_FMT_FLAG_RGB) && \

     supported_depth((d)->comp[0].depth) && \

     supported_subsampling((d)->log2_chroma_w, (d)->log2_chroma_h))

    if (!supported_format(in_desc)) {

        av_log(ctx, AV_LOG_ERROR,

               "Unsupported input format %d (%s) or bitdepth (%d)\n",

               in->format, av_get_pix_fmt_name(in->format),

               in_desc ? in_desc->comp[0].depth : -1);

        return AVERROR(EINVAL);

    }

    if (!supported_format(out_desc)) {

        av_log(ctx, AV_LOG_ERROR,

               "Unsupported output format %d (%s) or bitdepth (%d)\n",

               out->format, av_get_pix_fmt_name(out->format),

               out_desc ? out_desc->comp[0].depth : -1);

        return AVERROR(EINVAL);

    }

    if (in->color_primaries  != s->in_prm)  s->in_primaries  = NULL;

    if (out->color_primaries != s->out_prm) s->out_primaries = NULL;

    if (in->color_trc        != s->in_trc)  s->in_txchr      = NULL;

    if (out->color_trc       != s->out_trc) s->out_txchr     = NULL;

    if (in->colorspace       != s->in_csp ||

        in->color_range      != s->in_rng)  s->in_lumacoef   = NULL;

    if (out->colorspace      != s->out_csp ||

        out->color_range     != s->out_rng) s->out_lumacoef  = NULL;

    if (!s->out_primaries || !s->in_primaries) {

        s->in_prm = in->color_primaries;

        if (s->user_iall != CS_UNSPECIFIED)

            s->in_prm = default_prm[FFMIN(s->user_iall, CS_NB)];

        if (s->user_iprm != AVCOL_PRI_UNSPECIFIED)

            s->in_prm = s->user_iprm;

        s->in_primaries = get_color_primaries(s->in_prm);

        if (!s->in_primaries) {

            av_log(ctx, AV_LOG_ERROR,

                   "Unsupported input primaries %d (%s)\n",

                   s->in_prm, av_color_primaries_name(s->in_prm));

            return AVERROR(EINVAL);

        }

        s->out_prm = out->color_primaries;

        s->out_primaries = get_color_primaries(s->out_prm);

        if (!s->out_primaries) {

            if (s->out_prm == AVCOL_PRI_UNSPECIFIED) {

                if (s->user_all == CS_UNSPECIFIED) {

                    av_log(ctx, AV_LOG_ERROR, "Please specify output primaries\n");

                } else {

                    av_log(ctx, AV_LOG_ERROR,

                           "Unsupported output color property %d\n", s->user_all);

                }

            } else {

                av_log(ctx, AV_LOG_ERROR,

                       "Unsupported output primaries %d (%s)\n",

                       s->out_prm, av_color_primaries_name(s->out_prm));

            }

            return AVERROR(EINVAL);

        }

        s->lrgb2lrgb_passthrough = !memcmp(s->in_primaries, s->out_primaries,

                                           sizeof(*s->in_primaries));

        if (!s->lrgb2lrgb_passthrough) {

            double rgb2xyz[3][3], xyz2rgb[3][3], rgb2rgb[3][3];

            fill_rgb2xyz_table(s->out_primaries, rgb2xyz);

            invert_matrix3x3(rgb2xyz, xyz2rgb);

            fill_rgb2xyz_table(s->in_primaries, rgb2xyz);

            if (s->out_primaries->wp != s->in_primaries->wp &&

                s->wp_adapt != WP_ADAPT_IDENTITY) {

                double wpconv[3][3], tmp[3][3];

                fill_whitepoint_conv_table(wpconv, s->wp_adapt, s->in_primaries->wp,

                                           s->out_primaries->wp);

                mul3x3(tmp, rgb2xyz, wpconv);

                mul3x3(rgb2rgb, tmp, xyz2rgb);

            } else {

                mul3x3(rgb2rgb, rgb2xyz, xyz2rgb);

            }

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

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

                    s->lrgb2lrgb_coeffs[m][n][0] = lrint(16384.0 * rgb2rgb[m][n]);

                    for (o = 1; o < 8; o++)

                        s->lrgb2lrgb_coeffs[m][n][o] = s->lrgb2lrgb_coeffs[m][n][0];

                }

            emms = 1;

        }

    }

    if (!s->in_txchr) {

        av_freep(&s->lin_lut);

        s->in_trc = in->color_trc;

        if (s->user_iall != CS_UNSPECIFIED)

            s->in_trc = default_trc[FFMIN(s->user_iall, CS_NB)];

        if (s->user_itrc != AVCOL_TRC_UNSPECIFIED)

            s->in_trc = s->user_itrc;

        s->in_txchr = get_transfer_characteristics(s->in_trc);

        if (!s->in_txchr) {

            av_log(ctx, AV_LOG_ERROR,

                   "Unsupported input transfer characteristics %d (%s)\n",

                   s->in_trc, av_color_transfer_name(s->in_trc));

            return AVERROR(EINVAL);

        }

    }

    if (!s->out_txchr) {

        av_freep(&s->lin_lut);

        s->out_trc = out->color_trc;

        s->out_txchr = get_transfer_characteristics(s->out_trc);

        if (!s->out_txchr) {

            if (s->out_trc == AVCOL_TRC_UNSPECIFIED) {

                if (s->user_all == CS_UNSPECIFIED) {

                    av_log(ctx, AV_LOG_ERROR,

                           "Please specify output transfer characteristics\n");

                } else {

                    av_log(ctx, AV_LOG_ERROR,

                           "Unsupported output color property %d\n", s->user_all);

                }

            } else {

                av_log(ctx, AV_LOG_ERROR,

                       "Unsupported output transfer characteristics %d (%s)\n",

                       s->out_trc, av_color_transfer_name(s->out_trc));

            }

            return AVERROR(EINVAL);

        }

    }

    s->rgb2rgb_passthrough = s->fast_mode || (s->lrgb2lrgb_passthrough &&

                             !memcmp(s->in_txchr, s->out_txchr, sizeof(*s->in_txchr)));

    if (!s->rgb2rgb_passthrough && !s->lin_lut) {

        res = fill_gamma_table(s);

        if (res < 0)

            return res;

        emms = 1;

    }

    if (!s->in_lumacoef) {

        s->in_csp = in->colorspace;

        if (s->user_iall != CS_UNSPECIFIED)

            s->in_csp = default_csp[FFMIN(s->user_iall, CS_NB)];

        if (s->user_icsp != AVCOL_SPC_UNSPECIFIED)

            s->in_csp = s->user_icsp;

        s->in_rng = in->color_range;

        if (s->user_irng != AVCOL_RANGE_UNSPECIFIED)

            s->in_rng = s->user_irng;

        s->in_lumacoef = get_luma_coefficients(s->in_csp);

        if (!s->in_lumacoef) {

            av_log(ctx, AV_LOG_ERROR,

                   "Unsupported input colorspace %d (%s)\n",

                   s->in_csp, av_color_space_name(s->in_csp));

            return AVERROR(EINVAL);

        }

        redo_yuv2rgb = 1;

    }

    if (!s->out_lumacoef) {

        s->out_csp = out->colorspace;

        s->out_rng = out->color_range;

        s->out_lumacoef = get_luma_coefficients(s->out_csp);

        if (!s->out_lumacoef) {

            if (s->out_csp == AVCOL_SPC_UNSPECIFIED) {

                if (s->user_all == CS_UNSPECIFIED) {

                    av_log(ctx, AV_LOG_ERROR,

                           "Please specify output transfer characteristics\n");

                } else {

                    av_log(ctx, AV_LOG_ERROR,

                           "Unsupported output color property %d\n", s->user_all);

                }

            } else {

                av_log(ctx, AV_LOG_ERROR,

                       "Unsupported output transfer characteristics %d (%s)\n",

                       s->out_csp, av_color_space_name(s->out_csp));

            }

            return AVERROR(EINVAL);

        }

        redo_rgb2yuv = 1;

    }

    fmt_identical = in_desc->log2_chroma_h == out_desc->log2_chroma_h &&

                    in_desc->log2_chroma_w == out_desc->log2_chroma_w;

    s->yuv2yuv_fastmode = s->rgb2rgb_passthrough && fmt_identical;

    s->yuv2yuv_passthrough = s->yuv2yuv_fastmode && s->in_rng == s->out_rng &&

                             !memcmp(s->in_lumacoef, s->out_lumacoef,

                                     sizeof(*s->in_lumacoef)) &&

                             in_desc->comp[0].depth == out_desc->comp[0].depth;

    if (!s->yuv2yuv_passthrough) {

        if (redo_yuv2rgb) {

            double rgb2yuv[3][3], (*yuv2rgb)[3] = s->yuv2rgb_dbl_coeffs;

            int off, bits, in_rng;

            res = get_range_off(&off, &s->in_y_rng, &s->in_uv_rng,

                                s->in_rng, in_desc->comp[0].depth);

            if (res < 0) {

                av_log(ctx, AV_LOG_ERROR,

                       "Unsupported input color range %d (%s)\n",

                       s->in_rng, av_color_range_name(s->in_rng));

                return res;

            }

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

                s->yuv_offset[0][n] = off;

            fill_rgb2yuv_table(s->in_lumacoef, rgb2yuv);

            invert_matrix3x3(rgb2yuv, yuv2rgb);

            bits = 1 << (in_desc->comp[0].depth - 1);

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

                for (in_rng = s->in_y_rng, m = 0; m < 3; m++, in_rng = s->in_uv_rng) {

                    s->yuv2rgb_coeffs[n][m][0] = lrint(28672 * bits * yuv2rgb[n][m] / in_rng);

                    for (o = 1; o < 8; o++)

                        s->yuv2rgb_coeffs[n][m][o] = s->yuv2rgb_coeffs[n][m][0];

                }

            }

            av_assert2(s->yuv2rgb_coeffs[0][1][0] == 0);

            av_assert2(s->yuv2rgb_coeffs[2][2][0] == 0);

            av_assert2(s->yuv2rgb_coeffs[0][0][0] == s->yuv2rgb_coeffs[1][0][0]);

            av_assert2(s->yuv2rgb_coeffs[0][0][0] == s->yuv2rgb_coeffs[2][0][0]);

            s->yuv2rgb = s->dsp.yuv2rgb[(in_desc->comp[0].depth - 8) >> 1]

                                       [in_desc->log2_chroma_h + in_desc->log2_chroma_w];

            emms = 1;

        }

        if (redo_rgb2yuv) {

            double (*rgb2yuv)[3] = s->rgb2yuv_dbl_coeffs;

            int off, out_rng, bits;

            res = get_range_off(&off, &s->out_y_rng, &s->out_uv_rng,

                                s->out_rng, out_desc->comp[0].depth);

            if (res < 0) {

                av_log(ctx, AV_LOG_ERROR,

                       "Unsupported output color range %d (%s)\n",

                       s->out_rng, av_color_range_name(s->out_rng));

                return res;

            }

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

                s->yuv_offset[1][n] = off;

            fill_rgb2yuv_table(s->out_lumacoef, rgb2yuv);

            bits = 1 << (29 - out_desc->comp[0].depth);

            for (out_rng = s->out_y_rng, n = 0; n < 3; n++, out_rng = s->out_uv_rng) {

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

                    s->rgb2yuv_coeffs[n][m][0] = lrint(bits * out_rng * rgb2yuv[n][m] / 28672);

                    for (o = 1; o < 8; o++)

                        s->rgb2yuv_coeffs[n][m][o] = s->rgb2yuv_coeffs[n][m][0];

                }

            }

            av_assert2(s->rgb2yuv_coeffs[1][2][0] == s->rgb2yuv_coeffs[2][0][0]);

            s->rgb2yuv = s->dsp.rgb2yuv[(out_desc->comp[0].depth - 8) >> 1]

                                       [out_desc->log2_chroma_h + out_desc->log2_chroma_w];

            s->rgb2yuv_fsb = s->dsp.rgb2yuv_fsb[(out_desc->comp[0].depth - 8) >> 1]

                                       [out_desc->log2_chroma_h + out_desc->log2_chroma_w];

            emms = 1;

        }

        if (s->yuv2yuv_fastmode && (redo_yuv2rgb || redo_rgb2yuv)) {

            int idepth = in_desc->comp[0].depth, odepth = out_desc->comp[0].depth;

            double (*rgb2yuv)[3] = s->rgb2yuv_dbl_coeffs;

            double (*yuv2rgb)[3] = s->yuv2rgb_dbl_coeffs;

            double yuv2yuv[3][3];

            int in_rng, out_rng;

            mul3x3(yuv2yuv, yuv2rgb, rgb2yuv);

            for (out_rng = s->out_y_rng, m = 0; m < 3; m++, out_rng = s->out_uv_rng) {

                for (in_rng = s->in_y_rng, n = 0; n < 3; n++, in_rng = s->in_uv_rng) {

                    s->yuv2yuv_coeffs[m][n][0] =

                        lrint(16384 * yuv2yuv[m][n] * out_rng * (1 << idepth) /

                              (in_rng * (1 << odepth)));

                    for (o = 1; o < 8; o++)

                        s->yuv2yuv_coeffs[m][n][o] = s->yuv2yuv_coeffs[m][n][0];

                }

            }

            av_assert2(s->yuv2yuv_coeffs[1][0][0] == 0);

            av_assert2(s->yuv2yuv_coeffs[2][0][0] == 0);

            s->yuv2yuv = s->dsp.yuv2yuv[(idepth - 8) >> 1][(odepth - 8) >> 1]

                                       [in_desc->log2_chroma_h + in_desc->log2_chroma_w];

        }

    }

    if (emms)

        emms_c();

    return 0;

}


static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)

{

    StreamBlockJob *s = container_of(job, StreamBlockJob, common);

    if (speed < 0) {

        error_set(errp, QERR_INVALID_PARAMETER, "speed");

        return;

    }

    ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE);

}


static Rom *find_rom(target_phys_addr_t addr)

{

    Rom *rom;

    QTAILQ_FOREACH(rom, &roms, next) {

        if (rom->fw_file) {

            continue;

        }

        if (rom->addr > addr) {

            continue;

        }

        if (rom->addr + rom->romsize < addr) {

            continue;

        }

        return rom;

    }

    return NULL;

}


iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,

                QEMUIOVector *qiov, int nb_sectors,

                BlockDriverCompletionFunc *cb,

                void *opaque)

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = iscsilun->iscsi;

    IscsiAIOCB *acb;

    size_t qemu_read_size;

#if !defined(LIBISCSI_FEATURE_IOVECTOR)

    int i;

#endif

    int ret;

    uint64_t lba;

    uint32_t num_sectors;

    qemu_read_size = BDRV_SECTOR_SIZE * (size_t)nb_sectors;

    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);

    trace_iscsi_aio_readv(iscsi, sector_num, nb_sectors, opaque, acb);

    acb->iscsilun = iscsilun;

    acb->qiov     = qiov;

    acb->canceled    = 0;

    acb->bh          = NULL;

    acb->status      = -EINPROGRESS;

    acb->read_size   = qemu_read_size;

    acb->buf         = NULL;

    /* If LUN blocksize is bigger than BDRV_BLOCK_SIZE a read from QEMU

     * may be misaligned to the LUN, so we may need to read some extra

     * data.

     */

    acb->read_offset = 0;

    if (iscsilun->block_size > BDRV_SECTOR_SIZE) {

        uint64_t bdrv_offset = BDRV_SECTOR_SIZE * sector_num;

        acb->read_offset  = bdrv_offset % iscsilun->block_size;

    }

    num_sectors  = (qemu_read_size + iscsilun->block_size

                    + acb->read_offset - 1)

                    / iscsilun->block_size;

    acb->task = malloc(sizeof(struct scsi_task));

    if (acb->task == NULL) {

        error_report("iSCSI: Failed to allocate task for scsi READ16 "

                     "command. %s", iscsi_get_error(iscsi));

        qemu_aio_release(acb);

        return NULL;

    }

    memset(acb->task, 0, sizeof(struct scsi_task));

    acb->task->xfer_dir = SCSI_XFER_READ;

    lba = sector_qemu2lun(sector_num, iscsilun);

    acb->task->expxferlen = qemu_read_size;

    switch (iscsilun->type) {

    case TYPE_DISK:

        acb->task->cdb_size = 16;

        acb->task->cdb[0]  = 0x88;

        *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);

        *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);

        *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);

        break;

    default:

        acb->task->cdb_size = 10;

        acb->task->cdb[0]  = 0x28;

        *(uint32_t *)&acb->task->cdb[2] = htonl(lba);

        *(uint16_t *)&acb->task->cdb[7] = htons(num_sectors);

        break;

    }

    ret = iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,

                                   iscsi_aio_read16_cb,

                                   NULL,

                                   acb);

    if (ret != 0) {

        scsi_free_scsi_task(acb->task);

        qemu_aio_release(acb);

        return NULL;

    }

#if defined(LIBISCSI_FEATURE_IOVECTOR)

    scsi_task_set_iov_in(acb->task, (struct scsi_iovec*) acb->qiov->iov, acb->qiov->niov);

#else

    for (i = 0; i < acb->qiov->niov; i++) {

        scsi_task_add_data_in_buffer(acb->task,

                acb->qiov->iov[i].iov_len,

                acb->qiov->iov[i].iov_base);

    }

#endif

    iscsi_set_events(iscsilun);

    return &acb->common;

}


static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,

                           int count, int copy)

{

    struct target_iovec *target_vec;

    abi_ulong base;

    int i;

    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);

    if (!target_vec)

        return -TARGET_EFAULT;

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

        base = tswapal(target_vec[i].iov_base);

        vec[i].iov_len = tswapal(target_vec[i].iov_len);

        if (vec[i].iov_len != 0) {

            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);

            /* Don't check lock_user return value. We must call writev even

               if a element has invalid base address. */

        } else {

            /* zero length pointer is ignored */

            vec[i].iov_base = NULL;

        }

    }

    unlock_user (target_vec, target_addr, 0);

    return 0;

}


S390PCIBusDevice *s390_pci_find_next_avail_dev(S390PCIBusDevice *pbdev)

{

    int idx = 0;

    S390PCIBusDevice *dev = NULL;

    S390pciState *s = s390_get_phb();

    if (pbdev) {

        idx = (pbdev->fh & FH_MASK_INDEX) + 1;

    }

    for (; idx < PCI_SLOT_MAX; idx++) {

        dev = s->pbdev[idx];

        if (dev && dev->state != ZPCI_FS_RESERVED) {

            return dev;

        }

    }

    return NULL;

}


static void fw_cfg_ctl_mem_write(void *opaque, target_phys_addr_t addr,

                                 uint64_t value, unsigned size)

{

    fw_cfg_select(opaque, (uint16_t)value);

}


static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,

                                                     int64_t sector_num,

                                                     int nb_sectors, int *pnum,

                                                     BlockDriverState **file)

{

    int64_t total_sectors;

    int64_t n;

    int64_t ret, ret2;

    *file = NULL;

    total_sectors = bdrv_nb_sectors(bs);

    if (total_sectors < 0) {

        return total_sectors;

    }

    if (sector_num >= total_sectors) {

        *pnum = 0;

        return BDRV_BLOCK_EOF;

    }

    if (!nb_sectors) {

        *pnum = 0;

        return 0;

    }

    n = total_sectors - sector_num;

    if (n < nb_sectors) {

        nb_sectors = n;

    }

    if (!bs->drv->bdrv_co_get_block_status) {

        *pnum = nb_sectors;

        ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;

        if (sector_num + nb_sectors == total_sectors) {

            ret |= BDRV_BLOCK_EOF;

        }

        if (bs->drv->protocol_name) {

            ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);

            *file = bs;

        }

        return ret;

    }

    bdrv_inc_in_flight(bs);

    ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,

                                            file);

    if (ret < 0) {

        *pnum = 0;

        goto out;

    }

    if (ret & BDRV_BLOCK_RAW) {

        assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);

        ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,

                                       *pnum, pnum, file);

        goto out;

    }

    if (ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ZERO)) {

        ret |= BDRV_BLOCK_ALLOCATED;

    } else {

        if (bdrv_unallocated_blocks_are_zero(bs)) {

            ret |= BDRV_BLOCK_ZERO;

        } else if (bs->backing) {

            BlockDriverState *bs2 = bs->backing->bs;

            int64_t nb_sectors2 = bdrv_nb_sectors(bs2);

            if (nb_sectors2 >= 0 && sector_num >= nb_sectors2) {

                ret |= BDRV_BLOCK_ZERO;

            }

        }

    }

    if (*file && *file != bs &&

        (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&

        (ret & BDRV_BLOCK_OFFSET_VALID)) {

        BlockDriverState *file2;

        int file_pnum;

        ret2 = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,

                                        *pnum, &file_pnum, &file2);

        if (ret2 >= 0) {

            /* Ignore errors.  This is just providing extra information, it

             * is useful but not necessary.

             */

            if (ret2 & BDRV_BLOCK_EOF &&

                (!file_pnum || ret2 & BDRV_BLOCK_ZERO)) {

                /*

                 * It is valid for the format block driver to read

                 * beyond the end of the underlying file's current

                 * size; such areas read as zero.

                 */

                ret |= BDRV_BLOCK_ZERO;

            } else {

                /* Limit request to the range reported by the protocol driver */

                *pnum = file_pnum;

                ret |= (ret2 & BDRV_BLOCK_ZERO);

            }

        }

    }

out:

    bdrv_dec_in_flight(bs);

    if (ret >= 0 && sector_num + *pnum == total_sectors) {

        ret |= BDRV_BLOCK_EOF;

    }

    return ret;

}


static int dmg_read(BlockDriverState *bs, int64_t sector_num,

                    uint8_t *buf, int nb_sectors)

{

    BDRVDMGState *s = bs->opaque;

    int i;

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

	uint32_t sector_offset_in_chunk;

	if(dmg_read_chunk(bs, sector_num+i) != 0)

	    return -1;

	sector_offset_in_chunk = sector_num+i-s->sectors[s->current_chunk];

	memcpy(buf+i*512,s->uncompressed_chunk+sector_offset_in_chunk*512,512);

    }

    return 0;

}


static int nbd_can_read(void *opaque)

{

    NBDClient *client = opaque;

    return client->recv_coroutine || client->nb_requests < MAX_NBD_REQUESTS;

}


int avpriv_dca_parse_core_frame_header(DCACoreFrameHeader *h, const uint8_t *buf, int size)

{

    GetBitContext gb;

    if (init_get_bits8(&gb, buf, size) < 0)

        return DCA_PARSE_ERROR_INVALIDDATA;

    return ff_dca_parse_core_frame_header(h, &gb);

}


static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,

                          MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    unsigned int i;

    void *iommu, *espdma, *ledma, *nvram;

    qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],

        espdma_irq, ledma_irq;

    qemu_irq esp_reset, dma_enable;

    qemu_irq fdc_tc;

    qemu_irq *cpu_halt;

    unsigned long kernel_size;

    DriveInfo *fd[MAX_FD];

    FWCfgState *fw_cfg;

    unsigned int num_vsimms;

    /* init CPUs */

    if (!cpu_model)

        cpu_model = hwdef->default_cpu_model;

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

        cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);

    }

    for (i = smp_cpus; i < MAX_CPUS; i++)

        cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);

    /* set up devices */

    ram_init(0, machine->ram_size, hwdef->max_mem);

    /* models without ECC don't trap when missing ram is accessed */

    if (!hwdef->ecc_base) {

        empty_slot_init(machine->ram_size, hwdef->max_mem - machine->ram_size);

    }

    prom_init(hwdef->slavio_base, bios_name);

    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,

                                       hwdef->intctl_base + 0x10000ULL,

                                       cpu_irqs);

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

        slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i);

    }

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

        slavio_cpu_irq[i] = qdev_get_gpio_in(slavio_intctl, 32 + i);

    }

    if (hwdef->idreg_base) {

        idreg_init(hwdef->idreg_base);

    }

    if (hwdef->afx_base) {

        afx_init(hwdef->afx_base);

    }

    iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,

                       slavio_irq[30]);

    if (hwdef->iommu_pad_base) {

        /* On the real hardware (SS-5, LX) the MMU is not padded, but aliased.

           Software shouldn't use aliased addresses, neither should it crash

           when does. Using empty_slot instead of aliasing can help with

           debugging such accesses */

        empty_slot_init(hwdef->iommu_pad_base,hwdef->iommu_pad_len);

    }

    espdma = sparc32_dma_init(hwdef->dma_base, slavio_irq[18],

                              iommu, &espdma_irq, 0);

    ledma = sparc32_dma_init(hwdef->dma_base + 16ULL,

                             slavio_irq[16], iommu, &ledma_irq, 1);

    if (graphic_depth != 8 && graphic_depth != 24) {

        error_report("Unsupported depth: %d", graphic_depth);

        exit (1);

    }

    num_vsimms = 0;

    if (num_vsimms == 0) {

        if (vga_interface_type == VGA_CG3) {

            if (graphic_depth != 8) {

                error_report("Unsupported depth: %d", graphic_depth);

                exit(1);

            }

            if (!(graphic_width == 1024 && graphic_height == 768) &&

                !(graphic_width == 1152 && graphic_height == 900)) {

                error_report("Unsupported resolution: %d x %d", graphic_width,

                             graphic_height);

                exit(1);

            }

            /* sbus irq 5 */

            cg3_init(hwdef->tcx_base, slavio_irq[11], 0x00100000,

                     graphic_width, graphic_height, graphic_depth);

        } else {

            /* If no display specified, default to TCX */

            if (graphic_depth != 8 && graphic_depth != 24) {

                error_report("Unsupported depth: %d", graphic_depth);

                exit(1);

            }

            if (!(graphic_width == 1024 && graphic_height == 768)) {

                error_report("Unsupported resolution: %d x %d",

                             graphic_width, graphic_height);

                exit(1);

            }

            tcx_init(hwdef->tcx_base, slavio_irq[11], 0x00100000,

                     graphic_width, graphic_height, graphic_depth);

        }

    }

    for (i = num_vsimms; i < MAX_VSIMMS; i++) {

        /* vsimm registers probed by OBP */

        if (hwdef->vsimm[i].reg_base) {

            empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000);

        }

    }

    if (hwdef->sx_base) {

        empty_slot_init(hwdef->sx_base, 0x2000);

    }

    lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);

    nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8);

    slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus);

    slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],

                              display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);

    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device

       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */

    escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],

              serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);

    cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);

    if (hwdef->apc_base) {

        apc_init(hwdef->apc_base, cpu_halt[0]);

    }

    if (hwdef->fd_base) {

        /* there is zero or one floppy drive */

        memset(fd, 0, sizeof(fd));

        fd[0] = drive_get(IF_FLOPPY, 0, 0);

        sun4m_fdctrl_init(slavio_irq[22], hwdef->fd_base, fd,

                          &fdc_tc);

    } else {

        fdc_tc = *qemu_allocate_irqs(dummy_fdc_tc, NULL, 1);

    }

    slavio_misc_init(hwdef->slavio_base, hwdef->aux1_base, hwdef->aux2_base,

                     slavio_irq[30], fdc_tc);

    if (drive_get_max_bus(IF_SCSI) > 0) {

        fprintf(stderr, "qemu: too many SCSI bus\n");

        exit(1);

    }

    esp_init(hwdef->esp_base, 2,

             espdma_memory_read, espdma_memory_write,

             espdma, espdma_irq, &esp_reset, &dma_enable);

    qdev_connect_gpio_out(espdma, 0, esp_reset);

    qdev_connect_gpio_out(espdma, 1, dma_enable);

    if (hwdef->cs_base) {

        sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,

                             slavio_irq[5]);

    }

    if (hwdef->dbri_base) {

        /* ISDN chip with attached CS4215 audio codec */

        /* prom space */

        empty_slot_init(hwdef->dbri_base+0x1000, 0x30);

        /* reg space */

        empty_slot_init(hwdef->dbri_base+0x10000, 0x100);

    }

    if (hwdef->bpp_base) {

        /* parallel port */

        empty_slot_init(hwdef->bpp_base, 0x20);

    }

    kernel_size = sun4m_load_kernel(machine->kernel_filename,

                                    machine->initrd_filename,

                                    machine->ram_size);

    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, machine->kernel_cmdline,

               machine->boot_order, machine->ram_size, kernel_size,

               graphic_width, graphic_height, graphic_depth,

               hwdef->nvram_machine_id, "Sun4m");

    if (hwdef->ecc_base)

        ecc_init(hwdef->ecc_base, slavio_irq[28],

                 hwdef->ecc_version);

    fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2);

    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);

    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);

    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);

    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_DEPTH, graphic_depth);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_WIDTH, graphic_width);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_HEIGHT, graphic_height);

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);

    if (machine->kernel_cmdline) {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);

        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE,

                         machine->kernel_cmdline);

        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, machine->kernel_cmdline);

        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,

                       strlen(machine->kernel_cmdline) + 1);

    } else {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);

        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);

    }

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used

    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);

}


static inline int qemu_rdma_buffer_mergable(RDMAContext *rdma,

                    uint64_t offset, uint64_t len)

{

    RDMALocalBlock *block =

        &(rdma->local_ram_blocks.block[rdma->current_index]);

    uint8_t *host_addr = block->local_host_addr + (offset - block->offset);

    uint8_t *chunk_end = ram_chunk_end(block, rdma->current_chunk);

    if (rdma->current_length == 0) {

        return 0;

    }

    /*

     * Only merge into chunk sequentially.

     */

    if (offset != (rdma->current_addr + rdma->current_length)) {

        return 0;

    }

    if (rdma->current_index < 0) {

        return 0;

    }

    if (offset < block->offset) {

        return 0;

    }

    if ((offset + len) > (block->offset + block->length)) {

        return 0;

    }

    if (rdma->current_chunk < 0) {

        return 0;

    }

    if ((host_addr + len) > chunk_end) {

        return 0;

    }

    return 1;

}


static int ogg_new_buf(struct ogg *ogg, int idx)

{

    struct ogg_stream *os = ogg->streams + idx;

    uint8_t *nb = av_malloc(os->bufsize);

    int size = os->bufpos - os->pstart;

    if(os->buf){

        memcpy(nb, os->buf + os->pstart, size);

        av_free(os->buf);

    }

    os->buf = nb;

    os->bufpos = size;

    os->pstart = 0;

    return 0;

}


void s390_memory_init(ram_addr_t mem_size)

{

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    /* allocate RAM for core */

    memory_region_init_ram(ram, NULL, "s390.ram", mem_size, &error_abort);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(sysmem, 0, ram);

    /* Initialize storage key device */

    s390_skeys_init();

}


static void tracked_request_begin(BdrvTrackedRequest *req,
                                  BlockDriverState *bs,
                                  int64_t sector_num,
                                  int nb_sectors, bool is_write)
    *req = (BdrvTrackedRequest){
        .bs = bs,
        .sector_num = sector_num,
        .nb_sectors = nb_sectors,
        .is_write = is_write,
    };
    QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);


static inline int decode_seq_parameter_set(H264Context *h){

    MpegEncContext * const s = &h->s;

    int profile_idc, level_idc;

    int sps_id, i;

    SPS *sps;

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

    get_bits1(&s->gb);   //constraint_set0_flag

    get_bits1(&s->gb);   //constraint_set1_flag

    get_bits1(&s->gb);   //constraint_set2_flag

    get_bits1(&s->gb);   //constraint_set3_flag

    get_bits(&s->gb, 4); // reserved

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

    sps_id= get_ue_golomb(&s->gb);

    sps= &h->sps_buffer[ sps_id ];

    sps->profile_idc= profile_idc;

    sps->level_idc= level_idc;

    if(sps->profile_idc >= 100){ //high profile

        if(get_ue_golomb(&s->gb) == 3) //chroma_format_idc

            get_bits1(&s->gb);  //residual_color_transform_flag

        get_ue_golomb(&s->gb);  //bit_depth_luma_minus8

        get_ue_golomb(&s->gb);  //bit_depth_chroma_minus8

        sps->transform_bypass = get_bits1(&s->gb);

        decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);

    }else

        sps->scaling_matrix_present = 0;

    sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4;

    sps->poc_type= get_ue_golomb(&s->gb);

    if(sps->poc_type == 0){ //FIXME #define

        sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4;

    } else if(sps->poc_type == 1){//FIXME #define

        sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);

        sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);

        sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);

        sps->poc_cycle_length= get_ue_golomb(&s->gb);

        for(i=0; i<sps->poc_cycle_length; i++)

            sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb);

    }

    if(sps->poc_type > 2){

        av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);

        return -1;

    }

    sps->ref_frame_count= get_ue_golomb(&s->gb);

    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2){

        av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n");

    }

    sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);

    sps->mb_width= get_ue_golomb(&s->gb) + 1;

    sps->mb_height= get_ue_golomb(&s->gb) + 1;

    if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||

       avcodec_check_dimensions(NULL, 16*sps->mb_width, 16*sps->mb_height))

        return -1;

    sps->frame_mbs_only_flag= get_bits1(&s->gb);

    if(!sps->frame_mbs_only_flag)

        sps->mb_aff= get_bits1(&s->gb);

    else

        sps->mb_aff= 0;

    sps->direct_8x8_inference_flag= get_bits1(&s->gb);

#ifndef ALLOW_INTERLACE

    if(sps->mb_aff)

        av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");

#endif

    if(!sps->direct_8x8_inference_flag && sps->mb_aff)

        av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF + !direct_8x8_inference is not implemented\n");

    sps->crop= get_bits1(&s->gb);

    if(sps->crop){

        sps->crop_left  = get_ue_golomb(&s->gb);

        sps->crop_right = get_ue_golomb(&s->gb);

        sps->crop_top   = get_ue_golomb(&s->gb);

        sps->crop_bottom= get_ue_golomb(&s->gb);

        if(sps->crop_left || sps->crop_top){

            av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");

        }

    }else{

        sps->crop_left  =

        sps->crop_right =

        sps->crop_top   =

        sps->crop_bottom= 0;

    }

    sps->vui_parameters_present_flag= get_bits1(&s->gb);

    if( sps->vui_parameters_present_flag )

        decode_vui_parameters(h, sps);

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

        av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%d profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s\n",

               sps_id, sps->profile_idc, sps->level_idc,

               sps->poc_type,

               sps->ref_frame_count,

               sps->mb_width, sps->mb_height,

               sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"),

               sps->direct_8x8_inference_flag ? "8B8" : "",

               sps->crop_left, sps->crop_right,

               sps->crop_top, sps->crop_bottom,

               sps->vui_parameters_present_flag ? "VUI" : ""

               );

    }

    return 0;

}


static int usb_ehci_initfn(PCIDevice *dev)

{

    EHCIState *s = DO_UPCAST(EHCIState, dev, dev);

    uint8_t *pci_conf = s->dev.config;

    int i;

    pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20);

    /* capabilities pointer */

    pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);

    //pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50);

    pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); /* interrupt pin D */

    pci_set_byte(&pci_conf[PCI_MIN_GNT], 0);

    pci_set_byte(&pci_conf[PCI_MAX_LAT], 0);

    // pci_conf[0x50] = 0x01; // power management caps

    pci_set_byte(&pci_conf[USB_SBRN], USB_RELEASE_2); // release number (2.1.4)

    pci_set_byte(&pci_conf[0x61], 0x20);  // frame length adjustment (2.1.5)

    pci_set_word(&pci_conf[0x62], 0x00);  // port wake up capability (2.1.6)

    pci_conf[0x64] = 0x00;

    pci_conf[0x65] = 0x00;

    pci_conf[0x66] = 0x00;

    pci_conf[0x67] = 0x00;

    pci_conf[0x68] = 0x01;

    pci_conf[0x69] = 0x00;

    pci_conf[0x6a] = 0x00;

    pci_conf[0x6b] = 0x00;  // USBLEGSUP

    pci_conf[0x6c] = 0x00;

    pci_conf[0x6d] = 0x00;

    pci_conf[0x6e] = 0x00;

    pci_conf[0x6f] = 0xc0;  // USBLEFCTLSTS

    // 2.2 host controller interface version

    s->mmio[0x00] = (uint8_t) OPREGBASE;

    s->mmio[0x01] = 0x00;

    s->mmio[0x02] = 0x00;

    s->mmio[0x03] = 0x01;        // HC version

    s->mmio[0x04] = NB_PORTS;    // Number of downstream ports

    s->mmio[0x05] = 0x00;        // No companion ports at present

    s->mmio[0x06] = 0x00;

    s->mmio[0x07] = 0x00;

    s->mmio[0x08] = 0x80;        // We can cache whole frame, not 64-bit capable

    s->mmio[0x09] = 0x68;        // EECP

    s->mmio[0x0a] = 0x00;

    s->mmio[0x0b] = 0x00;

    s->irq = s->dev.irq[3];

    usb_bus_new(&s->bus, &ehci_bus_ops, &s->dev.qdev);

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

        usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,

                          USB_SPEED_MASK_HIGH);

        s->ports[i].dev = 0;

    }

    s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);

    s->async_bh = qemu_bh_new(ehci_async_bh, s);

    QTAILQ_INIT(&s->aqueues);

    QTAILQ_INIT(&s->pqueues);

    usb_packet_init(&s->ipacket);

    qemu_register_reset(ehci_reset, s);

    memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);

    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);

    return 0;

}


static int vnc_refresh_server_surface(VncDisplay *vd)

{

    int width = MIN(pixman_image_get_width(vd->guest.fb),

                    pixman_image_get_width(vd->server));

    int height = MIN(pixman_image_get_height(vd->guest.fb),

                     pixman_image_get_height(vd->server));

    int cmp_bytes, server_stride, min_stride, guest_stride, y = 0;

    uint8_t *guest_row0 = NULL, *server_row0;

    VncState *vs;

    int has_dirty = 0;

    pixman_image_t *tmpbuf = NULL;

    struct timeval tv = { 0, 0 };

    if (!vd->non_adaptive) {

        gettimeofday(&tv, NULL);

        has_dirty = vnc_update_stats(vd, &tv);

    }

    /*

     * Walk through the guest dirty map.

     * Check and copy modified bits from guest to server surface.

     * Update server dirty map.

     */

    server_row0 = (uint8_t *)pixman_image_get_data(vd->server);

    server_stride = guest_stride = pixman_image_get_stride(vd->server);

    cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,

                    server_stride);

    if (vd->guest.format != VNC_SERVER_FB_FORMAT) {

        int width = pixman_image_get_width(vd->server);

        tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);

    } else {

        guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);

        guest_stride = pixman_image_get_stride(vd->guest.fb);

    }

    min_stride = MIN(server_stride, guest_stride);

    for (;;) {

        int x;

        uint8_t *guest_ptr, *server_ptr;

        unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,

                                             height * VNC_DIRTY_BPL(&vd->guest),

                                             y * VNC_DIRTY_BPL(&vd->guest));

        if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {

            /* no more dirty bits */

            break;

        }

        y = offset / VNC_DIRTY_BPL(&vd->guest);

        x = offset % VNC_DIRTY_BPL(&vd->guest);

        server_ptr = server_row0 + y * server_stride + x * cmp_bytes;

        if (vd->guest.format != VNC_SERVER_FB_FORMAT) {

            qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);

            guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);

        } else {

            guest_ptr = guest_row0 + y * guest_stride;

        }

        guest_ptr += x * cmp_bytes;

        for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);

             x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {

            int _cmp_bytes = cmp_bytes;

            if (!test_and_clear_bit(x, vd->guest.dirty[y])) {

                continue;

            }

            if ((x + 1) * cmp_bytes > min_stride) {

                _cmp_bytes = min_stride - x * cmp_bytes;

            }

            if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {

                continue;

            }

            memcpy(server_ptr, guest_ptr, _cmp_bytes);

            if (!vd->non_adaptive) {

                vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,

                                 y, &tv);

            }

            QTAILQ_FOREACH(vs, &vd->clients, next) {

                set_bit(x, vs->dirty[y]);

            }

            has_dirty++;

        }

        y++;

    }

    qemu_pixman_image_unref(tmpbuf);

    return has_dirty;

}


static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                            AVPacket *avpkt)
{
    const AVPixFmtDescriptor *desc;
    SMVJpegDecodeContext *s = avctx->priv_data;
    AVFrame* mjpeg_data = s->picture[0];
    int i, cur_frame = 0, ret = 0;
    cur_frame = avpkt->pts % s->frames_per_jpeg;
    /* Are we at the start of a block? */
    if (!cur_frame) {
        av_frame_unref(mjpeg_data);
        ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
        if (ret < 0) {
            s->mjpeg_data_size = 0;
            return ret;
        }
    } else if (!s->mjpeg_data_size)
        return AVERROR(EINVAL);
    desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
    av_assert0(desc);
    if (mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
        av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
        return AVERROR_INVALIDDATA;
    }
    /*use the last lot... */
    *data_size = s->mjpeg_data_size;
    avctx->pix_fmt = s->avctx->pix_fmt;
    /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected
       in init */
    ret = ff_set_dimensions(avctx, mjpeg_data->width, mjpeg_data->height / s->frames_per_jpeg);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "Failed to set dimensions\n");
        return ret;
    }
    if (*data_size) {
        s->picture[1]->extended_data = NULL;
        s->picture[1]->width         = avctx->width;
        s->picture[1]->height        = avctx->height;
        s->picture[1]->format        = avctx->pix_fmt;
        /* ff_init_buffer_info(avctx, &s->picture[1]); */
        smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
                    avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
        for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
            s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
        ret = av_frame_ref(data, s->picture[1]);
    }
    return ret;
}


static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)

{

    VRingMemoryRegionCaches *caches = atomic_rcu_read(&vq->vring.caches);

    hwaddr pa = offsetof(VRingAvail, ring[i]);

    return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa);

}


static int open_f(BlockDriverState *bs, int argc, char **argv)

{

    int flags = 0;

    int readonly = 0;

    int growable = 0;

    int c;

    QemuOpts *qopts;

    QDict *opts;

    while ((c = getopt(argc, argv, "snrgo:")) != EOF) {

        switch (c) {

        case 's':

            flags |= BDRV_O_SNAPSHOT;

            break;

        case 'n':

            flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;

            break;

        case 'r':

            readonly = 1;

            break;

        case 'g':

            growable = 1;

            break;

        case 'o':

            if (!qemu_opts_parse(&empty_opts, optarg, 0)) {

                printf("could not parse option list -- %s\n", optarg);

                qemu_opts_reset(&empty_opts);

                return 0;

            }

            break;

        default:

            qemu_opts_reset(&empty_opts);

            return qemuio_command_usage(&open_cmd);

        }

    }

    if (!readonly) {

        flags |= BDRV_O_RDWR;

    }

    qopts = qemu_opts_find(&empty_opts, NULL);

    opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;

    qemu_opts_reset(&empty_opts);

    if (optind == argc - 1) {

        return openfile(argv[optind], flags, growable, opts);

    } else if (optind == argc) {

        return openfile(NULL, flags, growable, opts);

    } else {

        return qemuio_command_usage(&open_cmd);

    }

}


av_cold int ff_mdct_init(FFTContext *s, int nbits, int inverse, double scale)

{

    int n, n4, i;

    double alpha, theta;

    int tstep;

    memset(s, 0, sizeof(*s));

    n = 1 << nbits;

    s->mdct_bits = nbits;

    s->mdct_size = n;

    n4 = n >> 2;

    s->permutation = FF_MDCT_PERM_NONE;

    if (ff_fft_init(s, s->mdct_bits - 2, inverse) < 0)

        goto fail;

    s->tcos = av_malloc(n/2 * sizeof(FFTSample));

    if (!s->tcos)

        goto fail;

    switch (s->permutation) {

    case FF_MDCT_PERM_NONE:

        s->tsin = s->tcos + n4;

        tstep = 1;

        break;

    case FF_MDCT_PERM_INTERLEAVE:

        s->tsin = s->tcos + 1;

        tstep = 2;

        break;

    default:

        goto fail;

    }

    theta = 1.0 / 8.0 + (scale < 0 ? n4 : 0);

    scale = sqrt(fabs(scale));

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

        alpha = 2 * M_PI * (i + theta) / n;

        s->tcos[i*tstep] = -cos(alpha) * scale;

        s->tsin[i*tstep] = -sin(alpha) * scale;

    }

    return 0;

 fail:

    ff_mdct_end(s);

    return -1;

}


int ff_slice_thread_init(AVCodecContext *avctx)

{

    int i;

    ThreadContext *c;

    int thread_count = avctx->thread_count;

#if HAVE_W32THREADS

    w32thread_init();

#endif

    if (!thread_count) {

        int nb_cpus = av_cpu_count();

        av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);

        // use number of cores + 1 as thread count if there is more than one

        if (nb_cpus > 1)

            thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);

        else

            thread_count = avctx->thread_count = 1;

    }

    if (thread_count <= 1) {

        avctx->active_thread_type = 0;

        return 0;

    }

    c = av_mallocz(sizeof(ThreadContext));

    if (!c)

        return -1;

    c->workers = av_mallocz(sizeof(pthread_t)*thread_count);

    if (!c->workers) {

        av_free(c);

        return -1;

    }

    avctx->thread_opaque = c;

    c->current_job = 0;

    c->job_count = 0;

    c->job_size = 0;

    c->done = 0;

    pthread_cond_init(&c->current_job_cond, NULL);

    pthread_cond_init(&c->last_job_cond, NULL);

    pthread_mutex_init(&c->current_job_lock, NULL);

    pthread_mutex_lock(&c->current_job_lock);

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

        if(pthread_create(&c->workers[i], NULL, worker, avctx)) {

           avctx->thread_count = i;

           pthread_mutex_unlock(&c->current_job_lock);

           ff_thread_free(avctx);

           return -1;

        }

    }

    thread_park_workers(c, thread_count);

    avctx->execute = thread_execute;

    avctx->execute2 = thread_execute2;

    return 0;

}


void ff_avg_h264_qpel4_mc22_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_mid_and_aver_dst_4x4_msa(src - (2 * stride) - 2,

                                      stride, dst, stride);

}


int qsv_transcode_init(OutputStream *ost)

{

    InputStream *ist;

    const enum AVPixelFormat *pix_fmt;

    AVDictionaryEntry *e;

    const AVOption *opt;

    int flags = 0;

    int err, i;

    QSVContext *qsv = NULL;

    AVQSVContext *hwctx = NULL;

    mfxIMPL impl;

    mfxVersion ver = { { 3, 1 } };

    /* check if the encoder supports QSV */

    if (!ost->enc->pix_fmts)

        return 0;

    for (pix_fmt = ost->enc->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)

        if (*pix_fmt == AV_PIX_FMT_QSV)

            break;

    if (*pix_fmt == AV_PIX_FMT_NONE)

        return 0;

    if (strcmp(ost->avfilter, "null") || ost->source_index < 0)

        return 0;

    /* check if the decoder supports QSV and the output only goes to this stream */

    ist = input_streams[ost->source_index];

    if (ist->hwaccel_id != HWACCEL_QSV || !ist->dec || !ist->dec->pix_fmts)

        return 0;

    for (pix_fmt = ist->dec->pix_fmts; *pix_fmt != AV_PIX_FMT_NONE; pix_fmt++)

        if (*pix_fmt == AV_PIX_FMT_QSV)

            break;

    if (*pix_fmt == AV_PIX_FMT_NONE)

        return 0;

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

        if (output_streams[i] != ost &&

            output_streams[i]->source_index == ost->source_index)

            return 0;

    av_log(NULL, AV_LOG_VERBOSE, "Setting up QSV transcoding\n");

    qsv   = av_mallocz(sizeof(*qsv));

    hwctx = av_qsv_alloc_context();

    if (!qsv || !hwctx)

        goto fail;

    impl = choose_implementation(ist);

    err = MFXInit(impl, &ver, &qsv->session);

    if (err != MFX_ERR_NONE) {

        av_log(NULL, AV_LOG_ERROR, "Error initializing an MFX session: %d\n", err);

        goto fail;

    }

    e = av_dict_get(ost->encoder_opts, "flags", NULL, 0);

    opt = av_opt_find(ost->enc_ctx, "flags", NULL, 0, 0);

    if (e && opt)

        av_opt_eval_flags(ost->enc_ctx, opt, e->value, &flags);

    qsv->ost = ost;

    hwctx->session                = qsv->session;

    hwctx->iopattern              = MFX_IOPATTERN_IN_OPAQUE_MEMORY;

    hwctx->opaque_alloc           = 1;

    hwctx->nb_opaque_surfaces     = 16;

    ost->hwaccel_ctx              = qsv;

    ost->enc_ctx->hwaccel_context = hwctx;

    ost->enc_ctx->pix_fmt         = AV_PIX_FMT_QSV;

    ist->hwaccel_ctx              = qsv;

    ist->dec_ctx->pix_fmt         = AV_PIX_FMT_QSV;

    ist->resample_pix_fmt         = AV_PIX_FMT_QSV;

    return 0;

fail:

    av_freep(&hwctx);

    av_freep(&qsv);

    return AVERROR_UNKNOWN;

}


static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)

{

    MOVMuxContext *mov = s->priv_data;

    int64_t pos = avio_tell(pb);

    int has_h264 = 0, has_video = 0;

    int minor = 0x200;

    int i;

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

        AVStream *st = s->streams[i];

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

            has_video = 1;

        if (st->codec->codec_id == AV_CODEC_ID_H264)

            has_h264 = 1;

    }

    avio_wb32(pb, 0); /* size */

    ffio_wfourcc(pb, "ftyp");

    if (mov->mode == MODE_3GP) {

        ffio_wfourcc(pb, has_h264 ? "3gp6"  : "3gp4");

        minor =     has_h264 ?   0x100 :   0x200;

    } else if (mov->mode & MODE_3G2) {

        ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");

        minor =     has_h264 ? 0x20000 : 0x10000;

    } else if (mov->mode == MODE_PSP)

        ffio_wfourcc(pb, "MSNV");

    else if (mov->mode == MODE_MP4)

        ffio_wfourcc(pb, "isom");

    else if (mov->mode == MODE_IPOD)

        ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");

    else if (mov->mode == MODE_ISM)

        ffio_wfourcc(pb, "isml");

    else if (mov->mode == MODE_F4V)

        ffio_wfourcc(pb, "f4v ");

    else

        ffio_wfourcc(pb, "qt  ");

    avio_wb32(pb, minor);

    if (mov->mode == MODE_MOV)

        ffio_wfourcc(pb, "qt  ");

    else if (mov->mode == MODE_ISM) {

        ffio_wfourcc(pb, "piff");

        ffio_wfourcc(pb, "iso2");

    } else {

        ffio_wfourcc(pb, "isom");

        ffio_wfourcc(pb, "iso2");

        if (has_h264)

            ffio_wfourcc(pb, "avc1");

    }

    if (mov->mode == MODE_3GP)

        ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4");

    else if (mov->mode & MODE_3G2)

        ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a");

    else if (mov->mode == MODE_PSP)

        ffio_wfourcc(pb, "MSNV");

    else if (mov->mode == MODE_MP4)

        ffio_wfourcc(pb, "mp41");

    return update_size(pb, pos);

}