int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)

{

    int i, count, ret, read_size, j;

    AVStream *st;

    AVPacket pkt1, *pkt;

    int64_t old_offset = avio_tell(ic->pb);

    int orig_nb_streams = ic->nb_streams;        // new streams might appear, no options for those

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

        AVCodec *codec;

        AVDictionary *thread_opt = NULL;

        st = ic->streams[i];

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

            st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {

/*            if(!st->time_base.num)

                st->time_base= */

            if(!st->codec->time_base.num)

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

        }

        //only for the split stuff

        if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) {

            st->parser = av_parser_init(st->codec->codec_id);

            if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){

                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;

            }

        }

        assert(!st->codec->codec);

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

        /* force thread count to 1 since the h264 decoder will not extract SPS

         *  and PPS to extradata during multi-threaded decoding */

        av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0);

        /* Ensure that subtitle_header is properly set. */

        if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE

            && codec && !st->codec->codec)

            avcodec_open2(st->codec, codec, options ? &options[i]

                              : &thread_opt);

        //try to just open decoders, in case this is enough to get parameters

        if(!has_codec_parameters(st->codec)){

            if (codec && !st->codec->codec)

                avcodec_open2(st->codec, codec, options ? &options[i]

                              : &thread_opt);

        }

        if (!options)

            av_dict_free(&thread_opt);

    }

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

        ic->streams[i]->info->last_dts = AV_NOPTS_VALUE;

    }

    count = 0;

    read_size = 0;

    for(;;) {

        if (ff_check_interrupt(&ic->interrupt_callback)){

            ret= AVERROR_EXIT;

            av_log(ic, AV_LOG_DEBUG, "interrupted\n");

            break;

        }

        /* check if one codec still needs to be handled */

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

            int fps_analyze_framecount = 20;

            st = ic->streams[i];

            if (!has_codec_parameters(st->codec))

                break;

            /* if the timebase is coarse (like the usual millisecond precision

               of mkv), we need to analyze more frames to reliably arrive at

               the correct fps */

            if (av_q2d(st->time_base) > 0.0005)

                fps_analyze_framecount *= 2;

            if (ic->fps_probe_size >= 0)

                fps_analyze_framecount = ic->fps_probe_size;

            /* variable fps and no guess at the real fps */

            if(   tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)

               && st->info->duration_count < fps_analyze_framecount

               && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

                break;

            if(st->parser && st->parser->parser->split && !st->codec->extradata)

                break;

            if(st->first_dts == AV_NOPTS_VALUE)

                break;

        }

        if (i == ic->nb_streams) {

            /* NOTE: if the format has no header, then we need to read

               some packets to get most of the streams, so we cannot

               stop here */

            if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {

                /* if we found the info for all the codecs, we can stop */

                ret = count;

                av_log(ic, AV_LOG_DEBUG, "All info found\n");

                break;

            }

        }

        /* we did not get all the codec info, but we read too much data */

        if (read_size >= ic->probesize) {

            ret = count;

            av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit %d reached\n", ic->probesize);

            break;

        }

        /* NOTE: a new stream can be added there if no header in file

           (AVFMTCTX_NOHEADER) */

        ret = read_frame_internal(ic, &pkt1);

        if (ret == AVERROR(EAGAIN))

            continue;

        if (ret < 0) {

            /* EOF or error*/

            AVPacket empty_pkt = { 0 };

            int err;

            av_init_packet(&empty_pkt);

            ret = -1; /* we could not have all the codec parameters before EOF */

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

                st = ic->streams[i];

                /* flush the decoders */

                do {

                    err = try_decode_frame(st, &empty_pkt,

                                           (options && i < orig_nb_streams) ?

                                           &options[i] : NULL);

                } while (err > 0 && !has_codec_parameters(st->codec));

                if (err < 0) {

                    av_log(ic, AV_LOG_WARNING,

                           "decoding for stream %d failed\n", st->index);

                } else if (!has_codec_parameters(st->codec)){

                    char buf[256];

                    avcodec_string(buf, sizeof(buf), st->codec, 0);

                    av_log(ic, AV_LOG_WARNING,

                           "Could not find codec parameters (%s)\n", buf);

                } else {

                    ret = 0;

                }

            }

            break;

        }

        pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);

        if ((ret = av_dup_packet(pkt)) < 0)

            goto find_stream_info_err;

        read_size += pkt->size;

        st = ic->streams[pkt->stream_index];

        if (st->codec_info_nb_frames>1) {

            if (st->time_base.den > 0 && av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {

                av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");

                break;

            }

            st->info->codec_info_duration += pkt->duration;

        }

        {

            int64_t last = st->info->last_dts;

            if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){

                int64_t duration= pkt->dts - last;

                double dur= duration * av_q2d(st->time_base);

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

//                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);

                if (st->info->duration_count < 2)

                    memset(st->info->duration_error, 0, sizeof(st->info->duration_error));

                for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {

                    int framerate= get_std_framerate(i);

                    int ticks= lrintf(dur*framerate/(1001*12));

                    double error = dur - (double)ticks*1001*12 / framerate;

                    st->info->duration_error[i] += error*error;

                }

                st->info->duration_count++;

                // ignore the first 4 values, they might have some random jitter

                if (st->info->duration_count > 3)

                    st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration);

            }

            if (last == AV_NOPTS_VALUE || st->info->duration_count <= 1)

                st->info->last_dts = pkt->dts;

        }

        if(st->parser && st->parser->parser->split && !st->codec->extradata){

            int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);

            if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {

                st->codec->extradata_size= i;

                st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);

                if (!st->codec->extradata)

                    return AVERROR(ENOMEM);

                memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);

                memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);

            }

        }

        /* if still no information, we try to open the codec and to

           decompress the frame. We try to avoid that in most cases as

           it takes longer and uses more memory. For MPEG-4, we need to

           decompress for QuickTime.

           If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at

           least one frame of codec data, this makes sure the codec initializes

           the channel configuration and does not only trust the values from the container.

        */

        try_decode_frame(st, pkt, (options && i < orig_nb_streams ) ? &options[i] : NULL);

        st->codec_info_nb_frames++;

        count++;

    }

    // close codecs which were opened in try_decode_frame()

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

        st = ic->streams[i];

        if(st->codec->codec)

            avcodec_close(st->codec);

    }

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

        st = ic->streams[i];

        if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration)

            av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,

                     (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,

                      st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);

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

            // the check for tb_unreliable() is not completely correct, since this is not about handling

            // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.

            // ipmovie.c produces.

            if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)

                av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);

            if (st->info->duration_count && !st->r_frame_rate.num

               && tb_unreliable(st->codec) /*&&

               //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...

               st->time_base.num*duration_sum[i]/st->info->duration_count*101LL > st->time_base.den*/){

                int num = 0;

                double best_error= 2*av_q2d(st->time_base);

                best_error = best_error*best_error*st->info->duration_count*1000*12*30;

                for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {

                    double error = st->info->duration_error[j] * get_std_framerate(j);

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

//                        av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);

                    if(error < best_error){

                        best_error= error;

                        num = get_std_framerate(j);

                    }

                }

                // do not increase frame rate by more than 1 % in order to match a standard rate.

                if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))

                    av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);

            }

            if (!st->r_frame_rate.num){

                if(    st->codec->time_base.den * (int64_t)st->time_base.num

                    <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){

                    st->r_frame_rate.num = st->codec->time_base.den;

                    st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame;

                }else{

                    st->r_frame_rate.num = st->time_base.den;

                    st->r_frame_rate.den = st->time_base.num;

                }

            }

        }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

            if(!st->codec->bits_per_coded_sample)

                st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);

            // set stream disposition based on audio service type

            switch (st->codec->audio_service_type) {

            case AV_AUDIO_SERVICE_TYPE_EFFECTS:

                st->disposition = AV_DISPOSITION_CLEAN_EFFECTS;    break;

            case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:

                st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED;  break;

            case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:

                st->disposition = AV_DISPOSITION_HEARING_IMPAIRED; break;

            case AV_AUDIO_SERVICE_TYPE_COMMENTARY:

                st->disposition = AV_DISPOSITION_COMMENT;          break;

            case AV_AUDIO_SERVICE_TYPE_KARAOKE:

                st->disposition = AV_DISPOSITION_KARAOKE;          break;

            }

        }

    }

    estimate_timings(ic, old_offset);

    compute_chapters_end(ic);

#if 0

    /* correct DTS for B-frame streams with no timestamps */

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

        st = ic->streams[i];

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

            if(b-frames){

                ppktl = &ic->packet_buffer;

                while(ppkt1){

                    if(ppkt1->stream_index != i)

                        continue;

                    if(ppkt1->pkt->dts < 0)

                        break;

                    if(ppkt1->pkt->pts != AV_NOPTS_VALUE)

                        break;

                    ppkt1->pkt->dts -= delta;

                    ppkt1= ppkt1->next;

                }

                if(ppkt1)

                    continue;

                st->cur_dts -= delta;

            }

        }

    }

#endif

 find_stream_info_err:

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

        if (ic->streams[i]->codec)

            ic->streams[i]->codec->thread_count = 0;

        av_freep(&ic->streams[i]->info);

    }

    return ret;

}


static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)

{

    ppc4xx_sdram_t *sdram;

    sdram = opaque;

    switch (dcrn) {

    case SDRAM0_CFGADDR:

        sdram->addr = val;

        break;

    case SDRAM0_CFGDATA:

        switch (sdram->addr) {

        case 0x00: /* SDRAM_BESR0 */

            sdram->besr0 &= ~val;

            break;

        case 0x08: /* SDRAM_BESR1 */

            sdram->besr1 &= ~val;

            break;

        case 0x10: /* SDRAM_BEAR */

            sdram->bear = val;

            break;

        case 0x20: /* SDRAM_CFG */

            val &= 0xFFE00000;

            if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {

#ifdef DEBUG_SDRAM

                printf("%s: enable SDRAM controller\n", __func__);

#endif

                /* validate all RAM mappings */

                sdram_map_bcr(sdram);

                sdram->status &= ~0x80000000;

            } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {

#ifdef DEBUG_SDRAM

                printf("%s: disable SDRAM controller\n", __func__);

#endif

                /* invalidate all RAM mappings */

                sdram_unmap_bcr(sdram);

                sdram->status |= 0x80000000;

            }

            if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))

                sdram->status |= 0x40000000;

            else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))

                sdram->status &= ~0x40000000;

            sdram->cfg = val;

            break;

        case 0x24: /* SDRAM_STATUS */

            /* Read-only register */

            break;

        case 0x30: /* SDRAM_RTR */

            sdram->rtr = val & 0x3FF80000;

            break;

        case 0x34: /* SDRAM_PMIT */

            sdram->pmit = (val & 0xF8000000) | 0x07C00000;

            break;

        case 0x40: /* SDRAM_B0CR */

            sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);

            break;

        case 0x44: /* SDRAM_B1CR */

            sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);

            break;

        case 0x48: /* SDRAM_B2CR */

            sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);

            break;

        case 0x4C: /* SDRAM_B3CR */

            sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);

            break;

        case 0x80: /* SDRAM_TR */

            sdram->tr = val & 0x018FC01F;

            break;

        case 0x94: /* SDRAM_ECCCFG */

            sdram->ecccfg = val & 0x00F00000;

            break;

        case 0x98: /* SDRAM_ECCESR */

            val &= 0xFFF0F000;

            if (sdram->eccesr == 0 && val != 0)

                qemu_irq_raise(sdram->irq);

            else if (sdram->eccesr != 0 && val == 0)

                qemu_irq_lower(sdram->irq);

            sdram->eccesr = val;

            break;

        default: /* Error */

            break;

        }

        break;

    }

}


void object_property_add_alias(Object *obj, const char *name,

                               Object *target_obj, const char *target_name,

                               Error **errp)

{

    AliasProperty *prop;

    ObjectProperty *target_prop;

    target_prop = object_property_find(target_obj, target_name, errp);

    if (!target_prop) {

        return;

    }

    prop = g_malloc(sizeof(*prop));

    prop->target_obj = target_obj;

    prop->target_name = target_name;

    object_property_add(obj, name, target_prop->type,

                        property_get_alias,

                        property_set_alias,

                        property_release_alias,

                        prop, errp);

}


static inline int tcg_global_reg_new_internal(TCGType type, int reg,

                                              const char *name)

{

    TCGContext *s = &tcg_ctx;

    TCGTemp *ts;

    int idx;

#if TCG_TARGET_REG_BITS == 32

    if (type != TCG_TYPE_I32)

        tcg_abort();

#endif

    if (tcg_regset_test_reg(s->reserved_regs, reg))

        tcg_abort();

    idx = s->nb_globals;

    tcg_temp_alloc(s, s->nb_globals + 1);

    ts = &s->temps[s->nb_globals];

    ts->base_type = type;

    ts->type = type;

    ts->fixed_reg = 1;

    ts->reg = reg;

    ts->name = name;

    s->nb_globals++;

    tcg_regset_set_reg(s->reserved_regs, reg);

    return idx;

}


static SocketAddressLegacy *sd_socket_address(const char *path,

                                        const char *host, const char *port)

{

    SocketAddressLegacy *addr = g_new0(SocketAddressLegacy, 1);

    if (path) {

        addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;

        addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);

        addr->u.q_unix.data->path = g_strdup(path);

    } else {

        addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;

        addr->u.inet.data = g_new0(InetSocketAddress, 1);

        addr->u.inet.data->host = g_strdup(host ?: SD_DEFAULT_ADDR);

        addr->u.inet.data->port = g_strdup(port ?: stringify(SD_DEFAULT_PORT));

    }

    return addr;

}


void tcg_target_init(TCGContext *s)

{

    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);

#endif

    tcg_regset_set32(tcg_target_call_clobber_regs, 0,

                     (1 << TCG_REG_G1) |

                     (1 << TCG_REG_G2) |

                     (1 << TCG_REG_G3) |

                     (1 << TCG_REG_G4) |

                     (1 << TCG_REG_G5) |

                     (1 << TCG_REG_G6) |

                     (1 << TCG_REG_G7) |

                     (1 << TCG_REG_O0) |

                     (1 << TCG_REG_O1) |

                     (1 << TCG_REG_O2) |

                     (1 << TCG_REG_O3) |

                     (1 << TCG_REG_O4) |

                     (1 << TCG_REG_O5) |

                     (1 << TCG_REG_O7));

    tcg_regset_clear(s->reserved_regs);

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use

#endif

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);

    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);

    tcg_add_target_add_op_defs(sparc_op_defs);

}


int kvm_has_sync_mmu(void)

{

    return kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU);

}


static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)

{

    int sx = 0, sy = 0;

    int dx = 0, dy = 0;

    int depth = 0;

    int notify = 0;

    /* make sure to only copy if it's a plain copy ROP */

    if (*s->cirrus_rop == cirrus_bitblt_rop_fwd_src ||

        *s->cirrus_rop == cirrus_bitblt_rop_bkwd_src) {

        int width, height;

        depth = s->vga.get_bpp(&s->vga) / 8;

        s->vga.get_resolution(&s->vga, &width, &height);

        /* extra x, y */

        sx = (src % ABS(s->cirrus_blt_srcpitch)) / depth;

        sy = (src / ABS(s->cirrus_blt_srcpitch));

        dx = (dst % ABS(s->cirrus_blt_dstpitch)) / depth;

        dy = (dst / ABS(s->cirrus_blt_dstpitch));

        /* normalize width */

        w /= depth;

        /* if we're doing a backward copy, we have to adjust

           our x/y to be the upper left corner (instead of the lower

           right corner) */

        if (s->cirrus_blt_dstpitch < 0) {

            sx -= (s->cirrus_blt_width / depth) - 1;

            dx -= (s->cirrus_blt_width / depth) - 1;

            sy -= s->cirrus_blt_height - 1;

            dy -= s->cirrus_blt_height - 1;

        }

        /* are we in the visible portion of memory? */

        if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 &&

            (sx + w) <= width && (sy + h) <= height &&

            (dx + w) <= width && (dy + h) <= height) {

            notify = 1;

        }

    }

    /* we have to flush all pending changes so that the copy

       is generated at the appropriate moment in time */

    if (notify)

        graphic_hw_update(s->vga.con);

    (*s->cirrus_rop) (s, s->vga.vram_ptr +

		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),

		      s->vga.vram_ptr +

		      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),

		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,

		      s->cirrus_blt_width, s->cirrus_blt_height);

    if (notify) {

        qemu_console_copy(s->vga.con,

			  sx, sy, dx, dy,

			  s->cirrus_blt_width / depth,

			  s->cirrus_blt_height);

    }

    /* we don't have to notify the display that this portion has

       changed since qemu_console_copy implies this */

    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,

				s->cirrus_blt_dstpitch, s->cirrus_blt_width,

				s->cirrus_blt_height);

}


static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    PICCommonState *s = opaque;

    int ret;

    if (s->poll) {

        ret = pic_get_irq(s);

        if (ret >= 0) {

            pic_intack(s, ret);

            ret |= 0x80;

        } else {

            ret = 0;

        }

        s->poll = 0;

    } else {

        if (addr == 0) {

            if (s->read_reg_select) {

                ret = s->isr;

            } else {

                ret = s->irr;

            }

        } else {

            ret = s->imr;

        }

    }

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

    return ret;

}


ChardevReturn *qmp_chardev_add(const char *id, ChardevBackend *backend,

                               Error **errp)

{

    ChardevReturn *ret = g_new0(ChardevReturn, 1);

    CharDriverState *base, *chr = NULL;

    chr = qemu_chr_find(id);

    if (chr) {

        error_setg(errp, "Chardev '%s' already exists", id);

        g_free(ret);

        return NULL;

    }

    switch (backend->kind) {

    case CHARDEV_BACKEND_KIND_FILE:

        chr = qmp_chardev_open_file(backend->file, errp);

        break;

    case CHARDEV_BACKEND_KIND_SERIAL:

        chr = qmp_chardev_open_serial(backend->serial, errp);

        break;

    case CHARDEV_BACKEND_KIND_PARALLEL:

        chr = qmp_chardev_open_parallel(backend->parallel, errp);

        break;

    case CHARDEV_BACKEND_KIND_SOCKET:

        chr = qmp_chardev_open_socket(backend->socket, errp);

        break;

#ifdef HAVE_CHARDEV_TTY

    case CHARDEV_BACKEND_KIND_PTY:

    {

        /* qemu_chr_open_pty sets "path" in opts */

        QemuOpts *opts;

        opts = qemu_opts_create_nofail(qemu_find_opts("chardev"));

        chr = qemu_chr_open_pty(opts);

        ret->pty = g_strdup(qemu_opt_get(opts, "path"));

        ret->has_pty = true;

        qemu_opts_del(opts);

        break;

    }

#endif

    case CHARDEV_BACKEND_KIND_NULL:

        chr = qemu_chr_open_null();

        break;

    case CHARDEV_BACKEND_KIND_MUX:

        base = qemu_chr_find(backend->mux->chardev);

        if (base == NULL) {

            error_setg(errp, "mux: base chardev %s not found",

                       backend->mux->chardev);

            break;

        }

        chr = qemu_chr_open_mux(base);

        break;

    case CHARDEV_BACKEND_KIND_MSMOUSE:

        chr = qemu_chr_open_msmouse();

        break;

#ifdef CONFIG_BRLAPI

    case CHARDEV_BACKEND_KIND_BRAILLE:

        chr = chr_baum_init();

        break;

#endif

    case CHARDEV_BACKEND_KIND_STDIO:

        chr = qemu_chr_open_stdio(backend->stdio);

        break;

    default:

        error_setg(errp, "unknown chardev backend (%d)", backend->kind);

        break;

    }

    if (chr == NULL && !error_is_set(errp)) {

        error_setg(errp, "Failed to create chardev");

    }

    if (chr) {

        chr->label = g_strdup(id);

        chr->avail_connections =

            (backend->kind == CHARDEV_BACKEND_KIND_MUX) ? MAX_MUX : 1;

        QTAILQ_INSERT_TAIL(&chardevs, chr, next);

        return ret;

    } else {

        g_free(ret);

        return NULL;

    }

}


static int pbm_pci_host_init(PCIDevice *d)

{

    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);

    pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);

    pci_set_word(d->config + PCI_COMMAND,

                 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

    pci_set_word(d->config + PCI_STATUS,

                 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |

                 PCI_STATUS_DEVSEL_MEDIUM);

    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);

    return 0;

}


static int32_t read_s32(uint8_t *data, size_t offset)

{

    return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |

		     (data[offset + 2] << 8) | data[offset + 3]);

}


CPUSPARCState *cpu_sparc_init(void)

{

    CPUSPARCState *env;

    cpu_exec_init();

    if (!(env = malloc(sizeof(CPUSPARCState))))

	return (NULL);

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

    env->cwp = 0;

    env->wim = 1;

    env->regwptr = env->regbase + (env->cwp * 16);

    env->access_type = ACCESS_DATA;

#if defined(CONFIG_USER_ONLY)

    env->user_mode_only = 1;

#else

    /* Emulate Prom */

    env->psrs = 1;

    env->pc = 0x4000;

    env->npc = env->pc + 4;

    env->mmuregs[0] = (0x10<<24) | MMU_E; /* Impl 1, ver 0, MMU Enabled */

    env->mmuregs[1] = 0x3000 >> 4; /* MMU Context table */

#endif

    cpu_single_env = env;

    return (env);

}


void timer_init_tl(QEMUTimer *ts,

                   QEMUTimerList *timer_list, int scale,

                   QEMUTimerCB *cb, void *opaque)

{

    ts->timer_list = timer_list;

    ts->cb = cb;

    ts->opaque = opaque;

    ts->scale = scale;

    ts->expire_time = -1;

}


static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)

{

    VirtIONet *n = VIRTIO_NET(vdev);

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

    features |= (1 << VIRTIO_NET_F_MAC);

    if (!peer_has_vnet_hdr(n)) {

        features &= ~(0x1 << VIRTIO_NET_F_CSUM);

        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);

        features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);

        features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);

        features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);

        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);

        features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);

        features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);

    }

    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {

        features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);

        features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);

    }

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

        return features;

    }

    return vhost_net_get_features(get_vhost_net(nc->peer), features);

}


static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tracks, int num_tracks)

{

    MatroskaMuxContext *mkv = s->priv_data;

    AVIOContext *dyn_cp, *pb = s->pb;

    ebml_master cues_element;

    int64_t currentpos;

    int i, j, ret;

    currentpos = avio_tell(pb);

    ret = start_ebml_master_crc32(pb, &dyn_cp, &cues_element, MATROSKA_ID_CUES, 0);

    if (ret < 0)

        return ret;

    for (i = 0; i < cues->num_entries; i++) {

        ebml_master cuepoint, track_positions;

        mkv_cuepoint *entry = &cues->entries[i];

        uint64_t pts = entry->pts;

        int ctp_nb = 0;

        // Calculate the number of entries, so we know the element size

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

            tracks[j].has_cue = 0;

        for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {

            int tracknum = entry[j].stream_idx;

            av_assert0(tracknum>=0 && tracknum<num_tracks);

            if (tracks[tracknum].has_cue && s->streams[tracknum]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)

                continue;

            tracks[tracknum].has_cue = 1;

            ctp_nb ++;

        }

        cuepoint = start_ebml_master(dyn_cp, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(ctp_nb));

        put_ebml_uint(dyn_cp, MATROSKA_ID_CUETIME, pts);

        // put all the entries from different tracks that have the exact same

        // timestamp into the same CuePoint

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

            tracks[j].has_cue = 0;

        for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {

            int tracknum = entry[j].stream_idx;

            av_assert0(tracknum>=0 && tracknum<num_tracks);

            if (tracks[tracknum].has_cue && s->streams[tracknum]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)

                continue;

            tracks[tracknum].has_cue = 1;

            track_positions = start_ebml_master(dyn_cp, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);

            put_ebml_uint(dyn_cp, MATROSKA_ID_CUETRACK           , entry[j].tracknum   );

            put_ebml_uint(dyn_cp, MATROSKA_ID_CUECLUSTERPOSITION , entry[j].cluster_pos);

            put_ebml_uint(dyn_cp, MATROSKA_ID_CUERELATIVEPOSITION, entry[j].relative_pos);

            if (entry[j].duration != -1)

                put_ebml_uint(dyn_cp, MATROSKA_ID_CUEDURATION    , entry[j].duration);

            end_ebml_master(dyn_cp, track_positions);

        }

        i += j - 1;

        end_ebml_master(dyn_cp, cuepoint);

    }

    end_ebml_master_crc32(pb, &dyn_cp, mkv, cues_element);

    return currentpos;

}


av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,

                                 const VAAPIEncodeType *type)

{

    VAAPIEncodeContext *ctx = avctx->priv_data;

    AVVAAPIFramesContext *recon_hwctx = NULL;

    AVVAAPIHWConfig *hwconfig = NULL;

    AVHWFramesConstraints *constraints = NULL;

    enum AVPixelFormat recon_format;

    VAStatus vas;

    int err, i;

    if (!avctx->hw_frames_ctx) {

        av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "

               "required to associate the encoding device.\n");

        return AVERROR(EINVAL);

    }

    ctx->codec = type;

    ctx->codec_options = ctx->codec_options_data;

    ctx->va_config  = VA_INVALID_ID;

    ctx->va_context = VA_INVALID_ID;

    ctx->priv_data = av_mallocz(type->priv_data_size);

    if (!ctx->priv_data) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);

    if (!ctx->input_frames_ref) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;

    ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);

    if (!ctx->device_ref) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;

    ctx->hwctx = ctx->device->hwctx;

    err = ctx->codec->init(avctx);

    if (err < 0)

        goto fail;

    err = vaapi_encode_check_config(avctx);

    if (err < 0)

        goto fail;

    vas = vaCreateConfig(ctx->hwctx->display,

                         ctx->va_profile, ctx->va_entrypoint,

                         ctx->config_attributes, ctx->nb_config_attributes,

                         &ctx->va_config);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "

               "configuration: %d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail;

    }

    hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);

    if (!hwconfig) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    hwconfig->config_id = ctx->va_config;

    constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,

                                                      hwconfig);

    if (!constraints) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    // Probably we can use the input surface format as the surface format

    // of the reconstructed frames.  If not, we just pick the first (only?)

    // format in the valid list and hope that it all works.

    recon_format = AV_PIX_FMT_NONE;

    if (constraints->valid_sw_formats) {

        for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {

            if (ctx->input_frames->sw_format ==

                constraints->valid_sw_formats[i]) {

                recon_format = ctx->input_frames->sw_format;

                break;

            }

        }

        if (recon_format == AV_PIX_FMT_NONE) {

            // No match.  Just use the first in the supported list and

            // hope for the best.

            recon_format = constraints->valid_sw_formats[0];

        }

    } else {

        // No idea what to use; copy input format.

        recon_format = ctx->input_frames->sw_format;

    }

    av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "

           "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));

    if (ctx->aligned_width  < constraints->min_width  ||

        ctx->aligned_height < constraints->min_height ||

        ctx->aligned_width  > constraints->max_width ||

        ctx->aligned_height > constraints->max_height) {

        av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "

               "size %dx%d (constraints: width %d-%d height %d-%d).\n",

               ctx->aligned_width, ctx->aligned_height,

               constraints->min_width,  constraints->max_width,

               constraints->min_height, constraints->max_height);

        err = AVERROR(EINVAL);

        goto fail;

    }

    av_freep(&hwconfig);

    av_hwframe_constraints_free(&constraints);

    ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);

    if (!ctx->recon_frames_ref) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;

    ctx->recon_frames->format    = AV_PIX_FMT_VAAPI;

    ctx->recon_frames->sw_format = recon_format;

    ctx->recon_frames->width     = ctx->aligned_width;

    ctx->recon_frames->height    = ctx->aligned_height;

    ctx->recon_frames->initial_pool_size = ctx->nb_recon_frames;

    err = av_hwframe_ctx_init(ctx->recon_frames_ref);

    if (err < 0) {

        av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "

               "frame context: %d.\n", err);

        goto fail;

    }

    recon_hwctx = ctx->recon_frames->hwctx;

    vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,

                          ctx->aligned_width, ctx->aligned_height,

                          VA_PROGRESSIVE,

                          recon_hwctx->surface_ids,

                          recon_hwctx->nb_surfaces,

                          &ctx->va_context);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "

               "context: %d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail;

    }

    ctx->input_order  = 0;

    ctx->output_delay = avctx->max_b_frames;

    ctx->decode_delay = 1;

    ctx->output_order = - ctx->output_delay - 1;

    if (ctx->codec->sequence_params_size > 0) {

        ctx->codec_sequence_params =

            av_mallocz(ctx->codec->sequence_params_size);

        if (!ctx->codec_sequence_params) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

    }

    if (ctx->codec->picture_params_size > 0) {

        ctx->codec_picture_params =

            av_mallocz(ctx->codec->picture_params_size);

        if (!ctx->codec_picture_params) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

    }

    if (ctx->codec->init_sequence_params) {

        err = ctx->codec->init_sequence_params(avctx);

        if (err < 0) {

            av_log(avctx, AV_LOG_ERROR, "Codec sequence initialisation "

                   "failed: %d.\n", err);

            goto fail;

        }

    }

    ctx->output_buffer_pool =

        av_buffer_pool_init2(sizeof(VABufferID), avctx,

                             &vaapi_encode_alloc_output_buffer, NULL);

    if (!ctx->output_buffer_pool) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    // All I are IDR for now.

    ctx->i_per_idr = 0;

    ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /

                    (avctx->max_b_frames + 1));

    ctx->b_per_p = avctx->max_b_frames;

    // This should be configurable somehow.  (Needs testing on a machine

    // where it actually overlaps properly, though.)

    ctx->issue_mode = ISSUE_MODE_MAXIMISE_THROUGHPUT;

    return 0;

fail:

    av_freep(&hwconfig);

    av_hwframe_constraints_free(&constraints);

    ff_vaapi_encode_close(avctx);

    return err;

}


void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)

{

    if (   s->avctx->hwaccel || !pict || !pict->mb_type

        || (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU))

        return;

    if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {

        int x,y;

        av_log(s->avctx, AV_LOG_DEBUG, "New frame, type: %c\n",

               av_get_picture_type_char(pict->pict_type));

        for (y = 0; y < s->mb_height; y++) {

            for (x = 0; x < s->mb_width; x++) {

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

                    int count = s->mbskip_table[x + y * s->mb_stride];

                    if (count > 9)

                        count = 9;

                    av_log(s->avctx, AV_LOG_DEBUG, "%1d", count);

                }

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

                    av_log(s->avctx, AV_LOG_DEBUG, "%2d",

                           pict->qscale_table[x + y * s->mb_stride]);

                }

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

                    int mb_type = pict->mb_type[x + y * s->mb_stride];

                    // Type & MV direction

                    if (IS_PCM(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "P");

                    else if (IS_INTRA(mb_type) && IS_ACPRED(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "A");

                    else if (IS_INTRA4x4(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "i");

                    else if (IS_INTRA16x16(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "I");

                    else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type))

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

                    else if (IS_DIRECT(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "D");

                    else if (IS_GMC(mb_type) && IS_SKIP(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "g");

                    else if (IS_GMC(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "G");

                    else if (IS_SKIP(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "S");

                    else if (!USES_LIST(mb_type, 1))

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

                    else if (!USES_LIST(mb_type, 0))

                        av_log(s->avctx, AV_LOG_DEBUG, "<");

                    else {

                        av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));

                        av_log(s->avctx, AV_LOG_DEBUG, "X");

                    }

                    // segmentation

                    if (IS_8X8(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "+");

                    else if (IS_16X8(mb_type))

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

                    else if (IS_8X16(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "|");

                    else if (IS_INTRA(mb_type) || IS_16X16(mb_type))

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

                    else

                        av_log(s->avctx, AV_LOG_DEBUG, "?");

                    if (IS_INTERLACED(mb_type))

                        av_log(s->avctx, AV_LOG_DEBUG, "=");

                    else

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

                }

            }

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

        }

    }

    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||

        (s->avctx->debug_mv)) {

        const int shift = 1 + s->quarter_sample;

        int mb_y;

        uint8_t *ptr;

        int i;

        int h_chroma_shift, v_chroma_shift, block_height;

        const int width          = s->avctx->width;

        const int height         = s->avctx->height;

        const int mv_sample_log2 = 4 - pict->motion_subsample_log2;

        const int mv_stride      = (s->mb_width << mv_sample_log2) +

                                   (s->codec_id == AV_CODEC_ID_H264 ? 0 : 1);

        s->low_delay = 0; // needed to see the vectors without trashing the buffers

        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,

                                      &h_chroma_shift, &v_chroma_shift);

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

            size_t size= (i == 0) ? pict->linesize[i] * FFALIGN(height, 16):

                         pict->linesize[i] * FFALIGN(height, 16) >> v_chroma_shift;

            s->visualization_buffer[i]= av_realloc(s->visualization_buffer[i], size);

            memcpy(s->visualization_buffer[i], pict->data[i], size);

            pict->data[i] = s->visualization_buffer[i];

        }

        pict->type   = FF_BUFFER_TYPE_COPY;

        pict->opaque= NULL;

        ptr          = pict->data[0];

        block_height = 16 >> v_chroma_shift;

        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

            int mb_x;

            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

                const int mb_index = mb_x + mb_y * s->mb_stride;

                if ((s->avctx->debug_mv) && pict->motion_val) {

                    int type;

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

                        int direction = 0;

                        switch (type) {

                        case 0:

                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||

                                (pict->pict_type!= AV_PICTURE_TYPE_P))

                                continue;

                            direction = 0;

                            break;

                        case 1:

                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||

                                (pict->pict_type!= AV_PICTURE_TYPE_B))

                                continue;

                            direction = 0;

                            break;

                        case 2:

                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||

                                (pict->pict_type!= AV_PICTURE_TYPE_B))

                                continue;

                            direction = 1;

                            break;

                        }

                        if (!USES_LIST(pict->mb_type[mb_index], direction))

                            continue;

                        if (IS_8X8(pict->mb_type[mb_index])) {

                            int i;

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

                                int sx = mb_x * 16 + 4 + 8 * (i & 1);

                                int sy = mb_y * 16 + 4 + 8 * (i >> 1);

                                int xy = (mb_x * 2 + (i & 1) +

                                          (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);

                                int mx = (pict->motion_val[direction][xy][0] >> shift) + sx;

                                int my = (pict->motion_val[direction][xy][1] >> shift) + sy;

                                draw_arrow(ptr, sx, sy, mx, my, width,

                                           height, s->linesize, 100);

                            }

                        } else if (IS_16X8(pict->mb_type[mb_index])) {

                            int i;

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

                                int sx = mb_x * 16 + 8;

                                int sy = mb_y * 16 + 4 + 8 * i;

                                int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1);

                                int mx = (pict->motion_val[direction][xy][0] >> shift);

                                int my = (pict->motion_val[direction][xy][1] >> shift);

                                if (IS_INTERLACED(pict->mb_type[mb_index]))

                                    my *= 2;

                            draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,

                                       height, s->linesize, 100);

                            }

                        } else if (IS_8X16(pict->mb_type[mb_index])) {

                            int i;

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

                                int sx = mb_x * 16 + 4 + 8 * i;

                                int sy = mb_y * 16 + 8;

                                int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1);

                                int mx = pict->motion_val[direction][xy][0] >> shift;

                                int my = pict->motion_val[direction][xy][1] >> shift;

                                if (IS_INTERLACED(pict->mb_type[mb_index]))

                                    my *= 2;

                                draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,

                                           height, s->linesize, 100);

                            }

                        } else {

                              int sx= mb_x * 16 + 8;

                              int sy= mb_y * 16 + 8;

                              int xy= (mb_x + mb_y * mv_stride) << mv_sample_log2;

                              int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;

                              int my= (pict->motion_val[direction][xy][1]>>shift) + sy;

                              draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);

                        }

                    }

                }

                if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) {

                    uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *

                                 0x0101010101010101ULL;

                    int y;

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

                        *(uint64_t *)(pict->data[1] + 8 * mb_x +

                                      (block_height * mb_y + y) *

                                      pict->linesize[1]) = c;

                        *(uint64_t *)(pict->data[2] + 8 * mb_x +

                                      (block_height * mb_y + y) *

                                      pict->linesize[2]) = c;

                    }

                }

                if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&

                    pict->motion_val) {

                    int mb_type = pict->mb_type[mb_index];

                    uint64_t u,v;

                    int y;

#define COLOR(theta, r) \

    u = (int)(128 + r * cos(theta * 3.141592 / 180)); \

    v = (int)(128 + r * sin(theta * 3.141592 / 180));

                    u = v = 128;

                    if (IS_PCM(mb_type)) {

                        COLOR(120, 48)

                    } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) ||

                               IS_INTRA16x16(mb_type)) {

                        COLOR(30, 48)

                    } else if (IS_INTRA4x4(mb_type)) {

                        COLOR(90, 48)

                    } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) {

                        // COLOR(120, 48)

                    } else if (IS_DIRECT(mb_type)) {

                        COLOR(150, 48)

                    } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) {

                        COLOR(170, 48)

                    } else if (IS_GMC(mb_type)) {

                        COLOR(190, 48)

                    } else if (IS_SKIP(mb_type)) {

                        // COLOR(180, 48)

                    } else if (!USES_LIST(mb_type, 1)) {

                        COLOR(240, 48)

                    } else if (!USES_LIST(mb_type, 0)) {

                        COLOR(0, 48)

                    } else {

                        av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));

                        COLOR(300,48)

                    }

                    u *= 0x0101010101010101ULL;

                    v *= 0x0101010101010101ULL;

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

                        *(uint64_t *)(pict->data[1] + 8 * mb_x +

                                      (block_height * mb_y + y) * pict->linesize[1]) = u;

                        *(uint64_t *)(pict->data[2] + 8 * mb_x +

                                      (block_height * mb_y + y) * pict->linesize[2]) = v;

                    }

                    // segmentation

                    if (IS_8X8(mb_type) || IS_16X8(mb_type)) {

                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 +

                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;

                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 +

                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;

                    }

                    if (IS_8X8(mb_type) || IS_8X16(mb_type)) {

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

                            pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) *

                                          pict->linesize[0]] ^= 0x80;

                    }

                    if (IS_8X8(mb_type) && mv_sample_log2 >= 2) {

                        int dm = 1 << (mv_sample_log2 - 2);

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

                            int sx = mb_x * 16 + 8 * (i & 1);

                            int sy = mb_y * 16 + 8 * (i >> 1);

                            int xy = (mb_x * 2 + (i & 1) +

                                     (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);

                            // FIXME bidir

                            int32_t *mv = (int32_t *) &pict->motion_val[0][xy];

                            if (mv[0] != mv[dm] ||

                                mv[dm * mv_stride] != mv[dm * (mv_stride + 1)])

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

                                    pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80;

                            if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)])

                                *(uint64_t *)(pict->data[0] + sx + (sy + 4) *

                                              pict->linesize[0]) ^= 0x8080808080808080ULL;

                        }

                    }

                    if (IS_INTERLACED(mb_type) &&

                        s->codec_id == AV_CODEC_ID_H264) {

                        // hmm

                    }

                }

                s->mbskip_table[mb_index] = 0;

            }

        }

    }

}


static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)

{

    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;

    return qpci_io_readb(dev->pdev, CONFIG_BASE(dev) + off);

}


int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
{
    env->msr_mask = def->msr_mask;
    env->mmu_model = def->mmu_model;
    env->excp_model = def->excp_model;
    env->bus_model = def->bus_model;
    env->insns_flags = def->insns_flags;
    env->insns_flags2 = def->insns_flags2;
    env->flags = def->flags;
    env->bfd_mach = def->bfd_mach;
    env->check_pow = def->check_pow;
    if (kvm_enabled()) {
        if (kvmppc_fixup_cpu(env) != 0) {
            fprintf(stderr, "Unable to virtualize selected CPU with KVM\n");
            exit(1);
    } else {
        if (ppc_fixup_cpu(env) != 0) {
            fprintf(stderr, "Unable to emulate selected CPU with TCG\n");
            exit(1);
    if (create_ppc_opcodes(env, def) < 0)
        return -1;
    init_ppc_proc(env, def);
    if (def->insns_flags & PPC_FLOAT) {
        gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg,
                                 33, "power-fpu.xml", 0);
    if (def->insns_flags & PPC_ALTIVEC) {
        gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg,
                                 34, "power-altivec.xml", 0);
    if (def->insns_flags & PPC_SPE) {
        gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg,
                                 34, "power-spe.xml", 0);
#if defined(PPC_DUMP_CPU)
    {
        const char *mmu_model, *excp_model, *bus_model;
        switch (env->mmu_model) {
        case POWERPC_MMU_32B:
            mmu_model = "PowerPC 32";
            break;
        case POWERPC_MMU_SOFT_6xx:
            mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_74xx:
            mmu_model = "PowerPC 74xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_4xx:
            mmu_model = "PowerPC 4xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_4xx_Z:
            mmu_model = "PowerPC 4xx with software driven TLBs "
                "and zones protections";
            break;
        case POWERPC_MMU_REAL:
            mmu_model = "PowerPC real mode only";
            break;
        case POWERPC_MMU_MPC8xx:
            mmu_model = "PowerPC MPC8xx";
            break;
        case POWERPC_MMU_BOOKE:
            mmu_model = "PowerPC BookE";
            break;
        case POWERPC_MMU_BOOKE206:
            mmu_model = "PowerPC BookE 2.06";
            break;
        case POWERPC_MMU_601:
            mmu_model = "PowerPC 601";
            break;
#if defined (TARGET_PPC64)
        case POWERPC_MMU_64B:
            mmu_model = "PowerPC 64";
            break;
        case POWERPC_MMU_620:
            mmu_model = "PowerPC 620";
            break;
#endif
        default:
            mmu_model = "Unknown or invalid";
            break;
        switch (env->excp_model) {
        case POWERPC_EXCP_STD:
            excp_model = "PowerPC";
            break;
        case POWERPC_EXCP_40x:
            excp_model = "PowerPC 40x";
            break;
        case POWERPC_EXCP_601:
            excp_model = "PowerPC 601";
            break;
        case POWERPC_EXCP_602:
            excp_model = "PowerPC 602";
            break;
        case POWERPC_EXCP_603:
            excp_model = "PowerPC 603";
            break;
        case POWERPC_EXCP_603E:
            excp_model = "PowerPC 603e";
            break;
        case POWERPC_EXCP_604:
            excp_model = "PowerPC 604";
            break;
        case POWERPC_EXCP_7x0:
            excp_model = "PowerPC 740/750";
            break;
        case POWERPC_EXCP_7x5:
            excp_model = "PowerPC 745/755";
            break;
        case POWERPC_EXCP_74xx:
            excp_model = "PowerPC 74xx";
            break;
        case POWERPC_EXCP_BOOKE:
            excp_model = "PowerPC BookE";
            break;
#if defined (TARGET_PPC64)
        case POWERPC_EXCP_970:
            excp_model = "PowerPC 970";
            break;
#endif
        default:
            excp_model = "Unknown or invalid";
            break;
        switch (env->bus_model) {
        case PPC_FLAGS_INPUT_6xx:
            bus_model = "PowerPC 6xx";
            break;
        case PPC_FLAGS_INPUT_BookE:
            bus_model = "PowerPC BookE";
            break;
        case PPC_FLAGS_INPUT_405:
            bus_model = "PowerPC 405";
            break;
        case PPC_FLAGS_INPUT_401:
            bus_model = "PowerPC 401/403";
            break;
        case PPC_FLAGS_INPUT_RCPU:
            bus_model = "RCPU / MPC8xx";
            break;
#if defined (TARGET_PPC64)
        case PPC_FLAGS_INPUT_970:
            bus_model = "PowerPC 970";
            break;
#endif
        default:
            bus_model = "Unknown or invalid";
            break;
        printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
               "    MMU model        : %s\n",
               def->name, def->pvr, def->msr_mask, mmu_model);
#if !defined(CONFIG_USER_ONLY)
        if (env->tlb != NULL) {
            printf("                       %d %s TLB in %d ways\n",
                   env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
                   env->nb_ways);
#endif
        printf("    Exceptions model : %s\n"
               "    Bus model        : %s\n",
               excp_model, bus_model);
        printf("    MSR features     :\n");
        if (env->flags & POWERPC_FLAG_SPE)
            printf("                        signal processing engine enable"
                   "\n");
        else if (env->flags & POWERPC_FLAG_VRE)
            printf("                        vector processor enable\n");
        if (env->flags & POWERPC_FLAG_TGPR)
            printf("                        temporary GPRs\n");
        else if (env->flags & POWERPC_FLAG_CE)
            printf("                        critical input enable\n");
        if (env->flags & POWERPC_FLAG_SE)
            printf("                        single-step trace mode\n");
        else if (env->flags & POWERPC_FLAG_DWE)
            printf("                        debug wait enable\n");
        else if (env->flags & POWERPC_FLAG_UBLE)
            printf("                        user BTB lock enable\n");
        if (env->flags & POWERPC_FLAG_BE)
            printf("                        branch-step trace mode\n");
        else if (env->flags & POWERPC_FLAG_DE)
            printf("                        debug interrupt enable\n");
        if (env->flags & POWERPC_FLAG_PX)
            printf("                        inclusive protection\n");
        else if (env->flags & POWERPC_FLAG_PMM)
            printf("                        performance monitor mark\n");
        if (env->flags == POWERPC_FLAG_NONE)
            printf("                        none\n");
        printf("    Time-base/decrementer clock source: %s\n",
               env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
    dump_ppc_insns(env);
    dump_ppc_sprs(env);
    fflush(stdout);
#endif
    return 0;


static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,

                             int nb_sectors, int dirty)

{

    int64_t start, end;

    start = sector_num / BDRV_SECTORS_PER_DIRTY_CHUNK;

    end = (sector_num + nb_sectors) / BDRV_SECTORS_PER_DIRTY_CHUNK;

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

        bs->dirty_bitmap[start] = dirty;

    }

}


static void pc_dimm_unplug(HotplugHandler *hotplug_dev,

                           DeviceState *dev, Error **errp)

{

    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    PCDIMMDevice *dimm = PC_DIMM(dev);

    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);

    MemoryRegion *mr = ddc->get_memory_region(dimm);

    HotplugHandlerClass *hhc;

    Error *local_err = NULL;

    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);

    hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);

    if (local_err) {

        goto out;

    }

    pc_dimm_memory_unplug(dev, &pcms->hotplug_memory, mr);

    object_unparent(OBJECT(dev));

 out:

    error_propagate(errp, local_err);

}


uint64_t ram_bytes_remaining(void)

{

    return ram_state->migration_dirty_pages * TARGET_PAGE_SIZE;

}


QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)

/**

 * monitor_protocol_event(): Generate a Monitor event

 *

 * Event-specific data can be emitted through the (optional) 'data' parameter.

 */

void monitor_protocol_event(MonitorEvent event, QObject *data)

{

    QDict *qmp;

    const char *event_name;

    Monitor *mon;

    assert(event < QEVENT_MAX);

    event_name = monitor_event_names[event];

    assert(event_name != NULL);

    qmp = qdict_new();

    timestamp_put(qmp);

    qdict_put(qmp, "event", qstring_from_str(event_name));

    if (data) {

        qobject_incref(data);

        qdict_put_obj(qmp, "data", data);

    }

    QLIST_FOREACH(mon, &mon_list, entry) {

        if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {

            monitor_json_emitter(mon, QOBJECT(qmp));

        }

    }

    QDECREF(qmp);

}


static int preallocate(BlockDriverState *bs)

{

    uint64_t nb_sectors;

    uint64_t offset;

    int num;

    int ret;

    QCowL2Meta meta;

    nb_sectors = bdrv_getlength(bs) >> 9;

    offset = 0;

    QLIST_INIT(&meta.dependent_requests);

    meta.cluster_offset = 0;

    while (nb_sectors) {

        num = MIN(nb_sectors, INT_MAX >> 9);

        ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, &meta);

        if (ret < 0) {

            return -1;

        }

        if (qcow2_alloc_cluster_link_l2(bs, &meta) < 0) {

            qcow2_free_any_clusters(bs, meta.cluster_offset, meta.nb_clusters);

            return -1;

        }

        /* There are no dependent requests, but we need to remove our request

         * from the list of in-flight requests */

        run_dependent_requests(&meta);

        /* TODO Preallocate data if requested */

        nb_sectors -= num;

        offset += num << 9;

    }

    /*

     * It is expected that the image file is large enough to actually contain

     * all of the allocated clusters (otherwise we get failing reads after

     * EOF). Extend the image to the last allocated sector.

     */

    if (meta.cluster_offset != 0) {

        uint8_t buf[512];

        memset(buf, 0, 512);

        bdrv_write(bs->file, (meta.cluster_offset >> 9) + num - 1, buf, 1);

    }

    return 0;

}


static int msix_is_masked(PCIDevice *dev, int vector)

{

    unsigned offset =

        vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;

    return dev->msix_function_masked ||

	   dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;

}


static int vmdk_add_extent(BlockDriverState *bs,

                           BlockDriverState *file, bool flat, int64_t sectors,

                           int64_t l1_offset, int64_t l1_backup_offset,

                           uint32_t l1_size,

                           int l2_size, uint64_t cluster_sectors,

                           VmdkExtent **new_extent)

{

    VmdkExtent *extent;

    BDRVVmdkState *s = bs->opaque;

    if (cluster_sectors > 0x200000) {

        /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */

        error_report("invalid granularity, image may be corrupt");

        return -EINVAL;

    }

    if (l1_size > 512 * 1024 * 1024) {

        /* Although with big capacity and small l1_entry_sectors, we can get a

         * big l1_size, we don't want unbounded value to allocate the table.

         * Limit it to 512M, which is 16PB for default cluster and L2 table

         * size */

        error_report("L1 size too big");

        return -EFBIG;

    }

    s->extents = g_realloc(s->extents,

                              (s->num_extents + 1) * sizeof(VmdkExtent));

    extent = &s->extents[s->num_extents];

    s->num_extents++;

    memset(extent, 0, sizeof(VmdkExtent));

    extent->file = file;

    extent->flat = flat;

    extent->sectors = sectors;

    extent->l1_table_offset = l1_offset;

    extent->l1_backup_table_offset = l1_backup_offset;

    extent->l1_size = l1_size;

    extent->l1_entry_sectors = l2_size * cluster_sectors;

    extent->l2_size = l2_size;

    extent->cluster_sectors = cluster_sectors;

    if (s->num_extents > 1) {

        extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;

    } else {

        extent->end_sector = extent->sectors;

    }

    bs->total_sectors = extent->end_sector;

    if (new_extent) {

        *new_extent = extent;

    }

    return 0;

}


static int get_stream_info(AVCodecContext *avctx)

{

    FDKAACDecContext *s   = avctx->priv_data;

    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);

    int channel_counts[0x24] = { 0 };

    int i, ch_error       = 0;

    uint64_t ch_layout    = 0;

    if (!info) {

        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");

        return AVERROR_UNKNOWN;

    }

    if (info->sampleRate <= 0) {

        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");

        return AVERROR_UNKNOWN;

    }

    avctx->sample_rate = info->sampleRate;

    avctx->frame_size  = info->frameSize;

    for (i = 0; i < info->numChannels; i++) {

        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];

        if (ctype <= ACT_NONE || ctype > FF_ARRAY_ELEMS(channel_counts)) {

            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");

            break;

        }

        channel_counts[ctype]++;

    }

    av_log(avctx, AV_LOG_DEBUG,

           "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",

           info->numChannels,

           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],

           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],

           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +

           channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);

    switch (channel_counts[ACT_FRONT]) {

    case 4:

        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |

                     AV_CH_FRONT_RIGHT_OF_CENTER;

        break;

    case 3:

        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;

        break;

    case 2:

        ch_layout |= AV_CH_LAYOUT_STEREO;

        break;

    case 1:

        ch_layout |= AV_CH_FRONT_CENTER;

        break;

    default:

        av_log(avctx, AV_LOG_WARNING,

               "unsupported number of front channels: %d\n",

               channel_counts[ACT_FRONT]);

        ch_error = 1;

        break;

    }

    if (channel_counts[ACT_SIDE] > 0) {

        if (channel_counts[ACT_SIDE] == 2) {

            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;

        } else {

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of side channels: %d\n",

                   channel_counts[ACT_SIDE]);

            ch_error = 1;

        }

    }

    if (channel_counts[ACT_BACK] > 0) {

        switch (channel_counts[ACT_BACK]) {

        case 3:

            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;

            break;

        case 2:

            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;

            break;

        case 1:

            ch_layout |= AV_CH_BACK_CENTER;

            break;

        default:

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of back channels: %d\n",

                   channel_counts[ACT_BACK]);

            ch_error = 1;

            break;

        }

    }

    if (channel_counts[ACT_LFE] > 0) {

        if (channel_counts[ACT_LFE] == 1) {

            ch_layout |= AV_CH_LOW_FREQUENCY;

        } else {

            av_log(avctx, AV_LOG_WARNING,

                   "unsupported number of LFE channels: %d\n",

                   channel_counts[ACT_LFE]);

            ch_error = 1;

        }

    }

    if (!ch_error &&

        av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {

        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");

        ch_error = 1;

    }

    if (ch_error)

        avctx->channel_layout = 0;

    else

        avctx->channel_layout = ch_layout;

    avctx->channels = info->numChannels;

    return 0;

}


static void *qemu_rdma_data_init(const char *host_port, Error **errp)

{

    RDMAContext *rdma = NULL;

    InetSocketAddress *addr;

    if (host_port) {

        rdma = g_malloc0(sizeof(RDMAContext));

        memset(rdma, 0, sizeof(RDMAContext));

        rdma->current_index = -1;

        rdma->current_chunk = -1;

        addr = inet_parse(host_port, NULL);

        if (addr != NULL) {

            rdma->port = atoi(addr->port);

            rdma->host = g_strdup(addr->host);

        } else {

            ERROR(errp, "bad RDMA migration address '%s'", host_port);

            g_free(rdma);

            rdma = NULL;

        }

        qapi_free_InetSocketAddress(addr);

    }

    return rdma;

}


static void test_tco_second_timeout_pause(void)

{

    TestData td;

    const uint16_t ticks = TCO_SECS_TO_TICKS(32);

    QDict *ad;

    td.args = "-watchdog-action pause";

    td.noreboot = false;

    test_init(&td);

    stop_tco(&td);

    clear_tco_status(&td);

    reset_on_second_timeout(true);

    set_tco_timeout(&td, TCO_SECS_TO_TICKS(16));

    load_tco(&td);

    start_tco(&td);

    clock_step(ticks * TCO_TICK_NSEC * 2);

    ad = get_watchdog_action();

    g_assert(!strcmp(qdict_get_str(ad, "action"), "pause"));

    QDECREF(ad);

    stop_tco(&td);

    qtest_end();

}


static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, const int16_t bS[7], int bsi, int qp ) {

    const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);

    int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;

    int alpha = alpha_table[index_a];

    int beta  = beta_table[qp - qp_bd_offset + h->slice_beta_offset];

    if (alpha ==0 || beta == 0) return;

    if( bS[0] < 4 ) {

        int8_t tc[4];

        tc[0] = tc0_table[index_a][bS[0*bsi]];

        tc[1] = tc0_table[index_a][bS[1*bsi]];

        tc[2] = tc0_table[index_a][bS[2*bsi]];

        tc[3] = tc0_table[index_a][bS[3*bsi]];

        h->h264dsp.h264_h_loop_filter_luma_mbaff(pix, stride, alpha, beta, tc);

    } else {

        h->h264dsp.h264_h_loop_filter_luma_mbaff_intra(pix, stride, alpha, beta);

    }

}


static int rtsp_read_packet(AVFormatContext *s,

                            AVPacket *pkt)

{

    RTSPState *rt = s->priv_data;

    int ret;

    RTSPMessageHeader reply1, *reply = &reply1;

    char cmd[1024];

    if (rt->server_type == RTSP_SERVER_REAL) {

        int i;

        enum AVDiscard cache[MAX_STREAMS];

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

            cache[i] = s->streams[i]->discard;

        if (!rt->need_subscription) {

            if (memcmp (cache, rt->real_setup_cache,

                        sizeof(enum AVDiscard) * s->nb_streams)) {

                av_strlcatf(cmd, sizeof(cmd),

                            "SET_PARAMETER %s RTSP/1.0\r\n"

                            "Unsubscribe: %s\r\n",

                            s->filename, rt->last_subscription);

                rtsp_send_cmd(s, cmd, reply, NULL);

                if (reply->status_code != RTSP_STATUS_OK)

                    return AVERROR_INVALIDDATA;

                rt->need_subscription = 1;

            }

        }

        if (rt->need_subscription) {

            int r, rule_nr, first = 1;

            memcpy(rt->real_setup_cache, cache,

                   sizeof(enum AVDiscard) * s->nb_streams);

            rt->last_subscription[0] = 0;

            snprintf(cmd, sizeof(cmd),

                     "SET_PARAMETER %s RTSP/1.0\r\n"

                     "Subscribe: ",

                     s->filename);

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

                rule_nr = 0;

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

                    if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {

                        if (s->streams[r]->discard != AVDISCARD_ALL) {

                            if (!first)

                                av_strlcat(rt->last_subscription, ",",

                                           sizeof(rt->last_subscription));

                            ff_rdt_subscribe_rule(

                                rt->last_subscription,

                                sizeof(rt->last_subscription), i, rule_nr);

                            first = 0;

                        }

                        rule_nr++;

                    }

                }

            }

            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);

            rtsp_send_cmd(s, cmd, reply, NULL);

            if (reply->status_code != RTSP_STATUS_OK)

                return AVERROR_INVALIDDATA;

            rt->need_subscription = 0;

            if (rt->state == RTSP_STATE_PLAYING)

                rtsp_read_play (s);

        }

    }

    ret = rtsp_fetch_packet(s, pkt);

    if (ret < 0) {

        return ret;

    }

    /* send dummy request to keep TCP connection alive */

    if ((rt->server_type == RTSP_SERVER_WMS ||

         rt->server_type == RTSP_SERVER_REAL) &&

        (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {

        if (rt->server_type == RTSP_SERVER_WMS) {

            snprintf(cmd, sizeof(cmd) - 1,

                     "GET_PARAMETER %s RTSP/1.0\r\n",

                     s->filename);

            rtsp_send_cmd_async(s, cmd, reply, NULL);

        } else {

            rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n",

                                reply, NULL);

        }

    }

    return 0;

}


static int cudaupload_query_formats(AVFilterContext *ctx)

{

    static const enum AVPixelFormat input_pix_fmts[] = {

        AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P,

        AV_PIX_FMT_NONE,

    };

    static const enum AVPixelFormat output_pix_fmts[] = {

        AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE,

    };

    AVFilterFormats *in_fmts  = ff_make_format_list(input_pix_fmts);

    AVFilterFormats *out_fmts = ff_make_format_list(output_pix_fmts);

    ff_formats_ref(in_fmts,  &ctx->inputs[0]->out_formats);

    ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);

    return 0;

}


static void opt_audio_sample_fmt(const char *arg)

{

    if (strcmp(arg, "list"))

        audio_sample_fmt = av_get_sample_fmt(arg);

    else {

        list_fmts(av_get_sample_fmt_string, AV_SAMPLE_FMT_NB);

        ffmpeg_exit(0);

    }

}


static int wsvqa_read_header(AVFormatContext *s)

{

    WsVqaDemuxContext *wsvqa = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st;

    unsigned char *header;

    unsigned char scratch[VQA_PREAMBLE_SIZE];

    unsigned int chunk_tag;

    unsigned int chunk_size;

    int fps;

    /* initialize the video decoder stream */

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->start_time = 0;

    wsvqa->video_stream_index = st->index;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = AV_CODEC_ID_WS_VQA;

    st->codec->codec_tag = 0;  /* no fourcc */

    /* skip to the start of the VQA header */

    avio_seek(pb, 20, SEEK_SET);

    /* the VQA header needs to go to the decoder */

    st->codec->extradata_size = VQA_HEADER_SIZE;

    st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

    header = (unsigned char *)st->codec->extradata;

    if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=

        VQA_HEADER_SIZE) {

        av_free(st->codec->extradata);

        return AVERROR(EIO);

    }

    st->codec->width = AV_RL16(&header[6]);

    st->codec->height = AV_RL16(&header[8]);

    fps = header[12];

    st->nb_frames =

    st->duration  = AV_RL16(&header[4]);

    if (fps < 1 || fps > 30) {

        av_log(s, AV_LOG_ERROR, "invalid fps: %d\n", fps);

        return AVERROR_INVALIDDATA;

    }

    avpriv_set_pts_info(st, 64, 1, fps);

    wsvqa->version      = AV_RL16(&header[ 0]);

    wsvqa->sample_rate  = AV_RL16(&header[24]);

    wsvqa->channels     = header[26];

    wsvqa->bps          = header[27];

    wsvqa->audio_stream_index = -1;

    s->ctx_flags |= AVFMTCTX_NOHEADER;

    /* there are 0 or more chunks before the FINF chunk; iterate until

     * FINF has been skipped and the file will be ready to be demuxed */

    do {

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

            return AVERROR(EIO);

        chunk_tag = AV_RB32(&scratch[0]);

        chunk_size = AV_RB32(&scratch[4]);

        /* catch any unknown header tags, for curiousity */

        switch (chunk_tag) {

        case CINF_TAG:

        case CINH_TAG:

        case CIND_TAG:

        case PINF_TAG:

        case PINH_TAG:

        case PIND_TAG:

        case FINF_TAG:

        case CMDS_TAG:

            break;

        default:

            av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",

                scratch[0], scratch[1],

                scratch[2], scratch[3]);

            break;

        }

        avio_skip(pb, chunk_size);

    } while (chunk_tag != FINF_TAG);

    return 0;

}


static void flat_print_str(WriterContext *wctx, const char *key, const char *value)

{

    FlatContext *flat = wctx->priv;

    AVBPrint buf;

    flat_print_key_prefix(wctx);

    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);

    printf("%s=", flat_escape_key_str(&buf, key, flat->sep));

    av_bprint_clear(&buf);

    printf("\"%s\"\n", flat_escape_value_str(&buf, value));

    av_bprint_finalize(&buf, NULL);

}


static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){

    NUTContext *nut = s->priv_data;

    StreamContext *nus= &nut->stream[pkt->stream_index];

    AVIOContext *bc = s->pb, *dyn_bc;

    FrameCode *fc;

    int64_t coded_pts;

    int best_length, frame_code, flags, needed_flags, i, header_idx, best_header_idx;

    int key_frame = !!(pkt->flags & AV_PKT_FLAG_KEY);

    int store_sp=0;

    int ret;

    if(pkt->pts < 0)

        return -1;

    if(1LL<<(20+3*nut->header_count) <= avio_tell(bc))

        write_headers(s, bc);

    if(key_frame && !(nus->last_flags & FLAG_KEY))

        store_sp= 1;

    if(pkt->size + 30/*FIXME check*/ + avio_tell(bc) >= nut->last_syncpoint_pos + nut->max_distance)

        store_sp= 1;

//FIXME: Ensure store_sp is 1 in the first place.

    if(store_sp){

        Syncpoint *sp, dummy= {.pos= INT64_MAX};

        ff_nut_reset_ts(nut, *nus->time_base, pkt->dts);

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

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

            int64_t dts_tb = av_rescale_rnd(pkt->dts,

                nus->time_base->num * (int64_t)nut->stream[i].time_base->den,

                nus->time_base->den * (int64_t)nut->stream[i].time_base->num,

                AV_ROUND_DOWN);

            int index= av_index_search_timestamp(st, dts_tb, AVSEEK_FLAG_BACKWARD);

            if(index>=0) dummy.pos= FFMIN(dummy.pos, st->index_entries[index].pos);

        }

        if(dummy.pos == INT64_MAX)

            dummy.pos= 0;

        sp= av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,

                         NULL);

        nut->last_syncpoint_pos= avio_tell(bc);

        ret = avio_open_dyn_buf(&dyn_bc);

        if(ret < 0)

            return ret;

        put_tt(nut, nus->time_base, dyn_bc, pkt->dts);

        ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos)>>4 : 0);

        put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);

        ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0/*unused*/, pkt->dts);

    }

    av_assert0(nus->last_pts != AV_NOPTS_VALUE);

    coded_pts = pkt->pts & ((1<<nus->msb_pts_shift)-1);

    if(ff_lsb2full(nus, coded_pts) != pkt->pts)

        coded_pts= pkt->pts + (1<<nus->msb_pts_shift);

    best_header_idx= find_best_header_idx(nut, pkt);

    best_length=INT_MAX;

    frame_code= -1;

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

        int length= 0;

        FrameCode *fc= &nut->frame_code[i];

        int flags= fc->flags;

        if(flags & FLAG_INVALID)

            continue;

        needed_flags= get_needed_flags(nut, nus, fc, pkt);

        if(flags & FLAG_CODED){

            length++;

            flags = needed_flags;

        }

        if((flags & needed_flags) != needed_flags)

            continue;

        if((flags ^ needed_flags) & FLAG_KEY)

            continue;

        if(flags & FLAG_STREAM_ID)

            length+= ff_get_v_length(pkt->stream_index);

        if(pkt->size % fc->size_mul != fc->size_lsb)

            continue;

        if(flags & FLAG_SIZE_MSB)

            length += ff_get_v_length(pkt->size / fc->size_mul);

        if(flags & FLAG_CHECKSUM)

            length+=4;

        if(flags & FLAG_CODED_PTS)

            length += ff_get_v_length(coded_pts);

        if(   (flags & FLAG_CODED)

           && nut->header_len[best_header_idx] > nut->header_len[fc->header_idx]+1){

            flags |= FLAG_HEADER_IDX;

        }

        if(flags & FLAG_HEADER_IDX){

            length += 1 - nut->header_len[best_header_idx];

        }else{

            length -= nut->header_len[fc->header_idx];

        }

        length*=4;

        length+= !(flags & FLAG_CODED_PTS);

        length+= !(flags & FLAG_CHECKSUM);

        if(length < best_length){

            best_length= length;

            frame_code=i;

        }

    }

    av_assert0(frame_code != -1);

    fc= &nut->frame_code[frame_code];

    flags= fc->flags;

    needed_flags= get_needed_flags(nut, nus, fc, pkt);

    header_idx= fc->header_idx;

    ffio_init_checksum(bc, ff_crc04C11DB7_update, 0);

    avio_w8(bc, frame_code);

    if(flags & FLAG_CODED){

        ff_put_v(bc, (flags^needed_flags) & ~(FLAG_CODED));

        flags = needed_flags;

    }

    if(flags & FLAG_STREAM_ID)  ff_put_v(bc, pkt->stream_index);

    if(flags & FLAG_CODED_PTS)  ff_put_v(bc, coded_pts);

    if(flags & FLAG_SIZE_MSB)   ff_put_v(bc, pkt->size / fc->size_mul);

    if(flags & FLAG_HEADER_IDX) ff_put_v(bc, header_idx= best_header_idx);

    if(flags & FLAG_CHECKSUM)   avio_wl32(bc, ffio_get_checksum(bc));

    else                        ffio_get_checksum(bc);

    avio_write(bc, pkt->data + nut->header_len[header_idx], pkt->size - nut->header_len[header_idx]);

    nus->last_flags= flags;

    nus->last_pts= pkt->pts;

    //FIXME just store one per syncpoint

    if(flags & FLAG_KEY)

        av_add_index_entry(

            s->streams[pkt->stream_index],

            nut->last_syncpoint_pos,

            pkt->pts,

            0,

            0,

            AVINDEX_KEYFRAME);

    return 0;

}


ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb,

                    AVStream *st, RMStream *ast, int len, AVPacket *pkt,

                    int *seq, int *flags, int64_t *timestamp)

{

    RMDemuxContext *rm = s->priv_data;

    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {

        rm->current_stream= st->id;

        if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len))

            return -1; //got partial frame

    } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {

        if ((st->codec->codec_id == CODEC_ID_RA_288) ||

            (st->codec->codec_id == CODEC_ID_COOK) ||

            (st->codec->codec_id == CODEC_ID_ATRAC3) ||

            (st->codec->codec_id == CODEC_ID_SIPR)) {

            int x;

            int sps = ast->sub_packet_size;

            int cfs = ast->coded_framesize;

            int h = ast->sub_packet_h;

            int y = ast->sub_packet_cnt;

            int w = ast->audio_framesize;

            if (*flags & 2)

                y = ast->sub_packet_cnt = 0;

            if (!y)

                ast->audiotimestamp = *timestamp;

            switch(st->codec->codec_id) {

                case CODEC_ID_RA_288:

                    for (x = 0; x < h/2; x++)

                        get_buffer(pb, ast->pkt.data+x*2*w+y*cfs, cfs);

                    break;

                case CODEC_ID_ATRAC3:

                case CODEC_ID_COOK:

                    for (x = 0; x < w/sps; x++)

                        get_buffer(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);

                    break;

            }

            if (++(ast->sub_packet_cnt) < h)

                return -1;

            else {

                ast->sub_packet_cnt = 0;

                rm->audio_stream_num = st->index;

                rm->audio_pkt_cnt = h * w / st->codec->block_align - 1;

                // Release first audio packet

                av_new_packet(pkt, st->codec->block_align);

                memcpy(pkt->data, ast->pkt.data, st->codec->block_align); //FIXME avoid this

                *timestamp = ast->audiotimestamp;

                *flags = 2; // Mark first packet as keyframe

            }

        } else if (st->codec->codec_id == CODEC_ID_AAC) {

            int x;

            rm->audio_stream_num = st->index;

            ast->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4;

            if (ast->sub_packet_cnt) {

                for (x = 0; x < ast->sub_packet_cnt; x++)

                    ast->sub_packet_lengths[x] = get_be16(pb);

                // Release first audio packet

                rm->audio_pkt_cnt = ast->sub_packet_cnt - 1;

                av_get_packet(pb, pkt, ast->sub_packet_lengths[0]);

                *flags = 2; // Mark first packet as keyframe

            }

        } else {

            av_get_packet(pb, pkt, len);

            rm_ac3_swap_bytes(st, pkt);

        }

    } else

        av_get_packet(pb, pkt, len);

    if(  (st->discard >= AVDISCARD_NONKEY && !(*flags&2))

       || st->discard >= AVDISCARD_ALL){

        av_free_packet(pkt);

        return -1;

    }

    pkt->stream_index = st->index;

#if 0

    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {

        if(st->codec->codec_id == CODEC_ID_RV20){

            int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1);

            av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq);

            seq |= (*timestamp&~0x3FFF);

            if(seq - *timestamp >  0x2000) seq -= 0x4000;

            if(seq - *timestamp < -0x2000) seq += 0x4000;

        }

    }

#endif

    pkt->pts= *timestamp;

    if (*flags & 2)

        pkt->flags |= PKT_FLAG_KEY;

    return st->codec->codec_type == CODEC_TYPE_AUDIO ? rm->audio_pkt_cnt : 0;

}


static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){

    int c, line, pixels, code;

    const uint8_t *ssrc = src;

    int width = ((s->width * s->bpp) + 7) >> 3;

#if CONFIG_ZLIB

    uint8_t *zbuf; unsigned long outlen;

    if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){

        int ret;

        outlen = width * lines;

        zbuf = av_malloc(outlen);

        ret = tiff_uncompress(zbuf, &outlen, src, size);

        if(ret != Z_OK){

            av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu) with error %d\n", outlen, (unsigned long)width * lines, ret);

            av_free(zbuf);

            return -1;

        }

        src = zbuf;

        for(line = 0; line < lines; line++){

            memcpy(dst, src, width);

            dst += stride;

            src += width;

        }

        av_free(zbuf);

        return 0;

    }

#endif

    if(s->compr == TIFF_LZW){

        if(ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0){

            av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");

            return -1;

        }

    }

    if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){

        int i, ret = 0;

        uint8_t *src2 = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);

        if(!src2 || (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE < (unsigned)size){

            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");

            return -1;

        }

        if(s->fax_opts & 2){

            av_log(s->avctx, AV_LOG_ERROR, "Uncompressed fax mode is not supported (yet)\n");

            av_free(src2);

            return -1;

        }

        if(!s->fill_order){

            memcpy(src2, src, size);

        }else{

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

                src2[i] = av_reverse[src[i]];

        }

        memset(src2+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);

        switch(s->compr){

        case TIFF_CCITT_RLE:

        case TIFF_G3:

        case TIFF_G4:

            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);

            break;

        }

        av_free(src2);

        return ret;

    }

    for(line = 0; line < lines; line++){

        if(src - ssrc > size){

            av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");

            return -1;

        }

        switch(s->compr){

        case TIFF_RAW:

            if (ssrc + size - src < width)

                return AVERROR_INVALIDDATA;

            if (!s->fill_order) {

                memcpy(dst, src, width);

            } else {

                int i;

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

                    dst[i] = av_reverse[src[i]];

            }

            src += width;

            break;

        case TIFF_PACKBITS:

            for(pixels = 0; pixels < width;){

                code = (int8_t)*src++;

                if(code >= 0){

                    code++;

                    if(pixels + code > width){

                        av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");

                        return -1;

                    }

                    memcpy(dst + pixels, src, code);

                    src += code;

                    pixels += code;

                }else if(code != -128){ // -127..-1

                    code = (-code) + 1;

                    if(pixels + code > width){

                        av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n");

                        return -1;

                    }

                    c = *src++;

                    memset(dst + pixels, c, code);

                    pixels += code;

                }

            }

            break;

        case TIFF_LZW:

            pixels = ff_lzw_decode(s->lzw, dst, width);

            if(pixels < width){

                av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width);

                return -1;

            }

            break;

        }

        dst += stride;

    }

    return 0;

}


inline static void RENAME(hcscale)(SwsContext *c, uint16_t *dst, long dstWidth, const uint8_t *src1, const uint8_t *src2,

                                   int srcW, int xInc, int flags, const int16_t *hChrFilter,

                                   const int16_t *hChrFilterPos, int hChrFilterSize,

                                   enum PixelFormat srcFormat, uint8_t *formatConvBuffer,

                                   uint32_t *pal)

{

    int32_t av_unused *mmx2FilterPos = c->chrMmx2FilterPos;

    int16_t av_unused *mmx2Filter    = c->chrMmx2Filter;

    int     av_unused canMMX2BeUsed  = c->canMMX2BeUsed;

    void    av_unused *mmx2FilterCode= c->chrMmx2FilterCode;

    if (isGray(srcFormat) || srcFormat==PIX_FMT_MONOBLACK || srcFormat==PIX_FMT_MONOWHITE)

        return;

    src1 += c->chrSrcOffset;

    src2 += c->chrSrcOffset;

    if (c->hcscale_internal) {

        c->hcscale_internal(formatConvBuffer, formatConvBuffer+VOFW, src1, src2, srcW, pal);

        src1= formatConvBuffer;

        src2= formatConvBuffer+VOFW;

    }

    if (!c->hcscale_fast)

    {

        c->hScale(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

        c->hScale(dst+VOFW, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

    } else { // fast bilinear upscale / crap downscale

#if ARCH_X86 && CONFIG_GPL

#if COMPILE_TEMPLATE_MMX2

        int i;

#if defined(PIC)

        DECLARE_ALIGNED(8, uint64_t, ebxsave);

#endif

        if (canMMX2BeUsed) {

            __asm__ volatile(

#if defined(PIC)

                "mov          %%"REG_b", %6         \n\t"

#endif

                "pxor             %%mm7, %%mm7      \n\t"

                "mov                 %0, %%"REG_c"  \n\t"

                "mov                 %1, %%"REG_D"  \n\t"

                "mov                 %2, %%"REG_d"  \n\t"

                "mov                 %3, %%"REG_b"  \n\t"

                "xor          %%"REG_a", %%"REG_a"  \n\t" // i

                PREFETCH"   (%%"REG_c")             \n\t"

                PREFETCH" 32(%%"REG_c")             \n\t"

                PREFETCH" 64(%%"REG_c")             \n\t"

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                "xor          %%"REG_a", %%"REG_a"  \n\t" // i

                "mov                 %5, %%"REG_c"  \n\t" // src

                "mov                 %1, %%"REG_D"  \n\t" // buf1

                "add              $"AV_STRINGIFY(VOF)", %%"REG_D"  \n\t"

                PREFETCH"   (%%"REG_c")             \n\t"

                PREFETCH" 32(%%"REG_c")             \n\t"

                PREFETCH" 64(%%"REG_c")             \n\t"

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

                CALL_MMX2_FILTER_CODE

#if defined(PIC)

                "mov %6, %%"REG_b"    \n\t"

#endif

                :: "m" (src1), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),

                "m" (mmx2FilterCode), "m" (src2)

#if defined(PIC)

                ,"m" (ebxsave)

#endif

                : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

                ,"%"REG_b

#endif

            );

            for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {

                //printf("%d %d %d\n", dstWidth, i, srcW);

                dst[i] = src1[srcW-1]*128;

                dst[i+VOFW] = src2[srcW-1]*128;

            }

        } else {

#endif /* COMPILE_TEMPLATE_MMX2 */

            x86_reg xInc_shr16 = (x86_reg) (xInc >> 16);

            uint16_t xInc_mask = xInc & 0xffff;

            __asm__ volatile(

                "xor %%"REG_a", %%"REG_a"               \n\t" // i

                "xor %%"REG_d", %%"REG_d"               \n\t" // xx

                "xorl    %%ecx, %%ecx                   \n\t" // xalpha

                ASMALIGN(4)

                "1:                                     \n\t"

                "mov        %0, %%"REG_S"               \n\t"

                "movzbl  (%%"REG_S", %%"REG_d"), %%edi  \n\t" //src[xx]

                "movzbl 1(%%"REG_S", %%"REG_d"), %%esi  \n\t" //src[xx+1]

                FAST_BILINEAR_X86

                "movw     %%si, (%%"REG_D", %%"REG_a", 2)   \n\t"

                "movzbl    (%5, %%"REG_d"), %%edi       \n\t" //src[xx]

                "movzbl   1(%5, %%"REG_d"), %%esi       \n\t" //src[xx+1]

                FAST_BILINEAR_X86

                "movw     %%si, "AV_STRINGIFY(VOF)"(%%"REG_D", %%"REG_a", 2)   \n\t"

                "addw       %4, %%cx                    \n\t" //xalpha += xInc&0xFFFF

                "adc        %3, %%"REG_d"               \n\t" //xx+= xInc>>16 + carry

                "add        $1, %%"REG_a"               \n\t"

                "cmp        %2, %%"REG_a"               \n\t"

                " jb        1b                          \n\t"

/* GCC 3.3 makes MPlayer crash on IA-32 machines when using "g" operand here,

   which is needed to support GCC 4.0. */

#if ARCH_X86_64 && AV_GCC_VERSION_AT_LEAST(3,4)

                :: "m" (src1), "m" (dst), "g" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#else

                :: "m" (src1), "m" (dst), "m" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#endif

                "r" (src2)

                : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"

            );

#if COMPILE_TEMPLATE_MMX2

        } //if MMX2 can't be used

#endif

#else

        c->hcscale_fast(c, dst, dstWidth, src1, src2, srcW, xInc);

#endif /* ARCH_X86 */

    }

    if (c->chrConvertRange)

        c->chrConvertRange(dst, dstWidth);

}


static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,

                                   const QDict *params)

{

    int ret;

    MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));

    cb_data->mon = mon;

    cb_data->user_print = cmd->user_print;

    monitor_suspend(mon);

    ret = cmd->mhandler.cmd_async(mon, params,

                                  user_monitor_complete, cb_data);

    if (ret < 0) {

        monitor_resume(mon);

        g_free(cb_data);

    }

}


static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int flags)

{

    uint8_t *buf1;

    RMMuxContext *rm = s->priv_data;

    AVIOContext *pb = s->pb;

    StreamInfo *stream = rm->audio_stream;

    int i;

    /* XXX: suppress this malloc */

    buf1 = av_malloc(size * sizeof(uint8_t));

    write_packet_header(s, stream, size, !!(flags & AV_PKT_FLAG_KEY));

    if (stream->enc->codec_id == AV_CODEC_ID_AC3) {

        /* for AC-3, the words seem to be reversed */

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

            buf1[i] = buf[i+1];

            buf1[i+1] = buf[i];

        }

        avio_write(pb, buf1, size);

    } else {

        avio_write(pb, buf, size);

    }

    stream->nb_frames++;

    av_free(buf1);

    return 0;

}