static int parse_strk(AVFormatContext *s,

                      FourxmDemuxContext *fourxm, uint8_t *buf, int size,

                      int left)

{

    AVStream *st;

    int track;

    /* check that there is enough data */

    if (size != strk_SIZE || left < size + 8)

        return AVERROR_INVALIDDATA;

    track = AV_RL32(buf + 8);

    if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {

        av_log(s, AV_LOG_ERROR, "current_track too large\n");

        return AVERROR_INVALIDDATA;

    }

    if (track + 1 > fourxm->track_count) {

        if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))

            return AVERROR(ENOMEM);

        memset(&fourxm->tracks[fourxm->track_count], 0,

               sizeof(AudioTrack) * (track + 1 - fourxm->track_count));

        fourxm->track_count = track + 1;

    }

    fourxm->tracks[track].adpcm       = AV_RL32(buf + 12);

    fourxm->tracks[track].channels    = AV_RL32(buf + 36);

    fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);

    fourxm->tracks[track].bits        = AV_RL32(buf + 44);

    fourxm->tracks[track].audio_pts   = 0;

    if (fourxm->tracks[track].channels    <= 0 ||

        fourxm->tracks[track].sample_rate <= 0 ||

        fourxm->tracks[track].bits        <= 0) {

        av_log(s, AV_LOG_ERROR, "audio header invalid\n");

        return AVERROR_INVALIDDATA;

    }

    if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) {

        av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");

        return AVERROR_INVALIDDATA;

    }

    if (fourxm->tracks[track].sample_rate > INT64_MAX / fourxm->tracks[track].bits / fourxm->tracks[track].channels) {

        av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %d * %d * %d\n",

               fourxm->tracks[track].sample_rate, fourxm->tracks[track].bits, fourxm->tracks[track].channels);

        return AVERROR_INVALIDDATA;

    }

    /* allocate a new AVStream */

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->id = track;

    avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);

    fourxm->tracks[track].stream_index = st->index;

    st->codecpar->codec_type            = AVMEDIA_TYPE_AUDIO;

    st->codecpar->codec_tag             = 0;

    st->codecpar->channels              = fourxm->tracks[track].channels;

    st->codecpar->sample_rate           = fourxm->tracks[track].sample_rate;

    st->codecpar->bits_per_coded_sample = fourxm->tracks[track].bits;

    st->codecpar->bit_rate              = (int64_t)st->codecpar->channels *

                                          st->codecpar->sample_rate *

                                          st->codecpar->bits_per_coded_sample;

    st->codecpar->block_align           = st->codecpar->channels *

                                          st->codecpar->bits_per_coded_sample;

    if (fourxm->tracks[track].adpcm){

        st->codecpar->codec_id = AV_CODEC_ID_ADPCM_4XM;

    } else if (st->codecpar->bits_per_coded_sample == 8) {

        st->codecpar->codec_id = AV_CODEC_ID_PCM_U8;

    } else

        st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;

    return 0;

}


void yuv2rgb_altivec_init_tables (SwsContext *c, const int inv_table[4],int brightness,int contrast, int saturation)

{

  union {

  	signed short tmp[8] __attribute__ ((aligned(16)));

	vector signed short vec;

	} buf;

  buf.tmp[0] =  ( (0xffffLL) * contrast>>8 )>>9;			//cy

  buf.tmp[1] =  -256*brightness;					//oy

  buf.tmp[2] =  (inv_table[0]>>3) *(contrast>>16)*(saturation>>16);	//crv

  buf.tmp[3] =  (inv_table[1]>>3) *(contrast>>16)*(saturation>>16);	//cbu

  buf.tmp[4] = -((inv_table[2]>>1)*(contrast>>16)*(saturation>>16));	//cgu

  buf.tmp[5] = -((inv_table[3]>>1)*(contrast>>16)*(saturation>>16));	//cgv

  c->CSHIFT = (vector unsigned short)vec_splat_u16(2);

  c->CY  = vec_splat ((vector signed short)buf.vec, 0);

  c->OY  = vec_splat ((vector signed short)buf.vec, 1);

  c->CRV  = vec_splat ((vector signed short)buf.vec, 2);

  c->CBU  = vec_splat ((vector signed short)buf.vec, 3);

  c->CGU  = vec_splat ((vector signed short)buf.vec, 4);

  c->CGV  = vec_splat ((vector signed short)buf.vec, 5);

#if 0

{

int i;

char *v[6]={"cy","oy","crv","cbu","cgu","cgv"};

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

  printf("%s %d ", v[i],buf.tmp[i] );

  printf("\n");

}

#endif

 return;

}


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

{

    VirtQueueElement elem;

    VirtIOSerial *vser;

    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);

    while (virtqueue_pop(vq, &elem)) {

        handle_control_message(vser, elem.out_sg[0].iov_base);

        virtqueue_push(vq, &elem, elem.out_sg[0].iov_len);

    }

    virtio_notify(vdev, vq);

}


static int img_amend(int argc, char **argv)

{

    Error *err = NULL;

    int c, ret = 0;

    char *options = NULL;

    QemuOptsList *create_opts = NULL;

    QemuOpts *opts = NULL;

    const char *fmt = NULL, *filename, *cache;

    int flags;

    bool quiet = false, progress = false;

    BlockBackend *blk = NULL;

    BlockDriverState *bs = NULL;

    cache = BDRV_DEFAULT_CACHE;

    for (;;) {

        c = getopt(argc, argv, "ho:f:t:pq");

        if (c == -1) {

            break;

        }

        switch (c) {

            case 'h':

            case '?':

                help();

                break;

            case 'o':

                if (!is_valid_option_list(optarg)) {

                    error_report("Invalid option list: %s", optarg);

                    ret = -1;

                    goto out;

                }

                if (!options) {

                    options = g_strdup(optarg);

                } else {

                    char *old_options = options;

                    options = g_strdup_printf("%s,%s", options, optarg);

                    g_free(old_options);

                }

                break;

            case 'f':

                fmt = optarg;

                break;

            case 't':

                cache = optarg;

                break;

            case 'p':

                progress = true;

                break;

            case 'q':

                quiet = true;

                break;

        }

    }

    if (!options) {

        error_exit("Must specify options (-o)");

    }

    if (quiet) {

        progress = false;

    }

    qemu_progress_init(progress, 1.0);

    filename = (optind == argc - 1) ? argv[argc - 1] : NULL;

    if (fmt && has_help_option(options)) {

        /* If a format is explicitly specified (and possibly no filename is

         * given), print option help here */

        ret = print_block_option_help(filename, fmt);

        goto out;

    }

    if (optind != argc - 1) {

        error_report("Expecting one image file name");

        ret = -1;

        goto out;

    }

    flags = BDRV_O_FLAGS | BDRV_O_RDWR;

    ret = bdrv_parse_cache_flags(cache, &flags);

    if (ret < 0) {

        error_report("Invalid cache option: %s", cache);

        goto out;

    }

    blk = img_open("image", filename, fmt, flags, true, quiet);

    if (!blk) {

        ret = -1;

        goto out;

    }

    bs = blk_bs(blk);

    fmt = bs->drv->format_name;

    if (has_help_option(options)) {

        /* If the format was auto-detected, print option help here */

        ret = print_block_option_help(filename, fmt);

        goto out;

    }

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

        error_report("Format driver '%s' does not support any options to amend",

                     fmt);

        ret = -1;

        goto out;

    }

    create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);

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

    if (options) {

        qemu_opts_do_parse(opts, options, NULL, &err);

        if (err) {

            error_report_err(err);

            ret = -1;

            goto out;

        }

    }

    /* In case the driver does not call amend_status_cb() */

    qemu_progress_print(0.f, 0);

    ret = bdrv_amend_options(bs, opts, &amend_status_cb);

    qemu_progress_print(100.f, 0);

    if (ret < 0) {

        error_report("Error while amending options: %s", strerror(-ret));

        goto out;

    }

out:

    qemu_progress_end();

    blk_unref(blk);

    qemu_opts_del(opts);

    qemu_opts_free(create_opts);

    g_free(options);

    if (ret) {

        return 1;

    }

    return 0;

}


static void powernv_populate_chip(PnvChip *chip, void *fdt)
{
    PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
    char *typename = pnv_core_typename(pcc->cpu_model);
    size_t typesize = object_type_get_instance_size(typename);
    int i;
    for (i = 0; i < chip->nr_cores; i++) {
        PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize);
        powernv_create_core_node(chip, pnv_core, fdt);
    }
    if (chip->ram_size) {
        powernv_populate_memory_node(fdt, chip->chip_id, chip->ram_start,
                                     chip->ram_size);
    }
    g_free(typename);
}


static int virtio_rng_load_device(VirtIODevice *vdev, QEMUFile *f,

                                  int version_id)

{

    /* We may have an element ready but couldn't process it due to a quota

     * limit.  Make sure to try again after live migration when the quota may

     * have been reset.

     */

    virtio_rng_process(VIRTIO_RNG(vdev));

    return 0;

}


static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, int16_t *block, int n)

{

    int level, i, j, run;

    RLTable *rl = &ff_rl_mpeg1;

    uint8_t * const scantable = s->intra_scantable.permutated;

    const int qscale          = s->qscale;

    {

        OPEN_READER(re, &s->gb);

        i = -1;

        // special case for first coefficient, no need to add second VLC table

        UPDATE_CACHE(re, &s->gb);

        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {

            level = (3 * qscale) >> 1;

            level = (level - 1) | 1;

            if (GET_CACHE(re, &s->gb) & 0x40000000)

                level = -level;

            block[0] = level;

            i++;

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

            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)

                goto end;

        }

        /* now quantify & encode AC coefficients */

        for (;;) {

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

            if (level != 0) {

                i += run;

                j = scantable[i];

                level = ((level * 2 + 1) * qscale) >> 1;

                level = (level - 1) | 1;

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

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

            } else {

                /* escape */

                run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);

                UPDATE_CACHE(re, &s->gb);

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

                if (level == -128) {

                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);

                } else if (level == 0) {

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

                }

                i += run;

                j = scantable[i];

                if (level < 0) {

                    level = -level;

                    level = ((level * 2 + 1) * qscale) >> 1;

                    level = (level - 1) | 1;

                    level = -level;

                } else {

                    level = ((level * 2 + 1) * qscale) >> 1;

                    level = (level - 1) | 1;

                }

            }

            block[j] = level;

            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)

                break;

            UPDATE_CACHE(re, &s->gb);

        }

end:

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

        CLOSE_READER(re, &s->gb);

    }

    s->block_last_index[n] = i;

    return 0;

}


static int usb_net_handle_datain(USBNetState *s, USBPacket *p)

{

    int ret = USB_RET_NAK;

    if (s->in_ptr > s->in_len) {

        s->in_ptr = s->in_len = 0;

        ret = USB_RET_NAK;

        return ret;

    }

    if (!s->in_len) {

        ret = USB_RET_NAK;

        return ret;

    }

    ret = s->in_len - s->in_ptr;

    if (ret > p->len)

        ret = p->len;

    memcpy(p->data, &s->in_buf[s->in_ptr], ret);

    s->in_ptr += ret;

    if (s->in_ptr >= s->in_len &&

                    (is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) {

        /* no short packet necessary */

        s->in_ptr = s->in_len = 0;

    }

#ifdef TRAFFIC_DEBUG

    fprintf(stderr, "usbnet: data in len %u return %d", p->len, ret);

    {

        int i;

        fprintf(stderr, ":");

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

            if (!(i & 15))

                fprintf(stderr, "\n%04x:", i);

            fprintf(stderr, " %02x", p->data[i]);

        }

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

    }

#endif

    return ret;

}


static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration)

{

    int i;

    MP3DecContext *mp3 = s->priv_data;

    int fill_index = mp3->usetoc == 1 && duration > 0;

    if (!filesize &&

        !(filesize = avio_size(s->pb))) {

        av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n");

        fill_index = 0;

    }

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

        uint8_t b = avio_r8(s->pb);

        if (fill_index)

            av_add_index_entry(s->streams[0],

                           av_rescale(b, filesize, 256),

                           av_rescale(i, duration, XING_TOC_COUNT),

                           0, 0, AVINDEX_KEYFRAME);

    }

    if (fill_index)

        mp3->xing_toc = 1;

}


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

                                ptrdiff_t stride)

{

    copy_width8_msa(src, stride, dst, stride, 8);

}


static int ape_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    APEContext *s = avctx->priv_data;

    int16_t *samples = data;

    uint32_t nblocks;

    int i;

    int blockstodecode;

    int bytes_used;

    /* should not happen but who knows */

    if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) {

        av_log (avctx, AV_LOG_ERROR, "Output buffer is too small.\n");

        return AVERROR(EINVAL);

    }

    /* this should never be negative, but bad things will happen if it is, so

       check it just to make sure. */

    av_assert0(s->samples >= 0);

    if(!s->samples){

        uint32_t offset;

        void *tmp_data;

        if (buf_size < 8) {

            av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");

            return AVERROR_INVALIDDATA;

        }

        tmp_data = av_realloc(s->data, FFALIGN(buf_size, 4));

        if (!tmp_data)

            return AVERROR(ENOMEM);

        s->data = tmp_data;

        s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);

        s->ptr = s->last_ptr = s->data;

        s->data_end = s->data + buf_size;

        nblocks = bytestream_get_be32(&s->ptr);

        offset  = bytestream_get_be32(&s->ptr);

        if (offset > 3) {

            av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");

            s->data = NULL;

            return AVERROR_INVALIDDATA;

        }

        if (s->data_end - s->ptr < offset) {

            av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");

            return AVERROR_INVALIDDATA;

        }

        s->ptr += offset;

        if (!nblocks || nblocks > INT_MAX) {

            av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks);

            return AVERROR_INVALIDDATA;

        }

        s->samples = nblocks;

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

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

        /* Initialize the frame decoder */

        if (init_frame_decoder(s) < 0) {

            av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n");

            return AVERROR_INVALIDDATA;

        }

    }

    if (!s->data) {

        *data_size = 0;

        return buf_size;

    }

    nblocks = s->samples;

    blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);

    s->error=0;

    if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))

        ape_unpack_mono(s, blockstodecode);

    else

        ape_unpack_stereo(s, blockstodecode);

    emms_c();

    if (s->error) {

        s->samples=0;

        av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");

        return AVERROR_INVALIDDATA;

    }

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

        *samples++ = s->decoded0[i];

        if(s->channels == 2)

            *samples++ = s->decoded1[i];

    }

    s->samples -= blockstodecode;

    *data_size = blockstodecode * 2 * s->channels;

    bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size;

    s->last_ptr = s->ptr;

    return bytes_used;

}


static void sun4uv_init(ram_addr_t RAM_size,

                        const char *boot_devices,

                        const char *kernel_filename, const char *kernel_cmdline,

                        const char *initrd_filename, const char *cpu_model,

                        const struct hwdef *hwdef)

{

    CPUState *env;

    m48t59_t *nvram;

    unsigned int i;

    long initrd_size, kernel_size;

    PCIBus *pci_bus, *pci_bus2, *pci_bus3;

    qemu_irq *irq;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    DriveInfo *fd[MAX_FD];

    void *fw_cfg;

    /* init CPUs */

    env = cpu_devinit(cpu_model, hwdef);

    /* set up devices */

    ram_init(0, RAM_size);

    prom_init(hwdef->prom_addr, bios_name);

    irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);

    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,

                           &pci_bus3);

    isa_mem_base = VGA_BASE;

    pci_vga_init(pci_bus, 0, 0);

    // XXX Should be pci_bus3

    pci_ebus_init(pci_bus, -1);

    i = 0;

    if (hwdef->console_serial_base) {

        serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,

                       serial_hds[i], 1);

        i++;

    }

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

        if (serial_hds[i]) {

            serial_isa_init(i, serial_hds[i]);

        }

    }

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

        if (parallel_hds[i]) {

            parallel_init(i, parallel_hds[i]);

        }

    }

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

        pci_nic_init(&nd_table[i], "ne2k_pci", NULL);

    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {

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

        exit(1);

    }

    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {

        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS,

                          i % MAX_IDE_DEVS);

    }

    pci_cmd646_ide_init(pci_bus, hd, 1);

    isa_create_simple("i8042");

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

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

    }

    fdctrl_init_isa(fd);

    nvram = m48t59_init_isa(0x0074, NVRAM_SIZE, 59);

    initrd_size = 0;

    kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,

                                    ram_size, &initrd_size);

    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,

                           KERNEL_LOAD_ADDR, kernel_size,

                           kernel_cmdline,

                           INITRD_LOAD_ADDR, initrd_size,

                           /* XXX: need an option to load a NVRAM image */

                           0,

                           graphic_width, graphic_height, graphic_depth,

                           (uint8_t *)&nd_table[0].macaddr);

    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);

    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);

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

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

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);

    if (kernel_cmdline) {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, CMDLINE_ADDR);

        pstrcpy_targphys(CMDLINE_ADDR, TARGET_PAGE_SIZE, kernel_cmdline);

    } else {

        fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);

    }

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);

    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);

    fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_DEPTH, graphic_depth);

    qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);

}


bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)

{

    bool ok = true;

    BlockDriverState *bs;

    BdrvNextIterator it;

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

        AioContext *ctx = bdrv_get_aio_context(bs);

        aio_context_acquire(ctx);

        if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {

            ok = bdrv_can_snapshot(bs);

        }

        aio_context_release(ctx);

        if (!ok) {

            goto fail;

        }

    }

fail:

    *first_bad_bs = bs;

    return ok;

}


static void ps2_reset_keyboard(PS2KbdState *s)

{

    trace_ps2_reset_keyboard(s);

    s->scan_enabled = 1;

    s->scancode_set = 2;

    ps2_set_ledstate(s, 0);

}


int qemu_savevm_state_complete(QEMUFile *f)

{

    SaveStateEntry *se;

    TAILQ_FOREACH(se, &savevm_handlers, entry) {

        if (se->save_live_state == NULL)

            continue;

        /* Section type */

        qemu_put_byte(f, QEMU_VM_SECTION_END);

        qemu_put_be32(f, se->section_id);

        se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque);

    }

    TAILQ_FOREACH(se, &savevm_handlers, entry) {

        int len;

	if (se->save_state == NULL && se->vmsd == NULL)

	    continue;

        /* Section type */

        qemu_put_byte(f, QEMU_VM_SECTION_FULL);

        qemu_put_be32(f, se->section_id);

        /* ID string */

        len = strlen(se->idstr);

        qemu_put_byte(f, len);

        qemu_put_buffer(f, (uint8_t *)se->idstr, len);

        qemu_put_be32(f, se->instance_id);

        qemu_put_be32(f, se->version_id);

        vmstate_save(f, se);

    }

    qemu_put_byte(f, QEMU_VM_EOF);

    if (qemu_file_has_error(f))

        return -EIO;

    return 0;

}


static GenericList *next_list(Visitor *v, GenericList **list, size_t size)

{

    StringOutputVisitor *sov = to_sov(v);

    GenericList *ret = NULL;

    if (*list) {

        if (sov->head) {

            ret = *list;

        } else {

            ret = (*list)->next;

        }

        if (sov->head) {

            if (ret && ret->next == NULL) {

                sov->list_mode = LM_NONE;

            }

            sov->head = false;

        } else {

            if (ret && ret->next == NULL) {

                sov->list_mode = LM_END;

            }

        }

    }

    return ret;

}


static void curl_multi_timeout_do(void *arg)

{

#ifdef NEED_CURL_TIMER_CALLBACK

    BDRVCURLState *s = (BDRVCURLState *)arg;

    int running;

    if (!s->multi) {

        return;

    }

    aio_context_acquire(s->aio_context);

    curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running);

    curl_multi_check_completion(s);

    aio_context_release(s->aio_context);

#else

    abort();

#endif

}


static int virtio_pci_ioeventfd_assign(DeviceState *d, EventNotifier *notifier,

                                       int n, bool assign)

{

    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);

    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    VirtQueue *vq = virtio_get_queue(vdev, n);

    bool legacy = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_LEGACY);

    bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);

    bool fast_mmio = kvm_ioeventfd_any_length_enabled();

    bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY;

    MemoryRegion *modern_mr = &proxy->notify.mr;

    MemoryRegion *modern_notify_mr = &proxy->notify_pio.mr;

    MemoryRegion *legacy_mr = &proxy->bar;

    hwaddr modern_addr = QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *

                         virtio_get_queue_index(vq);

    hwaddr legacy_addr = VIRTIO_PCI_QUEUE_NOTIFY;

    if (assign) {

        if (modern) {

            if (fast_mmio) {

                memory_region_add_eventfd(modern_mr, modern_addr, 0,

                                          false, n, notifier);

            } else {

                memory_region_add_eventfd(modern_mr, modern_addr, 2,

                                          false, n, notifier);

            }

            if (modern_pio) {

                memory_region_add_eventfd(modern_notify_mr, 0, 2,

                                              true, n, notifier);

            }

        }

        if (legacy) {

            memory_region_add_eventfd(legacy_mr, legacy_addr, 2,

                                      true, n, notifier);

        }

    } else {

        if (modern) {

            if (fast_mmio) {

                memory_region_del_eventfd(modern_mr, modern_addr, 0,

                                          false, n, notifier);

            } else {

                memory_region_del_eventfd(modern_mr, modern_addr, 2,

                                          false, n, notifier);

            }

            if (modern_pio) {

                memory_region_del_eventfd(modern_notify_mr, 0, 2,

                                          true, n, notifier);

            }

        }

        if (legacy) {

            memory_region_del_eventfd(legacy_mr, legacy_addr, 2,

                                      true, n, notifier);

        }

    }

    return 0;

}


static uint64_t esp_pci_io_read(void *opaque, target_phys_addr_t addr,

                                unsigned int size)

{

    PCIESPState *pci = opaque;

    uint32_t ret;

    if (addr < 0x40) {

        /* SCSI core reg */

        ret = esp_reg_read(&pci->esp, addr >> 2);

    } else if (addr < 0x60) {

        /* PCI DMA CCB */

        ret = esp_pci_dma_read(pci, (addr - 0x40) >> 2);

    } else if (addr == 0x70) {

        /* DMA SCSI Bus and control */

        trace_esp_pci_sbac_read(pci->sbac);

        ret = pci->sbac;

    } else {

        /* Invalid region */

        trace_esp_pci_error_invalid_read((int)addr);

        ret = 0;

    }

    /* give only requested data */

    ret >>= (addr & 3) * 8;

    ret &= ~(~(uint64_t)0 << (8 * size));

    return ret;

}


sorecvfrom(struct socket *so)

{

	struct sockaddr_storage addr;

	socklen_t addrlen = sizeof(struct sockaddr_storage);

	DEBUG_CALL("sorecvfrom");

	DEBUG_ARG("so = %p", so);

	if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */

	  char buff[256];

	  int len;

	  len = recvfrom(so->s, buff, 256, 0,

			 (struct sockaddr *)&addr, &addrlen);

	  /* XXX Check if reply is "correct"? */

	  if(len == -1 || len == 0) {

	    u_char code=ICMP_UNREACH_PORT;

	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;

	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;

	    DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",

			errno,strerror(errno)));

	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));

	  } else {

	    icmp_reflect(so->so_m);

            so->so_m = NULL; /* Don't m_free() it again! */

	  }

	  /* No need for this socket anymore, udp_detach it */

	  udp_detach(so);

	} else {                            	/* A "normal" UDP packet */

	  struct mbuf *m;

          int len;

#ifdef _WIN32

          unsigned long n;

#else

          int n;

#endif

	  m = m_get(so->slirp);

	  if (!m) {

	      return;

	  }

	  m->m_data += IF_MAXLINKHDR;

	  /*

	   * XXX Shouldn't FIONREAD packets destined for port 53,

	   * but I don't know the max packet size for DNS lookups

	   */

	  len = M_FREEROOM(m);

	  /* if (so->so_fport != htons(53)) { */

	  ioctlsocket(so->s, FIONREAD, &n);

	  if (n > len) {

	    n = (m->m_data - m->m_dat) + m->m_len + n + 1;

	    m_inc(m, n);

	    len = M_FREEROOM(m);

	  }

	  /* } */

	  m->m_len = recvfrom(so->s, m->m_data, len, 0,

			      (struct sockaddr *)&addr, &addrlen);

	  DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",

		      m->m_len, errno,strerror(errno)));

	  if(m->m_len<0) {

	    u_char code=ICMP_UNREACH_PORT;

	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;

	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;

	    DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));

	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));

	    m_free(m);

	  } else {

	  /*

	   * Hack: domain name lookup will be used the most for UDP,

	   * and since they'll only be used once there's no need

	   * for the 4 minute (or whatever) timeout... So we time them

	   * out much quicker (10 seconds  for now...)

	   */

	    if (so->so_expire) {

	      if (so->so_fport == htons(53))

		so->so_expire = curtime + SO_EXPIREFAST;

	      else

		so->so_expire = curtime + SO_EXPIRE;

	    }

	    /*

	     * If this packet was destined for CTL_ADDR,

	     * make it look like that's where it came from, done by udp_output

	     */

	    switch (so->so_ffamily) {

	    case AF_INET:

	        udp_output(so, m, (struct sockaddr_in *) &addr);

	        break;

	    default:

	        break;

	    }

	  } /* rx error */

	} /* if ping packet */

}


static int pxa2xx_rtc_init(SysBusDevice *dev)

{

    PXA2xxRTCState *s = FROM_SYSBUS(PXA2xxRTCState, dev);

    struct tm tm;

    int wom;

    int iomemtype;

    s->rttr = 0x7fff;

    s->rtsr = 0;

    qemu_get_timedate(&tm, 0);

    wom = ((tm.tm_mday - 1) / 7) + 1;

    s->last_rcnr = (uint32_t) mktimegm(&tm);

    s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |

            (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;

    s->last_rycr = ((tm.tm_year + 1900) << 9) |

            ((tm.tm_mon + 1) << 5) | tm.tm_mday;

    s->last_swcr = (tm.tm_hour << 19) |

            (tm.tm_min << 13) | (tm.tm_sec << 7);

    s->last_rtcpicr = 0;

    s->last_hz = s->last_sw = s->last_pi = qemu_get_clock(rt_clock);

    s->rtc_hz    = qemu_new_timer(rt_clock, pxa2xx_rtc_hz_tick,    s);

    s->rtc_rdal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_rdal1_tick, s);

    s->rtc_rdal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_rdal2_tick, s);

    s->rtc_swal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal1_tick, s);

    s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s);

    s->rtc_pi    = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick,    s);

    sysbus_init_irq(dev, &s->rtc_irq);

    iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn,

                    pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);

    sysbus_init_mmio(dev, 0x10000, iomemtype);

    return 0;

}


static int transcode(AVFormatContext **output_files,

                     int nb_output_files,

                     AVFormatContext **input_files,

                     int nb_input_files,

                     AVStreamMap *stream_maps, int nb_stream_maps)

{

    int ret = 0, i, j, k, n, nb_istreams = 0, nb_ostreams = 0, step;

    AVFormatContext *is, *os;

    AVCodecContext *codec, *icodec;

    AVOutputStream *ost, **ost_table = NULL;

    AVInputStream *ist, **ist_table = NULL;

    AVInputFile *file_table;

    char error[1024];

    int key;

    int want_sdp = 1;

    uint8_t no_packet[MAX_FILES]={0};

    int no_packet_count=0;

    int nb_frame_threshold[AVMEDIA_TYPE_NB]={0};

    int nb_streams[AVMEDIA_TYPE_NB]={0};

    file_table= av_mallocz(nb_input_files * sizeof(AVInputFile));

    if (!file_table)

        goto fail;

    /* input stream init */

    j = 0;

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

        is = input_files[i];

        file_table[i].ist_index = j;

        file_table[i].nb_streams = is->nb_streams;

        j += is->nb_streams;

    }

    nb_istreams = j;

    ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *));

    if (!ist_table)

        goto fail;

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

        ist = av_mallocz(sizeof(AVInputStream));

        if (!ist)

            goto fail;

        ist_table[i] = ist;

    }

    j = 0;

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

        is = input_files[i];

        for(k=0;k<is->nb_streams;k++) {

            ist = ist_table[j++];

            ist->st = is->streams[k];

            ist->file_index = i;

            ist->index = k;

            ist->discard = 1; /* the stream is discarded by default

                                 (changed later) */

            if (rate_emu) {

                ist->start = av_gettime();

            }

        }

    }

    /* output stream init */

    nb_ostreams = 0;

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

        os = output_files[i];

        if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {

            av_dump_format(output_files[i], i, output_files[i]->filename, 1);

            fprintf(stderr, "Output file #%d does not contain any stream\n", i);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        nb_ostreams += os->nb_streams;

    }

    if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {

        fprintf(stderr, "Number of stream maps must match number of output streams\n");

        ret = AVERROR(EINVAL);

        goto fail;

    }

    /* Sanity check the mapping args -- do the input files & streams exist? */

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

        int fi = stream_maps[i].file_index;

        int si = stream_maps[i].stream_index;

        if (fi < 0 || fi > nb_input_files - 1 ||

            si < 0 || si > file_table[fi].nb_streams - 1) {

            fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        fi = stream_maps[i].sync_file_index;

        si = stream_maps[i].sync_stream_index;

        if (fi < 0 || fi > nb_input_files - 1 ||

            si < 0 || si > file_table[fi].nb_streams - 1) {

            fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si);

            ret = AVERROR(EINVAL);

            goto fail;

        }

    }

    ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);

    if (!ost_table)

        goto fail;

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

        os = output_files[k];

        for(i=0;i<os->nb_streams;i++,n++) {

            nb_streams[os->streams[i]->codec->codec_type]++;

        }

    }

    for(step=1<<30; step; step>>=1){

        int found_streams[AVMEDIA_TYPE_NB]={0};

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

            nb_frame_threshold[j] += step;

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

            int skip=0;

            ist = ist_table[j];

            if(opt_programid){

                int pi,si;

                AVFormatContext *f= input_files[ ist->file_index ];

                skip=1;

                for(pi=0; pi<f->nb_programs; pi++){

                    AVProgram *p= f->programs[pi];

                    if(p->id == opt_programid)

                        for(si=0; si<p->nb_stream_indexes; si++){

                            if(f->streams[ p->stream_index[si] ] == ist->st)

                                skip=0;

                        }

                }

            }

            if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip

                && nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames){

                found_streams[ist->st->codec->codec_type]++;

            }

        }

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

            if(found_streams[j] < nb_streams[j])

                nb_frame_threshold[j] -= step;

    }

    n = 0;

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

        os = output_files[k];

        for(i=0;i<os->nb_streams;i++,n++) {

            int found;

            ost = ost_table[n] = output_streams_for_file[k][i];

            ost->st = os->streams[i];

            if (nb_stream_maps > 0) {

                ost->source_index = file_table[stream_maps[n].file_index].ist_index +

                    stream_maps[n].stream_index;

                /* Sanity check that the stream types match */

                if (ist_table[ost->source_index]->st->codec->codec_type != ost->st->codec->codec_type) {

                    int i= ost->file_index;

                    av_dump_format(output_files[i], i, output_files[i]->filename, 1);

                    fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n",

                        stream_maps[n].file_index, stream_maps[n].stream_index,

                        ost->file_index, ost->index);

                    ffmpeg_exit(1);

                }

            } else {

                /* get corresponding input stream index : we select the first one with the right type */

                found = 0;

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

                    int skip=0;

                    ist = ist_table[j];

                    if(opt_programid){

                        int pi,si;

                        AVFormatContext *f= input_files[ ist->file_index ];

                        skip=1;

                        for(pi=0; pi<f->nb_programs; pi++){

                            AVProgram *p= f->programs[pi];

                            if(p->id == opt_programid)

                                for(si=0; si<p->nb_stream_indexes; si++){

                                    if(f->streams[ p->stream_index[si] ] == ist->st)

                                        skip=0;

                                }

                        }

                    }

                    if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&

                        ist->st->codec->codec_type == ost->st->codec->codec_type &&

                        nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames) {

                            ost->source_index = j;

                            found = 1;

                            break;

                    }

                }

                if (!found) {

                    if(! opt_programid) {

                        /* try again and reuse existing stream */

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

                            ist = ist_table[j];

                            if (   ist->st->codec->codec_type == ost->st->codec->codec_type

                                && ist->st->discard != AVDISCARD_ALL) {

                                ost->source_index = j;

                                found = 1;

                            }

                        }

                    }

                    if (!found) {

                        int i= ost->file_index;

                        av_dump_format(output_files[i], i, output_files[i]->filename, 1);

                        fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",

                                ost->file_index, ost->index);

                        ffmpeg_exit(1);

                    }

                }

            }

            ist = ist_table[ost->source_index];

            ist->discard = 0;

            ost->sync_ist = (nb_stream_maps > 0) ?

                ist_table[file_table[stream_maps[n].sync_file_index].ist_index +

                         stream_maps[n].sync_stream_index] : ist;

        }

    }

    /* for each output stream, we compute the right encoding parameters */

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

        ost = ost_table[i];

        os = output_files[ost->file_index];

        ist = ist_table[ost->source_index];

        codec = ost->st->codec;

        icodec = ist->st->codec;

        if (metadata_streams_autocopy)

            av_metadata_copy(&ost->st->metadata, ist->st->metadata,

                             AV_METADATA_DONT_OVERWRITE);

        ost->st->disposition = ist->st->disposition;

        codec->bits_per_raw_sample= icodec->bits_per_raw_sample;

        codec->chroma_sample_location = icodec->chroma_sample_location;

        if (ost->st->stream_copy) {

            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;

            if (extra_size > INT_MAX)

                goto fail;

            /* if stream_copy is selected, no need to decode or encode */

            codec->codec_id = icodec->codec_id;

            codec->codec_type = icodec->codec_type;

            if(!codec->codec_tag){

                if(   !os->oformat->codec_tag

                   || av_codec_get_id (os->oformat->codec_tag, icodec->codec_tag) == codec->codec_id

                   || av_codec_get_tag(os->oformat->codec_tag, icodec->codec_id) <= 0)

                    codec->codec_tag = icodec->codec_tag;

            }

            codec->bit_rate = icodec->bit_rate;

            codec->rc_max_rate    = icodec->rc_max_rate;

            codec->rc_buffer_size = icodec->rc_buffer_size;

            codec->extradata= av_mallocz(extra_size);

            if (!codec->extradata)

                goto fail;

            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);

            codec->extradata_size= icodec->extradata_size;

            if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                codec->time_base = icodec->time_base;

                codec->time_base.num *= icodec->ticks_per_frame;

                av_reduce(&codec->time_base.num, &codec->time_base.den,

                          codec->time_base.num, codec->time_base.den, INT_MAX);

            }else

                codec->time_base = ist->st->time_base;

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                if(audio_volume != 256) {

                    fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");

                    ffmpeg_exit(1);

                }

                codec->channel_layout = icodec->channel_layout;

                codec->sample_rate = icodec->sample_rate;

                codec->channels = icodec->channels;

                codec->frame_size = icodec->frame_size;

                codec->audio_service_type = icodec->audio_service_type;

                codec->block_align= icodec->block_align;

                if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)

                    codec->block_align= 0;

                if(codec->codec_id == CODEC_ID_AC3)

                    codec->block_align= 0;

                break;

            case AVMEDIA_TYPE_VIDEO:

                codec->pix_fmt = icodec->pix_fmt;

                codec->width = icodec->width;

                codec->height = icodec->height;

                codec->has_b_frames = icodec->has_b_frames;

                if (!codec->sample_aspect_ratio.num) {

                    codec->sample_aspect_ratio =

                    ost->st->sample_aspect_ratio =

                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :

                        ist->st->codec->sample_aspect_ratio.num ?

                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};

                }

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                codec->width = icodec->width;

                codec->height = icodec->height;

                break;

            case AVMEDIA_TYPE_DATA:

                break;

            default:

                abort();

            }

        } else {

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                ost->fifo= av_fifo_alloc(1024);

                if(!ost->fifo)

                    goto fail;

                ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);

                ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;

                icodec->request_channels = codec->channels;

                ist->decoding_needed = 1;

                ost->encoding_needed = 1;

                ost->resample_sample_fmt  = icodec->sample_fmt;

                ost->resample_sample_rate = icodec->sample_rate;

                ost->resample_channels    = icodec->channels;

                break;

            case AVMEDIA_TYPE_VIDEO:

                if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {

                    fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");

                    ffmpeg_exit(1);

                }

                ost->video_resample = codec->width   != icodec->width  ||

                                      codec->height  != icodec->height ||

                                      codec->pix_fmt != icodec->pix_fmt;

                if (ost->video_resample) {

#if !CONFIG_AVFILTER

                    avcodec_get_frame_defaults(&ost->pict_tmp);

                    if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,

                                         codec->width, codec->height)) {

                        fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");

                        ffmpeg_exit(1);

                    }

                    sws_flags = av_get_int(sws_opts, "sws_flags", NULL);

                    ost->img_resample_ctx = sws_getContext(

                        icodec->width,

                        icodec->height,

                            icodec->pix_fmt,

                            codec->width,

                            codec->height,

                            codec->pix_fmt,

                            sws_flags, NULL, NULL, NULL);

                    if (ost->img_resample_ctx == NULL) {

                        fprintf(stderr, "Cannot get resampling context\n");

                        ffmpeg_exit(1);

                    }

#endif

                    codec->bits_per_raw_sample= frame_bits_per_raw_sample;

                }

                ost->resample_height = icodec->height;

                ost->resample_width  = icodec->width;

                ost->resample_pix_fmt= icodec->pix_fmt;

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

#if CONFIG_AVFILTER

                if (configure_video_filters(ist, ost)) {

                    fprintf(stderr, "Error opening filters!\n");

                    exit(1);

                }

#endif

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                break;

            default:

                abort();

                break;

            }

            /* two pass mode */

            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&

                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {

                char logfilename[1024];

                FILE *f;

                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",

                         pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,

                         i);

                if (codec->flags & CODEC_FLAG_PASS1) {

                    f = fopen(logfilename, "wb");

                    if (!f) {

                        fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));

                        ffmpeg_exit(1);

                    }

                    ost->logfile = f;

                } else {

                    char  *logbuffer;

                    size_t logbuffer_size;

                    if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {

                        fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename);

                        ffmpeg_exit(1);

                    }

                    codec->stats_in = logbuffer;

                }

            }

        }

        if(codec->codec_type == AVMEDIA_TYPE_VIDEO){

            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */

            int size= codec->width * codec->height;

            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);

        }

    }

    if (!bit_buffer)

        bit_buffer = av_malloc(bit_buffer_size);

    if (!bit_buffer) {

        fprintf(stderr, "Cannot allocate %d bytes output buffer\n",

                bit_buffer_size);

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    /* open each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            AVCodec *codec = i < nb_output_codecs ? output_codecs[i] : NULL;

            AVCodecContext *dec = ist_table[ost->source_index]->st->codec;

            if (!codec)

                codec = avcodec_find_encoder(ost->st->codec->codec_id);

            if (!codec) {

                snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",

                         ost->st->codec->codec_id, ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (dec->subtitle_header) {

                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);

                if (!ost->st->codec->subtitle_header) {

                    ret = AVERROR(ENOMEM);

                    goto dump_format;

                }

                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);

                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;

            }

            if (avcodec_open(ost->st->codec, codec) < 0) {

                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",

                        ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            extra_size += ost->st->codec->extradata_size;

        }

    }

    /* open each decoder */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            AVCodec *codec = i < nb_input_codecs ? input_codecs[i] : NULL;

            if (!codec)

                codec = avcodec_find_decoder(ist->st->codec->codec_id);

            if (!codec) {

                snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d",

                        ist->st->codec->codec_id, ist->file_index, ist->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (avcodec_open(ist->st->codec, codec) < 0) {

                snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",

                        ist->file_index, ist->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

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

            //    ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;

        }

    }

    /* init pts */

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

        AVStream *st;

        ist = ist_table[i];

        st= ist->st;

        ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0;

        ist->next_pts = AV_NOPTS_VALUE;

        ist->is_start = 1;

    }

    /* set meta data information from input file if required */

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

        AVFormatContext *files[2];

        AVMetadata      **meta[2];

        int j;

#define METADATA_CHECK_INDEX(index, nb_elems, desc)\

        if ((index) < 0 || (index) >= (nb_elems)) {\

            snprintf(error, sizeof(error), "Invalid %s index %d while processing metadata maps\n",\

                     (desc), (index));\

            ret = AVERROR(EINVAL);\

            goto dump_format;\

        }

        int out_file_index = meta_data_maps[i][0].file;

        int in_file_index = meta_data_maps[i][1].file;

        if (in_file_index < 0 || out_file_index < 0)

            continue;

        METADATA_CHECK_INDEX(out_file_index, nb_output_files, "output file")

        METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")

        files[0] = output_files[out_file_index];

        files[1] = input_files[in_file_index];

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

            AVMetaDataMap *map = &meta_data_maps[i][j];

            switch (map->type) {

            case 'g':

                meta[j] = &files[j]->metadata;

                break;

            case 's':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")

                meta[j] = &files[j]->streams[map->index]->metadata;

                break;

            case 'c':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")

                meta[j] = &files[j]->chapters[map->index]->metadata;

                break;

            case 'p':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")

                meta[j] = &files[j]->programs[map->index]->metadata;

                break;

            }

        }

        av_metadata_copy(meta[0], *meta[1], AV_METADATA_DONT_OVERWRITE);

    }

    /* copy global metadata by default */

    if (metadata_global_autocopy) {

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

            av_metadata_copy(&output_files[i]->metadata, input_files[0]->metadata,

                             AV_METADATA_DONT_OVERWRITE);

    }

    /* copy chapters according to chapter maps */

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

        int infile  = chapter_maps[i].in_file;

        int outfile = chapter_maps[i].out_file;

        if (infile < 0 || outfile < 0)

            continue;

        if (infile >= nb_input_files) {

            snprintf(error, sizeof(error), "Invalid input file index %d in chapter mapping.\n", infile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        if (outfile >= nb_output_files) {

            snprintf(error, sizeof(error), "Invalid output file index %d in chapter mapping.\n",outfile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        copy_chapters(infile, outfile);

    }

    /* copy chapters from the first input file that has them*/

    if (!nb_chapter_maps)

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

            if (!input_files[i]->nb_chapters)

                continue;

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

                if ((ret = copy_chapters(i, j)) < 0)

                    goto dump_format;

            break;

        }

    /* open files and write file headers */

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

        os = output_files[i];

        if (av_write_header(os) < 0) {

            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        if (strcmp(output_files[i]->oformat->name, "rtp")) {

            want_sdp = 0;

        }

    }

 dump_format:

    /* dump the file output parameters - cannot be done before in case

       of stream copy */

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

        av_dump_format(output_files[i], i, output_files[i]->filename, 1);

    }

    /* dump the stream mapping */

    if (verbose >= 0) {

        fprintf(stderr, "Stream mapping:\n");

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

            ost = ost_table[i];

            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",

                    ist_table[ost->source_index]->file_index,

                    ist_table[ost->source_index]->index,

                    ost->file_index,

                    ost->index);

            if (ost->sync_ist != ist_table[ost->source_index])

                fprintf(stderr, " [sync #%d.%d]",

                        ost->sync_ist->file_index,

                        ost->sync_ist->index);

            fprintf(stderr, "\n");

        }

    }

    if (ret) {

        fprintf(stderr, "%s\n", error);

        goto fail;

    }

    if (want_sdp) {

        print_sdp(output_files, nb_output_files);

    }

    if (!using_stdin) {

        if(verbose >= 0)

            fprintf(stderr, "Press [q] to stop encoding\n");

        avio_set_interrupt_cb(decode_interrupt_cb);

    }

    term_init();

    timer_start = av_gettime();

    for(; received_sigterm == 0;) {

        int file_index, ist_index;

        AVPacket pkt;

        double ipts_min;

        double opts_min;

    redo:

        ipts_min= 1e100;

        opts_min= 1e100;

        /* if 'q' pressed, exits */

        if (!using_stdin) {

            if (q_pressed)

                break;

            /* read_key() returns 0 on EOF */

            key = read_key();

            if (key == 'q')

                break;

        }

        /* select the stream that we must read now by looking at the

           smallest output pts */

        file_index = -1;

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

            double ipts, opts;

            ost = ost_table[i];

            os = output_files[ost->file_index];

            ist = ist_table[ost->source_index];

            if(ist->is_past_recording_time || no_packet[ist->file_index])

                continue;

                opts = ost->st->pts.val * av_q2d(ost->st->time_base);

            ipts = (double)ist->pts;

            if (!file_table[ist->file_index].eof_reached){

                if(ipts < ipts_min) {

                    ipts_min = ipts;

                    if(input_sync ) file_index = ist->file_index;

                }

                if(opts < opts_min) {

                    opts_min = opts;

                    if(!input_sync) file_index = ist->file_index;

                }

            }

            if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){

                file_index= -1;

                break;

            }

        }

        /* if none, if is finished */

        if (file_index < 0) {

            if(no_packet_count){

                no_packet_count=0;

                memset(no_packet, 0, sizeof(no_packet));

                usleep(10000);

                continue;

            }

            break;

        }

        /* finish if limit size exhausted */

        if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb))

            break;

        /* read a frame from it and output it in the fifo */

        is = input_files[file_index];

        ret= av_read_frame(is, &pkt);

        if(ret == AVERROR(EAGAIN)){

            no_packet[file_index]=1;

            no_packet_count++;

            continue;

        }

        if (ret < 0) {

            file_table[file_index].eof_reached = 1;

            if (opt_shortest)

                break;

            else

                continue;

        }

        no_packet_count=0;

        memset(no_packet, 0, sizeof(no_packet));

        if (do_pkt_dump) {

            av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,

                             is->streams[pkt.stream_index]);

        }

        /* the following test is needed in case new streams appear

           dynamically in stream : we ignore them */

        if (pkt.stream_index >= file_table[file_index].nb_streams)

            goto discard_packet;

        ist_index = file_table[file_index].ist_index + pkt.stream_index;

        ist = ist_table[ist_index];

        if (ist->discard)

            goto discard_packet;

        if (pkt.dts != AV_NOPTS_VALUE)

            pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.pts != AV_NOPTS_VALUE)

            pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.stream_index < nb_input_files_ts_scale[file_index]

            && input_files_ts_scale[file_index][pkt.stream_index]){

            if(pkt.pts != AV_NOPTS_VALUE)

                pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index];

            if(pkt.dts != AV_NOPTS_VALUE)

                pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index];

        }

//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);

        if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE

            && (is->iformat->flags & AVFMT_TS_DISCONT)) {

            int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);

            int64_t delta= pkt_dts - ist->next_pts;

            if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){

                input_files_ts_offset[ist->file_index]-= delta;

                if (verbose > 2)

                    fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);

                pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

                if(pkt.pts != AV_NOPTS_VALUE)

                    pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

            }

        }

        /* finish if recording time exhausted */

        if (recording_time != INT64_MAX &&

            av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000}) >= 0) {

            ist->is_past_recording_time = 1;

            goto discard_packet;

        }

        //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);

        if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {

            if (verbose >= 0)

                fprintf(stderr, "Error while decoding stream #%d.%d\n",

                        ist->file_index, ist->index);

            if (exit_on_error)

                ffmpeg_exit(1);

            av_free_packet(&pkt);

            goto redo;

        }

    discard_packet:

        av_free_packet(&pkt);

        /* dump report by using the output first video and audio streams */

        print_report(output_files, ost_table, nb_ostreams, 0);

    }

    /* at the end of stream, we must flush the decoder buffers */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            output_packet(ist, i, ost_table, nb_ostreams, NULL);

        }

    }

    term_exit();

    /* write the trailer if needed and close file */

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

        os = output_files[i];

        av_write_trailer(os);

    }

    /* dump report by using the first video and audio streams */

    print_report(output_files, ost_table, nb_ostreams, 1);

    /* close each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            av_freep(&ost->st->codec->stats_in);

            avcodec_close(ost->st->codec);

        }

#if CONFIG_AVFILTER

        avfilter_graph_free(&ost->graph);

#endif

    }

    /* close each decoder */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            avcodec_close(ist->st->codec);

        }

    }

    /* finished ! */

    ret = 0;

 fail:

    av_freep(&bit_buffer);

    av_free(file_table);

    if (ist_table) {

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

            ist = ist_table[i];

            av_free(ist);

        }

        av_free(ist_table);

    }

    if (ost_table) {

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

            ost = ost_table[i];

            if (ost) {

                if (ost->st->stream_copy)

                    av_freep(&ost->st->codec->extradata);

                if (ost->logfile) {

                    fclose(ost->logfile);

                    ost->logfile = NULL;

                }

                av_fifo_free(ost->fifo); /* works even if fifo is not

                                             initialized but set to zero */

                av_freep(&ost->st->codec->subtitle_header);

                av_free(ost->pict_tmp.data[0]);

                av_free(ost->forced_kf_pts);

                if (ost->video_resample)

                    sws_freeContext(ost->img_resample_ctx);

                if (ost->resample)

                    audio_resample_close(ost->resample);

                if (ost->reformat_ctx)

                    av_audio_convert_free(ost->reformat_ctx);

                av_free(ost);

            }

        }

        av_free(ost_table);

    }

    return ret;

}


static void kqemu_vfree(void *ptr)

{

    /* may be useful some day, but currently we do not need to free */

}


static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)

{

    int cond;

    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);

    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);

    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);

    TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);

    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);

    TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    if (tf)

        cond = TCG_COND_EQ;

    else

        cond = TCG_COND_NE;

    gen_load_fpr32(fp0, fs);

    gen_load_fpr32h(fph0, fs);

    gen_load_fpr32(fp1, fd);

    gen_load_fpr32h(fph1, fd);

    get_fp_cond(r_tmp1);

    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);

    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);

    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);

    tcg_gen_mov_i32(fp1, fp0);

    tcg_temp_free(fp0);

    gen_set_label(l1);

    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);

    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);

    tcg_gen_mov_i32(fph1, fph0);

    tcg_temp_free(fph0);

    gen_set_label(l2);

    tcg_temp_free(r_tmp1);

    tcg_temp_free(r_tmp2);

    gen_store_fpr32(fp1, fd);

    gen_store_fpr32h(fph1, fd);

    tcg_temp_free(fp1);

    tcg_temp_free(fph1);

}


static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)

{

    BMDMAState *bm = opaque;

    PCIIDEState *pci_dev = pci_from_bm(bm);

#ifdef DEBUG_IDE

    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);

#endif

    switch(addr & 3) {

    case 1:

        pci_dev->dev.config[MRDMODE] =

            (pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30);

        cmd646_update_irq(pci_dev);

        break;

    case 2:

        bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);

        break;

    case 3:

        if (bm->unit == 0)

            pci_dev->dev.config[UDIDETCR0] = val;

        else

            pci_dev->dev.config[UDIDETCR1] = val;

        break;

    }

}


static uint64_t empty_slot_read(void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    DPRINTF("read from " TARGET_FMT_plx "\n", addr);

    return 0;

}


static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,

                qemu_irq *irqs)

{

    int i;

    int iomemtype;

    pxa2xx_timer_info *s;

    s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));

    s->irq_enabled = 0;

    s->oldclock = 0;

    s->clock = 0;

    s->lastload = qemu_get_clock(vm_clock);

    s->reset3 = 0;

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

        s->timer[i].value = 0;

        s->timer[i].irq = irqs[i];

        s->timer[i].info = s;

        s->timer[i].num = i;

        s->timer[i].level = 0;

        s->timer[i].qtimer = qemu_new_timer(vm_clock,

                        pxa2xx_timer_tick, &s->timer[i]);

    }

    iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn,

                    pxa2xx_timer_writefn, s, DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(base, 0x00001000, iomemtype);

    register_savevm(NULL, "pxa2xx_timer", 0, 0,

                    pxa2xx_timer_save, pxa2xx_timer_load, s);

    return s;

}


static int do_subchannel_work(SubchDev *sch)

{

    if (sch->do_subchannel_work) {

        return sch->do_subchannel_work(sch);

    } else {

        return -EINVAL;

    }

}


void block_job_enter(BlockJob *job)

{

    if (job->co && !job->busy) {

        bdrv_coroutine_enter(blk_bs(job->blk), job->co);

    }

}


static int get_physical_address (CPUMIPSState *env, hwaddr *physical,

                                int *prot, target_ulong real_address,

                                int rw, int access_type, int mmu_idx)

{

    /* User mode can only access useg/xuseg */

    int user_mode = mmu_idx == MIPS_HFLAG_UM;

    int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;

    int kernel_mode = !user_mode && !supervisor_mode;

#if defined(TARGET_MIPS64)

    int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;

    int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;

    int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;

#endif

    int ret = TLBRET_MATCH;

    /* effective address (modified for KVM T&E kernel segments) */

    target_ulong address = real_address;

#define USEG_LIMIT      0x7FFFFFFFUL

#define KSEG0_BASE      0x80000000UL

#define KSEG1_BASE      0xA0000000UL

#define KSEG2_BASE      0xC0000000UL

#define KSEG3_BASE      0xE0000000UL

#define KVM_KSEG0_BASE  0x40000000UL

#define KVM_KSEG2_BASE  0x60000000UL

    if (kvm_enabled()) {

        /* KVM T&E adds guest kernel segments in useg */

        if (real_address >= KVM_KSEG0_BASE) {

            if (real_address < KVM_KSEG2_BASE) {

                /* kseg0 */

                address += KSEG0_BASE - KVM_KSEG0_BASE;

            } else if (real_address <= USEG_LIMIT) {

                /* kseg2/3 */

                address += KSEG2_BASE - KVM_KSEG2_BASE;

            }

        }

    }

    if (address <= USEG_LIMIT) {

        /* useg */

        if (env->CP0_Status & (1 << CP0St_ERL)) {

            *physical = address & 0xFFFFFFFF;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        }

#if defined(TARGET_MIPS64)

    } else if (address < 0x4000000000000000ULL) {

        /* xuseg */

        if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0x8000000000000000ULL) {

        /* xsseg */

        if ((supervisor_mode || kernel_mode) &&

            SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0xC000000000000000ULL) {

        /* xkphys */

        if (kernel_mode && KX &&

            (address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {

            *physical = address & env->PAMask;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0xFFFFFFFF80000000ULL) {

        /* xkseg */

        if (kernel_mode && KX &&

            address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

#endif

    } else if (address < (int32_t)KSEG1_BASE) {

        /* kseg0 */

        if (kernel_mode) {

            *physical = address - (int32_t)KSEG0_BASE;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < (int32_t)KSEG2_BASE) {

        /* kseg1 */

        if (kernel_mode) {

            *physical = address - (int32_t)KSEG1_BASE;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < (int32_t)KSEG3_BASE) {

        /* sseg (kseg2) */

        if (supervisor_mode || kernel_mode) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else {

        /* kseg3 */

        /* XXX: debug segment is not emulated */

        if (kernel_mode) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    }

    return ret;

}


static int rv30_decode_mb_info(RV34DecContext *r)

{

    static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };

    static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 };

    MpegEncContext *s = &r->s;

    GetBitContext *gb = &s->gb;

    int code = svq3_get_ue_golomb(gb);

    if(code > 11){

        av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");

        return -1;

    }

    if(code > 5){

        av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n");

        code -= 6;

    }

    if(s->pict_type != AV_PICTURE_TYPE_B)

        return rv30_p_types[code];

    else

        return rv30_b_types[code];

}


static ssize_t test_block_write_func(QCryptoBlock *block,

                                     size_t offset,

                                     const uint8_t *buf,

                                     size_t buflen,

                                     Error **errp,

                                     void *opaque)

{

    Buffer *header = opaque;

    g_assert_cmpint(buflen + offset, <=, header->capacity);

    memcpy(header->buffer + offset, buf, buflen);

    header->offset = offset + buflen;

    return buflen;

}


int net_init_vde(const NetClientOptions *opts, const char *name,

                 NetClientState *peer, Error **errp)

{

    /* FIXME error_setg(errp, ...) on failure */

    const NetdevVdeOptions *vde;

    assert(opts->type == NET_CLIENT_OPTIONS_KIND_VDE);

    vde = opts->u.vde;

    /* missing optional values have been initialized to "all bits zero" */

    if (net_vde_init(peer, "vde", name, vde->sock, vde->port, vde->group,

                     vde->has_mode ? vde->mode : 0700) == -1) {

        return -1;

    }

    return 0;

}


static void tcx_rstip_writel(void *opaque, hwaddr addr,

                             uint64_t val, unsigned size)

{

    TCXState *s = opaque;

    int i;

    uint32_t col;

    if (!(addr & 4)) {

        s->tmpblit = val;

    } else {

        addr = (addr >> 3) & 0xfffff;

        col = cpu_to_be32(s->tmpblit);

        if (s->depth == 24) {

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

                if (val & 0x80000000) {

                    s->vram[addr + i] = s->tmpblit;

                    s->vram24[addr + i] = col;

                    s->cplane[addr + i] = col;

                }

                val <<= 1;

            }

        } else {

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

                if (val & 0x80000000) {

                    s->vram[addr + i] = s->tmpblit;

                }

                val <<= 1;

            }

        }

        memory_region_set_dirty(&s->vram_mem, addr, 32);

    }

}


static int load_flat_file(struct linux_binprm * bprm,

		struct lib_info *libinfo, int id, abi_ulong *extra_stack)

{

    struct flat_hdr * hdr;

    abi_ulong textpos = 0, datapos = 0;

    abi_long result;

    abi_ulong realdatastart = 0;

    abi_ulong text_len, data_len, bss_len, stack_len, flags;

    abi_ulong memp = 0; /* for finding the brk area */

    abi_ulong extra;

    abi_ulong reloc = 0, rp;

    int i, rev, relocs = 0;

    abi_ulong fpos;

    abi_ulong start_code, end_code;

    abi_ulong indx_len;

    hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */

    text_len  = ntohl(hdr->data_start);

    data_len  = ntohl(hdr->data_end) - ntohl(hdr->data_start);

    bss_len   = ntohl(hdr->bss_end) - ntohl(hdr->data_end);

    stack_len = ntohl(hdr->stack_size);

    if (extra_stack) {

        stack_len += *extra_stack;

        *extra_stack = stack_len;

    }

    relocs    = ntohl(hdr->reloc_count);

    flags     = ntohl(hdr->flags);

    rev       = ntohl(hdr->rev);

    DBG_FLT("BINFMT_FLAT: Loading file: %s\n", bprm->filename);

    if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {

        fprintf(stderr, "BINFMT_FLAT: bad magic/rev (0x%x, need 0x%x)\n",

                rev, (int) FLAT_VERSION);

        return -ENOEXEC;

    }

    /* Don't allow old format executables to use shared libraries */

    if (rev == OLD_FLAT_VERSION && id != 0) {

        fprintf(stderr, "BINFMT_FLAT: shared libraries are not available\n");

        return -ENOEXEC;

    }

    /*

     * fix up the flags for the older format,  there were all kinds

     * of endian hacks,  this only works for the simple cases

     */

    if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags))

        flags = FLAT_FLAG_RAM;

#ifndef CONFIG_BINFMT_ZFLAT

    if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {

        fprintf(stderr, "Support for ZFLAT executables is not enabled\n");

        return -ENOEXEC;

    }

#endif

    /*

     * calculate the extra space we need to map in

     */

    extra = relocs * sizeof(abi_ulong);

    if (extra < bss_len + stack_len)

        extra = bss_len + stack_len;

    /* Add space for library base pointers.  Make sure this does not

       misalign the  doesn't misalign the data segment.  */

    indx_len = MAX_SHARED_LIBS * sizeof(abi_ulong);

    indx_len = (indx_len + 15) & ~(abi_ulong)15;

    /*

     * there are a couple of cases here,  the separate code/data

     * case,  and then the fully copied to RAM case which lumps

     * it all together.

     */

    if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) {

        /*

         * this should give us a ROM ptr,  but if it doesn't we don't

         * really care

         */

        DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");

        textpos = target_mmap(0, text_len, PROT_READ|PROT_EXEC,

                              MAP_PRIVATE, bprm->fd, 0);

        if (textpos == -1) {

            fprintf(stderr, "Unable to mmap process text\n");

            return -1;

        }

        realdatastart = target_mmap(0, data_len + extra + indx_len,

                                    PROT_READ|PROT_WRITE|PROT_EXEC,

                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        if (realdatastart == -1) {

            fprintf(stderr, "Unable to allocate RAM for process data\n");

            return realdatastart;

        }

        datapos = realdatastart + indx_len;

        DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n",

                        (int)(data_len + bss_len + stack_len), (int)datapos);

        fpos = ntohl(hdr->data_start);

#ifdef CONFIG_BINFMT_ZFLAT

        if (flags & FLAT_FLAG_GZDATA) {

            result = decompress_exec(bprm, fpos, (char *) datapos,

                                     data_len + (relocs * sizeof(abi_ulong)))

        } else

#endif

        {

            result = target_pread(bprm->fd, datapos,

                                  data_len + (relocs * sizeof(abi_ulong)),

                                  fpos);

        }

        if (result < 0) {

            fprintf(stderr, "Unable to read data+bss\n");

            return result;

        }

        reloc = datapos + (ntohl(hdr->reloc_start) - text_len);

        memp = realdatastart;

    } else {

        textpos = target_mmap(0, text_len + data_len + extra + indx_len,

                              PROT_READ | PROT_EXEC | PROT_WRITE,

                              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        if (textpos == -1 ) {

            fprintf(stderr, "Unable to allocate RAM for process text/data\n");

            return -1;

        }

        realdatastart = textpos + ntohl(hdr->data_start);

        datapos = realdatastart + indx_len;

        reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);

        memp = textpos;

#ifdef CONFIG_BINFMT_ZFLAT

#error code needs checking

        /*

         * load it all in and treat it like a RAM load from now on

         */

        if (flags & FLAT_FLAG_GZIP) {

                result = decompress_exec(bprm, sizeof (struct flat_hdr),

                                 (((char *) textpos) + sizeof (struct flat_hdr)),

                                 (text_len + data_len + (relocs * sizeof(unsigned long))

                                          - sizeof (struct flat_hdr)),

                                 0);

                memmove((void *) datapos, (void *) realdatastart,

                                data_len + (relocs * sizeof(unsigned long)));

        } else if (flags & FLAT_FLAG_GZDATA) {

                fpos = 0;

                result = bprm->file->f_op->read(bprm->file,

                                (char *) textpos, text_len, &fpos);

                if (result < (unsigned long) -4096)

                        result = decompress_exec(bprm, text_len, (char *) datapos,

                                         data_len + (relocs * sizeof(unsigned long)), 0);

        }

        else

#endif

        {

            result = target_pread(bprm->fd, textpos,

                                  text_len, 0);

            if (result >= 0) {

                result = target_pread(bprm->fd, datapos,

                    data_len + (relocs * sizeof(abi_ulong)),

                    ntohl(hdr->data_start));

            }

        }

        if (result < 0) {

            fprintf(stderr, "Unable to read code+data+bss\n");

            return result;

        }

    }

    DBG_FLT("Mapping is 0x%x, Entry point is 0x%x, data_start is 0x%x\n",

            (int)textpos, 0x00ffffff&ntohl(hdr->entry),

            ntohl(hdr->data_start));

    /* The main program needs a little extra setup in the task structure */

    start_code = textpos + sizeof (struct flat_hdr);

    end_code = textpos + text_len;

    DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",

            id ? "Lib" : "Load", bprm->filename,

            (int) start_code, (int) end_code,

            (int) datapos,

            (int) (datapos + data_len),

            (int) (datapos + data_len),

            (int) (((datapos + data_len + bss_len) + 3) & ~3));

    text_len -= sizeof(struct flat_hdr); /* the real code len */

    /* Store the current module values into the global library structure */

    libinfo[id].start_code = start_code;

    libinfo[id].start_data = datapos;

    libinfo[id].end_data = datapos + data_len;

    libinfo[id].start_brk = datapos + data_len + bss_len;

    libinfo[id].text_len = text_len;

    libinfo[id].loaded = 1;

    libinfo[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;

    libinfo[id].build_date = ntohl(hdr->build_date);

    /*

     * We just load the allocations into some temporary memory to

     * help simplify all this mumbo jumbo

     *

     * We've got two different sections of relocation entries.

     * The first is the GOT which resides at the begining of the data segment

     * and is terminated with a -1.  This one can be relocated in place.

     * The second is the extra relocation entries tacked after the image's

     * data segment. These require a little more processing as the entry is

     * really an offset into the image which contains an offset into the

     * image.

     */

    if (flags & FLAT_FLAG_GOTPIC) {

        rp = datapos;

        while (1) {

            abi_ulong addr;

            if (get_user_ual(addr, rp))

                return -EFAULT;

            if (addr == -1)

                break;

            if (addr) {

                addr = calc_reloc(addr, libinfo, id, 0);

                if (addr == RELOC_FAILED)

                    return -ENOEXEC;

                if (put_user_ual(addr, rp))

                    return -EFAULT;

            }

            rp += sizeof(abi_ulong);

        }

    }

    /*

     * Now run through the relocation entries.

     * We've got to be careful here as C++ produces relocatable zero

     * entries in the constructor and destructor tables which are then

     * tested for being not zero (which will always occur unless we're

     * based from address zero).  This causes an endless loop as __start

     * is at zero.  The solution used is to not relocate zero addresses.

     * This has the negative side effect of not allowing a global data

     * reference to be statically initialised to _stext (I've moved

     * __start to address 4 so that is okay).

     */

    if (rev > OLD_FLAT_VERSION) {

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

            abi_ulong addr, relval;

            /* Get the address of the pointer to be

               relocated (of course, the address has to be

               relocated first).  */

            if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))

                return -EFAULT;

            addr = flat_get_relocate_addr(relval);

            rp = calc_reloc(addr, libinfo, id, 1);

            if (rp == RELOC_FAILED)

                return -ENOEXEC;

            /* Get the pointer's value.  */

            if (get_user_ual(addr, rp))

                return -EFAULT;

            if (addr != 0) {

                /*

                 * Do the relocation.  PIC relocs in the data section are

                 * already in target order

                 */

#ifndef TARGET_WORDS_BIGENDIAN

                if ((flags & FLAT_FLAG_GOTPIC) == 0)

                    addr = bswap32(addr);

#endif

                addr = calc_reloc(addr, libinfo, id, 0);

                if (addr == RELOC_FAILED)

                    return -ENOEXEC;

                /* Write back the relocated pointer.  */

                if (put_user_ual(addr, rp))

                    return -EFAULT;

            }

        }

    } else {

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

            abi_ulong relval;

            if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))

                return -EFAULT;

            old_reloc(&libinfo[0], relval);

        }

    }

    /* zero the BSS.  */

    memset((void *)((unsigned long)datapos + data_len), 0, bss_len);

    return 0;

}


static void tcg_out_bc(TCGContext *s, int bc, int label_index)

{

    TCGLabel *l = &s->labels[label_index];

    if (l->has_value) {

        tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));

    } else {

        tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);

        tcg_out_bc_noaddr(s, bc);

    }

}


static void rng_egd_free_request(RngRequest *req)

{

    g_free(req->data);

    g_free(req);

}


static int vhdx_create_bat(BlockDriverState *bs, BDRVVHDXState *s,

                           uint64_t image_size, VHDXImageType type,

                           bool use_zero_blocks, uint64_t file_offset,

                           uint32_t length)

{

    int ret = 0;

    uint64_t data_file_offset;

    uint64_t total_sectors = 0;

    uint64_t sector_num = 0;

    uint64_t unused;

    int block_state;

    VHDXSectorInfo sinfo;

    assert(s->bat == NULL);

    /* this gives a data start after BAT/bitmap entries, and well

     * past any metadata entries (with a 4 MB buffer for future

     * expansion */

    data_file_offset = file_offset + length + 5 * MiB;

    total_sectors = image_size >> s->logical_sector_size_bits;

    if (type == VHDX_TYPE_DYNAMIC) {

        /* All zeroes, so we can just extend the file - the end of the BAT

         * is the furthest thing we have written yet */

        ret = bdrv_truncate(bs, data_file_offset);

        if (ret < 0) {

            goto exit;

        }

    } else if (type == VHDX_TYPE_FIXED) {

        ret = bdrv_truncate(bs, data_file_offset + image_size);

        if (ret < 0) {

            goto exit;

        }

    } else {

        ret = -ENOTSUP;

        goto exit;

    }

    if (type == VHDX_TYPE_FIXED ||

                use_zero_blocks ||

                bdrv_has_zero_init(bs) == 0) {

        /* for a fixed file, the default BAT entry is not zero */

        s->bat = g_try_malloc0(length);

        if (length && s->bat != NULL) {

            ret = -ENOMEM;

            goto exit;

        }

        block_state = type == VHDX_TYPE_FIXED ? PAYLOAD_BLOCK_FULLY_PRESENT :

                                                PAYLOAD_BLOCK_NOT_PRESENT;

        block_state = use_zero_blocks ? PAYLOAD_BLOCK_ZERO : block_state;

        /* fill the BAT by emulating sector writes of sectors_per_block size */

        while (sector_num < total_sectors) {

            vhdx_block_translate(s, sector_num, s->sectors_per_block, &sinfo);

            sinfo.file_offset = data_file_offset +

                                (sector_num << s->logical_sector_size_bits);

            sinfo.file_offset = ROUND_UP(sinfo.file_offset, MiB);

            vhdx_update_bat_table_entry(bs, s, &sinfo, &unused, &unused,

                                        block_state);

            cpu_to_le64s(&s->bat[sinfo.bat_idx]);

            sector_num += s->sectors_per_block;

        }

        ret = bdrv_pwrite(bs, file_offset, s->bat, length);

        if (ret < 0) {

            goto exit;

        }

    }

exit:

    g_free(s->bat);

    return ret;

}


int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)

{

    struct kvm_signal_mask *sigmask;

    int r;

    if (!sigset) {

        return kvm_vcpu_ioctl(cpu, KVM_SET_SIGNAL_MASK, NULL);

    }

    sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset));

    sigmask->len = 8;

    memcpy(sigmask->sigset, sigset, sizeof(*sigset));

    r = kvm_vcpu_ioctl(cpu, KVM_SET_SIGNAL_MASK, sigmask);

    g_free(sigmask);

    return r;

}


unsigned avutil_version(void)

{

    av_assert0(AV_PIX_FMT_VDA_VLD == 81); //check if the pix fmt enum has not had anything inserted or removed by mistake

    av_assert0(AV_SAMPLE_FMT_DBLP == 9);

    av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4);

    av_assert0(AV_PICTURE_TYPE_BI == 7);

    av_assert0(LIBAVUTIL_VERSION_MICRO >= 100);

    av_assert0(HAVE_MMX2 == HAVE_MMXEXT);

    if (av_sat_dadd32(1, 2) != 5) {

        av_log(NULL, AV_LOG_FATAL, "Libavutil has been build with a broken binutils, please upgrade binutils and rebuild\n");

        abort();

    }

    ff_check_pixfmt_descriptors();

    return LIBAVUTIL_VERSION_INT;

}


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;

    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;

        }

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

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

        }

    }

    /* 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) {

        av_log(h, AV_LOG_ERROR, "bind failed: %s\n", strerror(errno));

        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 (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)

                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) {

            av_log(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno));

            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) {

            av_log(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno));

        }

        /* 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)) {

            av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno));

            goto fail;

        }

    }

    s->udp_fd = udp_fd;

#if HAVE_PTHREADS

    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_PTHREADS

 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);

    return AVERROR(EIO);

}