int drive_init(struct drive_opt *arg, int snapshot, void *opaque)

{

    char buf[128];

    char file[1024];

    char devname[128];

    char serial[21];

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriverState *bdrv;

    BlockDriver *drv = NULL;

    QEMUMachine *machine = opaque;

    int max_devs;

    int index;

    int cache;

    int bdrv_flags, onerror;

    int drives_table_idx;

    char *str = arg->opt;

    static const char * const params[] = { "bus", "unit", "if", "index",

                                           "cyls", "heads", "secs", "trans",

                                           "media", "snapshot", "file",

                                           "cache", "format", "serial", "werror",

                                           NULL };

    if (check_params(buf, sizeof(buf), params, str) < 0) {

         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",

                         buf, str);

         return -1;

    }

    file[0] = 0;

    cyls = heads = secs = 0;

    bus_id = 0;

    unit_id = -1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    index = -1;

    cache = 3;

    if (machine->use_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

        pstrcpy(devname, sizeof(devname), "scsi");

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

        pstrcpy(devname, sizeof(devname), "ide");

    }

    media = MEDIA_DISK;

    /* extract parameters */

    if (get_param_value(buf, sizeof(buf), "bus", str)) {

        bus_id = strtol(buf, NULL, 0);

	if (bus_id < 0) {

	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "unit", str)) {

        unit_id = strtol(buf, NULL, 0);

	if (unit_id < 0) {

	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "if", str)) {

        pstrcpy(devname, sizeof(devname), buf);

        if (!strcmp(buf, "ide")) {

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

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

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

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

	    type = IF_FLOPPY;

            max_devs = 0;

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

	    type = IF_PFLASH;

            max_devs = 0;

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

	    type = IF_MTD;

            max_devs = 0;

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

	    type = IF_SD;

            max_devs = 0;

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

            type = IF_VIRTIO;

            max_devs = 0;

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

	    type = IF_XEN;

            max_devs = 0;

	} else {

            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);

            return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "index", str)) {

        index = strtol(buf, NULL, 0);

	if (index < 0) {

	    fprintf(stderr, "qemu: '%s' invalid index\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "cyls", str)) {

        cyls = strtol(buf, NULL, 0);

    }

    if (get_param_value(buf, sizeof(buf), "heads", str)) {

        heads = strtol(buf, NULL, 0);

    }

    if (get_param_value(buf, sizeof(buf), "secs", str)) {

        secs = strtol(buf, NULL, 0);

    }

    if (cyls || heads || secs) {

        if (cyls < 1 || cyls > 16383) {

            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);

	    return -1;

	}

        if (heads < 1 || heads > 16) {

            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);

	    return -1;

	}

        if (secs < 1 || secs > 63) {

            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "trans", str)) {

        if (!cyls) {

            fprintf(stderr,

                    "qemu: '%s' trans must be used with cyls,heads and secs\n",

                    str);

            return -1;

        }

        if (!strcmp(buf, "none"))

            translation = BIOS_ATA_TRANSLATION_NONE;

        else if (!strcmp(buf, "lba"))

            translation = BIOS_ATA_TRANSLATION_LBA;

        else if (!strcmp(buf, "auto"))

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "media", str)) {

        if (!strcmp(buf, "disk")) {

	    media = MEDIA_DISK;

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

            if (cyls || secs || heads) {

                fprintf(stderr,

                        "qemu: '%s' invalid physical CHS format\n", str);

	        return -1;

            }

	    media = MEDIA_CDROM;

	} else {

	    fprintf(stderr, "qemu: '%s' invalid media\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {

        if (!strcmp(buf, "on"))

	    snapshot = 1;

        else if (!strcmp(buf, "off"))

	    snapshot = 0;

	else {

	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "cache", str)) {

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

            cache = 0;

        else if (!strcmp(buf, "writethrough"))

            cache = 1;

        else if (!strcmp(buf, "writeback"))

            cache = 2;

        else {

           fprintf(stderr, "qemu: invalid cache option\n");

           return -1;

        }

    }

    if (get_param_value(buf, sizeof(buf), "format", str)) {

       if (strcmp(buf, "?") == 0) {

            fprintf(stderr, "qemu: Supported formats:");

            bdrv_iterate_format(bdrv_format_print, NULL);

            fprintf(stderr, "\n");

	    return -1;

        }

        drv = bdrv_find_format(buf);

        if (!drv) {

            fprintf(stderr, "qemu: '%s' invalid format\n", buf);

            return -1;

        }

    }

    if (arg->file == NULL)

        get_param_value(file, sizeof(file), "file", str);

    else

        pstrcpy(file, sizeof(file), arg->file);

    if (!get_param_value(serial, sizeof(serial), "serial", str))

	    memset(serial, 0,  sizeof(serial));

    onerror = BLOCK_ERR_STOP_ENOSPC;

    if (get_param_value(buf, sizeof(serial), "werror", str)) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {

            fprintf(stderr, "werror is no supported by this format\n");

            return -1;

        }

        if (!strcmp(buf, "ignore"))

            onerror = BLOCK_ERR_IGNORE;

        else if (!strcmp(buf, "enospc"))

            onerror = BLOCK_ERR_STOP_ENOSPC;

        else if (!strcmp(buf, "stop"))

            onerror = BLOCK_ERR_STOP_ANY;

        else if (!strcmp(buf, "report"))

            onerror = BLOCK_ERR_REPORT;

        else {

            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);

            return -1;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

        if (bus_id != 0 || unit_id != -1) {

            fprintf(stderr,

                    "qemu: '%s' index cannot be used with bus and unit\n", str);

            return -1;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

       while (drive_get_index(type, bus_id, unit_id) != -1) {

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",

                        str, unit_id, max_devs - 1);

        return -1;

    }

    /*

     * ignore multiple definitions

     */

    if (drive_get_index(type, bus_id, unit_id) != -1)

        return -2;

    /* init */

    if (type == IF_IDE || type == IF_SCSI)

        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";

    if (max_devs)

        snprintf(buf, sizeof(buf), "%s%i%s%i",

                 devname, bus_id, mediastr, unit_id);

    else

        snprintf(buf, sizeof(buf), "%s%s%i",

                 devname, mediastr, unit_id);

    bdrv = bdrv_new(buf);

    drives_table_idx = drive_get_free_idx();

    drives_table[drives_table_idx].bdrv = bdrv;

    drives_table[drives_table_idx].type = type;

    drives_table[drives_table_idx].bus = bus_id;

    drives_table[drives_table_idx].unit = unit_id;

    drives_table[drives_table_idx].onerror = onerror;

    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;

    strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));

    nb_drives++;

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);

                bdrv_set_translation_hint(bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

        /* FIXME: This isn't really a floppy, but it's a reasonable

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

    case IF_VIRTIO:

        break;

    }

    if (!file[0])

        return -2;

    bdrv_flags = 0;

    if (snapshot) {

        bdrv_flags |= BDRV_O_SNAPSHOT;

        cache = 2; /* always use write-back with snapshot */

    }

    if (cache == 0) /* no caching */

        bdrv_flags |= BDRV_O_NOCACHE;

    else if (cache == 2) /* write-back */

        bdrv_flags |= BDRV_O_CACHE_WB;

    else if (cache == 3) /* not specified */

        bdrv_flags |= BDRV_O_CACHE_DEF;

    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {

        fprintf(stderr, "qemu: could not open disk image %s\n",

                        file);

        return -1;

    }

    if (bdrv_key_required(bdrv))

        autostart = 0;

    return drives_table_idx;

}


static void unix_wait_for_connect(int fd, Error *err, void *opaque)

{

    MigrationState *s = opaque;

    if (fd < 0) {

        DPRINTF("migrate connect error: %s\n", error_get_pretty(err));

        s->file = NULL;

        migrate_fd_error(s);

    } else {

        DPRINTF("migrate connect success\n");

        s->file = qemu_fopen_socket(fd, "wb");

        migrate_fd_connect(s);

    }

}


static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                              const AVFrame *pict, int *got_packet)

{

    LJpegEncContext *s = avctx->priv_data;

    PutBitContext pb;

    const int width  = avctx->width;

    const int height = avctx->height;

    const int mb_width  = (width  + s->hsample[0] - 1) / s->hsample[0];

    const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];

    int max_pkt_size = AV_INPUT_BUFFER_MIN_SIZE;

    int ret, header_bits;

    if (avctx->pix_fmt == AV_PIX_FMT_BGR24)

        max_pkt_size += width * height * 3 * 3;

    else {

        max_pkt_size += mb_width * mb_height * 3 * 4

                        * s->hsample[0] * s->vsample[0];

    }

    if ((ret = ff_alloc_packet(pkt, max_pkt_size)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", max_pkt_size);

        return ret;

    }

    init_put_bits(&pb, pkt->data, pkt->size);

    ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,

                                   s->matrix);

    header_bits = put_bits_count(&pb);

    if (avctx->pix_fmt == AV_PIX_FMT_BGR24)

        ret = ljpeg_encode_bgr(avctx, &pb, pict);

    else

        ret = ljpeg_encode_yuv(avctx, &pb, pict);

    if (ret < 0)

        return ret;

    emms_c();

    ff_mjpeg_encode_picture_trailer(&pb, header_bits);

    flush_put_bits(&pb);

    pkt->size   = put_bits_ptr(&pb) - pb.buf;

    pkt->flags |= AV_PKT_FLAG_KEY;

    *got_packet = 1;

    return 0;

}


int av_vsrc_buffer_add_video_buffer_ref(AVFilterContext *buffer_filter, AVFilterBufferRef *picref)

{

    BufferSourceContext *c = buffer_filter->priv;

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

    int ret;

    if (c->picref) {

        av_log(buffer_filter, AV_LOG_ERROR,

               "Buffering several frames is not supported. "

               "Please consume all available frames before adding a new one.\n"

            );

        //return -1;

    }

    if (picref->video->w != c->w || picref->video->h != c->h || picref->format != c->pix_fmt) {

        AVFilterContext *scale = buffer_filter->outputs[0]->dst;

        AVFilterLink *link;

        char scale_param[1024];

        av_log(buffer_filter, AV_LOG_INFO,

               "Buffer video input changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",

               c->w, c->h, av_pix_fmt_descriptors[c->pix_fmt].name,

               picref->video->w, picref->video->h, av_pix_fmt_descriptors[picref->format].name);

        if (!scale || strcmp(scale->filter->name, "scale")) {

            AVFilter *f = avfilter_get_by_name("scale");

            av_log(buffer_filter, AV_LOG_INFO, "Inserting scaler filter\n");

            if ((ret = avfilter_open(&scale, f, "Input equalizer")) < 0)

                return ret;

            snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s", c->w, c->h, c->sws_param);

            if ((ret = avfilter_init_filter(scale, scale_param, NULL)) < 0) {

                avfilter_free(scale);

                return ret;

            }

            if ((ret = avfilter_insert_filter(buffer_filter->outputs[0], scale, 0, 0)) < 0) {

                avfilter_free(scale);

                return ret;

            }

            scale->outputs[0]->time_base = scale->inputs[0]->time_base;

            scale->outputs[0]->format= c->pix_fmt;

        } else if (!strcmp(scale->filter->name, "scale")) {

            snprintf(scale_param, sizeof(scale_param)-1, "%d:%d:%s",

                     scale->outputs[0]->w, scale->outputs[0]->h, c->sws_param);

            scale->filter->init(scale, scale_param, NULL);

        }

        c->pix_fmt = scale->inputs[0]->format = picref->format;

        c->w       = scale->inputs[0]->w      = picref->video->w;

        c->h       = scale->inputs[0]->h      = picref->video->h;

        link = scale->outputs[0];

        if ((ret =  link->srcpad->config_props(link)) < 0)

            return ret;

    }

    c->picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,

                                          picref->video->w, picref->video->h);

    av_image_copy(c->picref->data, c->picref->linesize,

                  picref->data, picref->linesize,

                  picref->format, picref->video->w, picref->video->h);

    avfilter_copy_buffer_ref_props(c->picref, picref);

    return 0;

}


int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
                                         H264ParamSets *ps, int bit_length)
{
    AVBufferRef *pps_buf;
    const SPS *sps;
    unsigned int pps_id = get_ue_golomb(gb);
    PPS *pps;
    int qp_bd_offset;
    int bits_left;
    int ret;
    if (pps_id >= MAX_PPS_COUNT) {
        av_log(avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
        return AVERROR_INVALIDDATA;
    pps_buf = av_buffer_allocz(sizeof(*pps));
    if (!pps_buf)
        return AVERROR(ENOMEM);
    pps = (PPS*)pps_buf->data;
    pps->data_size = gb->buffer_end - gb->buffer;
    if (pps->data_size > sizeof(pps->data)) {
        av_log(avctx, AV_LOG_WARNING, "Truncating likely oversized PPS "
               "(%"SIZE_SPECIFIER" > %"SIZE_SPECIFIER")\n",
               pps->data_size, sizeof(pps->data));
        pps->data_size = sizeof(pps->data);
    memcpy(pps->data, gb->buffer, pps->data_size);
    pps->sps_id = get_ue_golomb_31(gb);
    if ((unsigned)pps->sps_id >= MAX_SPS_COUNT ||
        !ps->sps_list[pps->sps_id]) {
        av_log(avctx, AV_LOG_ERROR, "sps_id %u out of range\n", pps->sps_id);
    sps = (const SPS*)ps->sps_list[pps->sps_id]->data;
    if (sps->bit_depth_luma > 14) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid luma bit depth=%d\n",
               sps->bit_depth_luma);
    } else if (sps->bit_depth_luma == 11 || sps->bit_depth_luma == 13) {
        av_log(avctx, AV_LOG_ERROR,
               "Unimplemented luma bit depth=%d\n",
               sps->bit_depth_luma);
        ret = AVERROR_PATCHWELCOME;
    pps->cabac             = get_bits1(gb);
    pps->pic_order_present = get_bits1(gb);
    pps->slice_group_count = get_ue_golomb(gb) + 1;
    if (pps->slice_group_count > 1) {
        pps->mb_slice_group_map_type = get_ue_golomb(gb);
        av_log(avctx, AV_LOG_ERROR, "FMO not supported\n");
        switch (pps->mb_slice_group_map_type) {
        case 0:
#if 0
    |       for (i = 0; i <= num_slice_groups_minus1; i++)  |   |      |
    |           run_length[i]                               |1  |ue(v) |
#endif
            break;
        case 2:
#if 0
    |       for (i = 0; i < num_slice_groups_minus1; i++) { |   |      |
    |           top_left_mb[i]                              |1  |ue(v) |
    |           bottom_right_mb[i]                          |1  |ue(v) |
    |       }                                               |   |      |
#endif
            break;
        case 3:
        case 4:
        case 5:
#if 0
    |       slice_group_change_direction_flag               |1  |u(1)  |
    |       slice_group_change_rate_minus1                  |1  |ue(v) |
#endif
            break;
        case 6:
#if 0
    |       slice_group_id_cnt_minus1                       |1  |ue(v) |
    |       for (i = 0; i <= slice_group_id_cnt_minus1; i++)|   |      |
    |           slice_group_id[i]                           |1  |u(v)  |
#endif
            break;
    pps->ref_count[0] = get_ue_golomb(gb) + 1;
    pps->ref_count[1] = get_ue_golomb(gb) + 1;
    if (pps->ref_count[0] - 1 > 32 - 1 || pps->ref_count[1] - 1 > 32 - 1) {
        av_log(avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
    qp_bd_offset = 6 * (sps->bit_depth_luma - 8);
    pps->weighted_pred                        = get_bits1(gb);
    pps->weighted_bipred_idc                  = get_bits(gb, 2);
    pps->init_qp                              = get_se_golomb(gb) + 26 + qp_bd_offset;
    pps->init_qs                              = get_se_golomb(gb) + 26 + qp_bd_offset;
    pps->chroma_qp_index_offset[0]            = get_se_golomb(gb);
    pps->deblocking_filter_parameters_present = get_bits1(gb);
    pps->constrained_intra_pred               = get_bits1(gb);
    pps->redundant_pic_cnt_present            = get_bits1(gb);
    pps->transform_8x8_mode = 0;
    memcpy(pps->scaling_matrix4, sps->scaling_matrix4,
           sizeof(pps->scaling_matrix4));
    memcpy(pps->scaling_matrix8, sps->scaling_matrix8,
           sizeof(pps->scaling_matrix8));
    bits_left = bit_length - get_bits_count(gb);
    if (bits_left > 0 && more_rbsp_data_in_pps(sps, avctx)) {
        pps->transform_8x8_mode = get_bits1(gb);
        decode_scaling_matrices(gb, sps, pps, 0,
                                pps->scaling_matrix4, pps->scaling_matrix8);
        // second_chroma_qp_index_offset
        pps->chroma_qp_index_offset[1] = get_se_golomb(gb);
        if (pps->chroma_qp_index_offset[1] < -12 || pps->chroma_qp_index_offset[1] > 12) {
    } else {
        pps->chroma_qp_index_offset[1] = pps->chroma_qp_index_offset[0];
    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0],
                   sps->bit_depth_luma);
    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1],
                   sps->bit_depth_luma);
    init_dequant_tables(pps, sps);
    if (pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
        pps->chroma_qp_diff = 1;
    if (avctx->debug & FF_DEBUG_PICT_INFO) {
        av_log(avctx, AV_LOG_DEBUG,
               "pps:%u sps:%u %s slice_groups:%d ref:%u/%u %s qp:%d/%d/%d/%d %s %s %s %s\n",
               pps_id, pps->sps_id,
               pps->cabac ? "CABAC" : "CAVLC",
               pps->slice_group_count,
               pps->ref_count[0], pps->ref_count[1],
               pps->weighted_pred ? "weighted" : "",
               pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset[0], pps->chroma_qp_index_offset[1],
               pps->deblocking_filter_parameters_present ? "LPAR" : "",
               pps->constrained_intra_pred ? "CONSTR" : "",
               pps->redundant_pic_cnt_present ? "REDU" : "",
               pps->transform_8x8_mode ? "8x8DCT" : "");
    remove_pps(ps, pps_id);
    ps->pps_list[pps_id] = pps_buf;
    return 0;
fail:
    av_buffer_unref(&pps_buf);
    return ret;


static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)

{

    trace_qxl_spice_monitors_config(qxl->id);

    if (replay) {

        /*

         * don't use QXL_COOKIE_TYPE_IO:

         *  - we are not running yet (post_load), we will assert

         *    in send_events

         *  - this is not a guest io, but a reply, so async_io isn't set.

         */

        spice_qxl_monitors_config_async(&qxl->ssd.qxl,

                qxl->guest_monitors_config,

                MEMSLOT_GROUP_GUEST,

                (uintptr_t)qxl_cookie_new(

                    QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,

                    0));

    } else {

#if SPICE_SERVER_VERSION >= 0x000c06 /* release 0.12.6 */

        if (qxl->max_outputs) {

            spice_qxl_set_monitors_config_limit(&qxl->ssd.qxl,

                                                qxl->max_outputs);

        }

#endif

        qxl->guest_monitors_config = qxl->ram->monitors_config;

        spice_qxl_monitors_config_async(&qxl->ssd.qxl,

                qxl->ram->monitors_config,

                MEMSLOT_GROUP_GUEST,

                (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,

                                          QXL_IO_MONITORS_CONFIG_ASYNC));

    }

}


static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)

{

    VirtIODevice *vdev = VIRTIO_DEVICE(n);

    NetClientState *nc = qemu_get_queue(n->nic);

    int queues = n->multiqueue ? n->max_queues : 1;

    if (!get_vhost_net(nc->peer)) {

        return;

    }

    if (!!n->vhost_started ==

        (virtio_net_started(n, status) && !nc->peer->link_down)) {

        return;

    }

    if (!n->vhost_started) {

        int r;

        if (!vhost_net_query(get_vhost_net(nc->peer), vdev)) {

            return;

        }

        n->vhost_started = 1;

        r = vhost_net_start(vdev, n->nic->ncs, queues);

        if (r < 0) {

            error_report("unable to start vhost net: %d: "

                         "falling back on userspace virtio", -r);

            n->vhost_started = 0;

        }

    } else {

        vhost_net_stop(vdev, n->nic->ncs, queues);

        n->vhost_started = 0;

    }

}


static void spapr_cpu_core_host_initfn(Object *obj)

{

    sPAPRCPUCore *core = SPAPR_CPU_CORE(obj);

    char *name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, "host");

    ObjectClass *oc = object_class_by_name(name);

    g_assert(oc);

    g_free((void *)name);

    core->cpu_class = oc;

}


static void init_block_mapping(Vp3DecodeContext *s)

{

    int i, j;

    signed int hilbert_walk_y[16];

    signed int hilbert_walk_c[16];

    signed int hilbert_walk_mb[4];

    int current_fragment = 0;

    int current_width = 0;

    int current_height = 0;

    int right_edge = 0;

    int bottom_edge = 0;

    int superblock_row_inc = 0;

    int *hilbert = NULL;

    int mapping_index = 0;

    int current_macroblock;

    int c_fragment;

    signed char travel_width[16] = {

         1,  1,  0, -1,

         0,  0,  1,  0,

         1,  0,  1,  0,

         0, -1,  0,  1

    };

    signed char travel_height[16] = {

         0,  0,  1,  0,

         1,  1,  0, -1,

         0,  1,  0, -1,

        -1,  0, -1,  0

    };

    signed char travel_width_mb[4] = {

         1,  0,  1,  0

    };

    signed char travel_height_mb[4] = {

         0,  1,  0, -1

    };

    debug_vp3("  vp3: initialize block mapping tables\n");

    /* figure out hilbert pattern per these frame dimensions */

    hilbert_walk_y[0]  = 1;

    hilbert_walk_y[1]  = 1;

    hilbert_walk_y[2]  = s->fragment_width;

    hilbert_walk_y[3]  = -1;

    hilbert_walk_y[4]  = s->fragment_width;

    hilbert_walk_y[5]  = s->fragment_width;

    hilbert_walk_y[6]  = 1;

    hilbert_walk_y[7]  = -s->fragment_width;

    hilbert_walk_y[8]  = 1;

    hilbert_walk_y[9]  = s->fragment_width;

    hilbert_walk_y[10]  = 1;

    hilbert_walk_y[11] = -s->fragment_width;

    hilbert_walk_y[12] = -s->fragment_width;

    hilbert_walk_y[13] = -1;

    hilbert_walk_y[14] = -s->fragment_width;

    hilbert_walk_y[15] = 1;

    hilbert_walk_c[0]  = 1;

    hilbert_walk_c[1]  = 1;

    hilbert_walk_c[2]  = s->fragment_width / 2;

    hilbert_walk_c[3]  = -1;

    hilbert_walk_c[4]  = s->fragment_width / 2;

    hilbert_walk_c[5]  = s->fragment_width / 2;

    hilbert_walk_c[6]  = 1;

    hilbert_walk_c[7]  = -s->fragment_width / 2;

    hilbert_walk_c[8]  = 1;

    hilbert_walk_c[9]  = s->fragment_width / 2;

    hilbert_walk_c[10]  = 1;

    hilbert_walk_c[11] = -s->fragment_width / 2;

    hilbert_walk_c[12] = -s->fragment_width / 2;

    hilbert_walk_c[13] = -1;

    hilbert_walk_c[14] = -s->fragment_width / 2;

    hilbert_walk_c[15] = 1;

    hilbert_walk_mb[0] = 1;

    hilbert_walk_mb[1] = s->macroblock_width;

    hilbert_walk_mb[2] = 1;

    hilbert_walk_mb[3] = -s->macroblock_width;

    /* iterate through each superblock (all planes) and map the fragments */

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

        debug_init("    superblock %d (u starts @ %d, v starts @ %d)\n",

            i, s->u_superblock_start, s->v_superblock_start);

        /* time to re-assign the limits? */

        if (i == 0) {

            /* start of Y superblocks */

            right_edge = s->fragment_width;

            bottom_edge = s->fragment_height;

            current_width = 0;

            current_height = 0;

            superblock_row_inc = 3 * s->fragment_width;

            hilbert = hilbert_walk_y;

            /* the first operation for this variable is to advance by 1 */

            current_fragment = -1;

        } else if (i == s->u_superblock_start) {

            /* start of U superblocks */

            right_edge = s->fragment_width / 2;

            bottom_edge = s->fragment_height / 2;

            current_width = 0;

            current_height = 0;

            superblock_row_inc = 3 * (s->fragment_width / 2);

            hilbert = hilbert_walk_c;

            /* the first operation for this variable is to advance by 1 */

            current_fragment = s->u_fragment_start - 1;

        } else if (i == s->v_superblock_start) {

            /* start of V superblocks */

            right_edge = s->fragment_width / 2;

            bottom_edge = s->fragment_height / 2;

            current_width = 0;

            current_height = 0;

            superblock_row_inc = 3 * (s->fragment_width / 2);

            hilbert = hilbert_walk_c;

            /* the first operation for this variable is to advance by 1 */

            current_fragment = s->v_fragment_start - 1;

        }

        if (current_width >= right_edge) {

            /* reset width and move to next superblock row */

            current_width = 0;

            current_height += 4;

            /* fragment is now at the start of a new superblock row */

            current_fragment += superblock_row_inc;

        }

        /* iterate through all 16 fragments in a superblock */

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

            current_fragment += hilbert[j];

            current_height += travel_height[j];

            /* check if the fragment is in bounds */

            if ((current_width <= right_edge) &&

                (current_height < bottom_edge)) {

                s->superblock_fragments[mapping_index] = current_fragment;

                debug_init("    mapping fragment %d to superblock %d, position %d\n",

                    s->superblock_fragments[mapping_index], i, j);

            } else {

                s->superblock_fragments[mapping_index] = -1;

                debug_init("    superblock %d, position %d has no fragment\n",

                    i, j);

            }

            current_width += travel_width[j];

            mapping_index++;

        }

    }

    /* initialize the superblock <-> macroblock mapping; iterate through

     * all of the Y plane superblocks to build this mapping */

    right_edge = s->macroblock_width;

    bottom_edge = s->macroblock_height;

    current_width = 0;

    current_height = 0;

    superblock_row_inc = s->macroblock_width;

    hilbert = hilbert_walk_mb;

    mapping_index = 0;

    current_macroblock = -1;

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

        if (current_width >= right_edge) {

            /* reset width and move to next superblock row */

            current_width = 0;

            current_height += 2;

            /* macroblock is now at the start of a new superblock row */

            current_macroblock += superblock_row_inc;

        }

        /* iterate through each potential macroblock in the superblock */

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

            current_macroblock += hilbert_walk_mb[j];

            current_height += travel_height_mb[j];

            /* check if the macroblock is in bounds */

            if ((current_width <= right_edge) &&

                (current_height < bottom_edge)) {

                s->superblock_macroblocks[mapping_index] = current_macroblock;

                debug_init("    mapping macroblock %d to superblock %d, position %d\n",

                    s->superblock_macroblocks[mapping_index], i, j);

            } else {

                s->superblock_macroblocks[mapping_index] = -1;

                debug_init("    superblock %d, position %d has no macroblock\n",

                    i, j);

            }

            current_width += travel_width_mb[j];

            mapping_index++;

        }

    }

    /* initialize the macroblock <-> fragment mapping */

    current_fragment = 0;

    current_macroblock = 0;

    mapping_index = 0;

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

        for (j = 0; j < s->fragment_width; j += 2) {

            debug_init("    macroblock %d contains fragments: ", current_macroblock);

            s->all_fragments[current_fragment].macroblock = current_macroblock;

            s->macroblock_fragments[mapping_index++] = current_fragment;

            debug_init("%d ", current_fragment);

            if (j + 1 < s->fragment_width) {

                s->all_fragments[current_fragment + 1].macroblock = current_macroblock;

                s->macroblock_fragments[mapping_index++] = current_fragment + 1;

                debug_init("%d ", current_fragment + 1);

            } else

                s->macroblock_fragments[mapping_index++] = -1;

            if (i + 1 < s->fragment_height) {

                s->all_fragments[current_fragment + s->fragment_width].macroblock =

                    current_macroblock;

                s->macroblock_fragments[mapping_index++] =

                    current_fragment + s->fragment_width;

                debug_init("%d ", current_fragment + s->fragment_width);

            } else

                s->macroblock_fragments[mapping_index++] = -1;

            if ((j + 1 < s->fragment_width) && (i + 1 < s->fragment_height)) {

                s->all_fragments[current_fragment + s->fragment_width + 1].macroblock =

                    current_macroblock;

                s->macroblock_fragments[mapping_index++] =

                    current_fragment + s->fragment_width + 1;

                debug_init("%d ", current_fragment + s->fragment_width + 1);

            } else

                s->macroblock_fragments[mapping_index++] = -1;

            /* C planes */

            c_fragment = s->u_fragment_start +

                (i * s->fragment_width / 4) + (j / 2);

        s->all_fragments[c_fragment].macroblock = s->macroblock_count;

            s->macroblock_fragments[mapping_index++] = c_fragment;

            debug_init("%d ", c_fragment);

            c_fragment = s->v_fragment_start +

                (i * s->fragment_width / 4) + (j / 2);

        s->all_fragments[c_fragment].macroblock = s->macroblock_count;

            s->macroblock_fragments[mapping_index++] = c_fragment;

            debug_init("%d ", c_fragment);

            debug_init("\n");

            if (j + 2 <= s->fragment_width)

                current_fragment += 2;

            else

                current_fragment++;

            current_macroblock++;

        }

        current_fragment += s->fragment_width;

    }

}


void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))

{

    unsigned int i;

    for (i = 0; m68k_cpu_defs[i].name; i++) {

        (*cpu_fprintf)(f, "%s\n", m68k_cpu_defs[i].name);

    }

}


int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev,

                              PCIHotplugState state)

{

    int slot = PCI_SLOT(dev->devfn);

    int bsel = acpi_pcihp_get_bsel(dev->bus);

    if (bsel < 0) {

        return -1;

    }

    /* Don't send event when device is enabled during qemu machine creation:

     * it is present on boot, no hotplug event is necessary. We do send an

     * event when the device is disabled later. */

    if (state == PCI_COLDPLUG_ENABLED) {

        s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot);

        return 0;

    }

    if (state == PCI_HOTPLUG_ENABLED) {

        enable_device(s, bsel, slot);

    } else {

        disable_device(s, bsel, slot);

    }

    return 0;

}


static void frame_start(H264Context *h){

    MpegEncContext * const s = &h->s;

    int i;

    MPV_frame_start(s, s->avctx);

    ff_er_frame_start(s);

    assert(s->linesize && s->uvlinesize);

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

        h->block_offset[i]= 4*((scan8[i] - scan8[0])&7) + 4*s->linesize*((scan8[i] - scan8[0])>>3);

        h->block_offset[24+i]= 4*((scan8[i] - scan8[0])&7) + 8*s->linesize*((scan8[i] - scan8[0])>>3);

    }

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

        h->block_offset[16+i]=

        h->block_offset[20+i]= 4*((scan8[i] - scan8[0])&7) + 4*s->uvlinesize*((scan8[i] - scan8[0])>>3);

        h->block_offset[24+16+i]=

        h->block_offset[24+20+i]= 4*((scan8[i] - scan8[0])&7) + 8*s->uvlinesize*((scan8[i] - scan8[0])>>3);

    }

    /* can't be in alloc_tables because linesize isn't known there.

     * FIXME: redo bipred weight to not require extra buffer? */

    if(!s->obmc_scratchpad)

        s->obmc_scratchpad = av_malloc(16*s->linesize + 2*8*s->uvlinesize);

//    s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1;

}


static void test_flush_nodev(void)

{

    QPCIDevice *dev;

    QPCIBar bmdma_bar, ide_bar;

    ide_test_start("");

    dev = get_pci_device(&bmdma_bar, &ide_bar);

    /* FLUSH CACHE command on device 0*/

    qpci_io_writeb(dev, ide_bar, reg_device, 0);

    qpci_io_writeb(dev, ide_bar, reg_command, CMD_FLUSH_CACHE);

    /* Just testing that qemu doesn't crash... */

    ide_test_quit();

}


void qmp_guest_file_flush(int64_t handle, Error **errp)

{

    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);

    FILE *fh;

    int ret;

    if (!gfh) {

        return;

    }

    fh = gfh->fh;

    ret = fflush(fh);

    if (ret == EOF) {

        error_setg_errno(errp, errno, "failed to flush file");

    }

}


static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){

    MpegEncContext * const s = &h->s;

    Picture * const ref1 = &h->ref_list[1][0];

    int j, old_ref, rfield;

    int start= mbafi ? 16                      : 0;

    int end  = mbafi ? 16+2*h->ref_count[0]    : h->ref_count[0];

    int interl= mbafi || s->picture_structure != PICT_FRAME;

    /* bogus; fills in for missing frames */

    memset(map[list], 0, sizeof(map[list]));

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

        for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){

            int poc = ref1->ref_poc[colfield][list][old_ref];

            if     (!interl)

                poc |= 3;

            else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed

                poc= (poc&~3) + rfield + 1;

            for(j=start; j<end; j++){

                if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) {

                    int cur_ref= mbafi ? (j-16)^field : j;

                    map[list][2*old_ref + (rfield^field) + 16] = cur_ref;

                    if(rfield == field || !interl)

                        map[list][old_ref] = cur_ref;

                    break;

                }

            }

        }

    }

}


static void compute_frame_duration(int *pnum, int *pden,

                                   AVFormatContext *s, AVStream *st,

                                   AVCodecParserContext *pc, AVPacket *pkt)

{

    int frame_size;

    *pnum = 0;

    *pden = 0;

    switch(st->codec.codec_type) {

    case CODEC_TYPE_VIDEO:

        *pnum = st->codec.frame_rate_base;

        *pden = st->codec.frame_rate;

        if (pc && pc->repeat_pict) {

            *pden *= 2;

            *pnum = (*pnum) * (2 + pc->repeat_pict);

        }

        break;

    case CODEC_TYPE_AUDIO:

        frame_size = get_audio_frame_size(&st->codec, pkt->size);

        if (frame_size < 0)

            break;

        *pnum = frame_size;

        *pden = st->codec.sample_rate;

        break;

    default:

        break;

    }

}


static int os_host_main_loop_wait(int64_t timeout)
{
    GMainContext *context = g_main_context_default();
    GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
    int select_ret = 0;
    int g_poll_ret, ret, i, n_poll_fds;
    PollingEntry *pe;
    WaitObjects *w = &wait_objects;
    gint poll_timeout;
    int64_t poll_timeout_ns;
    static struct timeval tv0;
    fd_set rfds, wfds, xfds;
    int nfds;
    /* XXX: need to suppress polling by better using win32 events */
    ret = 0;
    for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
        ret |= pe->func(pe->opaque);
    }
    if (ret != 0) {
        return ret;
    }
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    FD_ZERO(&xfds);
    nfds = pollfds_fill(gpollfds, &rfds, &wfds, &xfds);
    if (nfds >= 0) {
        select_ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
        if (select_ret != 0) {
            timeout = 0;
        }
        if (select_ret > 0) {
            pollfds_poll(gpollfds, nfds, &rfds, &wfds, &xfds);
        }
    }
    g_main_context_prepare(context, &max_priority);
    n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
                                      poll_fds, ARRAY_SIZE(poll_fds));
    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
    for (i = 0; i < w->num; i++) {
        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
        poll_fds[n_poll_fds + i].events = G_IO_IN;
    }
    if (poll_timeout < 0) {
        poll_timeout_ns = -1;
    } else {
        poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
    }
    poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);
    qemu_mutex_unlock_iothread();
    g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);
    qemu_mutex_lock_iothread();
    if (g_poll_ret > 0) {
        for (i = 0; i < w->num; i++) {
            w->revents[i] = poll_fds[n_poll_fds + i].revents;
        }
        for (i = 0; i < w->num; i++) {
            if (w->revents[i] && w->func[i]) {
                w->func[i](w->opaque[i]);
            }
        }
    }
    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
        g_main_context_dispatch(context);
    }
    return select_ret || g_poll_ret;
}


int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)

{

    BlockDriver *drv = bs->drv;

    if (!drv) {

        return -ENOMEDIUM;

    }

    if (drv->bdrv_snapshot_delete) {

        return drv->bdrv_snapshot_delete(bs, snapshot_id);

    }

    if (bs->file) {

        return bdrv_snapshot_delete(bs->file, snapshot_id);

    }

    return -ENOTSUP;

}


static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)

{

    uint32_t val;

    val = bswap32(cpu_inl(addr & IOPORTS_MASK));

    return val;

}


static void qemu_fill_buffer(QEMUFile *f)

{

    int len;

    if (f->is_writable)

        return;

    if (f->is_file) {

        fseek(f->outfile, f->buf_offset, SEEK_SET);

        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);

        if (len < 0)

            len = 0;

    } else {

        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,

                         f->buf, IO_BUF_SIZE);

        if (len < 0)

            len = 0;

    }

    f->buf_index = 0;

    f->buf_size = len;

    f->buf_offset += len;

}


void net_hub_check_clients(void)

{

    NetHub *hub;

    NetHubPort *port;

    NetClientState *peer;

    QLIST_FOREACH(hub, &hubs, next) {

        int has_nic = 0, has_host_dev = 0;

        QLIST_FOREACH(port, &hub->ports, next) {

            peer = port->nc.peer;

            if (!peer) {

                fprintf(stderr, "Warning: hub port %s has no peer\n",

                        port->nc.name);

                continue;

            }

            switch (peer->info->type) {

            case NET_CLIENT_DRIVER_NIC:

                has_nic = 1;

                break;

            case NET_CLIENT_DRIVER_USER:

            case NET_CLIENT_DRIVER_TAP:

            case NET_CLIENT_DRIVER_SOCKET:

            case NET_CLIENT_DRIVER_VDE:

            case NET_CLIENT_DRIVER_VHOST_USER:

                has_host_dev = 1;

                break;

            default:

                break;

            }

        }

        if (has_host_dev && !has_nic) {

            warn_report("vlan %d with no nics", hub->id);

        }

        if (has_nic && !has_host_dev) {

            fprintf(stderr,

                    "Warning: vlan %d is not connected to host network\n",

                    hub->id);

        }

    }

}


DVDemuxContext* dv_init_demux(AVFormatContext *s)

{

    DVDemuxContext *c;

    c = av_mallocz(sizeof(DVDemuxContext));

    if (!c)

        return NULL;

    c->vst = av_new_stream(s, 0);

    c->ast[0] = av_new_stream(s, 0);

    if (!c->vst || !c->ast[0])

        goto fail;

    av_set_pts_info(c->vst, 64, 1, 30000);

    av_set_pts_info(c->ast[0], 64, 1, 30000);

    c->fctx = s;

    c->ast[1] = NULL;

    c->ach = 0;

    c->frames = 0;

    c->abytes = 0;

    c->audio_pkt[0].size = 0;

    c->audio_pkt[1].size = 0;

    c->vst->codec.codec_type = CODEC_TYPE_VIDEO;

    c->vst->codec.codec_id = CODEC_ID_DVVIDEO;

    c->vst->codec.bit_rate = 25000000;

    c->ast[0]->codec.codec_type = CODEC_TYPE_AUDIO;

    c->ast[0]->codec.codec_id = CODEC_ID_PCM_S16LE;

    s->ctx_flags |= AVFMTCTX_NOHEADER;

    return c;

fail:

    if (c->vst)

        av_free(c->vst);

    if (c->ast[0])

        av_free(c->ast[0]);

    av_free(c);

    return NULL;

}


static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,

    int64_t offset, int bytes, BdrvRequestFlags flags)

{

    BlockDriver *drv = bs->drv;

    QEMUIOVector qiov;

    struct iovec iov = {0};

    int ret = 0;

    bool need_flush = false;

    int head = 0;

    int tail = 0;

    int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);

    int alignment = MAX(bs->bl.pwrite_zeroes_alignment,

                        bs->bl.request_alignment);

    int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,

                                    MAX_WRITE_ZEROES_BOUNCE_BUFFER);

    assert(alignment % bs->bl.request_alignment == 0);

    head = offset % alignment;

    tail = (offset + bytes) % alignment;

    max_write_zeroes = QEMU_ALIGN_DOWN(max_write_zeroes, alignment);

    assert(max_write_zeroes >= bs->bl.request_alignment);

    while (bytes > 0 && !ret) {

        int num = bytes;

        /* Align request.  Block drivers can expect the "bulk" of the request

         * to be aligned, and that unaligned requests do not cross cluster

         * boundaries.

         */

        if (head) {

            /* Make a small request up to the first aligned sector. For

             * convenience, limit this request to max_transfer even if

             * we don't need to fall back to writes.  */

            num = MIN(MIN(bytes, max_transfer), alignment - head);

            head = (head + num) % alignment;

            assert(num < max_write_zeroes);

        } else if (tail && num > alignment) {

            /* Shorten the request to the last aligned sector.  */

            num -= tail;

        }

        /* limit request size */

        if (num > max_write_zeroes) {

            num = max_write_zeroes;

        }

        ret = -ENOTSUP;

        /* First try the efficient write zeroes operation */

        if (drv->bdrv_co_pwrite_zeroes) {

            ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num,

                                             flags & bs->supported_zero_flags);

            if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) &&

                !(bs->supported_zero_flags & BDRV_REQ_FUA)) {

                need_flush = true;

            }

        } else {

            assert(!bs->supported_zero_flags);

        }

        if (ret == -ENOTSUP) {

            /* Fall back to bounce buffer if write zeroes is unsupported */

            BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;

            if ((flags & BDRV_REQ_FUA) &&

                !(bs->supported_write_flags & BDRV_REQ_FUA)) {

                /* No need for bdrv_driver_pwrite() to do a fallback

                 * flush on each chunk; use just one at the end */

                write_flags &= ~BDRV_REQ_FUA;

                need_flush = true;

            }

            num = MIN(num, max_transfer);

            iov.iov_len = num;

            if (iov.iov_base == NULL) {

                iov.iov_base = qemu_try_blockalign(bs, num);

                if (iov.iov_base == NULL) {

                    ret = -ENOMEM;

                    goto fail;

                }

                memset(iov.iov_base, 0, num);

            }

            qemu_iovec_init_external(&qiov, &iov, 1);

            ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags);

            /* Keep bounce buffer around if it is big enough for all

             * all future requests.

             */

            if (num < max_transfer) {

                qemu_vfree(iov.iov_base);

                iov.iov_base = NULL;

            }

        }

        offset += num;

        bytes -= num;

    }

fail:

    if (ret == 0 && need_flush) {

        ret = bdrv_co_flush(bs);

    }

    qemu_vfree(iov.iov_base);

    return ret;

}


static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)

{

    unsigned int i;

    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)

        qemu_put_be32s(f, &q->queue[i]);

    qemu_put_sbe32s(f, &q->next);

    qemu_put_sbe32s(f, &q->priority);

}


static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)

{

    uint32_t entry;

    EHCIQueue *q;

    int reload;

    entry = ehci_get_fetch_addr(ehci, async);

    q = ehci_find_queue_by_qh(ehci, entry);

    if (NULL == q) {

        q = ehci_alloc_queue(ehci, async);

    }

    q->qhaddr = entry;

    q->seen++;

    if (q->seen > 1) {

        /* we are going in circles -- stop processing */

        ehci_set_state(ehci, async, EST_ACTIVE);

        q = NULL;

        goto out;

    }

    get_dwords(NLPTR_GET(q->qhaddr), (uint32_t *) &q->qh, sizeof(EHCIqh) >> 2);

    ehci_trace_qh(q, NLPTR_GET(q->qhaddr), &q->qh);

    if (q->async == EHCI_ASYNC_INFLIGHT) {

        /* I/O still in progress -- skip queue */

        ehci_set_state(ehci, async, EST_HORIZONTALQH);

        goto out;

    }

    if (q->async == EHCI_ASYNC_FINISHED) {

        /* I/O finished -- continue processing queue */

        trace_usb_ehci_queue_action(q, "resume");

        ehci_set_state(ehci, async, EST_EXECUTING);

        goto out;

    }

    if (async && (q->qh.epchar & QH_EPCHAR_H)) {

        /*  EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */

        if (ehci->usbsts & USBSTS_REC) {

            ehci_clear_usbsts(ehci, USBSTS_REC);

        } else {

            DPRINTF("FETCHQH:  QH 0x%08x. H-bit set, reclamation status reset"

                       " - done processing\n", q->qhaddr);

            ehci_set_state(ehci, async, EST_ACTIVE);

            q = NULL;

            goto out;

        }

    }

#if EHCI_DEBUG

    if (q->qhaddr != q->qh.next) {

    DPRINTF("FETCHQH:  QH 0x%08x (h %x halt %x active %x) next 0x%08x\n",

               q->qhaddr,

               q->qh.epchar & QH_EPCHAR_H,

               q->qh.token & QTD_TOKEN_HALT,

               q->qh.token & QTD_TOKEN_ACTIVE,

               q->qh.next);

    }

#endif

    reload = get_field(q->qh.epchar, QH_EPCHAR_RL);

    if (reload) {

        set_field(&q->qh.altnext_qtd, reload, QH_ALTNEXT_NAKCNT);

    }

    if (q->qh.token & QTD_TOKEN_HALT) {

        ehci_set_state(ehci, async, EST_HORIZONTALQH);

    } else if ((q->qh.token & QTD_TOKEN_ACTIVE) && (q->qh.current_qtd > 0x1000)) {

        q->qtdaddr = q->qh.current_qtd;

        ehci_set_state(ehci, async, EST_FETCHQTD);

    } else {

        /*  EHCI spec version 1.0 Section 4.10.2 */

        ehci_set_state(ehci, async, EST_ADVANCEQUEUE);

    }

out:

    return q;

}


static void omap_rtc_reset(struct omap_rtc_s *s)

{

    struct tm tm;

    s->interrupts = 0;

    s->comp_reg = 0;

    s->running = 0;

    s->pm_am = 0;

    s->auto_comp = 0;

    s->round = 0;

    s->tick = qemu_get_clock(rt_clock);

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

    s->alarm_tm.tm_mday = 0x01;

    s->status = 1 << 7;

    qemu_get_timedate(&tm, 0);

    s->ti = mktimegm(&tm);

    omap_rtc_alarm_update(s);

    omap_rtc_tick(s);

}


static void tosa_init(MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *rom = g_new(MemoryRegion, 1);

    PXA2xxState *mpu;

    TC6393xbState *tmio;

    DeviceState *scp0, *scp1;

    if (!cpu_model)

        cpu_model = "pxa255";

    mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);

    memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_abort);

    vmstate_register_ram_global(rom);

    memory_region_set_readonly(rom, true);

    memory_region_add_subregion(address_space_mem, 0, rom);

    tmio = tc6393xb_init(address_space_mem, 0x10000000,

            qdev_get_gpio_in(mpu->gpio, TOSA_GPIO_TC6393XB_INT));

    scp0 = sysbus_create_simple("scoop", 0x08800000, NULL);

    scp1 = sysbus_create_simple("scoop", 0x14800040, NULL);

    tosa_gpio_setup(mpu, scp0, scp1, tmio);

    tosa_microdrive_attach(mpu);

    tosa_tg_init(mpu);

    tosa_binfo.kernel_filename = kernel_filename;

    tosa_binfo.kernel_cmdline = kernel_cmdline;

    tosa_binfo.initrd_filename = initrd_filename;

    tosa_binfo.board_id = 0x208;

    arm_load_kernel(mpu->cpu, &tosa_binfo);

    sl_bootparam_write(SL_PXA_PARAM_BASE);

}


static void get_sensor_evt_enable(IPMIBmcSim *ibs,

                                  uint8_t *cmd, unsigned int cmd_len,

                                  uint8_t *rsp, unsigned int *rsp_len,

                                  unsigned int max_rsp_len)

{

    IPMISensor *sens;

    IPMI_CHECK_CMD_LEN(3);

    if ((cmd[2] > MAX_SENSORS) ||

        !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {

        rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;

        return;

    }

    sens = ibs->sensors + cmd[2];

    IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));

    IPMI_ADD_RSP_DATA(sens->assert_enable & 0xff);

    IPMI_ADD_RSP_DATA((sens->assert_enable >> 8) & 0xff);

    IPMI_ADD_RSP_DATA(sens->deassert_enable & 0xff);

    IPMI_ADD_RSP_DATA((sens->deassert_enable >> 8) & 0xff);

}


struct omap_uart_s *omap_uart_init(hwaddr base,

                qemu_irq irq, omap_clk fclk, omap_clk iclk,

                qemu_irq txdma, qemu_irq rxdma,

                const char *label, CharDriverState *chr)

{

    struct omap_uart_s *s = (struct omap_uart_s *)

            g_malloc0(sizeof(struct omap_uart_s));

    s->base = base;

    s->fclk = fclk;

    s->irq = irq;

    s->serial = serial_mm_init(get_system_memory(), base, 2, irq,

                               omap_clk_getrate(fclk)/16,

                               chr ?: qemu_chr_new(label, "null", NULL),

                               DEVICE_NATIVE_ENDIAN);

    return s;

}


static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)

{

    VHDDynDiskHeader *dyndisk_header =

        (VHDDynDiskHeader *) buf;

    size_t block_size, num_bat_entries;

    int i;

    int ret = -EIO;

    // Write the footer (twice: at the beginning and at the end)

    block_size = 0x200000;

    num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);

    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {

        goto fail;

    }

    if (lseek(fd, 1536 + ((num_bat_entries * 4 + 511) & ~511), SEEK_SET) < 0) {

        goto fail;

    }

    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {

        goto fail;

    }

    // Write the initial BAT

    if (lseek(fd, 3 * 512, SEEK_SET) < 0) {

        goto fail;

    }

    memset(buf, 0xFF, 512);

    for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++) {

        if (write(fd, buf, 512) != 512) {

            goto fail;

        }

    }

    // Prepare the Dynamic Disk Header

    memset(buf, 0, 1024);

    memcpy(dyndisk_header->magic, "cxsparse", 8);

    /*

     * Note: The spec is actually wrong here for data_offset, it says

     * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.

     */

    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);

    dyndisk_header->table_offset = be64_to_cpu(3 * 512);

    dyndisk_header->version = be32_to_cpu(0x00010000);

    dyndisk_header->block_size = be32_to_cpu(block_size);

    dyndisk_header->max_table_entries = be32_to_cpu(num_bat_entries);

    dyndisk_header->checksum = be32_to_cpu(vpc_checksum(buf, 1024));

    // Write the header

    if (lseek(fd, 512, SEEK_SET) < 0) {

        goto fail;

    }

    if (write(fd, buf, 1024) != 1024) {

        goto fail;

    }

    ret = 0;

 fail:

    return ret;

}


static int qemu_rbd_snap_list(BlockDriverState *bs,

                              QEMUSnapshotInfo **psn_tab)

{

    BDRVRBDState *s = bs->opaque;

    QEMUSnapshotInfo *sn_info, *sn_tab = NULL;

    int i, snap_count;

    rbd_snap_info_t *snaps;

    int max_snaps = RBD_MAX_SNAPS;

    do {

        snaps = g_malloc(sizeof(*snaps) * max_snaps);

        snap_count = rbd_snap_list(s->image, snaps, &max_snaps);

        if (snap_count < 0) {

            g_free(snaps);

        }

    } while (snap_count == -ERANGE);

    if (snap_count <= 0) {

        return snap_count;

    }

    sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));

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

        const char *snap_name = snaps[i].name;

        sn_info = sn_tab + i;

        pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), snap_name);

        pstrcpy(sn_info->name, sizeof(sn_info->name), snap_name);

        sn_info->vm_state_size = snaps[i].size;

        sn_info->date_sec = 0;

        sn_info->date_nsec = 0;

        sn_info->vm_clock_nsec = 0;

    }

    rbd_snap_list_end(snaps);

    *psn_tab = sn_tab;

    return snap_count;

}


static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,

                                 MMUAccessType access_type, ARMMMUIdx mmu_idx,

                                 hwaddr *phys_ptr, int *prot, uint32_t *fsr)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    bool is_user = regime_is_user(env, mmu_idx);

    int n;

    int matchregion = -1;

    bool hit = false;

    *phys_ptr = address;

    *prot = 0;

    /* Unlike the ARM ARM pseudocode, we don't need to check whether this

     * was an exception vector read from the vector table (which is always

     * done using the default system address map), because those accesses

     * are done in arm_v7m_load_vector(), which always does a direct

     * read using address_space_ldl(), rather than going via this function.

     */

    if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */

        hit = true;

    } else if (m_is_ppb_region(env, address)) {

        hit = true;

    } else if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {

        hit = true;

    } else {

        for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {

            /* region search */

            /* Note that the base address is bits [31:5] from the register

             * with bits [4:0] all zeroes, but the limit address is bits

             * [31:5] from the register with bits [4:0] all ones.

             */

            uint32_t base = env->pmsav8.rbar[n] & ~0x1f;

            uint32_t limit = env->pmsav8.rlar[n] | 0x1f;

            if (!(env->pmsav8.rlar[n] & 0x1)) {

                /* Region disabled */

                continue;

            }

            if (address < base || address > limit) {

                continue;

            }

            if (hit) {

                /* Multiple regions match -- always a failure (unlike

                 * PMSAv7 where highest-numbered-region wins)

                 */

                *fsr = 0x00d; /* permission fault */

                return true;

            }

            matchregion = n;

            hit = true;

            if (base & ~TARGET_PAGE_MASK) {

                qemu_log_mask(LOG_UNIMP,

                              "MPU_RBAR[%d]: No support for MPU region base"

                              "address of 0x%" PRIx32 ". Minimum alignment is "

                              "%d\n",

                              n, base, TARGET_PAGE_BITS);

                continue;

            }

            if ((limit + 1) & ~TARGET_PAGE_MASK) {

                qemu_log_mask(LOG_UNIMP,

                              "MPU_RBAR[%d]: No support for MPU region limit"

                              "address of 0x%" PRIx32 ". Minimum alignment is "

                              "%d\n",

                              n, limit, TARGET_PAGE_BITS);

                continue;

            }

        }

    }

    if (!hit) {

        /* background fault */

        *fsr = 0;

        return true;

    }

    if (matchregion == -1) {

        /* hit using the background region */

        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

    } else {

        uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);

        uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);

        if (m_is_system_region(env, address)) {

            /* System space is always execute never */

            xn = 1;

        }

        *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);

        if (*prot && !xn) {

            *prot |= PAGE_EXEC;

        }

        /* We don't need to look the attribute up in the MAIR0/MAIR1

         * registers because that only tells us about cacheability.

         */

    }

    *fsr = 0x00d; /* Permission fault */

    return !(*prot & (1 << access_type));

}


static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,

                           uint64_t off, uint32_t max_count)

{

    ssize_t err;

    size_t offset = 7;

    int read_count;

    int64_t xattr_len;

    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);

    VirtQueueElement *elem = v->elems[pdu->idx];

    xattr_len = fidp->fs.xattr.len;

    read_count = xattr_len - off;

    if (read_count > max_count) {

        read_count = max_count;

    } else if (read_count < 0) {

        /*

         * read beyond XATTR value

         */

        read_count = 0;

    }

    err = pdu_marshal(pdu, offset, "d", read_count);

    if (err < 0) {

        return err;

    }

    offset += err;

    err = v9fs_pack(elem->in_sg, elem->in_num, offset,

                    ((char *)fidp->fs.xattr.value) + off,

                    read_count);

    if (err < 0) {

        return err;

    }

    offset += err;

    return offset;

}


static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,

                                      const uint8_t *buf, int nb_sectors)

{

    int ret;

    BDRVVmdkState *s = bs->opaque;

    qemu_co_mutex_lock(&s->lock);

    ret = vmdk_write(bs, sector_num, buf, nb_sectors);

    qemu_co_mutex_unlock(&s->lock);

    return ret;

}


int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,

                         uint8_t *dst, int dlen)

{

    uint32_t zrun_len = 0, nzrun_len = 0;

    int d = 0, i = 0;

    long res, xor;

    uint8_t *nzrun_start = NULL;

    g_assert(!(((uintptr_t)old_buf | (uintptr_t)new_buf | slen) %

               sizeof(long)));

    while (i < slen) {

        /* overflow */

        if (d + 2 > dlen) {

            return -1;

        }

        /* not aligned to sizeof(long) */

        res = (slen - i) % sizeof(long);

        while (res && old_buf[i] == new_buf[i]) {

            zrun_len++;

            i++;

            res--;

        }

        /* word at a time for speed */

        if (!res) {

            while (i < slen &&

                   (*(long *)(old_buf + i)) == (*(long *)(new_buf + i))) {

                i += sizeof(long);

                zrun_len += sizeof(long);

            }

            /* go over the rest */

            while (i < slen && old_buf[i] == new_buf[i]) {

                zrun_len++;

                i++;

            }

        }

        /* buffer unchanged */

        if (zrun_len == slen) {

            return 0;

        }

        /* skip last zero run */

        if (i == slen) {

            return d;

        }

        d += uleb128_encode_small(dst + d, zrun_len);

        zrun_len = 0;

        nzrun_start = new_buf + i;

        /* overflow */

        if (d + 2 > dlen) {

            return -1;

        }

        /* not aligned to sizeof(long) */

        res = (slen - i) % sizeof(long);

        while (res && old_buf[i] != new_buf[i]) {

            i++;

            nzrun_len++;

            res--;

        }

        /* word at a time for speed, use of 32-bit long okay */

        if (!res) {

            /* truncation to 32-bit long okay */

            long mask = (long)0x0101010101010101ULL;

            while (i < slen) {

                xor = *(long *)(old_buf + i) ^ *(long *)(new_buf + i);

                if ((xor - mask) & ~xor & (mask << 7)) {

                    /* found the end of an nzrun within the current long */

                    while (old_buf[i] != new_buf[i]) {

                        nzrun_len++;

                        i++;

                    }

                    break;

                } else {

                    i += sizeof(long);

                    nzrun_len += sizeof(long);

                }

            }

        }

        d += uleb128_encode_small(dst + d, nzrun_len);

        /* overflow */

        if (d + nzrun_len > dlen) {

            return -1;

        }

        memcpy(dst + d, nzrun_start, nzrun_len);

        d += nzrun_len;

        nzrun_len = 0;

    }

    return d;

}


static av_cold void init_atrac3_transforms(ATRAC3Context *q) {

    float enc_window[256];

    int i;

    /* Generate the mdct window, for details see

     * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */

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

        enc_window[i] = (sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0) * 0.5;

    if (!mdct_window[0])

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

            mdct_window[i] = enc_window[i]/(enc_window[i]*enc_window[i] + enc_window[255-i]*enc_window[255-i]);

            mdct_window[511-i] = mdct_window[i];

        }

    /* Initialize the MDCT transform. */

    ff_mdct_init(&mdct_ctx, 9, 1, 1.0);

}


static void gd_resize(DisplayChangeListener *dcl,

                      DisplayState *ds)

{

    GtkDisplayState *s = ds->opaque;

    cairo_format_t kind;

    int stride;

    DPRINTF("resize(width=%d, height=%d)\n",

            ds_get_width(ds), ds_get_height(ds));

    if (s->surface) {

        cairo_surface_destroy(s->surface);

    }

    switch (ds->surface->pf.bits_per_pixel) {

    case 8:

        kind = CAIRO_FORMAT_A8;

        break;

    case 16:

        kind = CAIRO_FORMAT_RGB16_565;

        break;

    case 32:

        kind = CAIRO_FORMAT_RGB24;

        break;

    default:

        g_assert_not_reached();

        break;

    }

    stride = cairo_format_stride_for_width(kind, ds_get_width(ds));

    g_assert(ds_get_linesize(ds) == stride);

    s->surface = cairo_image_surface_create_for_data(ds_get_data(ds),

                                                     kind,

                                                     ds_get_width(ds),

                                                     ds_get_height(ds),

                                                     ds_get_linesize(ds));

    if (!s->full_screen) {

        GtkRequisition req;

        double sx, sy;

        if (s->free_scale) {

            sx = s->scale_x;

            sy = s->scale_y;

            s->scale_y = 1.0;

            s->scale_x = 1.0;

        } else {

            sx = 1.0;

            sy = 1.0;

        }

        gtk_widget_set_size_request(s->drawing_area,

                                    ds_get_width(ds) * s->scale_x,

                                    ds_get_height(ds) * s->scale_y);

#if GTK_CHECK_VERSION(3, 0, 0)

        gtk_widget_get_preferred_size(s->vbox, NULL, &req);

#else

        gtk_widget_size_request(s->vbox, &req);

#endif

        gtk_window_resize(GTK_WINDOW(s->window),

                          req.width * sx, req.height * sy);

    }

}


void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)

{

    LM32JuartState *s = LM32_JUART(d);

    unsigned char ch = jtx & 0xff;

    trace_lm32_juart_set_jtx(s->jtx);

    s->jtx = jtx;

    if (s->chr) {

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

    }

}


static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,

                                    AVPacket *pkt, uint64_t display_duration)

{

    char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size;

    for (; *ptr!=',' && ptr<end-1; ptr++);

    if (*ptr == ',')

        layer = ++ptr;

    for (; *ptr!=',' && ptr<end-1; ptr++);

    if (*ptr == ',') {

        int64_t end_pts = pkt->pts + display_duration;

        int sc = matroska->time_scale * pkt->pts / 10000000;

        int ec = matroska->time_scale * end_pts  / 10000000;

        int sh, sm, ss, eh, em, es, len;

        sh = sc/360000;  sc -= 360000*sh;

        sm = sc/  6000;  sc -=   6000*sm;

        ss = sc/   100;  sc -=    100*ss;

        eh = ec/360000;  ec -= 360000*eh;

        em = ec/  6000;  ec -=   6000*em;

        es = ec/   100;  ec -=    100*es;

        *ptr++ = '\0';

        len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE;

        if (!(line = av_malloc(len)))

            return;

        snprintf(line,len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s",

                 layer, sh, sm, ss, sc, eh, em, es, ec, ptr);

        av_free(pkt->data);

        pkt->data = line;

        pkt->size = strlen(line);

    }

}


send_msg(

    VSCMsgType type,

    uint32_t reader_id,

    const void *msg,

    unsigned int length

) {

    VSCMsgHeader mhHeader;

    qemu_mutex_lock(&socket_to_send_lock);

    if (verbose > 10) {

        printf("sending type=%d id=%u, len =%u (0x%x)\n",

               type, reader_id, length, length);

    }

    mhHeader.type = htonl(type);

    mhHeader.reader_id = 0;

    mhHeader.length = htonl(length);

    g_byte_array_append(socket_to_send, (guint8 *)&mhHeader, sizeof(mhHeader));

    g_byte_array_append(socket_to_send, (guint8 *)msg, length);

    g_idle_add(socket_prepare_sending, NULL);

    qemu_mutex_unlock(&socket_to_send_lock);

    return 0;

}


void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *block, int stride){

    int i, j;

    int dc = (((dctcoef*)block)[0] + 32) >> 6;

    pixel *dst = (pixel*)_dst;

    stride >>= sizeof(pixel)-1;

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

    {

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

            dst[i] = av_clip_pixel( dst[i] + dc );

        dst += stride;

    }

}


static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,

                             const AVFrame *pict, int *got_packet)

{

    const AVFrame *const p = pict;

    const int near         = avctx->prediction_method;

    PutBitContext pb, pb2;

    GetBitContext gb;

    uint8_t *buf2 = NULL;

    uint8_t *zero = NULL;

    uint8_t *cur  = NULL;

    uint8_t *last = NULL;

    JLSState *state;

    int i, size, ret;

    int comps;

    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||

        avctx->pix_fmt == AV_PIX_FMT_GRAY16)

        comps = 1;

    else

        comps = 3;

    if ((ret = ff_alloc_packet(pkt, avctx->width * avctx->height * comps * 4 +

                               AV_INPUT_BUFFER_MIN_SIZE)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");

        return ret;

    }

    buf2 = av_malloc(pkt->size);

    if (!buf2)

        goto memfail;

    init_put_bits(&pb, pkt->data, pkt->size);

    init_put_bits(&pb2, buf2, pkt->size);

    /* write our own JPEG header, can't use mjpeg_picture_header */

    put_marker(&pb, SOI);

    put_marker(&pb, SOF48);

    put_bits(&pb, 16, 8 + comps * 3); // header size depends on components

    put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp

    put_bits(&pb, 16, avctx->height);

    put_bits(&pb, 16, avctx->width);

    put_bits(&pb, 8, comps);          // components

    for (i = 1; i <= comps; i++) {

        put_bits(&pb, 8, i);     // component ID

        put_bits(&pb, 8, 0x11);  // subsampling: none

        put_bits(&pb, 8, 0);     // Tiq, used by JPEG-LS ext

    }

    put_marker(&pb, SOS);

    put_bits(&pb, 16, 6 + comps * 2);

    put_bits(&pb, 8, comps);

    for (i = 1; i <= comps; i++) {

        put_bits(&pb, 8, i);   // component ID

        put_bits(&pb, 8, 0);   // mapping index: none

    }

    put_bits(&pb, 8, near);

    put_bits(&pb, 8, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line

    put_bits(&pb, 8, 0);  // point transform: none

    state = av_mallocz(sizeof(JLSState));

    if (!state)

        goto memfail;

    /* initialize JPEG-LS state from JPEG parameters */

    state->near = near;

    state->bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;

    ff_jpegls_reset_coding_parameters(state, 0);

    ff_jpegls_init_state(state);

    ls_store_lse(state, &pb);

    zero = last = av_mallocz(p->linesize[0]);

    if (!zero)

        goto memfail;

    cur  = p->data[0];

    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {

        int t = 0;

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

            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8);

            t    = last[0];

            last = cur;

            cur += p->linesize[0];

        }

    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {

        int t = 0;

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

            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16);

            t    = *((uint16_t *)last);

            last = cur;

            cur += p->linesize[0];

        }

    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {

        int j, width;

        int Rc[3] = { 0, 0, 0 };

        width = avctx->width * 3;

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

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

                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],

                               width, 3, j, 8);

                Rc[j] = last[j];

            }

            last = cur;

            cur += p->linesize[0];

        }

    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {

        int j, width;

        int Rc[3] = { 0, 0, 0 };

        width = avctx->width * 3;

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

            for (j = 2; j >= 0; j--) {

                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],

                               width, 3, j, 8);

                Rc[j] = last[j];

            }

            last = cur;

            cur += p->linesize[0];

        }

    }

    av_freep(&zero);

    av_freep(&state);

    /* the specification says that after doing 0xff escaping unused bits in

     * the last byte must be set to 0, so just append 7 "optional" zero-bits

     * to avoid special-casing. */

    put_bits(&pb2, 7, 0);

    size = put_bits_count(&pb2);

    flush_put_bits(&pb2);

    /* do escape coding */

    init_get_bits(&gb, buf2, size);

    size -= 7;

    while (get_bits_count(&gb) < size) {

        int v;

        v = get_bits(&gb, 8);

        put_bits(&pb, 8, v);

        if (v == 0xFF) {

            v = get_bits(&gb, 7);

            put_bits(&pb, 8, v);

        }

    }

    avpriv_align_put_bits(&pb);

    av_freep(&buf2);

    /* End of image */

    put_marker(&pb, EOI);

    flush_put_bits(&pb);

    emms_c();

    pkt->size   = put_bits_count(&pb) >> 3;

    pkt->flags |= AV_PKT_FLAG_KEY;

    *got_packet = 1;

    return 0;

memfail:

    av_packet_unref(pkt);

    av_freep(&buf2);

    av_freep(&state);

    av_freep(&zero);

    return AVERROR(ENOMEM);

}


void ff_vc1_decode_blocks(VC1Context *v)

{

    v->s.esc3_level_length = 0;

    if (v->x8_type) {

        ff_intrax8_decode_picture(&v->x8, 2*v->pq + v->halfpq, v->pq * !v->pquantizer);

        ff_er_add_slice(&v->s.er, 0, 0,

                        (v->s.mb_x >> 1) - 1, (v->s.mb_y >> 1) - 1,

                        ER_MB_END);

    } else {

        v->cur_blk_idx     =  0;

        v->left_blk_idx    = -1;

        v->topleft_blk_idx =  1;

        v->top_blk_idx     =  2;

        switch (v->s.pict_type) {

        case AV_PICTURE_TYPE_I:

            if (v->profile == PROFILE_ADVANCED)

                vc1_decode_i_blocks_adv(v);

            else

                vc1_decode_i_blocks(v);

            break;

        case AV_PICTURE_TYPE_P:

            if (v->p_frame_skipped)

                vc1_decode_skip_blocks(v);

            else

                vc1_decode_p_blocks(v);

            break;

        case AV_PICTURE_TYPE_B:

            if (v->bi_type) {

                if (v->profile == PROFILE_ADVANCED)

                    vc1_decode_i_blocks_adv(v);

                else

                    vc1_decode_i_blocks(v);

            } else

                vc1_decode_b_blocks(v);

            break;

        }

    }

}


paint_mouse_pointer(XImage *image, struct x11_grab *s)

{

    int x_off = s->x_off;

    int y_off = s->y_off;

    int width = s->width;

    int height = s->height;

    Display *dpy = s->dpy;

    XFixesCursorImage *xcim;

    int x, y;

    int line, column;

    int to_line, to_column;

    int image_addr, xcim_addr;

    xcim = XFixesGetCursorImage(dpy);

    x = xcim->x - xcim->xhot;

    y = xcim->y - xcim->yhot;

    to_line = FFMIN((y + xcim->height), (height + y_off));

    to_column = FFMIN((x + xcim->width), (width + x_off));

    for (line = FFMAX(y, y_off); line < to_line; line++) {

        for (column = FFMAX(x, x_off); column < to_column; column++) {

            xcim_addr = (line - y) * xcim->width + column - x;

            if ((unsigned char)(xcim->pixels[xcim_addr] >> 24) != 0) { // skip fully transparent pixel

                image_addr = ((line - y_off) * width + column - x_off) * 4;

                image->data[image_addr] = (unsigned char)(xcim->pixels[xcim_addr] >> 0);

                image->data[image_addr+1] = (unsigned char)(xcim->pixels[xcim_addr] >> 8);

                image->data[image_addr+2] = (unsigned char)(xcim->pixels[xcim_addr] >> 16);

            }

        }

    }

    XFree(xcim);

    xcim = NULL;

}


static uint64_t boston_platreg_read(void *opaque, hwaddr addr,

                                    unsigned size)

{

    BostonState *s = opaque;

    uint32_t gic_freq, val;

    if (size != 4) {

        qemu_log_mask(LOG_UNIMP, "%uB platform register read", size);

        return 0;

    }

    switch (addr & 0xffff) {

    case PLAT_FPGA_BUILD:

    case PLAT_CORE_CL:

    case PLAT_WRAPPER_CL:

        return 0;

    case PLAT_DDR3_STATUS:

        return PLAT_DDR3_STATUS_LOCKED | PLAT_DDR3_STATUS_CALIBRATED;

    case PLAT_MMCM_DIV:

        gic_freq = mips_gictimer_get_freq(s->cps->gic.gic_timer) / 1000000;

        val = gic_freq << PLAT_MMCM_DIV_INPUT_SHIFT;

        val |= 1 << PLAT_MMCM_DIV_MUL_SHIFT;

        val |= 1 << PLAT_MMCM_DIV_CLK0DIV_SHIFT;

        val |= 1 << PLAT_MMCM_DIV_CLK1DIV_SHIFT;

        return val;

    case PLAT_BUILD_CFG:

        val = PLAT_BUILD_CFG_PCIE0_EN;

        val |= PLAT_BUILD_CFG_PCIE1_EN;

        val |= PLAT_BUILD_CFG_PCIE2_EN;

        return val;

    case PLAT_DDR_CFG:

        val = s->mach->ram_size / G_BYTE;

        assert(!(val & ~PLAT_DDR_CFG_SIZE));

        val |= PLAT_DDR_CFG_MHZ;

        return val;

    default:

        qemu_log_mask(LOG_UNIMP, "Read platform register 0x%" HWADDR_PRIx,

                      addr & 0xffff);

        return 0;

    }

}


int avfilter_register(AVFilter *filter)

{

    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)

        return -1;

    registered_avfilters[next_registered_avfilter_idx++] = filter;

    return 0;

}


void qmp_migrate_cancel(Error **errp)

{

    migrate_fd_cancel(migrate_get_current());

}


int load_snapshot(const char *name, Error **errp)

{

    BlockDriverState *bs, *bs_vm_state;

    QEMUSnapshotInfo sn;

    QEMUFile *f;

    int ret;

    AioContext *aio_context;

    MigrationIncomingState *mis = migration_incoming_get_current();

    if (!bdrv_all_can_snapshot(&bs)) {

        error_setg(errp,

                   "Device '%s' is writable but does not support snapshots",

                   bdrv_get_device_name(bs));

        return -ENOTSUP;

    }

    ret = bdrv_all_find_snapshot(name, &bs);

    if (ret < 0) {

        error_setg(errp,

                   "Device '%s' does not have the requested snapshot '%s'",

                   bdrv_get_device_name(bs), name);

        return ret;

    }

    bs_vm_state = bdrv_all_find_vmstate_bs();

    if (!bs_vm_state) {

        error_setg(errp, "No block device supports snapshots");

        return -ENOTSUP;

    }

    aio_context = bdrv_get_aio_context(bs_vm_state);

    /* Don't even try to load empty VM states */

    aio_context_acquire(aio_context);

    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);

    aio_context_release(aio_context);

    if (ret < 0) {

        return ret;

    } else if (sn.vm_state_size == 0) {

        error_setg(errp, "This is a disk-only snapshot. Revert to it "

                   " offline using qemu-img");

        return -EINVAL;

    }

    /* Flush all IO requests so they don't interfere with the new state.  */

    bdrv_drain_all();

    ret = bdrv_all_goto_snapshot(name, &bs);

    if (ret < 0) {

        error_setg(errp, "Error %d while activating snapshot '%s' on '%s'",

                     ret, name, bdrv_get_device_name(bs));

        return ret;

    }

    /* restore the VM state */

    f = qemu_fopen_bdrv(bs_vm_state, 0);

    if (!f) {

        error_setg(errp, "Could not open VM state file");

        return -EINVAL;

    }

    qemu_system_reset(SHUTDOWN_CAUSE_NONE);

    mis->from_src_file = f;

    aio_context_acquire(aio_context);

    ret = qemu_loadvm_state(f);

    qemu_fclose(f);

    aio_context_release(aio_context);

    migration_incoming_state_destroy();

    if (ret < 0) {

        error_setg(errp, "Error %d while loading VM state", ret);

        return ret;

    }

    return 0;

}


static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src,

                                             ptrdiff_t buf_stride,

                                             ptrdiff_t src_stride,

                                             int block_w, int block_h,

                                             int src_x, int src_y, int w, int h)

{

    emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,

                     src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse,

                     hfixtbl_mmxext, &ff_emu_edge_hvar_mmxext);

}


static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m)

{

    char *tx3g_ptr = avctx->extradata;

    int i, box_size, font_length;

    int8_t v_align, h_align;

    int style_fontID;

    StyleBox s_default;

    m->count_f = 0;

    m->ftab_entries = 0;

    box_size = BOX_SIZE_INITIAL; /* Size till ftab_entries */

    if (avctx->extradata_size < box_size)

        return -1;

    // Display Flags

    tx3g_ptr += 4;

    // Alignment

    h_align = *tx3g_ptr++;

    v_align = *tx3g_ptr++;

    if (h_align == 0) {

        if (v_align == 0)

            m->d.alignment = TOP_LEFT;

        if (v_align == 1)

            m->d.alignment = MIDDLE_LEFT;

        if (v_align == -1)

            m->d.alignment = BOTTOM_LEFT;

    }

    if (h_align == 1) {

        if (v_align == 0)

            m->d.alignment = TOP_CENTER;

        if (v_align == 1)

            m->d.alignment = MIDDLE_CENTER;

        if (v_align == -1)

            m->d.alignment = BOTTOM_CENTER;

    }

    if (h_align == -1) {

        if (v_align == 0)

            m->d.alignment = TOP_RIGHT;

        if (v_align == 1)

            m->d.alignment = MIDDLE_RIGHT;

        if (v_align == -1)

            m->d.alignment = BOTTOM_RIGHT;

    }

    // Background Color

    m->d.back_color = AV_RB24(tx3g_ptr);

    tx3g_ptr += 4;

    // BoxRecord

    tx3g_ptr += 8;

    // StyleRecord

    tx3g_ptr += 4;

    // fontID

    style_fontID = AV_RB16(tx3g_ptr);

    tx3g_ptr += 2;

    // face-style-flags

    s_default.style_flag = *tx3g_ptr++;

    m->d.bold = s_default.style_flag & STYLE_FLAG_BOLD;

    m->d.italic = s_default.style_flag & STYLE_FLAG_ITALIC;

    m->d.underline = s_default.style_flag & STYLE_FLAG_UNDERLINE;

    // fontsize

    m->d.fontsize = *tx3g_ptr++;

    // Primary color

    m->d.color = AV_RB24(tx3g_ptr);

    tx3g_ptr += 4;

    // FontRecord

    // FontRecord Size

    tx3g_ptr += 4;

    // ftab

    tx3g_ptr += 4;

    m->ftab_entries = AV_RB16(tx3g_ptr);

    tx3g_ptr += 2;

    for (i = 0; i < m->ftab_entries; i++) {

        box_size += 3;

        if (avctx->extradata_size < box_size) {

            mov_text_cleanup_ftab(m);

            m->ftab_entries = 0;

            return -1;

        }

        m->ftab_temp = av_malloc(sizeof(*m->ftab_temp));

        if (!m->ftab_temp) {

            mov_text_cleanup_ftab(m);

            return AVERROR(ENOMEM);

        }

        m->ftab_temp->fontID = AV_RB16(tx3g_ptr);

        tx3g_ptr += 2;

        font_length = *tx3g_ptr++;

        box_size = box_size + font_length;

        if (avctx->extradata_size < box_size) {

            mov_text_cleanup_ftab(m);

            m->ftab_entries = 0;

            return -1;

        }

        m->ftab_temp->font = av_malloc(font_length + 1);

        if (!m->ftab_temp->font) {

            mov_text_cleanup_ftab(m);

            return AVERROR(ENOMEM);

        }

        memcpy(m->ftab_temp->font, tx3g_ptr, font_length);

        m->ftab_temp->font[font_length] = '\0';

        av_dynarray_add(&m->ftab, &m->count_f, m->ftab_temp);

        if (!m->ftab) {

            mov_text_cleanup_ftab(m);

            return AVERROR(ENOMEM);

        }

        tx3g_ptr = tx3g_ptr + font_length;

    }

    for (i = 0; i < m->ftab_entries; i++) {

        if (style_fontID == m->ftab[i]->fontID)

            m->d.font = m->ftab[i]->font;

    }

    return 0;

}


static void msmouse_chr_close (struct CharDriverState *chr)

{

    MouseState *mouse = chr->opaque;

    qemu_input_handler_unregister(mouse->hs);

    g_free(mouse);

    g_free(chr);

}


int qemu_init_main_loop(void)

{

    int ret;

    ret = qemu_signal_init();

    if (ret) {

        return ret;

    }

    qemu_init_sigbus();

    return qemu_event_init();

}


envlist_parse(envlist_t *envlist, const char *env,

    int (*callback)(envlist_t *, const char *))

{

	char *tmpenv, *envvar;

	char *envsave = NULL;

	assert(callback != NULL);

	if ((envlist == NULL) || (env == NULL))

		return (EINVAL);

	/*

	 * We need to make temporary copy of the env string

	 * as strtok_r(3) modifies it while it tokenizes.

	 */

	if ((tmpenv = strdup(env)) == NULL)

		return (errno);

	envvar = strtok_r(tmpenv, ",", &envsave);

	while (envvar != NULL) {

		if ((*callback)(envlist, envvar) != 0) {

			free(tmpenv);

			return (errno);

		}

		envvar = strtok_r(NULL, ",", &envsave);

	}

	free(tmpenv);

	return (0);

}


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

{

    unsigned char tag[5];

    unsigned int flags = 0;

    const int stream_index = pkt->stream_index;

    int size               = pkt->size;

    AVIContext *avi     = s->priv_data;

    AVIOContext *pb     = s->pb;

    AVIStream *avist    = s->streams[stream_index]->priv_data;

    AVCodecParameters *par = s->streams[stream_index]->codecpar;

    while (par->block_align == 0 && pkt->dts != AV_NOPTS_VALUE &&

           pkt->dts > avist->packet_count) {

        AVPacket empty_packet;

        av_init_packet(&empty_packet);

        empty_packet.size         = 0;

        empty_packet.data         = NULL;

        empty_packet.stream_index = stream_index;

        avi_write_packet(s, &empty_packet);

    }

    avist->packet_count++;

    // Make sure to put an OpenDML chunk when the file size exceeds the limits

    if (pb->seekable &&

        (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) {

        avi_write_ix(s);

        ff_end_tag(pb, avi->movi_list);

        if (avi->riff_id == 1)

            avi_write_idx1(s);

        ff_end_tag(pb, avi->riff_start);

        avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi");

    }

    avi_stream2fourcc(tag, stream_index, par->codec_type);

    if (pkt->flags & AV_PKT_FLAG_KEY)

        flags = 0x10;

    if (par->codec_type == AVMEDIA_TYPE_AUDIO)

        avist->audio_strm_length += size;

    if (s->pb->seekable) {

        int err;

        AVIIndex *idx = &avist->indexes;

        int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;

        int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;

        if (idx->ents_allocated <= idx->entry) {

            if ((err = av_reallocp(&idx->cluster,

                                   (cl + 1) * sizeof(*idx->cluster))) < 0) {

                idx->ents_allocated = 0;

                idx->entry          = 0;

                return err;

            }

            idx->cluster[cl] =

                av_malloc(AVI_INDEX_CLUSTER_SIZE * sizeof(AVIIentry));

            if (!idx->cluster[cl])

                return -1;

            idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE;

        }

        idx->cluster[cl][id].flags = flags;

        idx->cluster[cl][id].pos   = avio_tell(pb) - avi->movi_list;

        idx->cluster[cl][id].len   = size;

        idx->entry++;

    }

    avio_write(pb, tag, 4);

    avio_wl32(pb, size);

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

    if (size & 1)

        avio_w8(pb, 0);

    return 0;

}


static av_cold int check_cuda_errors(AVCodecContext *avctx, CUresult err, const char *func)

{

    if (err != CUDA_SUCCESS) {

        av_log(avctx, AV_LOG_FATAL, ">> %s - failed with error code 0x%x\n", func, err);

        return 0;

    }

    return 1;

}


static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, int in_program)

{

    AVStream *stream = fmt_ctx->streams[stream_idx];

    AVCodecContext *dec_ctx;

    const AVCodec *dec;

    char val_str[128];

    const char *s;

    AVRational sar, dar;

    AVBPrint pbuf;

    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);

    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM : SECTION_ID_STREAM);

    print_int("index", stream->index);

    if ((dec_ctx = stream->codec)) {

        const char *profile = NULL;

        dec = dec_ctx->codec;

        if (dec) {

            print_str("codec_name", dec->name);

            if (!do_bitexact) {

                if (dec->long_name) print_str    ("codec_long_name", dec->long_name);

                else                print_str_opt("codec_long_name", "unknown");

            }

        } else {

            print_str_opt("codec_name", "unknown");

            if (!do_bitexact) {

                print_str_opt("codec_long_name", "unknown");

            }

        }

        if (dec && (profile = av_get_profile_name(dec, dec_ctx->profile)))

            print_str("profile", profile);

        else

            print_str_opt("profile", "unknown");

        s = av_get_media_type_string(dec_ctx->codec_type);

        if (s) print_str    ("codec_type", s);

        else   print_str_opt("codec_type", "unknown");

        print_q("codec_time_base", dec_ctx->time_base, '/');

        /* print AVI/FourCC tag */

        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);

        print_str("codec_tag_string",    val_str);

        print_fmt("codec_tag", "0x%04x", dec_ctx->codec_tag);

        switch (dec_ctx->codec_type) {

        case AVMEDIA_TYPE_VIDEO:

            print_int("width",        dec_ctx->width);

            print_int("height",       dec_ctx->height);

            print_int("has_b_frames", dec_ctx->has_b_frames);

            sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);

            if (sar.den) {

                print_q("sample_aspect_ratio", sar, ':');

                av_reduce(&dar.num, &dar.den,

                          dec_ctx->width  * sar.num,

                          dec_ctx->height * sar.den,

                          1024*1024);

                print_q("display_aspect_ratio", dar, ':');

            } else {

                print_str_opt("sample_aspect_ratio", "N/A");

                print_str_opt("display_aspect_ratio", "N/A");

            }

            s = av_get_pix_fmt_name(dec_ctx->pix_fmt);

            if (s) print_str    ("pix_fmt", s);

            else   print_str_opt("pix_fmt", "unknown");

            print_int("level",   dec_ctx->level);

            if (dec_ctx->timecode_frame_start >= 0) {

                char tcbuf[AV_TIMECODE_STR_SIZE];

                av_timecode_make_mpeg_tc_string(tcbuf, dec_ctx->timecode_frame_start);

                print_str("timecode", tcbuf);

            } else {

                print_str_opt("timecode", "N/A");

            }

            break;

        case AVMEDIA_TYPE_AUDIO:

            s = av_get_sample_fmt_name(dec_ctx->sample_fmt);

            if (s) print_str    ("sample_fmt", s);

            else   print_str_opt("sample_fmt", "unknown");

            print_val("sample_rate",     dec_ctx->sample_rate, unit_hertz_str);

            print_int("channels",        dec_ctx->channels);

            if (dec_ctx->channel_layout) {

                av_bprint_clear(&pbuf);

                av_bprint_channel_layout(&pbuf, dec_ctx->channels, dec_ctx->channel_layout);

                print_str    ("channel_layout", pbuf.str);

            } else {

                print_str_opt("channel_layout", "unknown");

            }

            print_int("bits_per_sample", av_get_bits_per_sample(dec_ctx->codec_id));

            break;

        case AVMEDIA_TYPE_SUBTITLE:

            if (dec_ctx->width)

                print_int("width",       dec_ctx->width);

            else

                print_str_opt("width",   "N/A");

            if (dec_ctx->height)

                print_int("height",      dec_ctx->height);

            else

                print_str_opt("height",  "N/A");

            break;

        }

    } else {

        print_str_opt("codec_type", "unknown");

    }

    if (dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {

        const AVOption *opt = NULL;

        while (opt = av_opt_next(dec_ctx->priv_data,opt)) {

            uint8_t *str;

            if (opt->flags) continue;

            if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {

                print_str(opt->name, str);

                av_free(str);

            }

        }

    }

    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt    ("id", "0x%x", stream->id);

    else                                          print_str_opt("id", "N/A");

    print_q("r_frame_rate",   stream->r_frame_rate,   '/');

    print_q("avg_frame_rate", stream->avg_frame_rate, '/');

    print_q("time_base",      stream->time_base,      '/');

    print_ts  ("start_pts",   stream->start_time);

    print_time("start_time",  stream->start_time, &stream->time_base);

    print_ts  ("duration_ts", stream->duration);

    print_time("duration",    stream->duration, &stream->time_base);

    if (dec_ctx->bit_rate > 0) print_val    ("bit_rate", dec_ctx->bit_rate, unit_bit_per_second_str);

    else                       print_str_opt("bit_rate", "N/A");

    if (stream->nb_frames) print_fmt    ("nb_frames", "%"PRId64, stream->nb_frames);

    else                   print_str_opt("nb_frames", "N/A");

    if (nb_streams_frames[stream_idx])  print_fmt    ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);

    else                                print_str_opt("nb_read_frames", "N/A");

    if (nb_streams_packets[stream_idx]) print_fmt    ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);

    else                                print_str_opt("nb_read_packets", "N/A");

    if (do_show_data)

        writer_print_data(w, "extradata", dec_ctx->extradata,

                                          dec_ctx->extradata_size);

    /* Print disposition information */

#define PRINT_DISPOSITION(flagname, name) do {                                \

        print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \

    } while (0)

    if (do_show_stream_disposition) {

    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION : SECTION_ID_STREAM_DISPOSITION);

    PRINT_DISPOSITION(DEFAULT,          "default");

    PRINT_DISPOSITION(DUB,              "dub");

    PRINT_DISPOSITION(ORIGINAL,         "original");

    PRINT_DISPOSITION(COMMENT,          "comment");

    PRINT_DISPOSITION(LYRICS,           "lyrics");

    PRINT_DISPOSITION(KARAOKE,          "karaoke");

    PRINT_DISPOSITION(FORCED,           "forced");

    PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");

    PRINT_DISPOSITION(VISUAL_IMPAIRED,  "visual_impaired");

    PRINT_DISPOSITION(CLEAN_EFFECTS,    "clean_effects");

    PRINT_DISPOSITION(ATTACHED_PIC,     "attached_pic");

    writer_print_section_footer(w);

    }

    show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);

    writer_print_section_footer(w);

    av_bprint_finalize(&pbuf, NULL);

    fflush(stdout);

}


static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan,

                            const uint32_t *quant) {

    int coeff, i, n;

    int8_t ac;

    uint8_t dc = get_bits(gb, 8);

    // block not coded

    if (dc == 255)

    // number of non-zero coefficients

    coeff = get_bits(gb, 6);

    if (get_bits_count(gb) + (coeff << 1) >= gb->size_in_bits)

    // normally we would only need to clear the (63 - coeff) last values,

    // but since we do not know where they are we just clear the whole block

    memset(block, 0, 64 * sizeof(DCTELEM));

    // 2 bits per coefficient

    while (coeff) {

        ac = get_sbits(gb, 2);

        if (ac == -2)

            break; // continue with more bits

        PUT_COEFF(ac);

    }

    // 4 bits per coefficient

    ALIGN(4);

    while (coeff) {

        ac = get_sbits(gb, 4);

        if (ac == -8)

            break; // continue with more bits

        PUT_COEFF(ac);

    }

    // 8 bits per coefficient

    ALIGN(8);

    if (get_bits_count(gb) + (coeff << 3) >= gb->size_in_bits)

    while (coeff) {

        ac = get_sbits(gb, 8);

        PUT_COEFF(ac);

    }

    PUT_COEFF(dc);

    return 1;

}


static void gen_neon_trn_u16(TCGv t0, TCGv t1)

{

    TCGv rd, tmp;

    rd = new_tmp();

    tmp = new_tmp();

    tcg_gen_shli_i32(rd, t0, 16);

    tcg_gen_andi_i32(tmp, t1, 0xffff);

    tcg_gen_or_i32(rd, rd, tmp);

    tcg_gen_shri_i32(t1, t1, 16);

    tcg_gen_andi_i32(tmp, t0, 0xffff0000);

    tcg_gen_or_i32(t1, t1, tmp);

    tcg_gen_mov_i32(t0, rd);

    dead_tmp(tmp);

    dead_tmp(rd);

}


static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)

{

    if (buf_size < 13)

        return AVERROR_INVALIDDATA;

    if (memcmp(buf, "FLV", 3))

        return AVERROR_INVALIDDATA;

    buf      += 13;

    buf_size -= 13;

    while (buf_size >= 11 + 4) {

        int type = buf[0];

        int size = AV_RB24(&buf[1]) + 11 + 4;

        if (size > buf_size)

            return AVERROR_INVALIDDATA;

        if (type == 8 || type == 9) {

            if (os->nb_extra_packets > FF_ARRAY_ELEMS(os->extra_packets))

                return AVERROR_INVALIDDATA;

            os->extra_packet_sizes[os->nb_extra_packets] = size;

            os->extra_packets[os->nb_extra_packets] = av_malloc(size);

            if (!os->extra_packets[os->nb_extra_packets])

                return AVERROR(ENOMEM);

            memcpy(os->extra_packets[os->nb_extra_packets], buf, size);

            os->nb_extra_packets++;

        } else if (type == 0x12) {

            if (os->metadata)

                return AVERROR_INVALIDDATA;

            os->metadata_size = size - 11 - 4;

            os->metadata      = av_malloc(os->metadata_size);

            if (!os->metadata)

                return AVERROR(ENOMEM);

            memcpy(os->metadata, buf + 11, os->metadata_size);

        }

        buf      += size;

        buf_size -= size;

    }

    if (!os->metadata)

        return AVERROR_INVALIDDATA;

    return 0;

}