static int ipvideo_decode_frame(AVCodecContext *avctx,

                                void *data, int *got_frame,

                                AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    IpvideoContext *s = avctx->priv_data;

    AVFrame *frame = data;

    int ret;

    if (buf_size < 2)

        return AVERROR_INVALIDDATA;

    /* decoding map contains 4 bits of information per 8x8 block */

    s->decoding_map_size = AV_RL16(avpkt->data);

    /* compressed buffer needs to be large enough to at least hold an entire

     * decoding map */

    if (buf_size < s->decoding_map_size + 2)

        return buf_size;

    if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {

        av_frame_unref(s->last_frame);

        av_frame_unref(s->second_last_frame);

    }

    s->decoding_map = buf + 2;

    bytestream2_init(&s->stream_ptr, buf + 2 + s->decoding_map_size,

                     buf_size - s->decoding_map_size);

    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

        return ret;

    if (!s->is_16bpp) {

        int size;

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);

        if (pal && size == AVPALETTE_SIZE) {

            frame->palette_has_changed = 1;

            memcpy(s->pal, pal, AVPALETTE_SIZE);

        } else if (pal) {

            av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);

        }

    }

    ipvideo_decode_opcodes(s, frame);

    *got_frame = 1;

    /* shuffle frames */

    av_frame_unref(s->second_last_frame);

    FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);

    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)

        return ret;

    /* report that the buffer was completely consumed */

    return buf_size;

}


static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,

    AVPacket *pkt)

{

    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];

    int chunk_type;

    int chunk_size;

    unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE];

    unsigned char opcode_type;

    unsigned char opcode_version;

    int opcode_size;

    unsigned char scratch[1024];

    int i, j;

    int first_color, last_color;

    int audio_flags;

    unsigned char r, g, b;

    unsigned int width, height;

    /* see if there are any pending packets */

    chunk_type = load_ipmovie_packet(s, pb, pkt);

    if (chunk_type != CHUNK_DONE)

        return chunk_type;

    /* read the next chunk, wherever the file happens to be pointing */

    if (avio_feof(pb))

        return CHUNK_EOF;

    if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=

        CHUNK_PREAMBLE_SIZE)

        return CHUNK_BAD;

    chunk_size = AV_RL16(&chunk_preamble[0]);

    chunk_type = AV_RL16(&chunk_preamble[2]);

    av_log(s->avf, AV_LOG_TRACE, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);

    switch (chunk_type) {

    case CHUNK_INIT_AUDIO:

        av_log(s->avf, AV_LOG_TRACE, "initialize audio\n");

        break;

    case CHUNK_AUDIO_ONLY:

        av_log(s->avf, AV_LOG_TRACE, "audio only\n");

        break;

    case CHUNK_INIT_VIDEO:

        av_log(s->avf, AV_LOG_TRACE, "initialize video\n");

        break;

    case CHUNK_VIDEO:

        av_log(s->avf, AV_LOG_TRACE, "video (and audio)\n");

        break;

    case CHUNK_SHUTDOWN:

        av_log(s->avf, AV_LOG_TRACE, "shutdown\n");

        break;

    case CHUNK_END:

        av_log(s->avf, AV_LOG_TRACE, "end\n");

        break;

    default:

        av_log(s->avf, AV_LOG_TRACE, "invalid chunk\n");

        chunk_type = CHUNK_BAD;

        break;

    }

    while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {

        /* read the next chunk, wherever the file happens to be pointing */

        if (avio_feof(pb)) {

            chunk_type = CHUNK_EOF;

            break;

        }

        if (avio_read(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=

            CHUNK_PREAMBLE_SIZE) {

            chunk_type = CHUNK_BAD;

            break;

        }

        opcode_size = AV_RL16(&opcode_preamble[0]);

        opcode_type = opcode_preamble[2];

        opcode_version = opcode_preamble[3];

        chunk_size -= OPCODE_PREAMBLE_SIZE;

        chunk_size -= opcode_size;

        if (chunk_size < 0) {

            av_log(s->avf, AV_LOG_TRACE, "chunk_size countdown just went negative\n");

            chunk_type = CHUNK_BAD;

            break;

        }

        av_log(s->avf, AV_LOG_TRACE, "  opcode type %02X, version %d, 0x%04X bytes: ",

                opcode_type, opcode_version, opcode_size);

        switch (opcode_type) {

        case OPCODE_END_OF_STREAM:

            av_log(s->avf, AV_LOG_TRACE, "end of stream\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_END_OF_CHUNK:

            av_log(s->avf, AV_LOG_TRACE, "end of chunk\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_CREATE_TIMER:

            av_log(s->avf, AV_LOG_TRACE, "create timer\n");

            if ((opcode_version > 0) || (opcode_size != 6)) {

                av_log(s->avf, AV_LOG_TRACE, "bad create_timer opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (avio_read(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]);

            break;

        case OPCODE_INIT_AUDIO_BUFFERS:

            av_log(s->avf, AV_LOG_TRACE, "initialize audio buffers\n");

            if (opcode_version > 1 || opcode_size > 10 || opcode_size < 6) {

                av_log(s->avf, AV_LOG_TRACE, "bad init_audio_buffers opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (avio_read(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            s->audio_sample_rate = AV_RL16(&scratch[4]);

            audio_flags = AV_RL16(&scratch[2]);

            /* bit 0 of the flags: 0 = mono, 1 = stereo */

            s->audio_channels = (audio_flags & 1) + 1;

            /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */

            s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8;

            /* bit 2 indicates compressed audio in version 1 opcode */

            if ((opcode_version == 1) && (audio_flags & 0x4))

                s->audio_type = AV_CODEC_ID_INTERPLAY_DPCM;

            else if (s->audio_bits == 16)

                s->audio_type = AV_CODEC_ID_PCM_S16LE;

            else

                s->audio_type = AV_CODEC_ID_PCM_U8;

            av_log(s->avf, AV_LOG_TRACE, "audio: %d bits, %d Hz, %s, %s format\n",

                    s->audio_bits, s->audio_sample_rate,

                    (s->audio_channels == 2) ? "stereo" : "mono",

                    (s->audio_type == AV_CODEC_ID_INTERPLAY_DPCM) ?

                    "Interplay audio" : "PCM");

            break;

        case OPCODE_START_STOP_AUDIO:

            av_log(s->avf, AV_LOG_TRACE, "start/stop audio\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_INIT_VIDEO_BUFFERS:

            av_log(s->avf, AV_LOG_TRACE, "initialize video buffers\n");

            if ((opcode_version > 2) || (opcode_size > 8) || opcode_size < 4

                || opcode_version == 2 && opcode_size < 8

            ) {

                av_log(s->avf, AV_LOG_TRACE, "bad init_video_buffers opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (avio_read(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            width  = AV_RL16(&scratch[0]) * 8;

            height = AV_RL16(&scratch[2]) * 8;

            if (width != s->video_width) {

                s->video_width = width;

                s->changed++;

            }

            if (height != s->video_height) {

                s->video_height = height;

                s->changed++;

            }

            if (opcode_version < 2 || !AV_RL16(&scratch[6])) {

                s->video_bpp = 8;

            } else {

                s->video_bpp = 16;

            }

            av_log(s->avf, AV_LOG_TRACE, "video resolution: %d x %d\n",

                    s->video_width, s->video_height);

            break;

        case OPCODE_UNKNOWN_06:

        case OPCODE_UNKNOWN_0E:

        case OPCODE_UNKNOWN_10:

        case OPCODE_UNKNOWN_12:

        case OPCODE_UNKNOWN_13:

        case OPCODE_UNKNOWN_14:

        case OPCODE_UNKNOWN_15:

            av_log(s->avf, AV_LOG_TRACE, "unknown (but documented) opcode %02X\n", opcode_type);

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_SEND_BUFFER:

            av_log(s->avf, AV_LOG_TRACE, "send buffer\n");

            avio_skip(pb, opcode_size);

            s->send_buffer = 1;

            break;

        case OPCODE_AUDIO_FRAME:

            av_log(s->avf, AV_LOG_TRACE, "audio frame\n");

            /* log position and move on for now */

            s->audio_chunk_offset = avio_tell(pb);

            s->audio_chunk_size = opcode_size;

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_SILENCE_FRAME:

            av_log(s->avf, AV_LOG_TRACE, "silence frame\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_INIT_VIDEO_MODE:

            av_log(s->avf, AV_LOG_TRACE, "initialize video mode\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_CREATE_GRADIENT:

            av_log(s->avf, AV_LOG_TRACE, "create gradient\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_SET_PALETTE:

            av_log(s->avf, AV_LOG_TRACE, "set palette\n");

            /* check for the logical maximum palette size

             * (3 * 256 + 4 bytes) */

            if (opcode_size > 0x304 || opcode_size < 4) {

                av_log(s->avf, AV_LOG_TRACE, "demux_ipmovie: set_palette opcode with invalid size\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (avio_read(pb, scratch, opcode_size) != opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            /* load the palette into internal data structure */

            first_color = AV_RL16(&scratch[0]);

            last_color = first_color + AV_RL16(&scratch[2]) - 1;

            /* sanity check (since they are 16 bit values) */

            if (   (first_color > 0xFF) || (last_color > 0xFF)

                || (last_color - first_color + 1)*3 + 4 > opcode_size) {

                av_log(s->avf, AV_LOG_TRACE, "demux_ipmovie: set_palette indexes out of range (%d -> %d)\n",

                    first_color, last_color);

                chunk_type = CHUNK_BAD;

                break;

            }

            j = 4;  /* offset of first palette data */

            for (i = first_color; i <= last_color; i++) {

                /* the palette is stored as a 6-bit VGA palette, thus each

                 * component is shifted up to a 8-bit range */

                r = scratch[j++] * 4;

                g = scratch[j++] * 4;

                b = scratch[j++] * 4;

                s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);

                s->palette[i] |= s->palette[i] >> 6 & 0x30303;

            }

            s->has_palette = 1;

            break;

        case OPCODE_SET_PALETTE_COMPRESSED:

            av_log(s->avf, AV_LOG_TRACE, "set palette compressed\n");

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_SET_DECODING_MAP:

            av_log(s->avf, AV_LOG_TRACE, "set decoding map\n");

            /* log position and move on for now */

            s->decode_map_chunk_offset = avio_tell(pb);

            s->decode_map_chunk_size = opcode_size;

            avio_skip(pb, opcode_size);

            break;

        case OPCODE_VIDEO_DATA_11:

            av_log(s->avf, AV_LOG_TRACE, "set video data\n");

            s->frame_format = 0x11;

            /* log position and move on for now */

            s->video_chunk_offset = avio_tell(pb);

            s->video_chunk_size = opcode_size;

            avio_skip(pb, opcode_size);

            break;

        default:

            av_log(s->avf, AV_LOG_TRACE, "*** unknown opcode type\n");

            chunk_type = CHUNK_BAD;

            break;

        }

    }

    if (s->avf->nb_streams == 1 && s->audio_type)

        init_audio(s->avf);

    /* make a note of where the stream is sitting */

    s->next_chunk_offset = avio_tell(pb);

    /* dispatch the first of any pending packets */

    if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY))

        chunk_type = load_ipmovie_packet(s, pb, pkt);

    return chunk_type;

}


static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)

{

    AVStream *st;

    OutputStream *ost;

    AVCodecContext *video_enc;

    char *frame_rate = NULL, *frame_aspect_ratio = NULL;

    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);

    st  = ost->st;

    video_enc = ost->enc_ctx;

    MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);

    if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {

        av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);

        exit_program(1);

    }

    if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH)

        av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid output files\n");

    MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);

    if (frame_aspect_ratio) {

        AVRational q;

        if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||

            q.num <= 0 || q.den <= 0) {

            av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);

            exit_program(1);

        }

        ost->frame_aspect_ratio = q;

    }

    MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);

    MATCH_PER_STREAM_OPT(filters,        str, ost->filters,        oc, st);

    if (!ost->stream_copy) {

        const char *p = NULL;

        char *frame_size = NULL;

        char *frame_pix_fmt = NULL;

        char *intra_matrix = NULL, *inter_matrix = NULL;

        char *chroma_intra_matrix = NULL;

        int do_pass = 0;

        int i;

        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);

        if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {

            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);

            exit_program(1);

        }

        video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;

        MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);

        if (frame_pix_fmt && *frame_pix_fmt == '+') {

            ost->keep_pix_fmt = 1;

            if (!*++frame_pix_fmt)

                frame_pix_fmt = NULL;

        }

        if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {

            av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);

            exit_program(1);

        }

        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;

        if (intra_only)

            video_enc->gop_size = 0;

        MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);

        if (intra_matrix) {

            if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {

                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");

                exit_program(1);

            }

            parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);

        }

        MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);

        if (chroma_intra_matrix) {

            uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);

            if (!p) {

                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");

                exit_program(1);

            }

            av_codec_set_chroma_intra_matrix(video_enc, p);

            parse_matrix_coeffs(p, chroma_intra_matrix);

        }

        MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);

        if (inter_matrix) {

            if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {

                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");

                exit_program(1);

            }

            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);

        }

        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);

        for (i = 0; p; i++) {

            int start, end, q;

            int e = sscanf(p, "%d,%d,%d", &start, &end, &q);

            if (e != 3) {

                av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");

                exit_program(1);

            }

            /* FIXME realloc failure */

            video_enc->rc_override =

                av_realloc_array(video_enc->rc_override,

                                 i + 1, sizeof(RcOverride));

            video_enc->rc_override[i].start_frame = start;

            video_enc->rc_override[i].end_frame   = end;

            if (q > 0) {

                video_enc->rc_override[i].qscale         = q;

                video_enc->rc_override[i].quality_factor = 1.0;

            }

            else {

                video_enc->rc_override[i].qscale         = 0;

                video_enc->rc_override[i].quality_factor = -q/100.0;

            }

            p = strchr(p, '/');

            if (p) p++;

        }

        video_enc->rc_override_count = i;

        if (do_psnr)

            video_enc->flags|= CODEC_FLAG_PSNR;

        /* two pass mode */

        MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);

        if (do_pass) {

            if (do_pass & 1) {

                video_enc->flags |= CODEC_FLAG_PASS1;

                av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);

            }

            if (do_pass & 2) {

                video_enc->flags |= CODEC_FLAG_PASS2;

                av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);

            }

        }

        MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);

        if (ost->logfile_prefix &&

            !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))

            exit_program(1);

        MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);

        if (ost->forced_keyframes)

            ost->forced_keyframes = av_strdup(ost->forced_keyframes);

        MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);

        ost->top_field_first = -1;

        MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);

        ost->avfilter = get_ost_filters(o, oc, ost);

        if (!ost->avfilter)

            exit_program(1);

    } else {

        MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);

    }

    if (ost->stream_copy)

        check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);

    return ost;

}


static void put_float64(QEMUFile *f, void *pv, size_t size)

{

    uint64_t *v = pv;

    qemu_put_be64(f, float64_val(*v));

}


static void pci_host_config_write(void *opaque, target_phys_addr_t addr,

                                  uint64_t val, unsigned len)

{

    PCIHostState *s = opaque;

    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",

                __func__, addr, len, val);

    s->config_reg = val;


static void qobject_input_type_number(Visitor *v, const char *name, double *obj,

                                      Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, true, errp);

    QInt *qint;

    QFloat *qfloat;

    if (!qobj) {

        return;

    }

    qint = qobject_to_qint(qobj);

    if (qint) {

        *obj = qint_get_int(qobject_to_qint(qobj));

        return;

    }

    qfloat = qobject_to_qfloat(qobj);

    if (qfloat) {

        *obj = qfloat_get_double(qobject_to_qfloat(qobj));

        return;

    }

    error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

               "number");

}


int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))

{

    if (lockmgr_cb) {

        // There is no good way to rollback a failure to destroy the

        // mutex, so we ignore failures.

        lockmgr_cb(&codec_mutex,    AV_LOCK_DESTROY);

        lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY);

        lockmgr_cb     = NULL;

        codec_mutex    = NULL;

        avformat_mutex = NULL;

    }

    if (cb) {

        void *new_codec_mutex    = NULL;

        void *new_avformat_mutex = NULL;

        int err;

        if (err = cb(&new_codec_mutex, AV_LOCK_CREATE)) {

            return err > 0 ? AVERROR_UNKNOWN : err;

        }

        if (err = cb(&new_avformat_mutex, AV_LOCK_CREATE)) {

            // Ignore failures to destroy the newly created mutex.

            cb(&new_codec_mutex, AV_LOCK_DESTROY);

            return err > 0 ? AVERROR_UNKNOWN : err;

        }

        lockmgr_cb     = cb;

        codec_mutex    = new_codec_mutex;

        avformat_mutex = new_avformat_mutex;

    }

    return 0;

}


static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)

{

    int i, j, k, l;

    int sf_max, sf, len, non_zero_found;

    INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;

    int non_zero_found_short[3];

    /* intensity stereo */

    if (s->mode_ext & MODE_EXT_I_STEREO) {

        if (!s->lsf) {

            is_tab = is_table;

            sf_max = 7;

        } else {

            is_tab = is_table_lsf[g1->scalefac_compress & 1];

            sf_max = 16;

        }

        tab0 = g0->sb_hybrid + 576;

        tab1 = g1->sb_hybrid + 576;

        non_zero_found_short[0] = 0;

        non_zero_found_short[1] = 0;

        non_zero_found_short[2] = 0;

        k = (13 - g1->short_start) * 3 + g1->long_end - 3;

        for (i = 12; i >= g1->short_start; i--) {

            /* for last band, use previous scale factor */

            if (i != 11)

                k -= 3;

            len = band_size_short[s->sample_rate_index][i];

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

                tab0 -= len;

                tab1 -= len;

                if (!non_zero_found_short[l]) {

                    /* test if non zero band. if so, stop doing i-stereo */

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

                        if (tab1[j] != 0) {

                            non_zero_found_short[l] = 1;

                            goto found1;

                        }

                    }

                    sf = g1->scale_factors[k + l];

                    if (sf >= sf_max)

                        goto found1;

                    v1 = is_tab[0][sf];

                    v2 = is_tab[1][sf];

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

                        tmp0    = tab0[j];

                        tab0[j] = MULLx(tmp0, v1, FRAC_BITS);

                        tab1[j] = MULLx(tmp0, v2, FRAC_BITS);

                    }

                } else {

found1:

                    if (s->mode_ext & MODE_EXT_MS_STEREO) {

                        /* lower part of the spectrum : do ms stereo

                           if enabled */

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

                            tmp0    = tab0[j];

                            tmp1    = tab1[j];

                            tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);

                            tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);

                        }

                    }

                }

            }

        }

        non_zero_found = non_zero_found_short[0] |

                         non_zero_found_short[1] |

                         non_zero_found_short[2];

        for (i = g1->long_end - 1;i >= 0;i--) {

            len   = band_size_long[s->sample_rate_index][i];

            tab0 -= len;

            tab1 -= len;

            /* test if non zero band. if so, stop doing i-stereo */

            if (!non_zero_found) {

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

                    if (tab1[j] != 0) {

                        non_zero_found = 1;

                        goto found2;

                    }

                }

                /* for last band, use previous scale factor */

                k  = (i == 21) ? 20 : i;

                sf = g1->scale_factors[k];

                if (sf >= sf_max)

                    goto found2;

                v1 = is_tab[0][sf];

                v2 = is_tab[1][sf];

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

                    tmp0    = tab0[j];

                    tab0[j] = MULLx(tmp0, v1, FRAC_BITS);

                    tab1[j] = MULLx(tmp0, v2, FRAC_BITS);

                }

            } else {

found2:

                if (s->mode_ext & MODE_EXT_MS_STEREO) {

                    /* lower part of the spectrum : do ms stereo

                       if enabled */

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

                        tmp0    = tab0[j];

                        tmp1    = tab1[j];

                        tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);

                        tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);

                    }

                }

            }

        }

    } else if (s->mode_ext & MODE_EXT_MS_STEREO) {

        /* ms stereo ONLY */

        /* NOTE: the 1/sqrt(2) normalization factor is included in the

           global gain */

#if USE_FLOATS

       s->fdsp->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);

#else

        tab0 = g0->sb_hybrid;

        tab1 = g1->sb_hybrid;

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

            tmp0    = tab0[i];

            tmp1    = tab1[i];

            tab0[i] = tmp0 + tmp1;

            tab1[i] = tmp0 - tmp1;

        }

#endif

    }

}


static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm)

{

    NVDIMMDevice *nvdimm = NVDIMM(dimm);

    return &nvdimm->nvdimm_mr;

}


static void usb_serial_realize(USBDevice *dev, Error **errp)

{

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

    usb_desc_create_serial(dev);

    usb_desc_init(dev);

    dev->auto_attach = 0;

    if (!s->cs) {

        error_setg(errp, "Property chardev is required");

        return;

    }

    qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,

                          usb_serial_event, s);

    usb_serial_handle_reset(dev);

    if (s->cs->be_open && !dev->attached) {

        usb_device_attach(dev, errp);

    }

}


static void tmu2_write(void *opaque, target_phys_addr_t addr, uint64_t value,

                       unsigned size)

{

    MilkymistTMU2State *s = opaque;

    trace_milkymist_tmu2_memory_write(addr, value);

    addr >>= 2;

    switch (addr) {

    case R_CTL:

        s->regs[addr] = value;

        if (value & CTL_START_BUSY) {

            tmu2_start(s);

        }

        break;

    case R_BRIGHTNESS:

    case R_HMESHLAST:

    case R_VMESHLAST:

    case R_CHROMAKEY:

    case R_VERTICESADDR:

    case R_TEXFBUF:

    case R_TEXHRES:

    case R_TEXVRES:

    case R_TEXHMASK:

    case R_TEXVMASK:

    case R_DSTFBUF:

    case R_DSTHRES:

    case R_DSTVRES:

    case R_DSTHOFFSET:

    case R_DSTVOFFSET:

    case R_DSTSQUAREW:

    case R_DSTSQUAREH:

    case R_ALPHA:

        s->regs[addr] = value;

        break;

    default:

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

                TARGET_FMT_plx, addr << 2);

        break;

    }

    tmu2_check_registers(s);

}


static int SocketAddress_to_str(char *dest, int max_len,

                                const char *prefix, SocketAddress *addr,

                                bool is_listen, bool is_telnet)

{

    switch (addr->type) {

    case SOCKET_ADDRESS_KIND_INET:

        return snprintf(dest, max_len, "%s%s:%s:%s%s", prefix,

                        is_telnet ? "telnet" : "tcp", addr->u.inet->host,

                        addr->u.inet->port, is_listen ? ",server" : "");

        break;

    case SOCKET_ADDRESS_KIND_UNIX:

        return snprintf(dest, max_len, "%sunix:%s%s", prefix,

                        addr->u.q_unix->path, is_listen ? ",server" : "");

        break;

    case SOCKET_ADDRESS_KIND_FD:

        return snprintf(dest, max_len, "%sfd:%s%s", prefix, addr->u.fd->str,

                        is_listen ? ",server" : "");

        break;

    default:

        abort();

    }

}


static int blkverify_open(BlockDriverState *bs, const char *filename, int flags)

{

    BDRVBlkverifyState *s = bs->opaque;

    int ret;

    char *raw, *c;

    /* Parse the blkverify: prefix */

    if (strncmp(filename, "blkverify:", strlen("blkverify:"))) {

        return -EINVAL;

    }

    filename += strlen("blkverify:");

    /* Parse the raw image filename */

    c = strchr(filename, ':');

    if (c == NULL) {

        return -EINVAL;

    }

    raw = strdup(filename);

    raw[c - filename] = '\0';

    ret = bdrv_file_open(&bs->file, raw, flags);

    free(raw);

    if (ret < 0) {

        return ret;

    }

    filename = c + 1;

    /* Open the test file */

    s->test_file = bdrv_new("");

    ret = bdrv_open(s->test_file, filename, flags, NULL);

    if (ret < 0) {

        bdrv_delete(s->test_file);

        s->test_file = NULL;

        return ret;

    }

    return 0;

}


static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)

{

    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);

    uint32_t len;

    uint8_t command;

    command = buf[0];

    if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {

        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));

        return 0;

    }

    len = scsi_data_cdb_length(r->req.cmd.buf);

    switch (command) {

    case READ_6:

    case READ_10:

    case READ_12:

    case READ_16:

        DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);

        if (r->req.cmd.buf[1] & 0xe0) {

            goto illegal_request;

        }

        if (!check_lba_range(s, r->req.cmd.lba, len)) {

            goto illegal_lba;

        }

        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);

        r->sector_count = len * (s->qdev.blocksize / 512);

        break;

    case WRITE_6:

    case WRITE_10:

    case WRITE_12:

    case WRITE_16:

    case WRITE_VERIFY_10:

    case WRITE_VERIFY_12:

    case WRITE_VERIFY_16:

        if (bdrv_is_read_only(s->qdev.conf.bs)) {

            scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));

            return 0;

        }

        DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",

                (command & 0xe) == 0xe ? "And Verify " : "",

                r->req.cmd.lba, len);

        if (r->req.cmd.buf[1] & 0xe0) {

            goto illegal_request;

        }

        if (!check_lba_range(s, r->req.cmd.lba, len)) {

            goto illegal_lba;

        }

        r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);

        r->sector_count = len * (s->qdev.blocksize / 512);

        break;

    default:

        abort();

    illegal_request:

        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));

        return 0;

    illegal_lba:

        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));

        return 0;

    }

    if (r->sector_count == 0) {

        scsi_req_complete(&r->req, GOOD);

    }

    assert(r->iov.iov_len == 0);

    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {

        return -r->sector_count * 512;

    } else {

        return r->sector_count * 512;

    }

}


static void core_begin(MemoryListener *listener)

{

    destroy_all_mappings();

    phys_sections_clear();

    phys_map.ptr = PHYS_MAP_NODE_NIL;

    phys_section_unassigned = dummy_section(&io_mem_unassigned);

    phys_section_notdirty = dummy_section(&io_mem_notdirty);

    phys_section_rom = dummy_section(&io_mem_rom);

    phys_section_watch = dummy_section(&io_mem_watch);

}


START_TEST(qlist_new_test)

{

    QList *qlist;

    qlist = qlist_new();

    fail_unless(qlist != NULL);

    fail_unless(qlist->base.refcnt == 1);

    fail_unless(qobject_type(QOBJECT(qlist)) == QTYPE_QLIST);

    // destroy doesn't exist yet

    g_free(qlist);

}


static void do_info(int argc, const char **argv)

{

    term_cmd_t *cmd;

    const char *item;

    if (argc < 2)

        goto help;

    item = argv[1];

    for(cmd = info_cmds; cmd->name != NULL; cmd++) {

        if (compare_cmd(argv[1], cmd->name))

            goto found;

    }

 help:

    help_cmd(argv[0]);

    return;

 found:

    cmd->handler(argc, argv);

}


static void scsi_command_complete(void *opaque, int ret)

{

    int status;

    SCSIGenericReq *r = (SCSIGenericReq *)opaque;

    r->req.aiocb = NULL;

    if (r->req.io_canceled) {

        goto done;

    }

    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {

        r->req.sense_len = r->io_header.sb_len_wr;

    }

    if (ret != 0) {

        switch (ret) {

        case -EDOM:

            status = TASK_SET_FULL;

            break;

        case -ENOMEM:

            status = CHECK_CONDITION;

            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));

            break;

        default:

            status = CHECK_CONDITION;

            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));

            break;

        }

    } else {

        if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||

            r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||

            r->io_header.host_status == SG_ERR_DID_TIME_OUT ||

            (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {

            status = BUSY;

            BADF("Driver Timeout\n");

        } else if (r->io_header.host_status) {

            status = CHECK_CONDITION;

            scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));

        } else if (r->io_header.status) {

            status = r->io_header.status;

        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {

            status = CHECK_CONDITION;

        } else {

            status = GOOD;

        }

    }

    DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",

            r, r->req.tag, status);

    scsi_req_complete(&r->req, status);

done:

    if (!r->req.io_canceled) {

        scsi_req_unref(&r->req);

    }

}


static bool iasl_installed(void)

{

    gchar *out = NULL, *out_err = NULL;

    bool ret;

    /* pass 'out' and 'out_err' in order to be redirected */

    ret = g_spawn_command_line_sync("iasl", &out, &out_err, NULL, NULL);

    if (out_err) {

        ret = ret && (out_err[0] == '\0');

        g_free(out_err);

    }

    if (out) {

        g_free(out);

    }

    return ret;

}


static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)

{

    DisplaySurface *surface = qemu_console_surface(qxl->vga.con);

    uint8_t *dst = surface_data(surface);

    uint8_t *src;

    int len, i;

    if (is_buffer_shared(surface)) {

        return;

    }

    if (!qxl->guest_primary.data) {

        trace_qxl_render_blit_guest_primary_initialized();

        qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);

    }

    trace_qxl_render_blit(qxl->guest_primary.qxl_stride,

            rect->left, rect->right, rect->top, rect->bottom);

    src = qxl->guest_primary.data;

    if (qxl->guest_primary.qxl_stride < 0) {

        /* qxl surface is upside down, walk src scanlines

         * in reverse order to flip it */

        src += (qxl->guest_primary.surface.height - rect->top - 1) *

            qxl->guest_primary.abs_stride;

    } else {

        src += rect->top * qxl->guest_primary.abs_stride;

    }

    dst += rect->top  * qxl->guest_primary.abs_stride;

    src += rect->left * qxl->guest_primary.bytes_pp;

    dst += rect->left * qxl->guest_primary.bytes_pp;

    len  = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;

    for (i = rect->top; i < rect->bottom; i++) {

        memcpy(dst, src, len);

        dst += qxl->guest_primary.abs_stride;

        src += qxl->guest_primary.qxl_stride;

    }

}


PCIDevice *pci_try_create(PCIBus *bus, int devfn, const char *name)

{

    return pci_try_create_multifunction(bus, devfn, false, name);

}


int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,

    int nb_sectors, enum qcow2_discard_type type, bool full_discard)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t end_offset;

    unsigned int nb_clusters;

    int ret;

    end_offset = offset + (nb_sectors << BDRV_SECTOR_BITS);

    /* Round start up and end down */

    offset = align_offset(offset, s->cluster_size);

    end_offset = start_of_cluster(s, end_offset);

    if (offset > end_offset) {

        return 0;

    }

    nb_clusters = size_to_clusters(s, end_offset - offset);

    s->cache_discards = true;

    /* Each L2 table is handled by its own loop iteration */

    while (nb_clusters > 0) {

        ret = discard_single_l2(bs, offset, nb_clusters, type, full_discard);

        if (ret < 0) {

            goto fail;

        }

        nb_clusters -= ret;

        offset += (ret * s->cluster_size);

    }

    ret = 0;

fail:

    s->cache_discards = false;

    qcow2_process_discards(bs, ret);

    return ret;

}


int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes)

{

    uint8_t buf[4096];

    target_phys_addr_t dst_begin = dst_addr;

    size_t want, did;

    while (nbytes) {

	want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;

	did = read(fd, buf, want);

	if (did != want) break;

	cpu_physical_memory_write_rom(dst_addr, buf, did);

	dst_addr += did;

	nbytes -= did;

    }

    return dst_addr - dst_begin;

}


static int gxf_probe(AVProbeData *p) {

    static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet

    static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2};

    if (p->buf_size < 16)

        return 0;

    if (!memcmp(p->buf, startcode, sizeof(startcode)) &&

        !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode)))

        return AVPROBE_SCORE_MAX;

    return 0;

}


uint32_t cpu_inl(CPUState *env, pio_addr_t addr)

{

    uint32_t val;

    val = ioport_read(2, addr);

    LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);

#ifdef CONFIG_KQEMU

    if (env)

        env->last_io_time = cpu_get_time_fast();

#endif

    return val;

}


e1000_receive(void *opaque, const uint8_t *buf, size_t size)

{

    E1000State *s = opaque;

    struct e1000_rx_desc desc;

    target_phys_addr_t base;

    unsigned int n, rdt;

    uint32_t rdh_start;

    uint16_t vlan_special = 0;

    uint8_t vlan_status = 0, vlan_offset = 0;

    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))

        return;

    if (size > s->rxbuf_size) {

        DBGOUT(RX, "packet too large for buffers (%lu > %d)\n",

               (unsigned long)size, s->rxbuf_size);

        return;

    }

    if (!receive_filter(s, buf, size))

        return;

    if (vlan_enabled(s) && is_vlan_packet(s, buf)) {

        vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));

        memmove((void *)(buf + 4), buf, 12);

        vlan_status = E1000_RXD_STAT_VP;

        vlan_offset = 4;

        size -= 4;

    }

    rdh_start = s->mac_reg[RDH];

    size += 4; // for the header

    do {

        if (s->mac_reg[RDH] == s->mac_reg[RDT] && s->check_rxov) {

            set_ics(s, 0, E1000_ICS_RXO);

            return;

        }

        base = ((uint64_t)s->mac_reg[RDBAH] << 32) + s->mac_reg[RDBAL] +

               sizeof(desc) * s->mac_reg[RDH];

        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));

        desc.special = vlan_special;

        desc.status |= (vlan_status | E1000_RXD_STAT_DD);

        if (desc.buffer_addr) {

            cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),

                                      (void *)(buf + vlan_offset), size);

            desc.length = cpu_to_le16(size);

            desc.status |= E1000_RXD_STAT_EOP|E1000_RXD_STAT_IXSM;

        } else // as per intel docs; skip descriptors with null buf addr

            DBGOUT(RX, "Null RX descriptor!!\n");

        cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));

        if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])

            s->mac_reg[RDH] = 0;

        s->check_rxov = 1;

        /* see comment in start_xmit; same here */

        if (s->mac_reg[RDH] == rdh_start) {

            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",

                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);

            set_ics(s, 0, E1000_ICS_RXO);

            return;

        }

    } while (desc.buffer_addr == 0);

    s->mac_reg[GPRC]++;

    s->mac_reg[TPR]++;

    n = s->mac_reg[TORL];

    if ((s->mac_reg[TORL] += size) < n)

        s->mac_reg[TORH]++;

    n = E1000_ICS_RXT0;

    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])

        rdt += s->mac_reg[RDLEN] / sizeof(desc);

    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >>

        s->rxbuf_min_shift)

        n |= E1000_ICS_RXDMT0;

    set_ics(s, 0, n);

}


static uint64_t omap_mcbsp_read(void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;

    int offset = addr & OMAP_MPUI_REG_MASK;

    uint16_t ret;

    if (size != 2) {

        return omap_badwidth_read16(opaque, addr);

    }

    switch (offset) {

    case 0x00:	/* DRR2 */

        if (((s->rcr[0] >> 5) & 7) < 3)			/* RWDLEN1 */

            return 0x0000;

        /* Fall through.  */

    case 0x02:	/* DRR1 */

        if (s->rx_req < 2) {

            printf("%s: Rx FIFO underrun\n", __FUNCTION__);

            omap_mcbsp_rx_done(s);

        } else {

            s->tx_req -= 2;

            if (s->codec && s->codec->in.len >= 2) {

                ret = s->codec->in.fifo[s->codec->in.start ++] << 8;

                ret |= s->codec->in.fifo[s->codec->in.start ++];

                s->codec->in.len -= 2;

            } else

                ret = 0x0000;

            if (!s->tx_req)

                omap_mcbsp_rx_done(s);

            return ret;

        }

        return 0x0000;

    case 0x04:	/* DXR2 */

    case 0x06:	/* DXR1 */

        return 0x0000;

    case 0x08:	/* SPCR2 */

        return s->spcr[1];

    case 0x0a:	/* SPCR1 */

        return s->spcr[0];

    case 0x0c:	/* RCR2 */

        return s->rcr[1];

    case 0x0e:	/* RCR1 */

        return s->rcr[0];

    case 0x10:	/* XCR2 */

        return s->xcr[1];

    case 0x12:	/* XCR1 */

        return s->xcr[0];

    case 0x14:	/* SRGR2 */

        return s->srgr[1];

    case 0x16:	/* SRGR1 */

        return s->srgr[0];

    case 0x18:	/* MCR2 */

        return s->mcr[1];

    case 0x1a:	/* MCR1 */

        return s->mcr[0];

    case 0x1c:	/* RCERA */

        return s->rcer[0];

    case 0x1e:	/* RCERB */

        return s->rcer[1];

    case 0x20:	/* XCERA */

        return s->xcer[0];

    case 0x22:	/* XCERB */

        return s->xcer[1];

    case 0x24:	/* PCR0 */

        return s->pcr;

    case 0x26:	/* RCERC */

        return s->rcer[2];

    case 0x28:	/* RCERD */

        return s->rcer[3];

    case 0x2a:	/* XCERC */

        return s->xcer[2];

    case 0x2c:	/* XCERD */

        return s->xcer[3];

    case 0x2e:	/* RCERE */

        return s->rcer[4];

    case 0x30:	/* RCERF */

        return s->rcer[5];

    case 0x32:	/* XCERE */

        return s->xcer[4];

    case 0x34:	/* XCERF */

        return s->xcer[5];

    case 0x36:	/* RCERG */

        return s->rcer[6];

    case 0x38:	/* RCERH */

        return s->rcer[7];

    case 0x3a:	/* XCERG */

        return s->xcer[6];

    case 0x3c:	/* XCERH */

        return s->xcer[7];

    }

    OMAP_BAD_REG(addr);

    return 0;

}


static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req)

{

    int status = VIRTIO_BLK_S_OK;

    struct virtio_scsi_inhdr *scsi = NULL;

    VirtIODevice *vdev = VIRTIO_DEVICE(req->dev);

    VirtQueueElement *elem = &req->elem;

    VirtIOBlock *blk = req->dev;

#ifdef __linux__

    int i;

    VirtIOBlockIoctlReq *ioctl_req;

#endif

    /*

     * We require at least one output segment each for the virtio_blk_outhdr

     * and the SCSI command block.

     *

     * We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr

     * and the sense buffer pointer in the input segments.

     */

    if (elem->out_num < 2 || elem->in_num < 3) {

        status = VIRTIO_BLK_S_IOERR;

        goto fail;

    }

    /*

     * The scsi inhdr is placed in the second-to-last input segment, just

     * before the regular inhdr.

     */

    scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;

    if (!blk->conf.scsi) {

        status = VIRTIO_BLK_S_UNSUPP;

        goto fail;

    }

    /*

     * No support for bidirection commands yet.

     */

    if (elem->out_num > 2 && elem->in_num > 3) {

        status = VIRTIO_BLK_S_UNSUPP;

        goto fail;

    }

#ifdef __linux__

    ioctl_req = g_new0(VirtIOBlockIoctlReq, 1);

    ioctl_req->req = req;

    ioctl_req->hdr.interface_id = 'S';

    ioctl_req->hdr.cmd_len = elem->out_sg[1].iov_len;

    ioctl_req->hdr.cmdp = elem->out_sg[1].iov_base;

    ioctl_req->hdr.dxfer_len = 0;

    if (elem->out_num > 2) {

        /*

         * If there are more than the minimally required 2 output segments

         * there is write payload starting from the third iovec.

         */

        ioctl_req->hdr.dxfer_direction = SG_DXFER_TO_DEV;

        ioctl_req->hdr.iovec_count = elem->out_num - 2;

        for (i = 0; i < ioctl_req->hdr.iovec_count; i++) {

            ioctl_req->hdr.dxfer_len += elem->out_sg[i + 2].iov_len;

        }

        ioctl_req->hdr.dxferp = elem->out_sg + 2;

    } else if (elem->in_num > 3) {

        /*

         * If we have more than 3 input segments the guest wants to actually

         * read data.

         */

        ioctl_req->hdr.dxfer_direction = SG_DXFER_FROM_DEV;

        ioctl_req->hdr.iovec_count = elem->in_num - 3;

        for (i = 0; i < ioctl_req->hdr.iovec_count; i++) {

            ioctl_req->hdr.dxfer_len += elem->in_sg[i].iov_len;

        }

        ioctl_req->hdr.dxferp = elem->in_sg;

    } else {

        /*

         * Some SCSI commands don't actually transfer any data.

         */

        ioctl_req->hdr.dxfer_direction = SG_DXFER_NONE;

    }

    ioctl_req->hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base;

    ioctl_req->hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len;

    blk_aio_ioctl(blk->blk, SG_IO, &ioctl_req->hdr,

                  virtio_blk_ioctl_complete, ioctl_req);

    return -EINPROGRESS;

#else

    abort();

#endif

fail:

    /* Just put anything nonzero so that the ioctl fails in the guest.  */

    if (scsi) {

        virtio_stl_p(vdev, &scsi->errors, 255);

    }

    return status;

}


static int targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_t *src, int src_size, uint8_t *dst, int w, int h, int stride, int bpp)

{

    int i, x, y;

    int depth = (bpp + 1) >> 3;

    int type, count;

    int diff;

    const uint8_t *src_end = src + src_size;

    diff = stride - w * depth;

    x = y = 0;

    while(y < h){

        CHECK_BUFFER_SIZE(src, src_end, 1, "image type");

        type = *src++;

        count = (type & 0x7F) + 1;

        type &= 0x80;

        if((x + count > w) && (x + count + 1 > (h - y) * w)){

            av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count);

            return -1;

        }

        if(type){

            CHECK_BUFFER_SIZE(src, src_end, depth, "image data");

        }else{

            CHECK_BUFFER_SIZE(src, src_end, count * depth, "image data");

        }

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

            switch(depth){

            case 1:

                *dst = *src;

                break;

            case 2:

                AV_WN16A(dst, AV_RN16A(src));

                break;

            case 3:

                dst[0] = src[0];

                dst[1] = src[1];

                dst[2] = src[2];

                break;

            case 4:

                AV_WN32A(dst, AV_RN32A(src));

                break;

            }

            dst += depth;

            if(!type)

                src += depth;

            x++;

            if(x == w){

                x = 0;

                y++;

                dst += diff;

            }

        }

        if(type)

            src += depth;

    }

    return src_size;

}


uint32_t pci_default_read_config(PCIDevice *d,

                                 uint32_t address, int len)

{

    uint32_t val = 0;

    assert(len == 1 || len == 2 || len == 4);

    len = MIN(len, pci_config_size(d) - address);

    memcpy(&val, d->config + address, len);

    return le32_to_cpu(val);

}


static void gen_rfci_40x(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    /* Restore CPU state */

    gen_helper_40x_rfci(cpu_env);

    gen_sync_exception(ctx);

#endif

}


static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,

                           uint8_t *buf, int buf_size)

{

    RTSPState *rt = s->priv_data;

    RTSPStream *rtsp_st;

    fd_set rfds;

    int fd, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;

    struct timeval tv;

    for (;;) {

        if (url_interrupt_cb())

            return AVERROR(EINTR);

        FD_ZERO(&rfds);

        if (rt->rtsp_hd) {

            tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);

            FD_SET(tcp_fd, &rfds);

        } else {

            fd_max = 0;

            tcp_fd = -1;

        }

        for (i = 0; i < rt->nb_rtsp_streams; i++) {

            rtsp_st = rt->rtsp_streams[i];

            if (rtsp_st->rtp_handle) {

                /* currently, we cannot probe RTCP handle because of

                 * blocking restrictions */

                fd = url_get_file_handle(rtsp_st->rtp_handle);

                if (fd > fd_max)

                    fd_max = fd;

                FD_SET(fd, &rfds);

            }

        }

        tv.tv_sec = 0;

        tv.tv_usec = SELECT_TIMEOUT_MS * 1000;

        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);

        if (n > 0) {

            timeout_cnt = 0;

            for (i = 0; i < rt->nb_rtsp_streams; i++) {

                rtsp_st = rt->rtsp_streams[i];

                if (rtsp_st->rtp_handle) {

                    fd = url_get_file_handle(rtsp_st->rtp_handle);

                    if (FD_ISSET(fd, &rfds)) {

                        ret = url_read(rtsp_st->rtp_handle, buf, buf_size);

                        if (ret > 0) {

                            *prtsp_st = rtsp_st;

                            return ret;

                        }

                    }

                }

            }

#if CONFIG_RTSP_DEMUXER

            if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {

                RTSPMessageHeader reply;

                ret = ff_rtsp_read_reply(s, &reply, NULL, 0);

                if (ret < 0)

                    return ret;

                /* XXX: parse message */

                if (rt->state != RTSP_STATE_STREAMING)

                    return 0;

            }

#endif

        } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {

            return FF_NETERROR(ETIMEDOUT);

        } else if (n < 0 && errno != EINTR)

            return AVERROR(errno);

    }

}


static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {

    AVCodecContext *acodec, *vcodec;

    ByteIOContext *ioc;

    AMFDataType amf_type;

    char str_val[256];

    double num_val;

    num_val = 0;

    ioc = s->pb;

    amf_type = get_byte(ioc);

    switch(amf_type) {

        case AMF_DATA_TYPE_NUMBER:

            num_val = av_int2dbl(get_be64(ioc)); break;

        case AMF_DATA_TYPE_BOOL:

            num_val = get_byte(ioc); break;

        case AMF_DATA_TYPE_STRING:

            if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)

                return -1;

            break;

        case AMF_DATA_TYPE_OBJECT: {

            unsigned int keylen;

            while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) {

                url_fskip(ioc, keylen); //skip key string

                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)

                    return -1; //if we couldn't skip, bomb out.

            }

            if(get_byte(ioc) != AMF_END_OF_OBJECT)

                return -1;

        }

            break;

        case AMF_DATA_TYPE_NULL:

        case AMF_DATA_TYPE_UNDEFINED:

        case AMF_DATA_TYPE_UNSUPPORTED:

            break; //these take up no additional space

        case AMF_DATA_TYPE_MIXEDARRAY:

            url_fskip(ioc, 4); //skip 32-bit max array index

            while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {

                //this is the only case in which we would want a nested parse to not skip over the object

                if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)

                    return -1;

            }

            if(get_byte(ioc) != AMF_END_OF_OBJECT)

                return -1;

            break;

        case AMF_DATA_TYPE_ARRAY: {

            unsigned int arraylen, i;

            arraylen = get_be32(ioc);

            for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) {

                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)

                    return -1; //if we couldn't skip, bomb out.

            }

        }

            break;

        case AMF_DATA_TYPE_DATE:

            url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)

            break;

        default: //unsupported type, we couldn't skip

            return -1;

    }

    if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL

        acodec = astream ? astream->codec : NULL;

        vcodec = vstream ? vstream->codec : NULL;

        if(amf_type == AMF_DATA_TYPE_BOOL) {

        } else if(amf_type == AMF_DATA_TYPE_NUMBER) {

            if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;

            else if(!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))

                vcodec->bit_rate = num_val * 1024.0;

        }

    }

    return 0;

}


static void mkv_write_simpletag(AVIOContext *pb, AVDictionaryEntry *t)

{

    uint8_t *key = av_strdup(t->key);

    uint8_t *p   = key;

    const uint8_t *lang = NULL;

    ebml_master tag;

    if ((p = strrchr(p, '-')) &&

        (lang = av_convert_lang_to(p + 1, AV_LANG_ISO639_2_BIBL)))

        *p = 0;

    p = key;

    while (*p) {

        if (*p == ' ')

            *p = '_';

        else if (*p >= 'a' && *p <= 'z')

            *p -= 'a' - 'A';

        p++;

    }

    tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0);

    put_ebml_string(pb, MATROSKA_ID_TAGNAME, key);

    if (lang)

        put_ebml_string(pb, MATROSKA_ID_TAGLANG, lang);

    put_ebml_string(pb, MATROSKA_ID_TAGSTRING, t->value);

    end_ebml_master(pb, tag);

    av_freep(&key);

}


static inline int decode_hrd_parameters(H264Context *h, SPS *sps)

{

    int cpb_count, i;

    cpb_count = get_ue_golomb_31(&h->gb) + 1;

    if (cpb_count > 32U) {

        av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);

        return AVERROR_INVALIDDATA;

    }

    get_bits(&h->gb, 4); /* bit_rate_scale */

    get_bits(&h->gb, 4); /* cpb_size_scale */

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

        get_ue_golomb_long(&h->gb); /* bit_rate_value_minus1 */

        get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */

        get_bits1(&h->gb);          /* cbr_flag */

    }

    sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;

    sps->cpb_removal_delay_length         = get_bits(&h->gb, 5) + 1;

    sps->dpb_output_delay_length          = get_bits(&h->gb, 5) + 1;

    sps->time_offset_length               = get_bits(&h->gb, 5);

    sps->cpb_cnt                          = cpb_count;

    return 0;

}


int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) {

    int i, j, t, rconpointer = 0;

    uint8_t tk[8][4];

    int KC= key_bits>>5;

    int rounds= KC + 6;

    uint8_t  log8[256];

    uint8_t alog8[512];

    if(!enc_multbl[4][1023]){

        j=1;

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

            alog8[i]=

            alog8[i+255]= j;

            log8[j]= i;

            j^= j+j;

            if(j>255) j^= 0x11B;

        }

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

            j= i ? alog8[255-log8[i]] : 0;

            j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4);

            j = (j ^ (j>>8) ^ 99) & 255;

            inv_sbox[j]= i;

            sbox    [i]= j;

        }

        init_multbl2(dec_multbl[0], (int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox);

        init_multbl2(enc_multbl[0], (int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox);

    }

    if(key_bits!=128 && key_bits!=192 && key_bits!=256)

        return -1;

    a->rounds= rounds;

    memcpy(tk, key, KC*4);

    for(t= 0; t < (rounds+1)*16;) {

        memcpy(a->round_key[0][0]+t, tk, KC*4);

        t+= KC*4;

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

            tk[0][i] ^= sbox[tk[KC-1][(i+1)&3]];

        tk[0][0] ^= rcon[rconpointer++];

        for(j = 1; j < KC; j++){

            if(KC != 8 || j != KC>>1)

                for(i = 0; i < 4; i++) tk[j][i] ^=      tk[j-1][i];

            else

                for(i = 0; i < 4; i++) tk[j][i] ^= sbox[tk[j-1][i]];

        }

    }

    if(decrypt){

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

            uint8_t tmp[3][16];

            memcpy(tmp[2], a->round_key[i][0], 16);

            subshift(tmp[1], 0, sbox);

            mix(tmp, dec_multbl, 1, 3);

            memcpy(a->round_key[i][0], tmp[0], 16);

        }

    }else{

        for(i=0; i<(rounds+1)>>1; i++){

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

                FFSWAP(int, a->round_key[i][0][j], a->round_key[rounds-i][0][j]);

        }

    }

    return 0;

}


static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)

{

    VideoData *s = s1->priv_data;

    AVStream *st;

    int video_fd;

    int desired_palette, desired_depth;

    struct video_tuner tuner;

    struct video_audio audio;

    struct video_picture pict;

    int j;

    int vformat_num = FF_ARRAY_ELEMS(video_formats);

    av_log(s1, AV_LOG_WARNING, "V4L input device is deprecated and will be removed in the next release.");

    if (ap->time_base.den <= 0) {

        av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den);

        return -1;

    }

    s->time_base = ap->time_base;

    s->video_win.width = ap->width;

    s->video_win.height = ap->height;

    st = avformat_new_stream(s1, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    video_fd = open(s1->filename, O_RDWR);

    if (video_fd < 0) {

        av_log(s1, AV_LOG_ERROR, "%s: %s\n", s1->filename, strerror(errno));

        goto fail;

    }

    if (ioctl(video_fd, VIDIOCGCAP, &s->video_cap) < 0) {

        av_log(s1, AV_LOG_ERROR, "VIDIOCGCAP: %s\n", strerror(errno));

        goto fail;

    }

    if (!(s->video_cap.type & VID_TYPE_CAPTURE)) {

        av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n");

        goto fail;

    }

    /* no values set, autodetect them */

    if (s->video_win.width <= 0 || s->video_win.height <= 0) {

        if (ioctl(video_fd, VIDIOCGWIN, &s->video_win, sizeof(s->video_win)) < 0) {

            av_log(s1, AV_LOG_ERROR, "VIDIOCGWIN: %s\n", strerror(errno));

            goto fail;

        }

    }

    if(av_image_check_size(s->video_win.width, s->video_win.height, 0, s1) < 0)

        return -1;

    desired_palette = -1;

    desired_depth = -1;

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

        if (ap->pix_fmt == video_formats[j].pix_fmt) {

            desired_palette = video_formats[j].palette;

            desired_depth = video_formats[j].depth;

            break;

        }

    }

    /* set tv standard */

    if (!ioctl(video_fd, VIDIOCGTUNER, &tuner)) {

        tuner.mode = s->standard;

        ioctl(video_fd, VIDIOCSTUNER, &tuner);

    }

    /* unmute audio */

    audio.audio = 0;

    ioctl(video_fd, VIDIOCGAUDIO, &audio);

    memcpy(&s->audio_saved, &audio, sizeof(audio));

    audio.flags &= ~VIDEO_AUDIO_MUTE;

    ioctl(video_fd, VIDIOCSAUDIO, &audio);

    ioctl(video_fd, VIDIOCGPICT, &pict);

    av_dlog(s1, "v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n",

            pict.colour, pict.hue, pict.brightness, pict.contrast, pict.whiteness);

    /* try to choose a suitable video format */

    pict.palette = desired_palette;

    pict.depth= desired_depth;

    if (desired_palette == -1 || ioctl(video_fd, VIDIOCSPICT, &pict) < 0) {

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

            pict.palette = video_formats[j].palette;

            pict.depth = video_formats[j].depth;

            if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict))

                break;

        }

        if (j >= vformat_num)

            goto fail1;

    }

    if (ioctl(video_fd, VIDIOCGMBUF, &s->gb_buffers) < 0) {

        /* try to use read based access */

        int val;

        s->video_win.x = 0;

        s->video_win.y = 0;

        s->video_win.chromakey = -1;

        s->video_win.flags = 0;

        if (ioctl(video_fd, VIDIOCSWIN, s->video_win) < 0) {

            av_log(s1, AV_LOG_ERROR, "VIDIOCSWIN: %s\n", strerror(errno));

            goto fail;

        }

        s->frame_format = pict.palette;

        val = 1;

        if (ioctl(video_fd, VIDIOCCAPTURE, &val) < 0) {

            av_log(s1, AV_LOG_ERROR, "VIDIOCCAPTURE: %s\n", strerror(errno));

            goto fail;

        }

        s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;

        s->use_mmap = 0;

    } else {

        s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, 0);

        if ((unsigned char*)-1 == s->video_buf) {

            s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_PRIVATE, video_fd, 0);

            if ((unsigned char*)-1 == s->video_buf) {

                av_log(s1, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));

                goto fail;

            }

        }

        s->gb_frame = 0;

        s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;

        /* start to grab the first frame */

        s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames;

        s->gb_buf.height = s->video_win.height;

        s->gb_buf.width = s->video_win.width;

        s->gb_buf.format = pict.palette;

        if (ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) {

            if (errno != EAGAIN) {

            fail1:

                av_log(s1, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno));

            } else {

                av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not receive any video signal\n");

            }

            goto fail;

        }

        for (j = 1; j < s->gb_buffers.frames; j++) {

          s->gb_buf.frame = j;

          ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf);

        }

        s->frame_format = s->gb_buf.format;

        s->use_mmap = 1;

    }

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

        if (s->frame_format == video_formats[j].palette) {

            s->frame_size = s->video_win.width * s->video_win.height * video_formats[j].depth / 8;

            st->codec->pix_fmt = video_formats[j].pix_fmt;

            break;

        }

    }

    if (j >= vformat_num)

        goto fail;

    s->fd = video_fd;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;

    st->codec->width = s->video_win.width;

    st->codec->height = s->video_win.height;

    st->codec->time_base = s->time_base;

    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;

    return 0;

 fail:

    if (video_fd >= 0)

        close(video_fd);

    return AVERROR(EIO);

}


int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)

{

    put_be32(pb, 0x14 ); /* size */

    put_tag(pb, "ftyp");

    if (!strcmp("3gp", s->oformat->name))

        put_tag(pb, "3gp4");

    else

        put_tag(pb, "isom");

    put_be32(pb, 0x200 );

    if (!strcmp("3gp", s->oformat->name))

        put_tag(pb, "3gp4");

    else

        put_tag(pb, "mp41");

    return 0x14;

}


int qemu_strtoul(const char *nptr, const char **endptr, int base,

                 unsigned long *result)

{

    char *p;

    int err = 0;

    if (!nptr) {

        if (endptr) {

            *endptr = nptr;

        }

        err = -EINVAL;

    } else {

        errno = 0;

        *result = strtoul(nptr, &p, base);

        err = check_strtox_error(endptr, p, errno);

    }

    return err;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->props = virtio_9p_properties;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

    vdc->realize = virtio_9p_device_realize;

    vdc->get_features = virtio_9p_get_features;

    vdc->get_config = virtio_9p_get_config;

}


static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2], int is34)

{

    int e, b, k;

    float (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11;

    float (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12;

    float (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21;

    float (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;

    int8_t *opd_hist = ps->opd_hist;

    int8_t *ipd_hist = ps->ipd_hist;

    int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf;

    int8_t (*icc_mapped)[PS_MAX_NR_IIDICC] = icc_mapped_buf;

    int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf;

    int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf;

    const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;

    TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;

    //Remapping

    if (ps->num_env_old) {

        memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0]));

        memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0]));

        memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0]));

        memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0]));

        memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0]));

        memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0]));

        memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0]));

        memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0]));

    }

    if (is34) {

        remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1);

        remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1);

        if (ps->enable_ipdopd) {

            remap34(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0);

            remap34(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0);

        }

        if (!ps->is34bands_old) {

            map_val_20_to_34(H11[0][0]);

            map_val_20_to_34(H11[1][0]);

            map_val_20_to_34(H12[0][0]);

            map_val_20_to_34(H12[1][0]);

            map_val_20_to_34(H21[0][0]);

            map_val_20_to_34(H21[1][0]);

            map_val_20_to_34(H22[0][0]);

            map_val_20_to_34(H22[1][0]);

            ipdopd_reset(ipd_hist, opd_hist);

        }

    } else {

        remap20(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1);

        remap20(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1);

        if (ps->enable_ipdopd) {

            remap20(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0);

            remap20(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0);

        }

        if (ps->is34bands_old) {

            map_val_34_to_20(H11[0][0]);

            map_val_34_to_20(H11[1][0]);

            map_val_34_to_20(H12[0][0]);

            map_val_34_to_20(H12[1][0]);

            map_val_34_to_20(H21[0][0]);

            map_val_34_to_20(H21[1][0]);

            map_val_34_to_20(H22[0][0]);

            map_val_34_to_20(H22[1][0]);

            ipdopd_reset(ipd_hist, opd_hist);

        }

    }

    //Mixing

    for (e = 0; e < ps->num_env; e++) {

        for (b = 0; b < NR_PAR_BANDS[is34]; b++) {

            float h11, h12, h21, h22;

            h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0];

            h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1];

            h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2];

            h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3];

            if (!PS_BASELINE && ps->enable_ipdopd && 2*b <= NR_PAR_BANDS[is34]) {

                //The spec say says to only run this smoother when enable_ipdopd

                //is set but the reference decoder appears to run it constantly

                float h11i, h12i, h21i, h22i;

                float ipd_adj_re, ipd_adj_im;

                int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b];

                int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b];

                float opd_re = pd_re_smooth[opd_idx];

                float opd_im = pd_im_smooth[opd_idx];

                float ipd_re = pd_re_smooth[ipd_idx];

                float ipd_im = pd_im_smooth[ipd_idx];

                opd_hist[b] = opd_idx & 0x3F;

                ipd_hist[b] = ipd_idx & 0x3F;

                ipd_adj_re = opd_re*ipd_re + opd_im*ipd_im;

                ipd_adj_im = opd_im*ipd_re - opd_re*ipd_im;

                h11i = h11 * opd_im;

                h11  = h11 * opd_re;

                h12i = h12 * ipd_adj_im;

                h12  = h12 * ipd_adj_re;

                h21i = h21 * opd_im;

                h21  = h21 * opd_re;

                h22i = h22 * ipd_adj_im;

                h22  = h22 * ipd_adj_re;

                H11[1][e+1][b] = h11i;

                H12[1][e+1][b] = h12i;

                H21[1][e+1][b] = h21i;

                H22[1][e+1][b] = h22i;

            }

            H11[0][e+1][b] = h11;

            H12[0][e+1][b] = h12;

            H21[0][e+1][b] = h21;

            H22[0][e+1][b] = h22;

        }

        for (k = 0; k < NR_BANDS[is34]; k++) {

            float h[2][4];

            float h_step[2][4];

            int start = ps->border_position[e];

            int stop  = ps->border_position[e+1];

            float width = 1.f / (stop - start);

            b = k_to_i[k];

            h[0][0] = H11[0][e][b];

            h[0][1] = H12[0][e][b];

            h[0][2] = H21[0][e][b];

            h[0][3] = H22[0][e][b];

            if (!PS_BASELINE && ps->enable_ipdopd) {

            //Is this necessary? ps_04_new seems unchanged

            if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) {

                h[1][0] = -H11[1][e][b];

                h[1][1] = -H12[1][e][b];

                h[1][2] = -H21[1][e][b];

                h[1][3] = -H22[1][e][b];

            } else {

                h[1][0] = H11[1][e][b];

                h[1][1] = H12[1][e][b];

                h[1][2] = H21[1][e][b];

                h[1][3] = H22[1][e][b];

            }

            }

            //Interpolation

            h_step[0][0] = (H11[0][e+1][b] - h[0][0]) * width;

            h_step[0][1] = (H12[0][e+1][b] - h[0][1]) * width;

            h_step[0][2] = (H21[0][e+1][b] - h[0][2]) * width;

            h_step[0][3] = (H22[0][e+1][b] - h[0][3]) * width;

            if (!PS_BASELINE && ps->enable_ipdopd) {

                h_step[1][0] = (H11[1][e+1][b] - h[1][0]) * width;

                h_step[1][1] = (H12[1][e+1][b] - h[1][1]) * width;

                h_step[1][2] = (H21[1][e+1][b] - h[1][2]) * width;

                h_step[1][3] = (H22[1][e+1][b] - h[1][3]) * width;

            }

            ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](

                l[k] + start + 1, r[k] + start + 1,

                h, h_step, stop - start);

        }

    }

}


static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,

                              unsigned len)

{

    OpenPICState *opp = opaque;

    IRQ_dst_t *dst;

    int idx;

    DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val);

    if (addr & 0xF)

        return;

    switch (addr) {

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

        break;

    case 0x40:

    case 0x50:

    case 0x60:

    case 0x70:

    case 0x80:

    case 0x90:

    case 0xA0:

    case 0xB0:

        openpic_cpu_write_internal(opp, addr, val, get_current_cpu());

        break;

    case 0x1000: /* FREP */

        break;

    case 0x1020: /* GLBC */

        if (val & GLBC_RESET) {

            openpic_reset(&opp->busdev.qdev);

        }

        break;

    case 0x1080: /* VENI */

        break;

    case 0x1090: /* PINT */

        for (idx = 0; idx < opp->nb_cpus; idx++) {

            if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) {

                DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx);

                dst = &opp->dst[idx];

                qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]);

            } else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) {

                DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx);

                dst = &opp->dst[idx];

                qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]);

            }

        }

        opp->pint = val;

        break;

    case 0x10A0: /* IPI_IPVP */

    case 0x10B0:

    case 0x10C0:

    case 0x10D0:

        {

            int idx;

            idx = (addr - 0x10A0) >> 4;

            write_IRQreg_ipvp(opp, opp->irq_ipi0 + idx, val);

        }

        break;

    case 0x10E0: /* SPVE */

        opp->spve = val & opp->vector_mask;

        break;

    default:

        break;

    }

}


static int decode_header(MPADecodeContext *s, uint32_t header)

{

    int sample_rate, frame_size, mpeg25, padding;

    int sample_rate_index, bitrate_index;

    if (header & (1<<20)) {

        s->lsf = (header & (1<<19)) ? 0 : 1;

        mpeg25 = 0;

    } else {

        s->lsf = 1;

        mpeg25 = 1;

    }

    s->layer = 4 - ((header >> 17) & 3);

    /* extract frequency */

    sample_rate_index = (header >> 10) & 3;

    sample_rate = mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);

    sample_rate_index += 3 * (s->lsf + mpeg25);

    s->sample_rate_index = sample_rate_index;

    s->error_protection = ((header >> 16) & 1) ^ 1;

    s->sample_rate = sample_rate;

    bitrate_index = (header >> 12) & 0xf;

    padding = (header >> 9) & 1;

    //extension = (header >> 8) & 1;

    s->mode = (header >> 6) & 3;

    s->mode_ext = (header >> 4) & 3;

    //copyright = (header >> 3) & 1;

    //original = (header >> 2) & 1;

    //emphasis = header & 3;

    if (s->mode == MPA_MONO)

        s->nb_channels = 1;

    else

        s->nb_channels = 2;

    if (bitrate_index != 0) {

        frame_size = mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];

        s->bit_rate = frame_size * 1000;

        switch(s->layer) {

        case 1:

            frame_size = (frame_size * 12000) / sample_rate;

            frame_size = (frame_size + padding) * 4;

            break;

        case 2:

            frame_size = (frame_size * 144000) / sample_rate;

            frame_size += padding;

            break;

        default:

        case 3:

            frame_size = (frame_size * 144000) / (sample_rate << s->lsf);

            frame_size += padding;

            break;

        }

        s->frame_size = frame_size;

    } else {

        /* if no frame size computed, signal it */

        if (!s->free_format_frame_size)

            return 1;

        /* free format: compute bitrate and real frame size from the

           frame size we extracted by reading the bitstream */

        s->frame_size = s->free_format_frame_size;

        switch(s->layer) {

        case 1:

            s->frame_size += padding  * 4;

            s->bit_rate = (s->frame_size * sample_rate) / 48000;

            break;

        case 2:

            s->frame_size += padding;

            s->bit_rate = (s->frame_size * sample_rate) / 144000;

            break;

        default:

        case 3:

            s->frame_size += padding;

            s->bit_rate = (s->frame_size * (sample_rate << s->lsf)) / 144000;

            break;

        }

    }

#if defined(DEBUG)

    dprintf("layer%d, %d Hz, %d kbits/s, ",

           s->layer, s->sample_rate, s->bit_rate);

    if (s->nb_channels == 2) {

        if (s->layer == 3) {

            if (s->mode_ext & MODE_EXT_MS_STEREO)

                dprintf("ms-");

            if (s->mode_ext & MODE_EXT_I_STEREO)

                dprintf("i-");

        }

        dprintf("stereo");

    } else {

        dprintf("mono");

    }

    dprintf("\n");

#endif

    return 0;

}


void HELPER(divs)(CPUM68KState *env, uint32_t word)

{

    int32_t num;

    int32_t den;

    int32_t quot;

    int32_t rem;

    num = env->div1;

    den = env->div2;

    if (den == 0) {

        raise_exception(env, EXCP_DIV0);

    }

    quot = num / den;

    rem = num % den;

    env->cc_v = (word && quot != (int16_t)quot ? -1 : 0);

    env->cc_z = quot;

    env->cc_n = quot;

    env->cc_c = 0;

    env->div1 = quot;

    env->div2 = rem;

}


static void dma_bdrv_cb(void *opaque, int ret)

{

    DMAAIOCB *dbs = (DMAAIOCB *)opaque;

    target_phys_addr_t cur_addr, cur_len;

    void *mem;

    dbs->acb = NULL;

    dbs->sector_num += dbs->iov.size / 512;

    dma_bdrv_unmap(dbs);

    qemu_iovec_reset(&dbs->iov);

    if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {

        dbs->common.cb(dbs->common.opaque, ret);

        qemu_iovec_destroy(&dbs->iov);

        qemu_aio_release(dbs);

        return;

    }

    while (dbs->sg_cur_index < dbs->sg->nsg) {

        cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;

        cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;

        mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->to_dev);

        if (!mem)

            break;

        qemu_iovec_add(&dbs->iov, mem, cur_len);

        dbs->sg_cur_byte += cur_len;

        if (dbs->sg_cur_byte == dbs->sg->sg[dbs->sg_cur_index].len) {

            dbs->sg_cur_byte = 0;

            ++dbs->sg_cur_index;

        }

    }

    if (dbs->iov.size == 0) {

        cpu_register_map_client(dbs, continue_after_map_failure);

        return;

    }

    dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov,

                            dbs->iov.size / 512, dma_bdrv_cb, dbs);

    if (!dbs->acb) {

        dma_bdrv_unmap(dbs);

        qemu_iovec_destroy(&dbs->iov);

        return;

    }

}


static uint64_t fw_cfg_data_mem_read(void *opaque, hwaddr addr,

                                     unsigned size)

{

    FWCfgState *s = opaque;

    uint8_t buf[8];

    unsigned i;

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

        buf[i] = fw_cfg_read(s);

    }

    switch (size) {

    case 1:

        return buf[0];

    case 2:

        return lduw_he_p(buf);

    case 4:

        return (uint32_t)ldl_he_p(buf);

    case 8:

        return ldq_he_p(buf);

    }

    abort();

}


static void test_redirector_rx(void)

{

#ifndef _WIN32

/* socketpair(PF_UNIX) which does not exist on windows */

    int backend_sock[2], send_sock;

    char *cmdline;

    uint32_t ret = 0, len = 0;

    char send_buf[] = "Hello!!";

    char sock_path0[] = "filter-redirector0.XXXXXX";

    char sock_path1[] = "filter-redirector1.XXXXXX";

    char *recv_buf;

    uint32_t size = sizeof(send_buf);

    size = htonl(size);

    ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);

    g_assert_cmpint(ret, !=, -1);

    ret = mkstemp(sock_path0);

    g_assert_cmpint(ret, !=, -1);

    ret = mkstemp(sock_path1);

    g_assert_cmpint(ret, !=, -1);

    cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "

                "-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "

                "-chardev socket,id=redirector0,path=%s,server,nowait "

                "-chardev socket,id=redirector1,path=%s,server,nowait "

                "-chardev socket,id=redirector2,path=%s,nowait "

                "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"

                "queue=rx,indev=redirector0 "

                "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"

                "queue=rx,outdev=redirector2 "

                "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"

                "queue=rx,indev=redirector1 "

                , backend_sock[1], sock_path0, sock_path1, sock_path0);

    qtest_start(cmdline);

    g_free(cmdline);

    struct iovec iov[] = {

        {

            .iov_base = &size,

            .iov_len = sizeof(size),

        }, {

            .iov_base = send_buf,

            .iov_len = sizeof(send_buf),

        },

    };

    send_sock = unix_connect(sock_path1, NULL);

    g_assert_cmpint(send_sock, !=, -1);

    /* send a qmp command to guarantee that 'connected' is setting to true. */

    qmp("{ 'execute' : 'query-status'}");

    ret = iov_send(send_sock, iov, 2, 0, sizeof(size) + sizeof(send_buf));

    g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));

    close(send_sock);

    ret = qemu_recv(backend_sock[0], &len, sizeof(len), 0);

    g_assert_cmpint(ret, ==, sizeof(len));

    len = ntohl(len);

    g_assert_cmpint(len, ==, sizeof(send_buf));

    recv_buf = g_malloc(len);

    ret = qemu_recv(backend_sock[0], recv_buf, len, 0);

    g_assert_cmpstr(recv_buf, ==, send_buf);

    g_free(recv_buf);

    unlink(sock_path0);

    unlink(sock_path1);

    qtest_end();

#endif

}


int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
                      target_phys_addr_t paddr, int prot,
                      int is_user, int is_softmmu)
{
    PhysPageDesc *p;
    unsigned long pd;
    unsigned int index;
    target_ulong address;
    target_phys_addr_t addend;
    int ret;
    CPUTLBEntry *te;
    int i;
    p = phys_page_find(paddr >> TARGET_PAGE_BITS);
    if (!p) {
        pd = IO_MEM_UNASSIGNED;
        pd = p->phys_offset;
#if defined(DEBUG_TLB)
    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
           vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
#endif
    ret = 0;
#if !defined(CONFIG_SOFTMMU)
    if (is_softmmu)
#endif
    {
        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
            /* IO memory case */
            address = vaddr | pd;
            addend = paddr;
            /* standard memory */
            address = vaddr;
            addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
        index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
        addend -= vaddr;
        te = &env->tlb_table[is_user][index];
        te->addend = addend;
        if (prot & PAGE_READ) {
            te->addr_read = address;
            te->addr_read = -1;
        if (prot & PAGE_EXEC) {
            te->addr_code = address;
            te->addr_code = -1;
        if (prot & PAGE_WRITE) {
            if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
                (pd & IO_MEM_ROMD)) {
                /* write access calls the I/O callback */
                te->addr_write = vaddr |
                    (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
            } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
                       !cpu_physical_memory_is_dirty(pd)) {
                te->addr_write = vaddr | IO_MEM_NOTDIRTY;
                te->addr_write = address;
            te->addr_write = -1;
#if !defined(CONFIG_SOFTMMU)
    else {
        if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
            /* IO access: no mapping is done as it will be handled by the
               soft MMU */
            if (!(env->hflags & HF_SOFTMMU_MASK))
                ret = 2;
            void *map_addr;
            if (vaddr >= MMAP_AREA_END) {
                ret = 2;
                if (prot & PROT_WRITE) {
                    if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
#if defined(TARGET_HAS_SMC) || 1
                        first_tb ||
#endif
                        ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
                         !cpu_physical_memory_is_dirty(pd))) {
                        /* ROM: we do as if code was inside */
                        /* if code is present, we only map as read only and save the
                           original mapping */
                        VirtPageDesc *vp;
                        vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
                        vp->phys_addr = pd;
                        vp->prot = prot;
                        vp->valid_tag = virt_valid_tag;
                        prot &= ~PAGE_WRITE;
                map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot,
                                MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
                if (map_addr == MAP_FAILED) {
                    cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
                              paddr, vaddr);
#endif
    return ret;


static void qed_aio_write_inplace(QEDAIOCB *acb, uint64_t offset, size_t len)

{

    /* Allocate buffer for zero writes */

    if (acb->flags & QED_AIOCB_ZERO) {

        struct iovec *iov = acb->qiov->iov;

        if (!iov->iov_base) {

            iov->iov_base = qemu_blockalign(acb->common.bs, iov->iov_len);

            memset(iov->iov_base, 0, iov->iov_len);

        }

    }

    /* Calculate the I/O vector */

    acb->cur_cluster = offset;

    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);

    /* Do the actual write */

    qed_aio_write_main(acb, 0);

}


static int dx2_decode_slice_rgb(GetBitContext *gb, AVFrame *frame,

                                int line, int left, uint8_t lru[3][8])

{

    int x, y;

    int width    = frame->width;

    int stride   = frame->linesize[0];

    uint8_t *dst = frame->data[0] + stride * line;

    for (y = 0; y < left && get_bits_left(gb) > 16; y++) {

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

            dst[x * 3 + 0] = decode_sym(gb, lru[0]);

            dst[x * 3 + 1] = decode_sym(gb, lru[1]);

            dst[x * 3 + 2] = decode_sym(gb, lru[2]);

        }

        dst += stride;

    }

    return y;

}


static int mjpeg_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              uint8_t *buf, int buf_size)

{

    MJpegDecodeContext *s = avctx->priv_data;

    uint8_t *buf_end, *buf_ptr;

    int i, start_code;

    AVPicture *picture = data;

    *data_size = 0;

    /* no supplementary picture */

    if (buf_size == 0)

        return 0;

    buf_ptr = buf;

    buf_end = buf + buf_size;

    while (buf_ptr < buf_end) {

        /* find start next marker */

        start_code = find_marker(&buf_ptr, buf_end);

	{

	    /* EOF */

            if (start_code < 0) {

		goto the_end;

            } else {

                dprintf("marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);

		if ((buf_end - buf_ptr) > s->buffer_size)

		{

		    av_free(s->buffer);

		    s->buffer_size = buf_end-buf_ptr;

		    s->buffer = av_malloc(s->buffer_size);

		    dprintf("buffer too small, expanding to %d bytes\n",

			s->buffer_size);

		}

		/* unescape buffer of SOS */

		if (start_code == SOS)

		{

		    uint8_t *src = buf_ptr;

		    uint8_t *dst = s->buffer;

		    while (src<buf_end)

		    {

			uint8_t x = *(src++);

			*(dst++) = x;

			if (x == 0xff)

			{

			    while(*src == 0xff) src++;

			    x = *(src++);

			    if (x >= 0xd0 && x <= 0xd7)

				*(dst++) = x;

			    else if (x)

				break;

			}

		    }

		    init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8);

		    dprintf("escaping removed %d bytes\n",

			(buf_end - buf_ptr) - (dst - s->buffer));

		}

		else

		    init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8);

		s->start_code = start_code;

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

                    printf("startcode: %X\n", start_code);

                }

		/* process markers */

		if (start_code >= 0xd0 && start_code <= 0xd7) {

		    dprintf("restart marker: %d\n", start_code&0x0f);

		} else if (s->first_picture) {

		    /* APP fields */

		    if (start_code >= 0xe0 && start_code <= 0xef)

			mjpeg_decode_app(s);

		    /* Comment */

		    else if (start_code == COM)

			mjpeg_decode_com(s);

		}

                switch(start_code) {

                case SOI:

		    s->restart_interval = 0;

                    /* nothing to do on SOI */

                    break;

                case DQT:

                    mjpeg_decode_dqt(s);

                    break;

                case DHT:

                    mjpeg_decode_dht(s);

                    break;

                case SOF0:

                    s->lossless=0;

                    if (mjpeg_decode_sof(s) < 0)

			return -1;

                    break;

                case SOF3:

                    s->lossless=1;

                    if (mjpeg_decode_sof(s) < 0)

			return -1;

                    break;

		case EOI:

eoi_parser:

		    {

                        if (s->interlaced) {

                            s->bottom_field ^= 1;

                            /* if not bottom field, do not output image yet */

                            if (s->bottom_field)

                                goto not_the_end;

                        }

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

                            picture->data[i] = s->current_picture[i];

			    picture->linesize[i] = (s->interlaced) ?

				s->linesize[i] >> 1 : s->linesize[i];

                        }

                        *data_size = sizeof(AVPicture);

                        avctx->height = s->height;

                        if (s->interlaced)

                            avctx->height *= 2;

                        avctx->width = s->width;

                        /* XXX: not complete test ! */

                        switch((s->h_count[0] << 4) | s->v_count[0]) {

                        case 0x11:

                            if(s->rgb){

                                avctx->pix_fmt = PIX_FMT_RGBA32;

                            }else

                                avctx->pix_fmt = PIX_FMT_YUV444P;

                            break;

                        case 0x21:

                            avctx->pix_fmt = PIX_FMT_YUV422P;

                            break;

                        default:

                        case 0x22:

                            avctx->pix_fmt = PIX_FMT_YUV420P;

                            break;

                        }

                        /* dummy quality */

                        /* XXX: infer it with matrix */

//                    	avctx->quality = 3;

                        goto the_end;

                    }

		    break;

                case SOS:

                    mjpeg_decode_sos(s);

		    /* buggy avid puts EOI every 10-20th frame */

		    /* if restart period is over process EOI */

		    if ((s->buggy_avid && !s->interlaced) || s->restart_interval)

			goto eoi_parser;

                    break;

		case DRI:

		    mjpeg_decode_dri(s);

		    break;

		case SOF1:

		case SOF2:

		case SOF5:

		case SOF6:

		case SOF7:

		case SOF9:

		case SOF10:

		case SOF11:

		case SOF13:

		case SOF14:

		case SOF15:

		case JPG:

		    printf("mjpeg: unsupported coding type (%x)\n", start_code);

		    break;

//		default:

//		    printf("mjpeg: unsupported marker (%x)\n", start_code);

//		    break;

                }

not_the_end:

		/* eof process start code */

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

		dprintf("marker parser used %d bytes (%d bits)\n",

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

            }

        }

    }

the_end:

    dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);

//    return buf_end - buf_ptr;

    return buf_ptr - buf;

}


static void do_ext_interrupt(CPUS390XState *env)

{

    S390CPU *cpu = s390_env_get_cpu(env);

    uint64_t mask, addr;

    LowCore *lowcore;

    ExtQueue *q;

    if (!(env->psw.mask & PSW_MASK_EXT)) {

        cpu_abort(CPU(cpu), "Ext int w/o ext mask\n");

    }

    if (env->ext_index < 0 || env->ext_index > MAX_EXT_QUEUE) {

        cpu_abort(CPU(cpu), "Ext queue overrun: %d\n", env->ext_index);

    }

    q = &env->ext_queue[env->ext_index];

    lowcore = cpu_map_lowcore(env);

    lowcore->ext_int_code = cpu_to_be16(q->code);

    lowcore->ext_params = cpu_to_be32(q->param);

    lowcore->ext_params2 = cpu_to_be64(q->param64);

    lowcore->external_old_psw.mask = cpu_to_be64(get_psw_mask(env));

    lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);

    lowcore->cpu_addr = cpu_to_be16(env->cpu_num | VIRTIO_SUBCODE_64);

    mask = be64_to_cpu(lowcore->external_new_psw.mask);

    addr = be64_to_cpu(lowcore->external_new_psw.addr);

    cpu_unmap_lowcore(lowcore);

    env->ext_index--;

    if (env->ext_index == -1) {

        env->pending_int &= ~INTERRUPT_EXT;

    }

    DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,

            env->psw.mask, env->psw.addr);

    load_psw(env, mask, addr);

}


static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,

                                        hwaddr base,

                                        qemu_irq timerirq, qemu_irq alarmirq,

                                        omap_clk clk)

{

    struct omap_rtc_s *s = (struct omap_rtc_s *)

            g_malloc0(sizeof(struct omap_rtc_s));

    s->irq = timerirq;

    s->alarm = alarmirq;

    s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);

    omap_rtc_reset(s);

    memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,

                          "omap-rtc", 0x800);

    memory_region_add_subregion(system_memory, base, &s->iomem);

    return s;

}


static void gen_mtmsrd(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

        return;

    }

    if (ctx->opcode & 0x00010000) {

        /* Special form that does not need any synchronisation */

        TCGv t0 = tcg_temp_new();

        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));

        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));

        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);

        tcg_temp_free(t0);

    } else {

        /* XXX: we need to update nip before the store

         *      if we enter power saving mode, we will exit the loop

         *      directly from ppc_store_msr

         */

        gen_update_nip(ctx, ctx->nip);

        gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);

        /* Must stop the translation as machine state (may have) changed */

        /* Note that mtmsr is not always defined as context-synchronizing */

        gen_stop_exception(ctx);

    }

#endif

}