static int flac_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            uint8_t *buf, int buf_size)

{

    FLACContext *s = avctx->priv_data;

    int metadata_last, metadata_type, metadata_size;

    int tmp = 0, i, j = 0, input_buf_size = 0;

    int16_t *samples = data;

    if(s->max_framesize == 0){

        s->max_framesize= 8192; // should hopefully be enough for the first header

        s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);

    }

    if(1 && s->max_framesize){//FIXME truncated

            buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);

            input_buf_size= buf_size;

            if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){

//                printf("memmove\n");

                memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);

                s->bitstream_index=0;

            }

            memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);

            buf= &s->bitstream[s->bitstream_index];

            buf_size += s->bitstream_size;

            s->bitstream_size= buf_size;

            if(buf_size < s->max_framesize){

//                printf("wanna more data ...\n");

                return input_buf_size;

            }

    }

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

    /* fLaC signature (be) */

    if (show_bits_long(&s->gb, 32) == bswap_32(ff_get_fourcc("fLaC")))

    {

        skip_bits(&s->gb, 32);

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

        do {

            metadata_last = get_bits(&s->gb, 1);

            metadata_type = get_bits(&s->gb, 7);

            metadata_size = get_bits_long(&s->gb, 24);

            av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n",

                metadata_last, metadata_type,

                metadata_size);

            if(metadata_size){

                switch(metadata_type)

                {

                case METADATA_TYPE_STREAMINFO:{

                    int bits_count= get_bits_count(&s->gb);

                    metadata_streaminfo(s);

                    buf= &s->bitstream[s->bitstream_index];

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

                    skip_bits(&s->gb, bits_count);

                    dump_headers(s);

                    break;}

                default:

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

                        skip_bits(&s->gb, 8);

                }

            }

        } while(!metadata_last);

    }

    else

    {

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

        if(tmp != 0xFFF8){

            av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n");

            while(get_bits_count(&s->gb)/8+2 < buf_size && show_bits(&s->gb, 16) != 0xFFF8)

                skip_bits(&s->gb, 8);

            goto end; // we may not have enough bits left to decode a frame, so try next time

        }

        skip_bits(&s->gb, 16);

        if (decode_frame(s) < 0){

            av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");

            s->bitstream_size=0;

            s->bitstream_index=0;

            return -1;

        }

    }

#if 0

    /* fix the channel order here */

    if (s->order == MID_SIDE)

    {

        short *left = samples;

        short *right = samples + s->blocksize;

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

        {

            uint32_t x = s->decoded[0][i];

            uint32_t y = s->decoded[0][i+1];

            right[i] = x - (y / 2);

            left[i] = right[i] + y;

        }

        *data_size = 2 * s->blocksize;

    }

    else

    {

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

    {

        switch(s->order)

        {

            case INDEPENDENT:

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

                    samples[(s->blocksize*i)+j] = s->decoded[i][j];

                break;

            case LEFT_SIDE:

            case RIGHT_SIDE:

                if (i == 0)

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

                        samples[(s->blocksize*i)+j] = s->decoded[0][j];

                else

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

                        samples[(s->blocksize*i)+j] = s->decoded[0][j] - s->decoded[i][j];

                break;

//            case MID_SIDE:

//                av_log(s->avctx, AV_LOG_DEBUG, "mid-side unsupported\n");

        }

        *data_size += s->blocksize;

    }

    }

#else

    switch(s->decorrelation)

    {

        case INDEPENDENT:

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

            {

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

                    *(samples++) = s->decoded[i][j];

            }

            break;

        case LEFT_SIDE:

            assert(s->channels == 2);

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

            {

                *(samples++) = s->decoded[0][i];

                *(samples++) = s->decoded[0][i] - s->decoded[1][i];

            }

            break;

        case RIGHT_SIDE:

            assert(s->channels == 2);

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

            {

                *(samples++) = s->decoded[0][i] + s->decoded[1][i];

                *(samples++) = s->decoded[1][i];

            }

            break;

        case MID_SIDE:

            assert(s->channels == 2);

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

            {

                int mid, side;

                mid = s->decoded[0][i];

                side = s->decoded[1][i];

#if 1 //needs to be checked but IMHO it should be binary identical

                mid -= side>>1;

                *(samples++) = mid + side;

                *(samples++) = mid;

#else

                mid <<= 1;

                if (side & 1)

                    mid++;

                *(samples++) = (mid + side) >> 1;

                *(samples++) = (mid - side) >> 1;

#endif

            }

            break;

    }

#endif

    *data_size = (int8_t *)samples - (int8_t *)data;

//    av_log(s->avctx, AV_LOG_DEBUG, "data size: %d\n", *data_size);

//    s->last_blocksize = s->blocksize;

end:

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

    if(i > buf_size){

        av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);

        s->bitstream_size=0;

        s->bitstream_index=0;

        return -1;

    }

    if(s->bitstream_size){

        s->bitstream_index += i;

        s->bitstream_size  -= i;

        return input_buf_size;

    }else

        return i;

}


static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,

                             mfxExtBuffer **coding_opts)

{

    mfxInfoMFX *info = &q->param.mfx;

    mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[0];

#if QSV_HAVE_CO2

    mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];

#endif

#if QSV_HAVE_CO3

    mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];

#endif

    av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",

           print_profile(info->CodecProfile), info->CodecLevel);

    av_log(avctx, AV_LOG_VERBOSE, "GopPicSize: %"PRIu16"; GopRefDist: %"PRIu16"; GopOptFlag: ",

           info->GopPicSize, info->GopRefDist);

    if (info->GopOptFlag & MFX_GOP_CLOSED)

        av_log(avctx, AV_LOG_VERBOSE, "closed ");

    if (info->GopOptFlag & MFX_GOP_STRICT)

        av_log(avctx, AV_LOG_VERBOSE, "strict ");

    av_log(avctx, AV_LOG_VERBOSE, "; IdrInterval: %"PRIu16"\n", info->IdrInterval);

    av_log(avctx, AV_LOG_VERBOSE, "TargetUsage: %"PRIu16"; RateControlMethod: %s\n",

           info->TargetUsage, print_ratecontrol(info->RateControlMethod));

    if (info->RateControlMethod == MFX_RATECONTROL_CBR ||

        info->RateControlMethod == MFX_RATECONTROL_VBR

#if QSV_HAVE_VCM

        || info->RateControlMethod == MFX_RATECONTROL_VCM

#endif

        ) {

        av_log(avctx, AV_LOG_VERBOSE,

               "InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"\n",

               info->InitialDelayInKB, info->TargetKbps, info->MaxKbps);

    } else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {

        av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",

               info->QPI, info->QPP, info->QPB);

    } else if (info->RateControlMethod == MFX_RATECONTROL_AVBR) {

        av_log(avctx, AV_LOG_VERBOSE,

               "TargetKbps: %"PRIu16"; Accuracy: %"PRIu16"; Convergence: %"PRIu16"\n",

               info->TargetKbps, info->Accuracy, info->Convergence);

    }

#if QSV_HAVE_LA

    else if (info->RateControlMethod == MFX_RATECONTROL_LA

#if QSV_HAVE_LA_HRD

             || info->RateControlMethod == MFX_RATECONTROL_LA_HRD

#endif

             ) {

        av_log(avctx, AV_LOG_VERBOSE,

               "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",

               info->TargetKbps, co2->LookAheadDepth);

    }

#endif

#if QSV_HAVE_ICQ

    else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {

        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);

    } else if (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ) {

        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",

               info->ICQQuality, co2->LookAheadDepth);

    }

#endif

#if QSV_HAVE_QVBR

    else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {

        av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",

               co3->QVBRQuality);

    }

#endif

    av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",

           info->NumSlice, info->NumRefFrame);

    av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",

           print_threestate(co->RateDistortionOpt));

#if QSV_HAVE_CO2

    av_log(avctx, AV_LOG_VERBOSE,

           "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",

           print_threestate(co->RecoveryPointSEI), co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);

    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %"PRIu16"; ", co2->MaxFrameSize);

#if QSV_VERSION_ATLEAST(1, 9)

    av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %"PRIu16"; ", co2->MaxSliceSize);

#endif

    av_log(avctx, AV_LOG_VERBOSE, "\n");

    av_log(avctx, AV_LOG_VERBOSE,

           "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",

           print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),

           print_threestate(co2->ExtBRC));

#if QSV_HAVE_TRELLIS

    av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");

    if (co2->Trellis & MFX_TRELLIS_OFF) {

        av_log(avctx, AV_LOG_VERBOSE, "off");

    } else if (!co2->Trellis) {

        av_log(avctx, AV_LOG_VERBOSE, "auto");

    } else {

        if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE, "I");

        if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE, "P");

        if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE, "B");

    }

    av_log(avctx, AV_LOG_VERBOSE, "\n");

#endif

#if QSV_VERSION_ATLEAST(1, 8)

    av_log(avctx, AV_LOG_VERBOSE,

           "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",

           print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);

    switch (co2->LookAheadDS) {

    case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");     break;

    case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");      break;

    case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");      break;

    default:                   av_log(avctx, AV_LOG_VERBOSE, "unknown"); break;

    }

    av_log(avctx, AV_LOG_VERBOSE, "\n");

    av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",

           print_threestate(co2->AdaptiveI), print_threestate(co2->AdaptiveB));

    switch (co2->BRefType) {

    case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");       break;

    case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;

    default:                av_log(avctx, AV_LOG_VERBOSE, "auto");      break;

    }

    av_log(avctx, AV_LOG_VERBOSE, "\n");

#endif

#if QSV_VERSION_ATLEAST(1, 9)

    av_log(avctx, AV_LOG_VERBOSE,

           "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",

           co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);

#endif

#endif

    if (avctx->codec_id == AV_CODEC_ID_H264) {

        av_log(avctx, AV_LOG_VERBOSE, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16"\n",

               co->CAVLC == MFX_CODINGOPTION_ON ? "CAVLC" : "CABAC", co->MaxDecFrameBuffering);

        av_log(avctx, AV_LOG_VERBOSE,

               "NalHrdConformance: %s; SingleSeiNalUnit: %s; VuiVclHrdParameters: %s VuiNalHrdParameters: %s\n",

               print_threestate(co->NalHrdConformance), print_threestate(co->SingleSeiNalUnit),

               print_threestate(co->VuiVclHrdParameters), print_threestate(co->VuiNalHrdParameters));

    }

}


static void *alloc_buffer(FFVAContext *vactx, int type, unsigned int size, uint32_t *buf_id)

{

    void *data = NULL;

    *buf_id = 0;

    if (vaCreateBuffer(vactx->display, vactx->context_id,

                       type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS)

        vaMapBuffer(vactx->display, *buf_id, &data);

    return data;

}


void ff_http_auth_handle_header(HTTPAuthState *state, const char *key,

                                const char *value)

{

    if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) {

        const char *p;

        if (av_stristart(value, "Basic ", &p) &&

            state->auth_type <= HTTP_AUTH_BASIC) {

            state->auth_type = HTTP_AUTH_BASIC;

            state->realm[0] = 0;

            state->stale = 0;

            ff_parse_key_value(p, (ff_parse_key_val_cb) handle_basic_params,

                               state);

        } else if (av_stristart(value, "Digest ", &p) &&

                   state->auth_type <= HTTP_AUTH_DIGEST) {

            state->auth_type = HTTP_AUTH_DIGEST;

            memset(&state->digest_params, 0, sizeof(DigestParams));

            state->realm[0] = 0;

            state->stale = 0;

            ff_parse_key_value(p, (ff_parse_key_val_cb) handle_digest_params,

                               state);

            choose_qop(state->digest_params.qop,

                       sizeof(state->digest_params.qop));

            if (!av_strcasecmp(state->digest_params.stale, "true"))

                state->stale = 1;

        }

    } else if (!strcmp(key, "Authentication-Info")) {

        ff_parse_key_value(value, (ff_parse_key_val_cb) handle_digest_update,

                           state);

    }

}


void ff_thread_report_progress(ThreadFrame *f, int n, int field)

{

    PerThreadContext *p;

    atomic_int *progress = f->progress ? (atomic_int*)f->progress->data : NULL;

    if (!progress ||

        atomic_load_explicit(&progress[field], memory_order_acquire) >= n)

        return;

    p = f->owner->internal->thread_ctx;

    if (f->owner->debug&FF_DEBUG_THREADS)

        av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);

    pthread_mutex_lock(&p->progress_mutex);

    atomic_store(&progress[field], n);

    pthread_cond_broadcast(&p->progress_cond);

    pthread_mutex_unlock(&p->progress_mutex);

}


static void mxf_write_system_item(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    AVIOContext *pb = s->pb;

    unsigned frame;

    uint32_t time_code;

    frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;

    // write system metadata pack

    avio_write(pb, system_metadata_pack_key, 16);

    klv_encode_ber4_length(pb, 57);

    avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present

    avio_w8(pb, 0x04); // content package rate

    avio_w8(pb, 0x00); // content package type

    avio_wb16(pb, 0x00); // channel handle

    avio_wb16(pb, mxf->tc.start + frame); // continuity count

    if (mxf->essence_container_count > 1)

        avio_write(pb, multiple_desc_ul, 16);

    else {

        MXFStreamContext *sc = s->streams[0]->priv_data;

        avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);

    }

    avio_w8(pb, 0);

    avio_wb64(pb, 0);

    avio_wb64(pb, 0); // creation date/time stamp

    avio_w8(pb, 0x81); // SMPTE 12M time code

    time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);

    avio_wb32(pb, time_code);

    avio_wb32(pb, 0); // binary group data

    avio_wb64(pb, 0);

    // write system metadata package set

    avio_write(pb, system_metadata_package_set_key, 16);

    klv_encode_ber4_length(pb, 35);

    avio_w8(pb, 0x83); // UMID

    avio_wb16(pb, 0x20);

    mxf_write_umid(s, 1);

}


petalogix_ml605_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    MemoryRegion *address_space_mem = get_system_memory();

    DeviceState *dev, *dma, *eth0;

    Object *ds, *cs;

    MicroBlazeCPU *cpu;

    SysBusDevice *busdev;

    DriveInfo *dinfo;

    int i;

    MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);

    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);

    qemu_irq irq[32];

    /* init CPUs */

    cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));

    /* Use FPU but don't use floating point conversion and square

     * root instructions

     */

    object_property_set_int(OBJECT(cpu), 1, "use-fpu", &error_abort);

    object_property_set_bool(OBJECT(cpu), true, "dcache-writeback",

                             &error_abort);

    object_property_set_bool(OBJECT(cpu), true, "endianness", &error_abort);

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

    /* Attach emulated BRAM through the LMB.  */

    memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",

                           LMB_BRAM_SIZE, &error_abort);

    vmstate_register_ram_global(phys_lmb_bram);

    memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);

    memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size,

                           &error_abort);

    vmstate_register_ram_global(phys_ram);

    memory_region_add_subregion(address_space_mem, MEMORY_BASEADDR, phys_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);

    /* 5th parameter 2 means bank-width

     * 10th paremeter 0 means little-endian */

    pflash_cfi01_register(FLASH_BASEADDR,

                          NULL, "petalogix_ml605.flash", FLASH_SIZE,

                          dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,

                          (64 * 1024), FLASH_SIZE >> 16,

                          2, 0x89, 0x18, 0x0000, 0x0, 0);

    dev = qdev_create(NULL, "xlnx.xps-intc");

    qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,

                       qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));

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

        irq[i] = qdev_get_gpio_in(dev, i);

    }

    serial_mm_init(address_space_mem, UART16550_BASEADDR + 0x1000, 2,

                   irq[UART16550_IRQ], 115200, serial_hds[0],

                   DEVICE_LITTLE_ENDIAN);

    /* 2 timers at irq 2 @ 100 Mhz.  */

    dev = qdev_create(NULL, "xlnx.xps-timer");

    qdev_prop_set_uint32(dev, "one-timer-only", 0);

    qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);

    /* axi ethernet and dma initialization. */

    qemu_check_nic_model(&nd_table[0], "xlnx.axi-ethernet");

    eth0 = qdev_create(NULL, "xlnx.axi-ethernet");

    dma = qdev_create(NULL, "xlnx.axi-dma");

    /* FIXME: attach to the sysbus instead */

    object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0),

                              NULL);

    object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma),

                              NULL);

    ds = object_property_get_link(OBJECT(dma),

                                  "axistream-connected-target", NULL);

    cs = object_property_get_link(OBJECT(dma),

                                  "axistream-control-connected-target", NULL);

    qdev_set_nic_properties(eth0, &nd_table[0]);

    qdev_prop_set_uint32(eth0, "rxmem", 0x1000);

    qdev_prop_set_uint32(eth0, "txmem", 0x1000);

    object_property_set_link(OBJECT(eth0), OBJECT(ds),

                             "axistream-connected", &error_abort);

    object_property_set_link(OBJECT(eth0), OBJECT(cs),

                             "axistream-control-connected", &error_abort);

    qdev_init_nofail(eth0);

    sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]);

    ds = object_property_get_link(OBJECT(eth0),

                                  "axistream-connected-target", NULL);

    cs = object_property_get_link(OBJECT(eth0),

                                  "axistream-control-connected-target", NULL);

    qdev_prop_set_uint32(dma, "freqhz", 100 * 1000000);

    object_property_set_link(OBJECT(dma), OBJECT(ds),

                             "axistream-connected", &error_abort);

    object_property_set_link(OBJECT(dma), OBJECT(cs),

                             "axistream-control-connected", &error_abort);

    qdev_init_nofail(dma);

    sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]);

    sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]);

    {

        SSIBus *spi;

        dev = qdev_create(NULL, "xlnx.xps-spi");

        qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES);

        qdev_init_nofail(dev);

        busdev = SYS_BUS_DEVICE(dev);

        sysbus_mmio_map(busdev, 0, SPI_BASEADDR);

        sysbus_connect_irq(busdev, 0, irq[SPI_IRQ]);

        spi = (SSIBus *)qdev_get_child_bus(dev, "spi");

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

            qemu_irq cs_line;

            dev = ssi_create_slave(spi, "n25q128");

            cs_line = qdev_get_gpio_in_named(dev, SSI_GPIO_CS, 0);

            sysbus_connect_irq(busdev, i+1, cs_line);

        }

    }

    /* setup PVR to match kernel settings */

    cpu->env.pvr.regs[4] = 0xc56b8000;

    cpu->env.pvr.regs[5] = 0xc56be000;

    cpu->env.pvr.regs[10] = 0x0e000000; /* virtex 6 */

    microblaze_load_kernel(cpu, MEMORY_BASEADDR, ram_size,

                           machine->initrd_filename,

                           BINARY_DEVICE_TREE_FILE,

                           NULL);

}


static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep)

{

    FILE *fp = NULL;

    int fop_ret;

    int file_size;

    int file_type = -1;

    unsigned char buf[2] = {0, 0};

    unsigned int filehead_value = 0;

    int bmp_bpp;

    fp = fopen(filename, "rb");

    if (fp == NULL) {

        error_report("failed to open file '%s'.", filename);

    /* check file size */

    fseek(fp, 0L, SEEK_END);

    file_size = ftell(fp);

    if (file_size < 2) {

        error_report("file size is less than 2 bytes '%s'.", filename);

    /* check magic ID */

    fseek(fp, 0L, SEEK_SET);

    fop_ret = fread(buf, 1, 2, fp);

    filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff;

    if (filehead_value == 0xd8ff) {

        file_type = JPG_FILE;

    } else {

        if (filehead_value == 0x4d42) {

            file_type = BMP_FILE;

    if (file_type < 0) {

        error_report("'%s' not jpg/bmp file,head:0x%x.",

                         filename, filehead_value);

    /* check BMP bpp */

    if (file_type == BMP_FILE) {

        fseek(fp, 28, SEEK_SET);

        fop_ret = fread(buf, 1, 2, fp);

        bmp_bpp = (buf[0] + (buf[1] << 8)) & 0xffff;

        if (bmp_bpp != 24) {

            error_report("only 24bpp bmp file is supported.");

    /* return values */

    *file_sizep = file_size;

    *file_typep = file_type;


vmxnet3_read_next_rx_descr(VMXNET3State *s, int qidx, int ridx,

                           struct Vmxnet3_RxDesc *dbuf, uint32_t *didx)

{

    Vmxnet3Ring *ring = &s->rxq_descr[qidx].rx_ring[ridx];

    *didx = vmxnet3_ring_curr_cell_idx(ring);

    vmxnet3_ring_read_curr_cell(ring, dbuf);

}


static av_cold int aac_encode_end(AVCodecContext *avctx)

{

    AACEncContext *s = avctx->priv_data;

    ff_mdct_end(&s->mdct1024);

    ff_mdct_end(&s->mdct128);

    ff_psy_end(&s->psy);

    ff_psy_preprocess_end(s->psypp);

    av_freep(&s->samples);

    av_freep(&s->cpe);

    return 0;

}


static int rice_count_exact(int32_t *res, int n, int k)

{

    int i;

    int count = 0;

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

        int32_t v = -2 * res[i] - 1;

        v ^= v >> 31;

        count += (v >> k) + 1 + k;

    }

    return count;

}


static uint64_t boston_lcd_read(void *opaque, hwaddr addr,

                                unsigned size)

{

    BostonState *s = opaque;

    uint64_t val = 0;

    switch (size) {

    case 8:

        val |= (uint64_t)s->lcd_content[(addr + 7) & 0x7] << 56;

        val |= (uint64_t)s->lcd_content[(addr + 6) & 0x7] << 48;

        val |= (uint64_t)s->lcd_content[(addr + 5) & 0x7] << 40;

        val |= (uint64_t)s->lcd_content[(addr + 4) & 0x7] << 32;

        /* fall through */

    case 4:

        val |= (uint64_t)s->lcd_content[(addr + 3) & 0x7] << 24;

        val |= (uint64_t)s->lcd_content[(addr + 2) & 0x7] << 16;

        /* fall through */

    case 2:

        val |= (uint64_t)s->lcd_content[(addr + 1) & 0x7] << 8;

        /* fall through */

    case 1:

        val |= (uint64_t)s->lcd_content[(addr + 0) & 0x7];

        break;

    }

    return val;

}


static inline int mix_core(uint32_t multbl[][256], int a, int b, int c, int d){

#if CONFIG_SMALL

#define ROT(x,s) ((x<<s)|(x>>(32-s)))

    return multbl[0][a] ^ ROT(multbl[0][b], 8) ^ ROT(multbl[0][c], 16) ^ ROT(multbl[0][d], 24);

#else

    return multbl[0][a] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d];

#endif

}


void ff_generate_sliding_window_mmcos(H264Context *h) {

    MpegEncContext * const s = &h->s;

    assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count);

    h->mmco_index= 0;

    if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&

            !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->f.reference)) {

        h->mmco[0].opcode= MMCO_SHORT2UNUSED;

        h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num;

        h->mmco_index= 1;

        if (FIELD_PICTURE) {

            h->mmco[0].short_pic_num *= 2;

            h->mmco[1].opcode= MMCO_SHORT2UNUSED;

            h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1;

            h->mmco_index= 2;

        }

    }

}


static unsigned long copy_elf_strings(int argc,char ** argv, void **page,

                                      unsigned long p)

{

    char *tmp, *tmp1, *pag = NULL;

    int len, offset = 0;

    if (!p) {

	return 0;       /* bullet-proofing */

    }

    while (argc-- > 0) {

        tmp = argv[argc];

        if (!tmp) {

	    fprintf(stderr, "VFS: argc is wrong");

	    exit(-1);

	}

        tmp1 = tmp;

	while (*tmp++);

	len = tmp - tmp1;

	if (p < len) {  /* this shouldn't happen - 128kB */

		return 0;

	}

	while (len) {

	    --p; --tmp; --len;

	    if (--offset < 0) {

		offset = p % TARGET_PAGE_SIZE;

                pag = (char *)page[p/TARGET_PAGE_SIZE];

                if (!pag) {

                    pag = (char *)malloc(TARGET_PAGE_SIZE);

                    page[p/TARGET_PAGE_SIZE] = pag;

                    if (!pag)

                        return 0;

		}

	    }

	    if (len == 0 || offset == 0) {

	        *(pag + offset) = *tmp;

	    }

	    else {

	      int bytes_to_copy = (len > offset) ? offset : len;

	      tmp -= bytes_to_copy;

	      p -= bytes_to_copy;

	      offset -= bytes_to_copy;

	      len -= bytes_to_copy;

	      memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);

	    }

	}

    }

    return p;

}


void fork_end(int child)

{

    mmap_fork_end(child);

    if (child) {

        CPUState *cpu, *next_cpu;

        /* Child processes created by fork() only have a single thread.

           Discard information about the parent threads.  */

        CPU_FOREACH_SAFE(cpu, next_cpu) {

            if (cpu != thread_cpu) {

                QTAILQ_REMOVE(&cpus, cpu, node);

            }

        }

        qemu_mutex_init(&tb_ctx.tb_lock);

        qemu_init_cpu_list();

        gdbserver_fork(thread_cpu);

    } else {

        qemu_mutex_unlock(&tb_ctx.tb_lock);

        cpu_list_unlock();

    }

}


static int mpc8_probe(AVProbeData *p)

{

    const uint8_t *bs = p->buf + 4;

    const uint8_t *bs_end = bs + p->buf_size;

    int64_t size;

    if (p->buf_size < 16)

        return 0;

    if (AV_RL32(p->buf) != TAG_MPCK)

        return 0;

    while (bs < bs_end + 3) {

        int header_found = (bs[0] == 'S' && bs[1] == 'H');

        if (bs[0] < 'A' || bs[0] > 'Z' || bs[1] < 'A' || bs[1] > 'Z')

            return 0;

        bs += 2;

        size = bs_get_v(&bs);

        if (size < 2)

            return 0;

        if (bs + size - 2 >= bs_end)

            return AVPROBE_SCORE_EXTENSION - 1; // seems to be valid MPC but no header yet

        if (header_found) {

            if (size < 11 || size > 28)

                return 0;

            if (!AV_RL32(bs)) //zero CRC is invalid

                return 0;

            return AVPROBE_SCORE_MAX;

        } else {

            bs += size - 2;

        }

    }

    return 0;

}


static TranslationBlock *tb_find_slow(target_ulong pc,

                                      target_ulong cs_base,

                                      uint64_t flags)

{

    TranslationBlock *tb, **ptb1;

    int code_gen_size;

    unsigned int h;

    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;

    uint8_t *tc_ptr;

    spin_lock(&tb_lock);

    tb_invalidated_flag = 0;

    regs_to_env(); /* XXX: do it just before cpu_gen_code() */

    /* find translated block using physical mappings */

    phys_pc = get_phys_addr_code(env, pc);

    phys_page1 = phys_pc & TARGET_PAGE_MASK;

    phys_page2 = -1;

    h = tb_phys_hash_func(phys_pc);

    ptb1 = &tb_phys_hash[h];

    for(;;) {

        tb = *ptb1;

        if (!tb)

            goto not_found;

        if (tb->pc == pc &&

            tb->page_addr[0] == phys_page1 &&

            tb->cs_base == cs_base &&

            tb->flags == flags) {

            /* check next page if needed */

            if (tb->page_addr[1] != -1) {

                virt_page2 = (pc & TARGET_PAGE_MASK) +

                    TARGET_PAGE_SIZE;

                phys_page2 = get_phys_addr_code(env, virt_page2);

                if (tb->page_addr[1] == phys_page2)

                    goto found;

            } else {

                goto found;

            }

        }

        ptb1 = &tb->phys_hash_next;

    }

 not_found:

    /* if no translated code available, then translate it now */

    tb = tb_alloc(pc);

    if (!tb) {

        /* flush must be done */

        tb_flush(env);

        /* cannot fail at this point */

        tb = tb_alloc(pc);

        /* don't forget to invalidate previous TB info */

        tb_invalidated_flag = 1;

    }

    tc_ptr = code_gen_ptr;

    tb->tc_ptr = tc_ptr;

    tb->cs_base = cs_base;

    tb->flags = flags;

    cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);

    code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));

    /* check next page if needed */

    virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;

    phys_page2 = -1;

    if ((pc & TARGET_PAGE_MASK) != virt_page2) {

        phys_page2 = get_phys_addr_code(env, virt_page2);

    }

    tb_link_phys(tb, phys_pc, phys_page2);

 found:

    /* we add the TB in the virtual pc hash table */

    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;

    spin_unlock(&tb_lock);

    return tb;

}


static int decode_block(MJpegDecodeContext *s, DCTELEM *block,

                        int component, int dc_index, int ac_index, int16_t *quant_matrix)

{

    int code, i, j, level, val;

    VLC *ac_vlc;

    /* DC coef */

    val = mjpeg_decode_dc(s, dc_index);

    if (val == 0xffff) {

        dprintf("error dc\n");

        return -1;

    }

    val = val * quant_matrix[0] + s->last_dc[component];

    s->last_dc[component] = val;

    block[0] = val;

    /* AC coefs */

    ac_vlc = &s->vlcs[1][ac_index];

    i = 0;

    {OPEN_READER(re, &s->gb)

    for(;;) {

        UPDATE_CACHE(re, &s->gb);

        GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2)

        /* EOB */

        if (code == 0x10)

            break;

        if (code == 0x100) {

            i += 16;

        } else {

            i += ((unsigned)code) >> 4;

            code &= 0xf;

            if(code > MIN_CACHE_BITS - 16){

                UPDATE_CACHE(re, &s->gb)

            }

            {

                int cache=GET_CACHE(re,gb);

                int sign=(~cache)>>31;

                level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;

            }

            LAST_SKIP_BITS(re, &s->gb, code)

            if (i >= 63) {

                if(i == 63){

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

                    block[j] = level * quant_matrix[j];

                    break;

                }

                dprintf("error count: %d\n", i);

                return -1;

            }

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

            block[j] = level * quant_matrix[j];

        }

    }

    CLOSE_READER(re, &s->gb)}

    return 0;

}


static int gif_read_image(GifState *s, AVFrame *frame)

{

    int left, top, width, height, bits_per_pixel, code_size, flags;

    int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i;

    uint8_t *ptr, *spal, *palette, *ptr1;

    left = bytestream_get_le16(&s->bytestream);

    top = bytestream_get_le16(&s->bytestream);

    width = bytestream_get_le16(&s->bytestream);

    height = bytestream_get_le16(&s->bytestream);

    flags = bytestream_get_byte(&s->bytestream);

    is_interleaved = flags & 0x40;

    has_local_palette = flags & 0x80;

    bits_per_pixel = (flags & 0x07) + 1;

    av_dlog(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height);

    if (has_local_palette) {

        bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel));

        palette = s->local_palette;

    } else {

        palette = s->global_palette;

        bits_per_pixel = s->bits_per_pixel;

    }

    /* verify that all the image is inside the screen dimensions */

    if (left + width > s->screen_width ||

        top + height > s->screen_height)

        return AVERROR(EINVAL);

    /* build the palette */

    n = (1 << bits_per_pixel);

    spal = palette;

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

        s->image_palette[i] = (0xffu << 24) | AV_RB24(spal);

        spal += 3;

    }

    for(; i < 256; i++)

        s->image_palette[i] = (0xffu << 24);

    /* handle transparency */

    if (s->transparent_color_index >= 0)

        s->image_palette[s->transparent_color_index] = 0;

    /* now get the image data */

    code_size = bytestream_get_byte(&s->bytestream);

    ff_lzw_decode_init(s->lzw, code_size, s->bytestream,

                       s->bytestream_end - s->bytestream, FF_LZW_GIF);

    /* read all the image */

    linesize = frame->linesize[0];

    ptr1 = frame->data[0] + top * linesize + left;

    ptr = ptr1;

    pass = 0;

    y1 = 0;

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

        ff_lzw_decode(s->lzw, ptr, width);

        if (is_interleaved) {

            switch(pass) {

            default:

            case 0:

            case 1:

                y1 += 8;

                ptr += linesize * 8;

                if (y1 >= height) {

                    y1 = pass ? 2 : 4;

                    ptr = ptr1 + linesize * y1;

                    pass++;

                }

                break;

            case 2:

                y1 += 4;

                ptr += linesize * 4;

                if (y1 >= height) {

                    y1 = 1;

                    ptr = ptr1 + linesize;

                    pass++;

                }

                break;

            case 3:

                y1 += 2;

                ptr += linesize * 2;

                break;

            }

        } else {

            ptr += linesize;

        }

    }

    /* read the garbage data until end marker is found */

    ff_lzw_decode_tail(s->lzw);

    s->bytestream = ff_lzw_cur_ptr(s->lzw);

    return 0;

}


static int oss_poll_in (HWVoiceIn *hw)

{

    OSSVoiceIn *oss = (OSSVoiceIn *) hw;

    return qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL);

}


static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr)

{

    struct sbg_fade f;

    if (lex_char(p, '<'))

        f.in = SBG_FADE_SILENCE;

    else if (lex_char(p, '-'))

        f.in = SBG_FADE_SAME;

    else if (lex_char(p, '='))

        f.in = SBG_FADE_ADAPT;

    else

        return 0;

    if (lex_char(p, '>'))

        f.out = SBG_FADE_SILENCE;

    else if (lex_char(p, '-'))

        f.out = SBG_FADE_SAME;

    else if (lex_char(p, '='))

        f.out = SBG_FADE_ADAPT;

    else

        return AVERROR_INVALIDDATA;

    *fr = f;

    return 1;

}


void qdev_prop_register_global(GlobalProperty *prop)

{

    QTAILQ_INSERT_TAIL(&global_props, prop, next);

}


int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,

                                  const HEVCSPS *sps, int is_slice_header)

{

    HEVCLocalContext *lc = s->HEVClc;

    uint8_t rps_predict = 0;

    int delta_poc;

    int k0 = 0;

    int k1 = 0;

    int k  = 0;

    int i;

    GetBitContext *gb = &lc->gb;

    if (rps != sps->st_rps && sps->nb_st_rps)

        rps_predict = get_bits1(gb);

    if (rps_predict) {

        const ShortTermRPS *rps_ridx;

        int delta_rps, abs_delta_rps;

        uint8_t use_delta_flag = 0;

        uint8_t delta_rps_sign;

        if (is_slice_header) {

            unsigned int delta_idx = get_ue_golomb_long(gb) + 1;

            if (delta_idx > sps->nb_st_rps) {

                av_log(s->avctx, AV_LOG_ERROR,

                       "Invalid value of delta_idx in slice header RPS: %d > %d.\n",

                       delta_idx, sps->nb_st_rps);

                return AVERROR_INVALIDDATA;

            }

            rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];

        } else

            rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];

        delta_rps_sign = get_bits1(gb);

        abs_delta_rps  = get_ue_golomb_long(gb) + 1;

        delta_rps      = (1 - (delta_rps_sign << 1)) * abs_delta_rps;

        for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {

            int used = rps->used[k] = get_bits1(gb);

            if (!used)

                use_delta_flag = get_bits1(gb);

            if (used || use_delta_flag) {

                if (i < rps_ridx->num_delta_pocs)

                    delta_poc = delta_rps + rps_ridx->delta_poc[i];

                else

                    delta_poc = delta_rps;

                rps->delta_poc[k] = delta_poc;

                if (delta_poc < 0)

                    k0++;

                else

                    k1++;

                k++;

            }

        }

        rps->num_delta_pocs    = k;

        rps->num_negative_pics = k0;

        // sort in increasing order (smallest first)

        if (rps->num_delta_pocs != 0) {

            int used, tmp;

            for (i = 1; i < rps->num_delta_pocs; i++) {

                delta_poc = rps->delta_poc[i];

                used      = rps->used[i];

                for (k = i - 1; k >= 0; k--) {

                    tmp = rps->delta_poc[k];

                    if (delta_poc < tmp) {

                        rps->delta_poc[k + 1] = tmp;

                        rps->used[k + 1]      = rps->used[k];

                        rps->delta_poc[k]     = delta_poc;

                        rps->used[k]          = used;

                    }

                }

            }

        }

        if ((rps->num_negative_pics >> 1) != 0) {

            int used;

            k = rps->num_negative_pics - 1;

            // flip the negative values to largest first

            for (i = 0; i < rps->num_negative_pics >> 1; i++) {

                delta_poc         = rps->delta_poc[i];

                used              = rps->used[i];

                rps->delta_poc[i] = rps->delta_poc[k];

                rps->used[i]      = rps->used[k];

                rps->delta_poc[k] = delta_poc;

                rps->used[k]      = used;

                k--;

            }

        }

    } else {

        unsigned int prev, nb_positive_pics;

        rps->num_negative_pics = get_ue_golomb_long(gb);

        nb_positive_pics       = get_ue_golomb_long(gb);

        if (rps->num_negative_pics >= MAX_REFS ||

            nb_positive_pics >= MAX_REFS) {

            av_log(s->avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");

            return AVERROR_INVALIDDATA;

        }

        rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;

        if (rps->num_delta_pocs) {

            prev = 0;

            for (i = 0; i < rps->num_negative_pics; i++) {

                delta_poc = get_ue_golomb_long(gb) + 1;

                prev -= delta_poc;

                rps->delta_poc[i] = prev;

                rps->used[i]      = get_bits1(gb);

            }

            prev = 0;

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

                delta_poc = get_ue_golomb_long(gb) + 1;

                prev += delta_poc;

                rps->delta_poc[rps->num_negative_pics + i] = prev;

                rps->used[rps->num_negative_pics + i]      = get_bits1(gb);

            }

        }

    }

    return 0;

}


iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
                QEMUIOVector *qiov, int nb_sectors,
                BlockDriverCompletionFunc *cb,
                void *opaque)
{
    IscsiLun *iscsilun = bs->opaque;
    IscsiAIOCB *acb;
    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);
    trace_iscsi_aio_readv(iscsilun->iscsi, sector_num, nb_sectors, opaque, acb);
    acb->nb_sectors  = nb_sectors;
    acb->sector_num  = sector_num;
    acb->iscsilun    = iscsilun;
    acb->qiov        = qiov;
    acb->retries     = ISCSI_CMD_RETRIES;
    if (iscsi_aio_readv_acb(acb) != 0) {
        qemu_aio_release(acb);
    iscsi_set_events(iscsilun);
    return &acb->common;


static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,

                              QemuConsole *con, int idx,

                              GSList *group, GtkWidget *view_menu)

{

    Error *local_err = NULL;

    Object *obj;

    obj = object_property_get_link(OBJECT(con), "device", &local_err);

    if (obj) {

        vc->label = g_strdup_printf("%s", object_get_typename(obj));

    } else {

        vc->label = g_strdup_printf("VGA");

    }

    vc->s = s;

    vc->gfx.scale_x = 1.0;

    vc->gfx.scale_y = 1.0;

    vc->gfx.drawing_area = gtk_drawing_area_new();

    gtk_widget_add_events(vc->gfx.drawing_area,

                          GDK_POINTER_MOTION_MASK |

                          GDK_BUTTON_PRESS_MASK |

                          GDK_BUTTON_RELEASE_MASK |

                          GDK_BUTTON_MOTION_MASK |

                          GDK_ENTER_NOTIFY_MASK |

                          GDK_LEAVE_NOTIFY_MASK |

                          GDK_SCROLL_MASK |

                          GDK_KEY_PRESS_MASK);

    gtk_widget_set_can_focus(vc->gfx.drawing_area, TRUE);

    vc->type = GD_VC_GFX;

    vc->tab_item = vc->gfx.drawing_area;

    gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),

                             vc->tab_item, gtk_label_new(vc->label));

    gd_connect_vc_gfx_signals(vc);

    group = gd_vc_menu_init(s, vc, idx, group, view_menu);

    vc->gfx.dcl.ops = &dcl_ops;

    vc->gfx.dcl.con = con;

    register_displaychangelistener(&vc->gfx.dcl);

    return group;

}


int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options)

{

    int port;

    const char *p;

    char buf[200], opts[50] = "";

    struct addrinfo hints = { 0 }, *ai = NULL;

    const char *proxy_path;

    int use_proxy;

    set_options(c, uri);

    if (c->listen)

        snprintf(opts, sizeof(opts), "?listen=1");

    av_url_split(NULL, 0, NULL, 0, c->host, sizeof(c->host), &port, NULL, 0, uri);

    p = strchr(uri, '?');

    if (!p) {

        p = opts;

    } else {

        if (av_find_info_tag(opts, sizeof(opts), "listen", p))

            c->listen = 1;

    }

    ff_url_join(buf, sizeof(buf), "tcp", NULL, c->host, port, "%s", p);

    hints.ai_flags = AI_NUMERICHOST;

    if (!getaddrinfo(c->host, NULL, &hints, &ai)) {

        c->numerichost = 1;

        freeaddrinfo(ai);

    }

    proxy_path = getenv("http_proxy");

    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->host) &&

                proxy_path && av_strstart(proxy_path, "http://", NULL);

    if (use_proxy) {

        char proxy_host[200], proxy_auth[200], dest[200];

        int proxy_port;

        av_url_split(NULL, 0, proxy_auth, sizeof(proxy_auth),

                     proxy_host, sizeof(proxy_host), &proxy_port, NULL, 0,

                     proxy_path);

        ff_url_join(dest, sizeof(dest), NULL, NULL, c->host, port, NULL);

        ff_url_join(buf, sizeof(buf), "httpproxy", proxy_auth, proxy_host,

                    proxy_port, "/%s", dest);

    }

    return ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE,

                      &parent->interrupt_callback, options);

}


static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)

{

    static int apic_mapped;

    CPUX86State *env = &cpu->env;

    APICCommonState *apic;

    const char *apic_type = "apic";

    if (kvm_irqchip_in_kernel()) {

        apic_type = "kvm-apic";

    } else if (xen_enabled()) {

        apic_type = "xen-apic";

    }

    env->apic_state = qdev_try_create(NULL, apic_type);

    if (env->apic_state == NULL) {

        error_setg(errp, "APIC device '%s' could not be created", apic_type);

        return;

    }

    object_property_add_child(OBJECT(cpu), "apic",

                              OBJECT(env->apic_state), NULL);

    qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);

    /* TODO: convert to link<> */

    apic = APIC_COMMON(env->apic_state);

    apic->cpu = cpu;

    if (qdev_init(env->apic_state)) {

        error_setg(errp, "APIC device '%s' could not be initialized",

                   object_get_typename(OBJECT(env->apic_state)));

        return;

    }

    /* XXX: mapping more APICs at the same memory location */

    if (apic_mapped == 0) {

        /* NOTE: the APIC is directly connected to the CPU - it is not

           on the global memory bus. */

        /* XXX: what if the base changes? */

        sysbus_mmio_map_overlap(SYS_BUS_DEVICE(env->apic_state), 0,

                                APIC_DEFAULT_ADDRESS, 0x1000);

        apic_mapped = 1;

    }

}


static inline int clamp(int value, int min, int max)

{

   if (value < min)

       return min;

   else if (value > max)

       return max;

   else

       return value;

}


void audio_init(ISABus *isa_bus, PCIBus *pci_bus)

{

}


static void nand_command(NANDFlashState *s)

{

    unsigned int offset;

    switch (s->cmd) {

    case NAND_CMD_READ0:

        s->iolen = 0;

        break;

    case NAND_CMD_READID:

        s->ioaddr = s->io;

        s->iolen = 0;

        nand_pushio_byte(s, s->manf_id);

        nand_pushio_byte(s, s->chip_id);

        nand_pushio_byte(s, 'Q'); /* Don't-care byte (often 0xa5) */

        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {

            /* Page Size, Block Size, Spare Size; bit 6 indicates

             * 8 vs 16 bit width NAND.

             */

            nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15);

        } else {

            nand_pushio_byte(s, 0xc0); /* Multi-plane */

        }

        break;

    case NAND_CMD_RANDOMREAD2:

    case NAND_CMD_NOSERIALREAD2:

        if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))

            break;

        offset = s->addr & ((1 << s->addr_shift) - 1);

        s->blk_load(s, s->addr, offset);

        if (s->gnd)

            s->iolen = (1 << s->page_shift) - offset;

        else

            s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;

        break;

    case NAND_CMD_RESET:

        nand_reset(DEVICE(s));

        break;

    case NAND_CMD_PAGEPROGRAM1:

        s->ioaddr = s->io;

        s->iolen = 0;

        break;

    case NAND_CMD_PAGEPROGRAM2:

        if (s->wp) {

            s->blk_write(s);

        }

        break;

    case NAND_CMD_BLOCKERASE1:

        break;

    case NAND_CMD_BLOCKERASE2:

        s->addr &= (1ull << s->addrlen * 8) - 1;

        s->addr <<= nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP ?

                                                                    16 : 8;

        if (s->wp) {

            s->blk_erase(s);

        }

        break;

    case NAND_CMD_READSTATUS:

        s->ioaddr = s->io;

        s->iolen = 0;

        nand_pushio_byte(s, s->status);

        break;

    default:

        printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);

    }

}


int64_t qemu_clock_deadline_ns_all(QEMUClockType type)

{

    int64_t deadline = -1;

    QEMUTimerList *timer_list;

    QEMUClock *clock = qemu_clock_ptr(type);

    QLIST_FOREACH(timer_list, &clock->timerlists, list) {

        deadline = qemu_soonest_timeout(deadline,

                                        timerlist_deadline_ns(timer_list));

    }

    return deadline;

}


UserDefTwo *qmp_user_def_cmd2(UserDefOne *ud1a,

                              bool has_udb1, UserDefOne *ud1b,

                              Error **errp)

{

    UserDefTwo *ret;

    UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));

    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));

    ud1c->string = strdup(ud1a->string);

    ud1c->base = g_new0(UserDefZero, 1);

    ud1c->base->integer = ud1a->base->integer;

    ud1d->string = strdup(has_udb1 ? ud1b->string : "blah0");

    ud1d->base = g_new0(UserDefZero, 1);

    ud1d->base->integer = has_udb1 ? ud1b->base->integer : 0;

    ret = g_new0(UserDefTwo, 1);

    ret->string0 = strdup("blah1");

    ret->dict1 = g_new0(UserDefTwoDict, 1);

    ret->dict1->string1 = strdup("blah2");

    ret->dict1->dict2 = g_new0(UserDefTwoDictDict, 1);

    ret->dict1->dict2->userdef = ud1c;

    ret->dict1->dict2->string = strdup("blah3");

    ret->dict1->dict3 = g_new0(UserDefTwoDictDict, 1);

    ret->dict1->has_dict3 = true;

    ret->dict1->dict3->userdef = ud1d;

    ret->dict1->dict3->string = strdup("blah4");

    return ret;

}


static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,

                                 uint64_t value)

{

    int maskshift = extract32(value, 0, 3);

    if (arm_feature(env, ARM_FEATURE_LPAE) && (value & (1 << 31))) {

        value &= ~((7 << 19) | (3 << 14) | (0xf << 3));

    } else {

        value &= 7;

    }

    /* Note that we always calculate c2_mask and c2_base_mask, but

     * they are only used for short-descriptor tables (ie if EAE is 0);

     * for long-descriptor tables the TTBCR fields are used differently

     * and the c2_mask and c2_base_mask values are meaningless.

     */

    env->cp15.c2_control = value;

    env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> maskshift);

    env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> maskshift);

}


static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,

                                          int idx)

{

    openpic_t *opp = opaque;

    IRQ_src_t *src;

    IRQ_dst_t *dst;

    uint32_t retval;

    int n_IRQ;

    DPRINTF("%s: cpu %d addr " TARGET_FMT_plx "\n", __func__, idx, addr);

    retval = 0xFFFFFFFF;

    if (addr & 0xF)

        return retval;

    dst = &opp->dst[idx];

    addr &= 0xFF0;

    switch (addr) {

    case 0x00: /* Block Revision Register1 (BRR1) */

        retval = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;

        break;

    case 0x80: /* PCTP */

        retval = dst->pctp;

        break;

    case 0x90: /* WHOAMI */

        retval = idx;

        break;

    case 0xA0: /* PIAC */

        DPRINTF("Lower OpenPIC INT output\n");

        qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]);

        n_IRQ = IRQ_get_next(opp, &dst->raised);

        DPRINTF("PIAC: irq=%d\n", n_IRQ);

        if (n_IRQ == -1) {

            /* No more interrupt pending */

            retval = IPVP_VECTOR(opp->spve);

        } else {

            src = &opp->src[n_IRQ];

            if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||

                !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {

                /* - Spurious level-sensitive IRQ

                 * - Priorities has been changed

                 *   and the pending IRQ isn't allowed anymore

                 */

                reset_bit(&src->ipvp, IPVP_ACTIVITY);

                retval = IPVP_VECTOR(opp->spve);

            } else {

                /* IRQ enter servicing state */

                IRQ_setbit(&dst->servicing, n_IRQ);

                retval = IPVP_VECTOR(src->ipvp);

            }

            IRQ_resetbit(&dst->raised, n_IRQ);

            dst->raised.next = -1;

            if (!test_bit(&src->ipvp, IPVP_SENSE)) {

                /* edge-sensitive IRQ */

                reset_bit(&src->ipvp, IPVP_ACTIVITY);

                src->pending = 0;

            }

            if ((n_IRQ >= opp->irq_ipi0) &&  (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) {

                src->ide &= ~(1 << idx);

                if (src->ide && !test_bit(&src->ipvp, IPVP_SENSE)) {

                    /* trigger on CPUs that didn't know about it yet */

                    openpic_set_irq(opp, n_IRQ, 1);

                    openpic_set_irq(opp, n_IRQ, 0);

                    /* if all CPUs knew about it, set active bit again */

                    set_bit(&src->ipvp, IPVP_ACTIVITY);

                }

            }

        }

        break;

    case 0xB0: /* PEOI */

        retval = 0;

        break;

    default:

        break;

    }

    DPRINTF("%s: => %08x\n", __func__, retval);

    return retval;

}


static int faac_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             uint8_t *buf, int buf_size)

{

    FAACContext *s = (FAACContext *) avctx->priv_data;

#ifndef FAAD2_VERSION

    unsigned long bytesconsumed;

    short *sample_buffer = NULL;

    unsigned long samples;

    int out;

#else

    faacDecFrameInfo frame_info;

    void *out;

#endif

    if(buf_size == 0)

        return 0;

#ifndef FAAD2_VERSION

    out = s->faacDecDecode(s->faac_handle,

                           (unsigned char*)buf,

                           &bytesconsumed,

                           data,

                           &samples);

    samples *= s->sample_size;

    if (data_size)

        *data_size = samples;

    return (buf_size < (int)bytesconsumed)

        ? buf_size : (int)bytesconsumed;

#else

    if(!s->init){

        unsigned long srate;

        unsigned char channels;

        int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels);

        if(r < 0){

            av_log(avctx, AV_LOG_ERROR, "faac: codec init failed: %s\n",

                   s->faacDecGetErrorMessage(frame_info.error));

            return 0;

        }

        avctx->sample_rate = srate;

        avctx->channels = channels;

        s->init = 1;

    }

    out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size);

    if (frame_info.error > 0) {

        av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n",

                s->faacDecGetErrorMessage(frame_info.error));

        return 0;

    }

    frame_info.samples *= s->sample_size;

    memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one

    if (data_size)

        *data_size = frame_info.samples;

    return (buf_size < (int)frame_info.bytesconsumed)

        ? buf_size : (int)frame_info.bytesconsumed;

#endif

}


void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms,

                         MemoryRegion *mr, uint64_t align, Error **errp)

{

    int slot;

    MachineState *machine = MACHINE(qdev_get_machine());

    PCDIMMDevice *dimm = PC_DIMM(dev);

    Error *local_err = NULL;

    uint64_t existing_dimms_capacity = 0;

    uint64_t addr;

    addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);

    if (local_err) {

        goto out;

    }

    addr = pc_dimm_get_free_addr(hpms->base,

                                 memory_region_size(&hpms->mr),

                                 !addr ? NULL : &addr, align,

                                 memory_region_size(mr), &local_err);

    if (local_err) {

        goto out;

    }

    existing_dimms_capacity = pc_existing_dimms_capacity(&local_err);

    if (local_err) {

        goto out;

    }

    if (existing_dimms_capacity + memory_region_size(mr) >

        machine->maxram_size - machine->ram_size) {

        error_setg(&local_err, "not enough space, currently 0x%" PRIx64

                   " in use of total hot pluggable 0x" RAM_ADDR_FMT,

                   existing_dimms_capacity,

                   machine->maxram_size - machine->ram_size);

        goto out;

    }

    object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err);

    if (local_err) {

        goto out;

    }

    trace_mhp_pc_dimm_assigned_address(addr);

    slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, &local_err);

    if (local_err) {

        goto out;

    }

    slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,

                                 machine->ram_slots, &local_err);

    if (local_err) {

        goto out;

    }

    object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &local_err);

    if (local_err) {

        goto out;

    }

    trace_mhp_pc_dimm_assigned_slot(slot);

    if (kvm_enabled() && !kvm_has_free_slot(machine)) {

        error_setg(&local_err, "hypervisor has no free memory slots left");

        goto out;

    }

    if (!vhost_has_free_slot()) {

        error_setg(&local_err, "a used vhost backend has no free"

                               " memory slots left");

        goto out;

    }

    memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr);

    vmstate_register_ram(mr, dev);

    numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node);

out:

    error_propagate(errp, local_err);

}


static BOOL WINAPI qemu_ctrl_handler(DWORD type)

{

    exit(STATUS_CONTROL_C_EXIT);

    return TRUE;

}


static int spapr_phb_init(SysBusDevice *s)

{

    sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);

    PCIHostState *phb = PCI_HOST_BRIDGE(s);

    char *namebuf;

    int i;

    PCIBus *bus;

    sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);

    namebuf = alloca(strlen(sphb->dtbusname) + 32);

    /* Initialize memory regions */

    sprintf(namebuf, "%s.mmio", sphb->dtbusname);

    memory_region_init(&sphb->memspace, namebuf, INT64_MAX);

    sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname);

    memory_region_init_alias(&sphb->memwindow, namebuf, &sphb->memspace,

                             SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);

    memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,

                                &sphb->memwindow);

    /* On ppc, we only have MMIO no specific IO space from the CPU

     * perspective.  In theory we ought to be able to embed the PCI IO

     * memory region direction in the system memory space.  However,

     * if any of the IO BAR subregions use the old_portio mechanism,

     * that won't be processed properly unless accessed from the

     * system io address space.  This hack to bounce things via

     * system_io works around the problem until all the users of

     * old_portion are updated */

    sprintf(namebuf, "%s.io", sphb->dtbusname);

    memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);

    /* FIXME: fix to support multiple PHBs */

    memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);

    sprintf(namebuf, "%s.io-alias", sphb->dtbusname);

    memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,

                          namebuf, SPAPR_PCI_IO_WIN_SIZE);

    memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,

                                &sphb->iowindow);

    /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,

     * we need to allocate some memory to catch those writes coming

     * from msi_notify()/msix_notify() */

    if (msi_supported) {

        sprintf(namebuf, "%s.msi", sphb->dtbusname);

        memory_region_init_io(&sphb->msiwindow, &spapr_msi_ops, sphb,

                              namebuf, SPAPR_MSIX_MAX_DEVS * 0x10000);

        memory_region_add_subregion(get_system_memory(), sphb->msi_win_addr,

                                    &sphb->msiwindow);

    }

    bus = pci_register_bus(DEVICE(s),

                           sphb->busname ? sphb->busname : sphb->dtbusname,

                           pci_spapr_set_irq, pci_spapr_map_irq, sphb,

                           &sphb->memspace, &sphb->iospace,

                           PCI_DEVFN(0, 0), PCI_NUM_PINS);

    phb->bus = bus;

    sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);

    sphb->dma_window_start = 0;

    sphb->dma_window_size = 0x40000000;

    sphb->dma = spapr_tce_new_dma_context(sphb->dma_liobn, sphb->dma_window_size);

    pci_setup_iommu(bus, spapr_pci_dma_context_fn, sphb);

    QLIST_INSERT_HEAD(&spapr->phbs, sphb, list);

    /* Initialize the LSI table */

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

        uint32_t irq;

        irq = spapr_allocate_lsi(0);

        if (!irq) {

            return -1;

        }

        sphb->lsi_table[i].irq = irq;

    }

    return 0;

}


static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,

                           unsigned size)

{

    IMXEPITState *s = IMX_EPIT(opaque);

    uint32_t reg = offset >> 2;

    uint64_t oldcr;

    DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(reg), (uint32_t)value);

    switch (reg) {

    case 0: /* CR */

        oldcr = s->cr;

        s->cr = value & 0x03ffffff;

        if (s->cr & CR_SWR) {

            /* handle the reset */

            imx_epit_reset(DEVICE(s));

        } else {

            imx_epit_set_freq(s);

        }

        if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {

            if (s->cr & CR_ENMOD) {

                if (s->cr & CR_RLD) {

                    ptimer_set_limit(s->timer_reload, s->lr, 1);

                    ptimer_set_limit(s->timer_cmp, s->lr, 1);

                } else {

                    ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);

                    ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);

                }

            }

            imx_epit_reload_compare_timer(s);

            ptimer_run(s->timer_reload, 0);

            if (s->cr & CR_OCIEN) {

                ptimer_run(s->timer_cmp, 0);

            } else {

                ptimer_stop(s->timer_cmp);

            }

        } else if (!(s->cr & CR_EN)) {

            /* stop both timers */

            ptimer_stop(s->timer_reload);

            ptimer_stop(s->timer_cmp);

        } else  if (s->cr & CR_OCIEN) {

            if (!(oldcr & CR_OCIEN)) {

                imx_epit_reload_compare_timer(s);

                ptimer_run(s->timer_cmp, 0);

            }

        } else {

            ptimer_stop(s->timer_cmp);

        }

        break;

    case 1: /* SR - ACK*/

        /* writing 1 to OCIF clear the OCIF bit */

        if (value & 0x01) {

            s->sr = 0;

            imx_epit_update_int(s);

        }

        break;

    case 2: /* LR - set ticks */

        s->lr = value;

        if (s->cr & CR_RLD) {

            /* Also set the limit if the LRD bit is set */

            /* If IOVW bit is set then set the timer value */

            ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);

            ptimer_set_limit(s->timer_cmp, s->lr, 0);

        } else if (s->cr & CR_IOVW) {

            /* If IOVW bit is set then set the timer value */

            ptimer_set_count(s->timer_reload, s->lr);

        }

        imx_epit_reload_compare_timer(s);

        break;

    case 3: /* CMP */

        s->cmp = value;

        imx_epit_reload_compare_timer(s);

        break;

    default:

        IPRINTF("Bad offset %x\n", reg);

        break;

    }

}


uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)

{

    if (r2 > ram_size) {

        return 0;

    }

    /* XXX implement */

#if 0

    env->storage_keys[r2 / TARGET_PAGE_SIZE] &= ~SK_REFERENCED;

#endif

    /*

     * cc

     *

     * 0  Reference bit zero; change bit zero

     * 1  Reference bit zero; change bit one

     * 2  Reference bit one; change bit zero

     * 3  Reference bit one; change bit one

     */

    return 0;

}


static void ivshmem_io_write(void *opaque, target_phys_addr_t addr,

                             uint64_t val, unsigned size)

{

    IVShmemState *s = opaque;

    uint16_t dest = val >> 16;

    uint16_t vector = val & 0xff;

    addr &= 0xfc;

    IVSHMEM_DPRINTF("writing to addr " TARGET_FMT_plx "\n", addr);

    switch (addr)

    {

        case INTRMASK:

            ivshmem_IntrMask_write(s, val);

            break;

        case INTRSTATUS:

            ivshmem_IntrStatus_write(s, val);

            break;

        case DOORBELL:

            /* check that dest VM ID is reasonable */

            if (dest > s->max_peer) {

                IVSHMEM_DPRINTF("Invalid destination VM ID (%d)\n", dest);

                break;

            }

            /* check doorbell range */

            if (vector < s->peers[dest].nb_eventfds) {

                IVSHMEM_DPRINTF("Notifying VM %d on vector %d\n", dest, vector);

                event_notifier_set(&s->peers[dest].eventfds[vector]);

            }

            break;

        default:

            IVSHMEM_DPRINTF("Invalid VM Doorbell VM %d\n", dest);

    }

}


SpiceInfo *qmp_query_spice(Error **errp)

{

    QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);

    int port, tls_port;

    const char *addr;

    SpiceInfo *info;

    char version_string[20]; /* 12 = |255.255.255\0| is the max */

    info = g_malloc0(sizeof(*info));

    if (!spice_server || !opts) {

        info->enabled = false;

        return info;

    }

    info->enabled = true;

    info->migrated = spice_migration_completed;

    addr = qemu_opt_get(opts, "addr");

    port = qemu_opt_get_number(opts, "port", 0);

    tls_port = qemu_opt_get_number(opts, "tls-port", 0);

    info->has_auth = true;

    info->auth = g_strdup(auth);

    info->has_host = true;

    info->host = g_strdup(addr ? addr : "0.0.0.0");

    info->has_compiled_version = true;

    snprintf(version_string, sizeof(version_string), "%d.%d.%d",

             (SPICE_SERVER_VERSION & 0xff0000) >> 16,

             (SPICE_SERVER_VERSION & 0xff00) >> 8,

             SPICE_SERVER_VERSION & 0xff);

    info->compiled_version = g_strdup(version_string);

    if (port) {

        info->has_port = true;

        info->port = port;

    }

    if (tls_port) {

        info->has_tls_port = true;

        info->tls_port = tls_port;

    }

    info->mouse_mode = spice_server_is_server_mouse(spice_server) ?

                       SPICE_QUERY_MOUSE_MODE_SERVER :

                       SPICE_QUERY_MOUSE_MODE_CLIENT;

    /* for compatibility with the original command */

    info->has_channels = true;

    info->channels = qmp_query_spice_channels();

    return info;

}


void memory_region_init_rom_device(MemoryRegion *mr,

                                   const MemoryRegionOps *ops,

                                   void *opaque,

                                   const char *name,

                                   uint64_t size)

{

    memory_region_init(mr, name, size);

    mr->ops = ops;

    mr->opaque = opaque;

    mr->terminates = true;

    mr->destructor = memory_region_destructor_rom_device;

    mr->ram_addr = qemu_ram_alloc(size, mr);

    mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,

                                           memory_region_write_thunk,

                                           mr);

    mr->ram_addr |= IO_MEM_ROMD;

    mr->backend_registered = true;

}


av_cold int ff_rv34_decode_init(AVCodecContext *avctx)

{

    RV34DecContext *r = avctx->priv_data;

    MpegEncContext *s = &r->s;

    MPV_decode_defaults(s);

    s->avctx= avctx;

    s->out_format = FMT_H263;

    s->codec_id= avctx->codec_id;

    s->width = avctx->width;

    s->height = avctx->height;

    r->s.avctx = avctx;

    avctx->flags |= CODEC_FLAG_EMU_EDGE;

    r->s.flags |= CODEC_FLAG_EMU_EDGE;

    avctx->pix_fmt = PIX_FMT_YUV420P;

    avctx->has_b_frames = 1;

    s->low_delay = 0;

    if (MPV_common_init(s) < 0)

        return -1;

    ff_h264_pred_init(&r->h, CODEC_ID_RV40);

    r->intra_types_hist = av_malloc(s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist));

    r->intra_types = r->intra_types_hist + s->b4_stride * 4;

    r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type));

    r->cbp_luma   = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma));

    r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma));

    r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs));

    if(!intra_vlcs[0].cbppattern[0].bits)

        rv34_init_tables();

    return 0;

}


static inline void mix_2f_2r_to_stereo(AC3DecodeContext *ctx)

{

    int i;

    float (*output)[256] = ctx->audio_block.block_output;

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

        output[1][i] += output[3][i];

        output[2][i] += output[4][i];

    }

    memset(output[3], 0, sizeof(output[3]));

    memset(output[4], 0, sizeof(output[4]));

}


void *qemu_vmalloc(size_t size)

{

    void *p;

    unsigned long addr;

    mmap_lock();

    /* Use map and mark the pages as used.  */

    p = mmap(NULL, size, PROT_READ | PROT_WRITE,

             MAP_PRIVATE | MAP_ANON, -1, 0);

    addr = (unsigned long)p;

    if (addr == (target_ulong) addr) {

        /* Allocated region overlaps guest address space.

           This may recurse.  */

        page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),

                       PAGE_RESERVED);

    }

    mmap_unlock();

    return p;

}


static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,

                                         uint32_t token, uint32_t nargs,

                                         target_ulong args,

                                         uint32_t nret, target_ulong rets)

{

    target_ulong id;

    CPUState *cpu;

    if (nargs != 1 || nret != 2) {

        rtas_st(rets, 0, -3);

        return;

    }

    id = rtas_ld(args, 0);

    cpu = qemu_get_cpu(id);

    if (cpu != NULL) {

        if (cpu->halted) {

            rtas_st(rets, 1, 0);

        } else {

            rtas_st(rets, 1, 2);

        }

        rtas_st(rets, 0, 0);

        return;

    }

    /* Didn't find a matching cpu */

    rtas_st(rets, 0, -3);

}


static void nvic_recompute_state(NVICState *s)

{

    int i;

    int pend_prio = NVIC_NOEXC_PRIO;

    int active_prio = NVIC_NOEXC_PRIO;

    int pend_irq = 0;

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

        VecInfo *vec = &s->vectors[i];

        if (vec->enabled && vec->pending && vec->prio < pend_prio) {

            pend_prio = vec->prio;

            pend_irq = i;

        }

        if (vec->active && vec->prio < active_prio) {

            active_prio = vec->prio;

        }

    }

    if (active_prio > 0) {

        active_prio &= nvic_gprio_mask(s);

    }

    s->vectpending = pend_irq;

    s->exception_prio = active_prio;

    trace_nvic_recompute_state(s->vectpending, s->exception_prio);

}


static int local_fsync(FsContext *ctx, int fd)

{

    if (0) /* Just to supress the warning. Will be removed in next patch. */

        (void)local_set_xattr(NULL, NULL);

    return fsync(fd);

}


void qmp_blockdev_add(BlockdevOptions *options, Error **errp)

{

    BlockDriverState *bs;

    QObject *obj;

    Visitor *v = qmp_output_visitor_new(&obj);

    QDict *qdict;

    Error *local_err = NULL;

    visit_type_BlockdevOptions(v, NULL, &options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        goto fail;

    }

    visit_complete(v, &obj);

    qdict = qobject_to_qdict(obj);

    qdict_flatten(qdict);

    if (!qdict_get_try_str(qdict, "node-name")) {

        error_setg(errp, "'node-name' must be specified for the root node");

        goto fail;

    }

    bs = bds_tree_init(qdict, errp);

    if (!bs) {

        goto fail;

    }

    QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);

    if (bs && bdrv_key_required(bs)) {

        QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);

        bdrv_unref(bs);

        error_setg(errp, "blockdev-add doesn't support encrypted devices");

        goto fail;

    }

fail:

    visit_free(v);

}


static int segment_start(AVFormatContext *s)

{

    SegmentContext *seg = s->priv_data;

    AVFormatContext *oc = seg->avf;

    int err = 0;

    if (seg->wrap)

        seg->number %= seg->wrap;

    if (av_get_frame_filename(oc->filename, sizeof(oc->filename),

                              s->filename, seg->number++) < 0)

        return AVERROR(EINVAL);

    if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,

                          &s->interrupt_callback, NULL)) < 0)

        return err;

    if (!oc->priv_data && oc->oformat->priv_data_size > 0) {

        oc->priv_data = av_mallocz(oc->oformat->priv_data_size);

        if (!oc->priv_data) {

            avio_close(oc->pb);

            return AVERROR(ENOMEM);

        }

        if (oc->oformat->priv_class) {

            *(const AVClass**)oc->priv_data = oc->oformat->priv_class;

            av_opt_set_defaults(oc->priv_data);

        }

    }

    if ((err = oc->oformat->write_header(oc)) < 0) {

        goto fail;

    }

    return 0;

fail:

    av_log(oc, AV_LOG_ERROR, "Failure occurred when starting segment '%s'\n",

           oc->filename);

    avio_close(oc->pb);

    av_freep(&oc->priv_data);

    return err;

}


static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)

{

    mp_image_t *dmpi;

    if (vf->priv->in.fmt == vf->priv->out.fmt) { //nothing to do

        dmpi = mpi;

    } else {

        int out_off_left, out_off_right;

        int in_off_left  = vf->priv->in.row_left   * mpi->stride[0]  +

                           vf->priv->in.off_left;

        int in_off_right = vf->priv->in.row_right  * mpi->stride[0]  +

                           vf->priv->in.off_right;

        dmpi = ff_vf_get_image(vf->next, IMGFMT_RGB24, MP_IMGTYPE_TEMP,

                            MP_IMGFLAG_ACCEPT_STRIDE,

                            vf->priv->out.width, vf->priv->out.height);

        out_off_left   = vf->priv->out.row_left  * dmpi->stride[0] +

                         vf->priv->out.off_left;

        out_off_right  = vf->priv->out.row_right * dmpi->stride[0] +

                         vf->priv->out.off_right;

        switch (vf->priv->out.fmt) {

        case SIDE_BY_SIDE_LR:

        case SIDE_BY_SIDE_RL:

        case SIDE_BY_SIDE_2_LR:

        case SIDE_BY_SIDE_2_RL:

        case ABOVE_BELOW_LR:

        case ABOVE_BELOW_RL:

        case ABOVE_BELOW_2_LR:

        case ABOVE_BELOW_2_RL:

        case INTERLEAVE_ROWS_LR:

        case INTERLEAVE_ROWS_RL:

            memcpy_pic2(dmpi->planes[0] + out_off_left,

                       mpi->planes[0] + in_off_left,

                       3 * vf->priv->width,

                       vf->priv->height,

                       dmpi->stride[0] * vf->priv->row_step,

                       mpi->stride[0] * vf->priv->row_step,

                       vf->priv->row_step != 1);

            memcpy_pic2(dmpi->planes[0] + out_off_right,

                       mpi->planes[0] + in_off_right,

                       3 * vf->priv->width,

                       vf->priv->height,

                       dmpi->stride[0] * vf->priv->row_step,

                       mpi->stride[0] * vf->priv->row_step,

                       vf->priv->row_step != 1);

            break;

        case MONO_L:

        case MONO_R:

            memcpy_pic(dmpi->planes[0],

                       mpi->planes[0] + in_off_left,

                       3 * vf->priv->width,

                       vf->priv->height,

                       dmpi->stride[0],

                       mpi->stride[0]);

            break;

        case ANAGLYPH_RC_GRAY:

        case ANAGLYPH_RC_HALF:

        case ANAGLYPH_RC_COLOR:

        case ANAGLYPH_RC_DUBOIS:

        case ANAGLYPH_GM_GRAY:

        case ANAGLYPH_GM_HALF:

        case ANAGLYPH_GM_COLOR:

        case ANAGLYPH_YB_GRAY:

        case ANAGLYPH_YB_HALF:

        case ANAGLYPH_YB_COLOR: {

            int i,x,y,il,ir,o;

            unsigned char *source     = mpi->planes[0];

            unsigned char *dest       = dmpi->planes[0];

            unsigned int   out_width  = vf->priv->out.width;

            int           *ana_matrix[3];

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

                ana_matrix[i] = vf->priv->ana_matrix[i];

            for (y = 0; y < vf->priv->out.height; y++) {

                o   = dmpi->stride[0] * y;

                il  = in_off_left  + y * mpi->stride[0];

                ir  = in_off_right + y * mpi->stride[0];

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

                    dest[o    ]  = ana_convert(

                                   ana_matrix[0], source + il, source + ir); //red out

                    dest[o + 1]  = ana_convert(

                                   ana_matrix[1], source + il, source + ir); //green out

                    dest[o + 2]  = ana_convert(

                                   ana_matrix[2], source + il, source + ir); //blue out

                    il += 3;

                    ir += 3;

                    o  += 3;

                }

            }

            break;

        }

        default:

            ff_mp_msg(MSGT_VFILTER, MSGL_WARN,

                   "[stereo3d] stereo format of output is not supported\n");

            return 0;

            break;

        }

    }

    return ff_vf_next_put_image(vf, dmpi, pts);

}


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

{

    VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);

    SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);

    VFIODevice *vbasedev = &vdev->vbasedev;

    int i, ret;

    vbasedev->type = VFIO_DEVICE_TYPE_PLATFORM;

    vbasedev->ops = &vfio_platform_ops;

    trace_vfio_platform_realize(vbasedev->name, vdev->compat);

    ret = vfio_base_device_init(vbasedev);

    if (ret) {

        error_setg(errp, "vfio: vfio_base_device_init failed for %s",

                   vbasedev->name);

        return;

    }

    for (i = 0; i < vbasedev->num_regions; i++) {

        vfio_map_region(vdev, i);

        sysbus_init_mmio(sbdev, &vdev->regions[i]->mem);

    }

}


void json_lexer_destroy(JSONLexer *lexer)

{

    QDECREF(lexer->token);

}


static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,

                               uint64_t data, unsigned size)

{

    PCNetState *d = opaque;

    if (addr < 16 && size == 1) {

        return pcnet_aprom_writeb(d, addr, data);

    } else if (addr >= 0x10 && addr < 0x20 && size == 2) {

        return pcnet_ioport_writew(d, addr, data);

    } else if (addr >= 0x10 && addr < 0x20 && size == 4) {

        return pcnet_ioport_writel(d, addr, data);

    }

}


build_hash_table (const sparc_opcode **opcode_table,

                  sparc_opcode_hash **hash_table,

                  int num_opcodes)

{

  int i;

  int hash_count[HASH_SIZE];

  static sparc_opcode_hash *hash_buf = NULL;

  /* Start at the end of the table and work backwards so that each

     chain is sorted.  */

  memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));

  memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));

  if (hash_buf != NULL)

    free (hash_buf);

  hash_buf = malloc (sizeof (* hash_buf) * num_opcodes);

  for (i = num_opcodes - 1; i >= 0; --i)

    {

      int hash = HASH_INSN (opcode_table[i]->match);

      sparc_opcode_hash *h = &hash_buf[i];

      h->next = hash_table[hash];

      h->opcode = opcode_table[i];

      hash_table[hash] = h;

      ++hash_count[hash];

    }

#if 0 /* for debugging */

  {

    int min_count = num_opcodes, max_count = 0;

    int total;

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

      {

        if (hash_count[i] < min_count)

          min_count = hash_count[i];

        if (hash_count[i] > max_count)

          max_count = hash_count[i];

        total += hash_count[i];

      }

    printf ("Opcode hash table stats: min %d, max %d, ave %f\n",

            min_count, max_count, (double) total / HASH_SIZE);

  }

#endif

}


void nbd_export_close(NBDExport *exp)

{

    NBDClient *client, *next;

    nbd_export_get(exp);

    QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {

        nbd_client_close(client);

    }

    nbd_export_set_name(exp, NULL);

    nbd_export_put(exp);

    if (exp->blk) {

        blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,

                                        blk_aio_detach, exp);

        blk_unref(exp->blk);

        exp->blk = NULL;

    }

}


static void gen_spr_power8_book4(CPUPPCState *env)

{

    /* Add a number of P8 book4 registers */

#if !defined(CONFIG_USER_ONLY)

    spr_register_kvm(env, SPR_ACOP, "ACOP",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_ACOP, 0);

    spr_register_kvm(env, SPR_BOOKS_PID, "PID",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_PID, 0);

    spr_register_kvm(env, SPR_WORT, "WORT",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_WORT, 0);

#endif

}


int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,

                               int mmu_idx, int is_softmmu)

{

    int prot;

    address &= TARGET_PAGE_MASK;

    prot = PAGE_READ | PAGE_WRITE;

    return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);

}


void helper_movl_crN_T0(int reg)

{

    env->cr[reg] = T0;

    switch(reg) {

    case 0:

        cpu_x86_update_cr0(env);

        break;

    case 3:

        cpu_x86_update_cr3(env);

        break;

    }

}


static bool pmsav7_needed(void *opaque)

{

    ARMCPU *cpu = opaque;

    CPUARMState *env = &cpu->env;

    return arm_feature(env, ARM_FEATURE_PMSA) &&

           arm_feature(env, ARM_FEATURE_V7);

}


int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,

                                 target_ulong address, int rw, int access_type)

{

    ppcemb_tlb_t *tlb;

    target_phys_addr_t raddr;

    int i, ret, zsel, zpr;

    ret = -1;

    raddr = -1;

    for (i = 0; i < env->nb_tlb; i++) {

        tlb = &env->tlb[i].tlbe;

        if (ppcemb_tlb_check(env, tlb, &raddr, address,

                             env->spr[SPR_40x_PID], 0, i) < 0)

            continue;

        zsel = (tlb->attr >> 4) & 0xF;

        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",

                    __func__, i, zsel, zpr, rw, tlb->attr);

        }

#endif

        if (access_type == ACCESS_CODE) {

            /* Check execute enable bit */

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_exec_perm;

                goto exec_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -3;

                    break;

                }

                /* No break here */

            case 0x1:

            check_exec_perm:

                /* Check from TLB entry */

                if (!(tlb->prot & PAGE_EXEC)) {

                    ret = -3;

                } else {

                    if (tlb->prot & PAGE_WRITE) {

                        ctx->prot = PAGE_READ | PAGE_WRITE;

                    } else {

                        ctx->prot = PAGE_READ;

                    }

                    ret = 0;

                }

                break;

            case 0x3:

            exec_granted:

                /* All accesses granted */

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        } else {

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_rw_perm;

                goto rw_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -2;

                    break;

                }

                /* No break here */

            case 0x1:

            check_rw_perm:

                /* Check from TLB entry */

                /* Check write protection bit */

                if (tlb->prot & PAGE_WRITE) {

                    ctx->prot = PAGE_READ | PAGE_WRITE;

                    ret = 0;

                } else {

                    ctx->prot = PAGE_READ;

                    if (rw)

                        ret = -2;

                    else

                        ret = 0;

                }

                break;

            case 0x3:

            rw_granted:

                /* All accesses granted */

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        }

        if (ret >= 0) {

            ctx->raddr = raddr;

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "%s: access granted " ADDRX " => " REGX

                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,

                        ret);

            }

#endif

            return 0;

        }

    }

#if defined (DEBUG_SOFTWARE_TLB)

    if (loglevel != 0) {

        fprintf(logfile, "%s: access refused " ADDRX " => " REGX

                " %d %d\n", __func__, address, raddr, ctx->prot,

                ret);

    }

#endif

    return ret;

}


static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)

{

    struct dirent *entry;

again:

    entry = readdir(fs->dir.stream);

    if (!entry) {

        return NULL;

    }

    if (ctx->export_flags & V9FS_SM_MAPPED) {

        entry->d_type = DT_UNKNOWN;

    } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {

        if (local_is_mapped_file_metadata(ctx, entry->d_name)) {

            /* skip the meta data directory */

            goto again;

        }

        entry->d_type = DT_UNKNOWN;

    }

    return entry;

}


static void tricore_cpu_class_init(ObjectClass *c, void *data)

{

    TriCoreCPUClass *mcc = TRICORE_CPU_CLASS(c);

    CPUClass *cc = CPU_CLASS(c);

    DeviceClass *dc = DEVICE_CLASS(c);

    mcc->parent_realize = dc->realize;

    dc->realize = tricore_cpu_realizefn;

    mcc->parent_reset = cc->reset;

    cc->reset = tricore_cpu_reset;

    cc->class_by_name = tricore_cpu_class_by_name;

    cc->has_work = tricore_cpu_has_work;

    cc->dump_state = tricore_cpu_dump_state;

    cc->set_pc = tricore_cpu_set_pc;

    cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;

}


static int udp_open(URLContext *h, const char *uri, int flags)

{

    char hostname[1024], localaddr[1024] = "";

    int port, udp_fd = -1, tmp, bind_ret = -1;

    UDPContext *s = h->priv_data;

    int is_output;

    const char *p;

    char buf[256];

    struct sockaddr_storage my_addr;

    int len;

    int reuse_specified = 0;

    int i, include = 0, num_sources = 0;

    char *sources[32];

    h->is_streamed = 1;

    h->max_packet_size = 1472;

    is_output = !(flags & AVIO_FLAG_READ);

    s->ttl = 16;

    s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;

    s->circular_buffer_size = 7*188*4096;

    p = strchr(uri, '?');

    if (p) {

        if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {

            char *endptr = NULL;

            s->reuse_socket = strtol(buf, &endptr, 10);

            /* assume if no digits were found it is a request to enable it */

            if (buf == endptr)

                s->reuse_socket = 1;

            reuse_specified = 1;

        }

        if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) {

            char *endptr = NULL;

            s->overrun_nonfatal = strtol(buf, &endptr, 10);

            /* assume if no digits were found it is a request to enable it */

            if (buf == endptr)

                s->overrun_nonfatal = 1;

        }

        if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {

            s->ttl = strtol(buf, NULL, 10);

        }

        if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {

            s->local_port = strtol(buf, NULL, 10);

        }

        if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {

            h->max_packet_size = strtol(buf, NULL, 10);

        }

        if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {

            s->buffer_size = strtol(buf, NULL, 10);

        }

        if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {

            s->is_connected = strtol(buf, NULL, 10);

        }

        if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {

            s->circular_buffer_size = strtol(buf, NULL, 10)*188;

                       "'circular_buffer_size' option was set but it is not supported "

        }

        if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {

            av_strlcpy(localaddr, buf, sizeof(localaddr));

        }

        if (av_find_info_tag(buf, sizeof(buf), "sources", p))

            include = 1;

        if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {

            char *source_start;

            source_start = buf;

            while (1) {

                char *next = strchr(source_start, ',');

                if (next)

                    *next = '\0';

                sources[num_sources] = av_strdup(source_start);

                if (!sources[num_sources])

                    goto fail;

                source_start = next + 1;

                num_sources++;

                if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)

                    break;

            }

        }

    }

    /* fill the dest addr */

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);

    /* XXX: fix av_url_split */

    if (hostname[0] == '\0' || hostname[0] == '?') {

        /* only accepts null hostname if input */

        if (!(flags & AVIO_FLAG_READ))

            goto fail;

    } else {

        if (ff_udp_set_remote_url(h, uri) < 0)

            goto fail;

    }

    if ((s->is_multicast || !s->local_port) && (h->flags & AVIO_FLAG_READ))

        s->local_port = port;

    udp_fd = udp_socket_create(s, &my_addr, &len, localaddr);

    if (udp_fd < 0)

        goto fail;

    /* Follow the requested reuse option, unless it's multicast in which

     * case enable reuse unless explicitly disabled.

     */

    if (s->reuse_socket || (s->is_multicast && !reuse_specified)) {

        s->reuse_socket = 1;

        if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)

            goto fail;

    }

    /* If multicast, try binding the multicast address first, to avoid

     * receiving UDP packets from other sources aimed at the same UDP

     * port. This fails on windows. This makes sending to the same address

     * using sendto() fail, so only do it if we're opened in read-only mode. */

    if (s->is_multicast && !(h->flags & AVIO_FLAG_WRITE)) {

        bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);

    }

    /* bind to the local address if not multicast or if the multicast

     * bind failed */

    /* the bind is needed to give a port to the socket now */

    if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) {

        log_net_error(h, AV_LOG_ERROR, "bind failed");

        goto fail;

    }

    len = sizeof(my_addr);

    getsockname(udp_fd, (struct sockaddr *)&my_addr, &len);

    s->local_port = udp_port(&my_addr, len);

    if (s->is_multicast) {

        if (h->flags & AVIO_FLAG_WRITE) {

            /* output */

            if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)

                goto fail;

        }

        if (h->flags & AVIO_FLAG_READ) {

            /* input */

            if (num_sources == 0 || !include) {

                if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)

                    goto fail;

                if (num_sources) {

                    if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)

                        goto fail;

                }

            } else if (include && num_sources) {

                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)

                    goto fail;

            } else {

                av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");

                goto fail;

            }

        }

    }

    if (is_output) {

        /* limit the tx buf size to limit latency */

        tmp = s->buffer_size;

        if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {

            log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)");

            goto fail;

        }

    } else {

        /* set udp recv buffer size to the largest possible udp packet size to

         * avoid losing data on OSes that set this too low by default. */

        tmp = s->buffer_size;

        if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {

            log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)");

        }

        /* make the socket non-blocking */

        ff_socket_nonblock(udp_fd, 1);

    }

    if (s->is_connected) {

        if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) {

            log_net_error(h, AV_LOG_ERROR, "connect");

            goto fail;

        }

    }

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

        av_freep(&sources[i]);

    s->udp_fd = udp_fd;

#if HAVE_PTHREAD_CANCEL

    if (!is_output && s->circular_buffer_size) {

        int ret;

        /* start the task going */

        s->fifo = av_fifo_alloc(s->circular_buffer_size);

        ret = pthread_mutex_init(&s->mutex, NULL);

        if (ret != 0) {

            av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret));

            goto fail;

        }

        ret = pthread_cond_init(&s->cond, NULL);

        if (ret != 0) {

            av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret));

            goto cond_fail;

        }

        ret = pthread_create(&s->circular_buffer_thread, NULL, circular_buffer_task, h);

        if (ret != 0) {

            av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret));

            goto thread_fail;

        }

        s->thread_started = 1;

    }

#endif

    return 0;

#if HAVE_PTHREAD_CANCEL

 thread_fail:

    pthread_cond_destroy(&s->cond);

 cond_fail:

    pthread_mutex_destroy(&s->mutex);

#endif

 fail:

    if (udp_fd >= 0)

        closesocket(udp_fd);

    av_fifo_free(s->fifo);

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

        av_freep(&sources[i]);

    return AVERROR(EIO);

}