int use_gdb_syscalls(void)

{

    if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {

        gdb_syscall_mode = (gdb_syscall_state ? GDB_SYS_ENABLED

                                              : GDB_SYS_DISABLED);

    }

    return gdb_syscall_mode == GDB_SYS_ENABLED;

}


static void s390_hot_add_cpu(const int64_t id, Error **errp)

{

    MachineState *machine = MACHINE(qdev_get_machine());

    s390x_new_cpu(machine->cpu_model, id, errp);

}


static bool virtio_pci_modern_state_needed(void *opaque)

{

    VirtIOPCIProxy *proxy = opaque;

    return !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);

}


static int on2avc_decode_band_types(On2AVCContext *c, GetBitContext *gb)

{

    int bits_per_sect = c->is_long ? 5 : 3;

    int esc_val = (1 << bits_per_sect) - 1;

    int num_bands = c->num_bands * c->num_windows;

    int band = 0, i, band_type, run_len, run;

    while (band < num_bands) {

        band_type = get_bits(gb, 4);

        run_len   = 1;

        do {

            run = get_bits(gb, bits_per_sect);

            run_len += run;

        } while (run == esc_val);

        if (band + run_len > num_bands) {

            av_log(c->avctx, AV_LOG_ERROR, "Invalid band type run\n");

            return AVERROR_INVALIDDATA;

        }

        for (i = band; i < band + run_len; i++) {

            c->band_type[i]    = band_type;

            c->band_run_end[i] = band + run_len;

        }

        band += run_len;

    }

    return 0;

}


static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band,

                           float *bits, float lambda)

{

    int i, b = 0;

    uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };

    const int band_size = ff_celt_freq_range[band] << f->size;

    float buf[176 * 2], lowband_scratch[176], norm1[176], norm2[176];

    float dist, cost, err_x = 0.0f, err_y = 0.0f;

    float *X = buf;

    float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size);

    float *Y = (f->channels == 2) ? &buf[176] : NULL;

    float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size);

    OPUS_RC_CHECKPOINT_SPAWN(rc);

    memcpy(X, X_orig, band_size*sizeof(float));

    if (Y)

        memcpy(Y, Y_orig, band_size*sizeof(float));

    f->remaining2 = ((f->framebits << 3) - f->anticollapse_needed) - opus_rc_tell_frac(rc) - 1;

    if (band <= f->coded_bands - 1) {

        int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band);

        b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14);

    }

    if (f->dual_stereo) {

        pvq->quant_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL,

                        f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]);

        pvq->quant_band(pvq, f, rc, band, Y, NULL, band_size, b / 2, f->blocks, NULL,

                        f->size, norm2, 0, 1.0f, lowband_scratch, cm[1]);

    } else {

        pvq->quant_band(pvq, f, rc, band, X, Y, band_size, b, f->blocks, NULL, f->size,

                        norm1, 0, 1.0f, lowband_scratch, cm[0] | cm[1]);

    }

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

        err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]);

        if (Y)

            err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]);

    }

    dist = sqrtf(err_x) + sqrtf(err_y);

    cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f;

    *bits += cost;

    OPUS_RC_CHECKPOINT_ROLLBACK(rc);

    return lambda*dist*cost;

}


static int mpegts_read_header(AVFormatContext *s)

{

    MpegTSContext *ts = s->priv_data;

    AVIOContext *pb   = s->pb;

    uint8_t buf[8 * 1024] = {0};

    int len;

    int64_t pos, probesize =

#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI

                             s->probesize ? s->probesize : s->probesize2;

#else

                             s->probesize;

#endif

    if (ffio_ensure_seekback(pb, probesize) < 0)

        av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");

    /* read the first 8192 bytes to get packet size */

    pos = avio_tell(pb);

    len = avio_read(pb, buf, sizeof(buf));

    ts->raw_packet_size = get_packet_size(buf, len);

    if (ts->raw_packet_size <= 0) {

        av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");

        ts->raw_packet_size = TS_PACKET_SIZE;

    }

    ts->stream     = s;

    ts->auto_guess = 0;

    if (s->iformat == &ff_mpegts_demuxer) {

        /* normal demux */

        /* first do a scan to get all the services */

        seek_back(s, pb, pos);

        mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);

        mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);

        handle_packets(ts, probesize / ts->raw_packet_size);

        /* if could not find service, enable auto_guess */

        ts->auto_guess = 1;

        av_log(ts->stream, AV_LOG_TRACE, "tuning done\n");

        s->ctx_flags |= AVFMTCTX_NOHEADER;

    } else {

        AVStream *st;

        int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l;

        int64_t pcrs[2], pcr_h;

        int packet_count[2];

        uint8_t packet[TS_PACKET_SIZE];

        const uint8_t *data;

        /* only read packets */

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        avpriv_set_pts_info(st, 60, 1, 27000000);

        st->codec->codec_type = AVMEDIA_TYPE_DATA;

        st->codec->codec_id   = AV_CODEC_ID_MPEG2TS;

        /* we iterate until we find two PCRs to estimate the bitrate */

        pcr_pid    = -1;

        nb_pcrs    = 0;

        nb_packets = 0;

        for (;;) {

            ret = read_packet(s, packet, ts->raw_packet_size, &data);

            if (ret < 0)

                return ret;

            pid = AV_RB16(data + 1) & 0x1fff;

            if ((pcr_pid == -1 || pcr_pid == pid) &&

                parse_pcr(&pcr_h, &pcr_l, data) == 0) {

                finished_reading_packet(s, ts->raw_packet_size);

                pcr_pid = pid;

                packet_count[nb_pcrs] = nb_packets;

                pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;

                nb_pcrs++;

                if (nb_pcrs >= 2)

                    break;

            } else {

                finished_reading_packet(s, ts->raw_packet_size);

            }

            nb_packets++;

        }

        /* NOTE1: the bitrate is computed without the FEC */

        /* NOTE2: it is only the bitrate of the start of the stream */

        ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]);

        ts->cur_pcr  = pcrs[0] - ts->pcr_incr * packet_count[0];

        s->bit_rate  = TS_PACKET_SIZE * 8 * 27000000LL / ts->pcr_incr;

        st->codec->bit_rate = s->bit_rate;

        st->start_time      = ts->cur_pcr;

        av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%d\n",

                st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);

    }

    seek_back(s, pb, pos);

    return 0;

}


static void apply_tns(float coef[1024], TemporalNoiseShaping *tns,

                      IndividualChannelStream *ics, int decode)

{

    const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);

    int w, filt, m, i;

    int bottom, top, order, start, end, size, inc;

    float lpc[TNS_MAX_ORDER];

    float tmp[TNS_MAX_ORDER];

    for (w = 0; w < ics->num_windows; w++) {

        bottom = ics->num_swb;

        for (filt = 0; filt < tns->n_filt[w]; filt++) {

            top    = bottom;

            bottom = FFMAX(0, top - tns->length[w][filt]);

            order  = tns->order[w][filt];

            if (order == 0)

                continue;

            // tns_decode_coef

            compute_lpc_coefs(tns->coef[w][filt], order, lpc, 0, 0, 0);

            start = ics->swb_offset[FFMIN(bottom, mmm)];

            end   = ics->swb_offset[FFMIN(   top, mmm)];

            if ((size = end - start) <= 0)

                continue;

            if (tns->direction[w][filt]) {

                inc = -1;

                start = end - 1;

            } else {

                inc = 1;

            }

            start += w * 128;

            if (decode) {

                // ar filter

                for (m = 0; m < size; m++, start += inc)

                    for (i = 1; i <= FFMIN(m, order); i++)

                        coef[start] -= coef[start - i * inc] * lpc[i - 1];

            } else {

                // ma filter

                for (m = 0; m < size; m++, start += inc) {

                    tmp[0] = coef[start];

                    for (i = 1; i <= FFMIN(m, order); i++)

                        coef[start] += tmp[i] * lpc[i - 1];

                    for (i = order; i > 0; i--)

                        tmp[i] = tmp[i - 1];

                }

            }

        }

    }

}


void do_info_snapshots(Monitor *mon)

{

    DriveInfo *dinfo;

    BlockDriverState *bs, *bs1;

    QEMUSnapshotInfo *sn_tab, *sn;

    int nb_sns, i;

    char buf[256];

    bs = get_bs_snapshots();

    if (!bs) {

        monitor_printf(mon, "No available block device supports snapshots\n");

        return;

    }

    monitor_printf(mon, "Snapshot devices:");

    QTAILQ_FOREACH(dinfo, &drives, next) {

        bs1 = dinfo->bdrv;

        if (bdrv_has_snapshot(bs1)) {

            if (bs == bs1)

                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));

        }

    }

    monitor_printf(mon, "\n");

    nb_sns = bdrv_snapshot_list(bs, &sn_tab);

    if (nb_sns < 0) {

        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);

        return;

    }

    monitor_printf(mon, "Snapshot list (from %s):\n",

                   bdrv_get_device_name(bs));

    monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));

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

        sn = &sn_tab[i];

        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));

    }

    qemu_free(sn_tab);

}


static int activate(AVFilterContext *ctx)

{

    PreMultiplyContext *s = ctx->priv;

    if (s->inplace) {

        AVFrame *frame = NULL;

        AVFrame *out = NULL;

        int ret, status;

        int64_t pts;

        if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) {

            if ((ret = filter_frame(ctx, &out, frame, frame)) < 0)

                return ret;

            av_frame_free(&frame);

            ret = ff_filter_frame(ctx->outputs[0], out);

        }

        if (ret < 0) {

            return ret;

        } else if (ff_inlink_acknowledge_status(ctx->inputs[0], &status, &pts)) {

            ff_outlink_set_status(ctx->outputs[0], status, pts);

            return 0;

        } else {

            if (ff_outlink_frame_wanted(ctx->outputs[0]))

                ff_inlink_request_frame(ctx->inputs[0]);

            return 0;

        }

    } else {

        return ff_framesync_activate(&s->fs);

    }

}


int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)

{

    return -EINVAL;

}


static int unix_open(URLContext *h, const char *filename, int flags)

{

    UnixContext *s = h->priv_data;

    int fd, ret;

    av_strstart(filename, "unix:", &filename);

    s->addr.sun_family = AF_UNIX;

    av_strlcpy(s->addr.sun_path, filename, sizeof(s->addr.sun_path));

    if ((fd = ff_socket(AF_UNIX, s->type, 0)) < 0)

        return ff_neterrno();

    if (s->listen) {

        fd = ff_listen_bind(fd, (struct sockaddr *)&s->addr,

                            sizeof(s->addr), s->timeout, h);

        if (fd < 0) {

            ret = fd;

            goto fail;

        }

    } else {

        ret = ff_listen_connect(fd, (struct sockaddr *)&s->addr,

                                sizeof(s->addr), s->timeout, h, 0);

        if (ret < 0)

            goto fail;

    }

    s->fd = fd;

    return 0;

fail:

    if (s->listen && AVUNERROR(ret) != EADDRINUSE)

        unlink(s->addr.sun_path);

    if (fd >= 0)

        closesocket(fd);

    return ret;

}


static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)

{

    gen_set_cpsr(cpsr, 0xffffffff);

    dead_tmp(cpsr);

    store_reg(s, 15, pc);

    s->is_jmp = DISAS_UPDATE;

}


static inline void RENAME(rgb16ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)

{

	int i;

        assert(src1 == src2);

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

	{

		int d0= ((uint32_t*)src1)[i];

		int dl= (d0&0x07E0F81F);

		int dh= ((d0>>5)&0x07C0F83F);

		int dh2= (dh>>11) + (dh<<21);

		int d= dh2 + dl;

		int r= d&0x7F;

		int b= (d>>11)&0x7F;

		int g= d>>21;

		dstU[i]= ((2*RU*r + GU*g + 2*BU*b)>>(RGB2YUV_SHIFT+1-2)) + 128;

		dstV[i]= ((2*RV*r + GV*g + 2*BV*b)>>(RGB2YUV_SHIFT+1-2)) + 128;

	}

}


static int rtl8139_cplus_transmit_one(RTL8139State *s)

{

    if (!rtl8139_transmitter_enabled(s))

    {

        DPRINTF("+++ C+ mode: transmitter disabled\n");

        return 0;

    }

    if (!rtl8139_cp_transmitter_enabled(s))

    {

        DPRINTF("+++ C+ mode: C+ transmitter disabled\n");

        return 0 ;

    }

    int descriptor = s->currCPlusTxDesc;

    dma_addr_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);

    /* Normal priority ring */

    cplus_tx_ring_desc += 16 * descriptor;

    DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at "

        "%08x %08x = 0x"DMA_ADDR_FMT"\n", descriptor, s->TxAddr[1],

        s->TxAddr[0], cplus_tx_ring_desc);

    uint32_t val, txdw0,txdw1,txbufLO,txbufHI;

    pci_dma_read(&s->dev, cplus_tx_ring_desc,    (uint8_t *)&val, 4);

    txdw0 = le32_to_cpu(val);

    pci_dma_read(&s->dev, cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);

    txdw1 = le32_to_cpu(val);

    pci_dma_read(&s->dev, cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);

    txbufLO = le32_to_cpu(val);

    pci_dma_read(&s->dev, cplus_tx_ring_desc+12, (uint8_t *)&val, 4);

    txbufHI = le32_to_cpu(val);

    DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor,

        txdw0, txdw1, txbufLO, txbufHI);

/* w0 ownership flag */

#define CP_TX_OWN (1<<31)

/* w0 end of ring flag */

#define CP_TX_EOR (1<<30)

/* first segment of received packet flag */

#define CP_TX_FS (1<<29)

/* last segment of received packet flag */

#define CP_TX_LS (1<<28)

/* large send packet flag */

#define CP_TX_LGSEN (1<<27)

/* large send MSS mask, bits 16...25 */

#define CP_TC_LGSEN_MSS_MASK ((1 << 12) - 1)

/* IP checksum offload flag */

#define CP_TX_IPCS (1<<18)

/* UDP checksum offload flag */

#define CP_TX_UDPCS (1<<17)

/* TCP checksum offload flag */

#define CP_TX_TCPCS (1<<16)

/* w0 bits 0...15 : buffer size */

#define CP_TX_BUFFER_SIZE (1<<16)

#define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1)

/* w1 add tag flag */

#define CP_TX_TAGC (1<<17)

/* w1 bits 0...15 : VLAN tag (big endian) */

#define CP_TX_VLAN_TAG_MASK ((1<<16) - 1)

/* w2 low  32bit of Rx buffer ptr */

/* w3 high 32bit of Rx buffer ptr */

/* set after transmission */

/* FIFO underrun flag */

#define CP_TX_STATUS_UNF (1<<25)

/* transmit error summary flag, valid if set any of three below */

#define CP_TX_STATUS_TES (1<<23)

/* out-of-window collision flag */

#define CP_TX_STATUS_OWC (1<<22)

/* link failure flag */

#define CP_TX_STATUS_LNKF (1<<21)

/* excessive collisions flag */

#define CP_TX_STATUS_EXC (1<<20)

    if (!(txdw0 & CP_TX_OWN))

    {

        DPRINTF("C+ Tx mode : descriptor %d is owned by host\n", descriptor);

        return 0 ;

    }

    DPRINTF("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor);

    if (txdw0 & CP_TX_FS)

    {

        DPRINTF("+++ C+ Tx mode : descriptor %d is first segment "

            "descriptor\n", descriptor);

        /* reset internal buffer offset */

        s->cplus_txbuffer_offset = 0;

    }

    int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK;

    dma_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);

    /* make sure we have enough space to assemble the packet */

    if (!s->cplus_txbuffer)

    {

        s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;

        s->cplus_txbuffer = g_malloc(s->cplus_txbuffer_len);

        s->cplus_txbuffer_offset = 0;

        DPRINTF("+++ C+ mode transmission buffer allocated space %d\n",

            s->cplus_txbuffer_len);

    }

    while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)

    {

        s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;

        s->cplus_txbuffer = g_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);

        DPRINTF("+++ C+ mode transmission buffer space changed to %d\n",

            s->cplus_txbuffer_len);

    }

    if (!s->cplus_txbuffer)

    {

        /* out of memory */

        DPRINTF("+++ C+ mode transmiter failed to reallocate %d bytes\n",

            s->cplus_txbuffer_len);

        /* update tally counter */

        ++s->tally_counters.TxERR;

        ++s->tally_counters.TxAbt;

        return 0;

    }

    /* append more data to the packet */

    DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at "

            DMA_ADDR_FMT" to offset %d\n", txsize, tx_addr,

            s->cplus_txbuffer_offset);

    pci_dma_read(&s->dev, tx_addr,

                 s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);

    s->cplus_txbuffer_offset += txsize;

    /* seek to next Rx descriptor */

    if (txdw0 & CP_TX_EOR)

    {

        s->currCPlusTxDesc = 0;

    }

    else

    {

        ++s->currCPlusTxDesc;

        if (s->currCPlusTxDesc >= 64)

            s->currCPlusTxDesc = 0;

    }

    /* transfer ownership to target */

    txdw0 &= ~CP_RX_OWN;

    /* reset error indicator bits */

    txdw0 &= ~CP_TX_STATUS_UNF;

    txdw0 &= ~CP_TX_STATUS_TES;

    txdw0 &= ~CP_TX_STATUS_OWC;

    txdw0 &= ~CP_TX_STATUS_LNKF;

    txdw0 &= ~CP_TX_STATUS_EXC;

    /* update ring data */

    val = cpu_to_le32(txdw0);

    pci_dma_write(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4);

    /* Now decide if descriptor being processed is holding the last segment of packet */

    if (txdw0 & CP_TX_LS)

    {

        uint8_t dot1q_buffer_space[VLAN_HLEN];

        uint16_t *dot1q_buffer;

        DPRINTF("+++ C+ Tx mode : descriptor %d is last segment descriptor\n",

            descriptor);

        /* can transfer fully assembled packet */

        uint8_t *saved_buffer  = s->cplus_txbuffer;

        int      saved_size    = s->cplus_txbuffer_offset;

        int      saved_buffer_len = s->cplus_txbuffer_len;

        /* create vlan tag */

        if (txdw1 & CP_TX_TAGC) {

            /* the vlan tag is in BE byte order in the descriptor

             * BE + le_to_cpu() + ~swap()~ = cpu */

            DPRINTF("+++ C+ Tx mode : inserting vlan tag with ""tci: %u\n",

                bswap16(txdw1 & CP_TX_VLAN_TAG_MASK));

            dot1q_buffer = (uint16_t *) dot1q_buffer_space;

            dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q);

            /* BE + le_to_cpu() + ~cpu_to_le()~ = BE */

            dot1q_buffer[1] = cpu_to_le16(txdw1 & CP_TX_VLAN_TAG_MASK);

        } else {

            dot1q_buffer = NULL;

        }

        /* reset the card space to protect from recursive call */

        s->cplus_txbuffer = NULL;

        s->cplus_txbuffer_offset = 0;

        s->cplus_txbuffer_len = 0;

        if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))

        {

            DPRINTF("+++ C+ mode offloaded task checksum\n");

            /* ip packet header */

            ip_header *ip = NULL;

            int hlen = 0;

            uint8_t  ip_protocol = 0;

            uint16_t ip_data_len = 0;

            uint8_t *eth_payload_data = NULL;

            size_t   eth_payload_len  = 0;

            int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));

            if (proto == ETH_P_IP)

            {

                DPRINTF("+++ C+ mode has IP packet\n");

                /* not aligned */

                eth_payload_data = saved_buffer + ETH_HLEN;

                eth_payload_len  = saved_size   - ETH_HLEN;

                ip = (ip_header*)eth_payload_data;

                if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {

                    DPRINTF("+++ C+ mode packet has bad IP version %d "

                        "expected %d\n", IP_HEADER_VERSION(ip),

                        IP_HEADER_VERSION_4);

                    ip = NULL;

                } else {

                    hlen = IP_HEADER_LENGTH(ip);

                    ip_protocol = ip->ip_p;

                    ip_data_len = be16_to_cpu(ip->ip_len) - hlen;

                }

            }

            if (ip)

            {

                if (txdw0 & CP_TX_IPCS)

                {

                    DPRINTF("+++ C+ mode need IP checksum\n");

                    if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */

                        /* bad packet header len */

                        /* or packet too short */

                    }

                    else

                    {

                        ip->ip_sum = 0;

                        ip->ip_sum = ip_checksum(ip, hlen);

                        DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",

                            hlen, ip->ip_sum);

                    }

                }

                if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)

                {

                    int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;

                    DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "

                        "frame data %d specified MSS=%d\n", ETH_MTU,

                        ip_data_len, saved_size - ETH_HLEN, large_send_mss);

                    int tcp_send_offset = 0;

                    int send_count = 0;

                    /* maximum IP header length is 60 bytes */

                    uint8_t saved_ip_header[60];

                    /* save IP header template; data area is used in tcp checksum calculation */

                    memcpy(saved_ip_header, eth_payload_data, hlen);

                    /* a placeholder for checksum calculation routine in tcp case */

                    uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;

                    //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;

                    /* pointer to TCP header */

                    tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);

                    int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);

                    /* ETH_MTU = ip header len + tcp header len + payload */

                    int tcp_data_len = ip_data_len - tcp_hlen;

                    int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;

                    DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "

                        "data len %d TCP chunk size %d\n", ip_data_len,

                        tcp_hlen, tcp_data_len, tcp_chunk_size);

                    /* note the cycle below overwrites IP header data,

                       but restores it from saved_ip_header before sending packet */

                    int is_last_frame = 0;

                    for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)

                    {

                        uint16_t chunk_size = tcp_chunk_size;

                        /* check if this is the last frame */

                        if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)

                        {

                            is_last_frame = 1;

                            chunk_size = tcp_data_len - tcp_send_offset;

                        }

                        DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",

                            be32_to_cpu(p_tcp_hdr->th_seq));

                        /* add 4 TCP pseudoheader fields */

                        /* copy IP source and destination fields */

                        memcpy(data_to_checksum, saved_ip_header + 12, 8);

                        DPRINTF("+++ C+ mode TSO calculating TCP checksum for "

                            "packet with %d bytes data\n", tcp_hlen +

                            chunk_size);

                        if (tcp_send_offset)

                        {

                            memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);

                        }

                        /* keep PUSH and FIN flags only for the last frame */

                        if (!is_last_frame)

                        {

                            TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);

                        }

                        /* recalculate TCP checksum */

                        ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_tcpip_hdr->zeros      = 0;

                        p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;

                        p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);

                        p_tcp_hdr->th_sum = 0;

                        int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);

                        DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",

                            tcp_checksum);

                        p_tcp_hdr->th_sum = tcp_checksum;

                        /* restore IP header */

                        memcpy(eth_payload_data, saved_ip_header, hlen);

                        /* set IP data length and recalculate IP checksum */

                        ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);

                        /* increment IP id for subsequent frames */

                        ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));

                        ip->ip_sum = 0;

                        ip->ip_sum = ip_checksum(eth_payload_data, hlen);

                        DPRINTF("+++ C+ mode TSO IP header len=%d "

                            "checksum=%04x\n", hlen, ip->ip_sum);

                        int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;

                        DPRINTF("+++ C+ mode TSO transferring packet size "

                            "%d\n", tso_send_size);

                        rtl8139_transfer_frame(s, saved_buffer, tso_send_size,

                            0, (uint8_t *) dot1q_buffer);

                        /* add transferred count to TCP sequence number */

                        p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));

                        ++send_count;

                    }

                    /* Stop sending this frame */

                    saved_size = 0;

                }

                else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))

                {

                    DPRINTF("+++ C+ mode need TCP or UDP checksum\n");

                    /* maximum IP header length is 60 bytes */

                    uint8_t saved_ip_header[60];

                    memcpy(saved_ip_header, eth_payload_data, hlen);

                    uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;

                    //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;

                    /* add 4 TCP pseudoheader fields */

                    /* copy IP source and destination fields */

                    memcpy(data_to_checksum, saved_ip_header + 12, 8);

                    if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)

                    {

                        DPRINTF("+++ C+ mode calculating TCP checksum for "

                            "packet with %d bytes data\n", ip_data_len);

                        ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_tcpip_hdr->zeros      = 0;

                        p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;

                        p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);

                        tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);

                        p_tcp_hdr->th_sum = 0;

                        int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);

                        DPRINTF("+++ C+ mode TCP checksum %04x\n",

                            tcp_checksum);

                        p_tcp_hdr->th_sum = tcp_checksum;

                    }

                    else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)

                    {

                        DPRINTF("+++ C+ mode calculating UDP checksum for "

                            "packet with %d bytes data\n", ip_data_len);

                        ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_udpip_hdr->zeros      = 0;

                        p_udpip_hdr->ip_proto   = IP_PROTO_UDP;

                        p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);

                        udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);

                        p_udp_hdr->uh_sum = 0;

                        int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);

                        DPRINTF("+++ C+ mode UDP checksum %04x\n",

                            udp_checksum);

                        p_udp_hdr->uh_sum = udp_checksum;

                    }

                    /* restore IP header */

                    memcpy(eth_payload_data, saved_ip_header, hlen);

                }

            }

        }

        /* update tally counter */

        ++s->tally_counters.TxOk;

        DPRINTF("+++ C+ mode transmitting %d bytes packet\n", saved_size);

        rtl8139_transfer_frame(s, saved_buffer, saved_size, 1,

            (uint8_t *) dot1q_buffer);

        /* restore card space if there was no recursion and reset offset */

        if (!s->cplus_txbuffer)

        {

            s->cplus_txbuffer        = saved_buffer;

            s->cplus_txbuffer_len    = saved_buffer_len;

            s->cplus_txbuffer_offset = 0;

        }

        else

        {

            g_free(saved_buffer);

        }

    }

    else

    {

        DPRINTF("+++ C+ mode transmission continue to next descriptor\n");

    }

    return 1;

}


static int adpcm_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    ADPCMDecodeContext *c = avctx->priv_data;

    ADPCMChannelStatus *cs;

    int n, m, channel, i;

    int block_predictor[2];

    short *samples;

    short *samples_end;

    const uint8_t *src;

    int st; /* stereo */

    /* DK3 ADPCM accounting variables */

    unsigned char last_byte = 0;

    unsigned char nibble;

    int decode_top_nibble_next = 0;

    int diff_channel;

    /* EA ADPCM state variables */

    uint32_t samples_in_chunk;

    int32_t previous_left_sample, previous_right_sample;

    int32_t current_left_sample, current_right_sample;

    int32_t next_left_sample, next_right_sample;

    int32_t coeff1l, coeff2l, coeff1r, coeff2r;

    uint8_t shift_left, shift_right;

    int count1, count2;

    int coeff[2][2], shift[2];//used in EA MAXIS ADPCM

    if (!buf_size)

        return 0;

    //should protect all 4bit ADPCM variants

    //8 is needed for CODEC_ID_ADPCM_IMA_WAV with 2 channels

    //

    if(*data_size/4 < buf_size + 8)

        return -1;

    samples = data;

    samples_end= samples + *data_size/2;

    *data_size= 0;

    src = buf;

    st = avctx->channels == 2 ? 1 : 0;

    switch(avctx->codec->id) {

    case CODEC_ID_ADPCM_IMA_QT:

        n = buf_size - 2*avctx->channels;

        for (channel = 0; channel < avctx->channels; channel++) {

            int16_t predictor;

            int step_index;

            cs = &(c->status[channel]);

            /* (pppppp) (piiiiiii) */

            /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */

            predictor = AV_RB16(src);

            step_index = predictor & 0x7F;

            predictor &= 0xFF80;

            src += 2;

            if (cs->step_index == step_index) {

                int diff = (int)predictor - cs->predictor;

                if (diff < 0)

                    diff = - diff;

                if (diff > 0x7f)

                    goto update;

            } else {

            update:

                cs->step_index = step_index;

                cs->predictor = predictor;

            }

            if (cs->step_index > 88){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index);

                cs->step_index = 88;

            }

            samples = (short*)data + channel;

            for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */

                *samples = adpcm_ima_qt_expand_nibble(cs, src[0] & 0x0F, 3);

                samples += avctx->channels;

                *samples = adpcm_ima_qt_expand_nibble(cs, src[0] >> 4  , 3);

                samples += avctx->channels;

                src ++;

            }

        }

        if (st)

            samples--;

        break;

    case CODEC_ID_ADPCM_IMA_WAV:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

//        samples_per_block= (block_align-4*chanels)*8 / (bits_per_sample * chanels) + 1;

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

            cs = &(c->status[i]);

            cs->predictor = *samples++ = (int16_t)bytestream_get_le16(&src);

            cs->step_index = *src++;

            if (cs->step_index > 88){

                av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index);

                cs->step_index = 88;

            }

            if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null but is %d!!\n", src[-1]); /* unused */

        }

        while(src < buf + buf_size){

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

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

                    *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3);

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

                    *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4  , 3);

                src++;

            }

            src += 4*st;

        }

        break;

    case CODEC_ID_ADPCM_4XM:

        cs = &(c->status[0]);

        c->status[0].predictor= (int16_t)bytestream_get_le16(&src);

        if(st){

            c->status[1].predictor= (int16_t)bytestream_get_le16(&src);

        }

        c->status[0].step_index= (int16_t)bytestream_get_le16(&src);

        if(st){

            c->status[1].step_index= (int16_t)bytestream_get_le16(&src);

        }

        if (cs->step_index < 0) cs->step_index = 0;

        if (cs->step_index > 88) cs->step_index = 88;

        m= (buf_size - (src - buf))>>st;

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

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] & 0x0F, 4);

            if (st)

                *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4);

            if (st)

                *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4);

        }

        src += m<<st;

        break;

    case CODEC_ID_ADPCM_MS:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

        n = buf_size - 7 * avctx->channels;

        if (n < 0)

            return -1;

        block_predictor[0] = av_clip(*src++, 0, 6);

        block_predictor[1] = 0;

        if (st)

            block_predictor[1] = av_clip(*src++, 0, 6);

        c->status[0].idelta = (int16_t)bytestream_get_le16(&src);

        if (st){

            c->status[1].idelta = (int16_t)bytestream_get_le16(&src);

        }

        c->status[0].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[0]];

        c->status[0].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[0]];

        c->status[1].coeff1 = ff_adpcm_AdaptCoeff1[block_predictor[1]];

        c->status[1].coeff2 = ff_adpcm_AdaptCoeff2[block_predictor[1]];

        c->status[0].sample1 = bytestream_get_le16(&src);

        if (st) c->status[1].sample1 = bytestream_get_le16(&src);

        c->status[0].sample2 = bytestream_get_le16(&src);

        if (st) c->status[1].sample2 = bytestream_get_le16(&src);

        *samples++ = c->status[0].sample2;

        if (st) *samples++ = c->status[1].sample2;

        *samples++ = c->status[0].sample1;

        if (st) *samples++ = c->status[1].sample1;

        for(;n>0;n--) {

            *samples++ = adpcm_ms_expand_nibble(&c->status[0 ], src[0] >> 4  );

            *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F);

            src ++;

        }

        break;

    case CODEC_ID_ADPCM_IMA_DK4:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

        c->status[0].predictor  = (int16_t)bytestream_get_le16(&src);

        c->status[0].step_index = *src++;

        src++;

        *samples++ = c->status[0].predictor;

        if (st) {

            c->status[1].predictor  = (int16_t)bytestream_get_le16(&src);

            c->status[1].step_index = *src++;

            src++;

            *samples++ = c->status[1].predictor;

        }

        while (src < buf + buf_size) {

            /* take care of the top nibble (always left or mono channel) */

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                src[0] >> 4, 3);

            /* take care of the bottom nibble, which is right sample for

             * stereo, or another mono sample */

            if (st)

                *samples++ = adpcm_ima_expand_nibble(&c->status[1],

                    src[0] & 0x0F, 3);

            else

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] & 0x0F, 3);

            src++;

        }

        break;

    case CODEC_ID_ADPCM_IMA_DK3:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

        if(buf_size + 16 > (samples_end - samples)*3/8)

            return -1;

        c->status[0].predictor  = (int16_t)AV_RL16(src + 10);

        c->status[1].predictor  = (int16_t)AV_RL16(src + 12);

        c->status[0].step_index = src[14];

        c->status[1].step_index = src[15];

        /* sign extend the predictors */

        src += 16;

        diff_channel = c->status[1].predictor;

        /* the DK3_GET_NEXT_NIBBLE macro issues the break statement when

         * the buffer is consumed */

        while (1) {

            /* for this algorithm, c->status[0] is the sum channel and

             * c->status[1] is the diff channel */

            /* process the first predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble, 3);

            /* process the diff channel predictor */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[1], nibble, 3);

            /* process the first pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

            /* process the second predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble, 3);

            /* process the second pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

        }

        break;

    case CODEC_ID_ADPCM_IMA_ISS:

        c->status[0].predictor  = (int16_t)AV_RL16(src + 0);

        c->status[0].step_index = src[2];

        src += 4;

        if(st) {

            c->status[1].predictor  = (int16_t)AV_RL16(src + 0);

            c->status[1].step_index = src[2];

            src += 4;

        }

        while (src < buf + buf_size) {

            if (st) {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] >> 4  , 3);

                *samples++ = adpcm_ima_expand_nibble(&c->status[1],

                    src[0] & 0x0F, 3);

            } else {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] & 0x0F, 3);

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] >> 4  , 3);

            }

            src++;

        }

        break;

    case CODEC_ID_ADPCM_IMA_WS:

        /* no per-block initialization; just start decoding the data */

        while (src < buf + buf_size) {

            if (st) {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] >> 4  , 3);

                *samples++ = adpcm_ima_expand_nibble(&c->status[1],

                    src[0] & 0x0F, 3);

            } else {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] >> 4  , 3);

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] & 0x0F, 3);

            }

            src++;

        }

        break;

    case CODEC_ID_ADPCM_XA:

        while (buf_size >= 128) {

            xa_decode(samples, src, &c->status[0], &c->status[1],

                avctx->channels);

            src += 128;

            samples += 28 * 8;

            buf_size -= 128;

        }

        break;

    case CODEC_ID_ADPCM_IMA_EA_EACS:

        samples_in_chunk = bytestream_get_le32(&src) >> (1-st);

        if (samples_in_chunk > buf_size-4-(8<<st)) {

            src += buf_size - 4;

            break;

        }

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

            c->status[i].step_index = bytestream_get_le32(&src);

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

            c->status[i].predictor  = bytestream_get_le32(&src);

        for (; samples_in_chunk; samples_in_chunk--, src++) {

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],  *src>>4,   3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3);

        }

        break;

    case CODEC_ID_ADPCM_IMA_EA_SEAD:

        for (; src < buf+buf_size; src++) {

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6);

            *samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F, 6);

        }

        break;

    case CODEC_ID_ADPCM_EA:

        /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,

           each coding 28 stereo samples. */

        if (buf_size < 12) {

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

            return AVERROR(EINVAL);

        }

        samples_in_chunk = AV_RL32(src);

        if (samples_in_chunk / 28 > (buf_size - 12) / 30) {

            av_log(avctx, AV_LOG_ERROR, "invalid frame\n");

            return AVERROR(EINVAL);

        }

        src += 4;

        current_left_sample   = (int16_t)bytestream_get_le16(&src);

        previous_left_sample  = (int16_t)bytestream_get_le16(&src);

        current_right_sample  = (int16_t)bytestream_get_le16(&src);

        previous_right_sample = (int16_t)bytestream_get_le16(&src);

        for (count1 = 0; count1 < samples_in_chunk/28;count1++) {

            coeff1l = ea_adpcm_table[ *src >> 4       ];

            coeff2l = ea_adpcm_table[(*src >> 4  ) + 4];

            coeff1r = ea_adpcm_table[*src & 0x0F];

            coeff2r = ea_adpcm_table[(*src & 0x0F) + 4];

            src++;

            shift_left  = (*src >> 4  ) + 8;

            shift_right = (*src & 0x0F) + 8;

            src++;

            for (count2 = 0; count2 < 28; count2++) {

                next_left_sample  = (int32_t)((*src & 0xF0) << 24) >> shift_left;

                next_right_sample = (int32_t)((*src & 0x0F) << 28) >> shift_right;

                src++;

                next_left_sample = (next_left_sample +

                    (current_left_sample * coeff1l) +

                    (previous_left_sample * coeff2l) + 0x80) >> 8;

                next_right_sample = (next_right_sample +

                    (current_right_sample * coeff1r) +

                    (previous_right_sample * coeff2r) + 0x80) >> 8;

                previous_left_sample = current_left_sample;

                current_left_sample = av_clip_int16(next_left_sample);

                previous_right_sample = current_right_sample;

                current_right_sample = av_clip_int16(next_right_sample);

                *samples++ = (unsigned short)current_left_sample;

                *samples++ = (unsigned short)current_right_sample;

            }

        }

        if (src - buf == buf_size - 2)

            src += 2; // Skip terminating 0x0000

        break;

    case CODEC_ID_ADPCM_EA_MAXIS_XA:

        for(channel = 0; channel < avctx->channels; channel++) {

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

                coeff[channel][i] = ea_adpcm_table[(*src >> 4) + 4*i];

            shift[channel] = (*src & 0x0F) + 8;

            src++;

        }

        for (count1 = 0; count1 < (buf_size - avctx->channels) / avctx->channels; count1++) {

            for(i = 4; i >= 0; i-=4) { /* Pairwise samples LL RR (st) or LL LL (mono) */

                for(channel = 0; channel < avctx->channels; channel++) {

                    int32_t sample = (int32_t)(((*(src+channel) >> i) & 0x0F) << 0x1C) >> shift[channel];

                    sample = (sample +

                             c->status[channel].sample1 * coeff[channel][0] +

                             c->status[channel].sample2 * coeff[channel][1] + 0x80) >> 8;

                    c->status[channel].sample2 = c->status[channel].sample1;

                    c->status[channel].sample1 = av_clip_int16(sample);

                    *samples++ = c->status[channel].sample1;

                }

            }

            src+=avctx->channels;

        }

        break;

    case CODEC_ID_ADPCM_EA_R1:

    case CODEC_ID_ADPCM_EA_R2:

    case CODEC_ID_ADPCM_EA_R3: {

        /* channel numbering

           2chan: 0=fl, 1=fr

           4chan: 0=fl, 1=rl, 2=fr, 3=rr

           6chan: 0=fl, 1=c,  2=fr, 3=rl,  4=rr, 5=sub */

        const int big_endian = avctx->codec->id == CODEC_ID_ADPCM_EA_R3;

        int32_t previous_sample, current_sample, next_sample;

        int32_t coeff1, coeff2;

        uint8_t shift;

        unsigned int channel;

        uint16_t *samplesC;

        const uint8_t *srcC;

        const uint8_t *src_end = buf + buf_size;

        samples_in_chunk = (big_endian ? bytestream_get_be32(&src)

                                       : bytestream_get_le32(&src)) / 28;

        if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) ||

            28*samples_in_chunk*avctx->channels > samples_end-samples) {

            src += buf_size - 4;

            break;

        }

        for (channel=0; channel<avctx->channels; channel++) {

            int32_t offset = (big_endian ? bytestream_get_be32(&src)

                                         : bytestream_get_le32(&src))

                           + (avctx->channels-channel-1) * 4;

            if ((offset < 0) || (offset >= src_end - src - 4)) break;

            srcC  = src + offset;

            samplesC = samples + channel;

            if (avctx->codec->id == CODEC_ID_ADPCM_EA_R1) {

                current_sample  = (int16_t)bytestream_get_le16(&srcC);

                previous_sample = (int16_t)bytestream_get_le16(&srcC);

            } else {

                current_sample  = c->status[channel].predictor;

                previous_sample = c->status[channel].prev_sample;

            }

            for (count1=0; count1<samples_in_chunk; count1++) {

                if (*srcC == 0xEE) {  /* only seen in R2 and R3 */

                    srcC++;

                    if (srcC > src_end - 30*2) break;

                    current_sample  = (int16_t)bytestream_get_be16(&srcC);

                    previous_sample = (int16_t)bytestream_get_be16(&srcC);

                    for (count2=0; count2<28; count2++) {

                        *samplesC = (int16_t)bytestream_get_be16(&srcC);

                        samplesC += avctx->channels;

                    }

                } else {

                    coeff1 = ea_adpcm_table[ *srcC>>4     ];

                    coeff2 = ea_adpcm_table[(*srcC>>4) + 4];

                    shift = (*srcC++ & 0x0F) + 8;

                    if (srcC > src_end - 14) break;

                    for (count2=0; count2<28; count2++) {

                        if (count2 & 1)

                            next_sample = (int32_t)((*srcC++ & 0x0F) << 28) >> shift;

                        else

                            next_sample = (int32_t)((*srcC   & 0xF0) << 24) >> shift;

                        next_sample += (current_sample  * coeff1) +

                                       (previous_sample * coeff2);

                        next_sample = av_clip_int16(next_sample >> 8);

                        previous_sample = current_sample;

                        current_sample  = next_sample;

                        *samplesC = current_sample;

                        samplesC += avctx->channels;

                    }

                }

            }

            if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) {

                c->status[channel].predictor   = current_sample;

                c->status[channel].prev_sample = previous_sample;

            }

        }

        src = src + buf_size - (4 + 4*avctx->channels);

        samples += 28 * samples_in_chunk * avctx->channels;

        break;

    }

    case CODEC_ID_ADPCM_EA_XAS:

        if (samples_end-samples < 32*4*avctx->channels

            || buf_size < (4+15)*4*avctx->channels) {

            src += buf_size;

            break;

        }

        for (channel=0; channel<avctx->channels; channel++) {

            int coeff[2][4], shift[4];

            short *s2, *s = &samples[channel];

            for (n=0; n<4; n++, s+=32*avctx->channels) {

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

                    coeff[i][n] = ea_adpcm_table[(src[0]&0x0F)+4*i];

                shift[n] = (src[2]&0x0F) + 8;

                for (s2=s, i=0; i<2; i++, src+=2, s2+=avctx->channels)

                    s2[0] = (src[0]&0xF0) + (src[1]<<8);

            }

            for (m=2; m<32; m+=2) {

                s = &samples[m*avctx->channels + channel];

                for (n=0; n<4; n++, src++, s+=32*avctx->channels) {

                    for (s2=s, i=0; i<8; i+=4, s2+=avctx->channels) {

                        int level = (int32_t)((*src & (0xF0>>i)) << (24+i)) >> shift[n];

                        int pred  = s2[-1*avctx->channels] * coeff[0][n]

                                  + s2[-2*avctx->channels] * coeff[1][n];

                        s2[0] = av_clip_int16((level + pred + 0x80) >> 8);

                    }

                }

            }

        }

        samples += 32*4*avctx->channels;

        break;

    case CODEC_ID_ADPCM_IMA_AMV:

    case CODEC_ID_ADPCM_IMA_SMJPEG:

        c->status[0].predictor = (int16_t)bytestream_get_le16(&src);

        c->status[0].step_index = bytestream_get_le16(&src);

        if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)

            src+=4;

        while (src < buf + buf_size) {

            char hi, lo;

            lo = *src & 0x0F;

            hi = *src >> 4;

            if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV)

                FFSWAP(char, hi, lo);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                lo, 3);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                hi, 3);

            src++;

        }

        break;

    case CODEC_ID_ADPCM_CT:

        while (src < buf + buf_size) {

            if (st) {

                *samples++ = adpcm_ct_expand_nibble(&c->status[0],

                    src[0] >> 4);

                *samples++ = adpcm_ct_expand_nibble(&c->status[1],

                    src[0] & 0x0F);

            } else {

                *samples++ = adpcm_ct_expand_nibble(&c->status[0],

                    src[0] >> 4);

                *samples++ = adpcm_ct_expand_nibble(&c->status[0],

                    src[0] & 0x0F);

            }

            src++;

        }

        break;

    case CODEC_ID_ADPCM_SBPRO_4:

    case CODEC_ID_ADPCM_SBPRO_3:

    case CODEC_ID_ADPCM_SBPRO_2:

        if (!c->status[0].step_index) {

            /* the first byte is a raw sample */

            *samples++ = 128 * (*src++ - 0x80);

            if (st)

              *samples++ = 128 * (*src++ - 0x80);

            c->status[0].step_index = 1;

        }

        if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) {

            while (src < buf + buf_size) {

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                    src[0] >> 4, 4, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                    src[0] & 0x0F, 4, 0);

                src++;

            }

        } else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) {

            while (src < buf + buf_size && samples + 2 < samples_end) {

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                     src[0] >> 5        , 3, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                    (src[0] >> 2) & 0x07, 3, 0);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                    src[0] & 0x03, 2, 0);

                src++;

            }

        } else {

            while (src < buf + buf_size && samples + 3 < samples_end) {

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                     src[0] >> 6        , 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                    (src[0] >> 4) & 0x03, 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[0],

                    (src[0] >> 2) & 0x03, 2, 2);

                *samples++ = adpcm_sbpro_expand_nibble(&c->status[st],

                    src[0] & 0x03, 2, 2);

                src++;

            }

        }

        break;

    case CODEC_ID_ADPCM_SWF:

    {

        GetBitContext gb;

        const int *table;

        int k0, signmask, nb_bits, count;

        int size = buf_size*8;

        init_get_bits(&gb, buf, size);

        //read bits & initial values

        nb_bits = get_bits(&gb, 2)+2;

        //av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits);

        table = swf_index_tables[nb_bits-2];

        k0 = 1 << (nb_bits-2);

        signmask = 1 << (nb_bits-1);

        while (get_bits_count(&gb) <= size - 22*avctx->channels) {

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

                *samples++ = c->status[i].predictor = get_sbits(&gb, 16);

                c->status[i].step_index = get_bits(&gb, 6);

            }

            for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) {

                int i;

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

                    // similar to IMA adpcm

                    int delta = get_bits(&gb, nb_bits);

                    int step = ff_adpcm_step_table[c->status[i].step_index];

                    long vpdiff = 0; // vpdiff = (delta+0.5)*step/4

                    int k = k0;

                    do {

                        if (delta & k)

                            vpdiff += step;

                        step >>= 1;

                        k >>= 1;

                    } while(k);

                    vpdiff += step;

                    if (delta & signmask)

                        c->status[i].predictor -= vpdiff;

                    else

                        c->status[i].predictor += vpdiff;

                    c->status[i].step_index += table[delta & (~signmask)];

                    c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88);

                    c->status[i].predictor = av_clip_int16(c->status[i].predictor);

                    *samples++ = c->status[i].predictor;

                    if (samples >= samples_end) {

                        av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");

                        return -1;

                    }

                }

            }

        }

        src += buf_size;

        break;

    }

    case CODEC_ID_ADPCM_YAMAHA:

        while (src < buf + buf_size) {

            if (st) {

                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],

                        src[0] & 0x0F);

                *samples++ = adpcm_yamaha_expand_nibble(&c->status[1],

                        src[0] >> 4  );

            } else {

                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],

                        src[0] & 0x0F);

                *samples++ = adpcm_yamaha_expand_nibble(&c->status[0],

                        src[0] >> 4  );

            }

            src++;

        }

        break;

    case CODEC_ID_ADPCM_THP:

    {

        int table[2][16];

        unsigned int samplecnt;

        int prev[2][2];

        int ch;

        if (buf_size < 80) {

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

            return -1;

        }

        src+=4;

        samplecnt = bytestream_get_be32(&src);

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

            table[0][i] = (int16_t)bytestream_get_be16(&src);

        /* Initialize the previous sample.  */

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

            prev[0][i] = (int16_t)bytestream_get_be16(&src);

        if (samplecnt >= (samples_end - samples) /  (st + 1)) {

            av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n");

            return -1;

        }

        for (ch = 0; ch <= st; ch++) {

            samples = (unsigned short *) data + ch;

            /* Read in every sample for this channel.  */

            for (i = 0; i < samplecnt / 14; i++) {

                int index = (*src >> 4) & 7;

                unsigned int exp = 28 - (*src++ & 15);

                int factor1 = table[ch][index * 2];

                int factor2 = table[ch][index * 2 + 1];

                /* Decode 14 samples.  */

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

                    int32_t sampledat;

                    if(n&1) sampledat=  *src++    <<28;

                    else    sampledat= (*src&0xF0)<<24;

                    sampledat = ((prev[ch][0]*factor1

                                + prev[ch][1]*factor2) >> 11) + (sampledat>>exp);

                    *samples = av_clip_int16(sampledat);

                    prev[ch][1] = prev[ch][0];

                    prev[ch][0] = *samples++;

                    /* In case of stereo, skip one sample, this sample

                       is for the other channel.  */

                    samples += st;

                }

            }

        }

        /* In the previous loop, in case stereo is used, samples is

           increased exactly one time too often.  */

        samples -= st;

        break;

    }

    default:

        return -1;

    }

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

    return src - buf;

}


int DCT_common_init(MpegEncContext *s)

{

    int i;

    ff_put_pixels_clamped = s->dsp.put_pixels_clamped;

    ff_add_pixels_clamped = s->dsp.add_pixels_clamped;

    s->dct_unquantize_h263 = dct_unquantize_h263_c;

    s->dct_unquantize_mpeg1 = dct_unquantize_mpeg1_c;

    s->dct_unquantize_mpeg2 = dct_unquantize_mpeg2_c;

    s->dct_quantize= dct_quantize_c;

    if(s->avctx->dct_algo==FF_DCT_FASTINT)

        s->fdct = fdct_ifast;

    else

        s->fdct = ff_jpeg_fdct_islow; //slow/accurate/default

    if(s->avctx->idct_algo==FF_IDCT_INT){

        s->idct_put= ff_jref_idct_put;

        s->idct_add= ff_jref_idct_add;

        s->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;

    }else{ //accurate/default

        s->idct_put= simple_idct_put;

        s->idct_add= simple_idct_add;

        s->idct_permutation_type= FF_NO_IDCT_PERM;

    }

#ifdef HAVE_MMX

    MPV_common_init_mmx(s);

#endif

#ifdef ARCH_ALPHA

    MPV_common_init_axp(s);

#endif

#ifdef HAVE_MLIB

    MPV_common_init_mlib(s);

#endif

#ifdef HAVE_MMI

    MPV_common_init_mmi(s);

#endif

#ifdef ARCH_ARMV4L

    MPV_common_init_armv4l();

#endif

#ifdef ARCH_POWERPC

    MPV_common_init_ppc(s);

#endif

    switch(s->idct_permutation_type){

    case FF_NO_IDCT_PERM:

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

            s->idct_permutation[i]= i;

        break;

    case FF_LIBMPEG2_IDCT_PERM:

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

            s->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);

        break;

    case FF_SIMPLE_IDCT_PERM:

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

            s->idct_permutation[i]= simple_mmx_permutation[i];

        break;

    case FF_TRANSPOSE_IDCT_PERM:

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

            s->idct_permutation[i]= ((i&7)<<3) | (i>>3);

        break;

    default:

        fprintf(stderr, "Internal error, IDCT permutation not set\n");

        return -1;

    }

    /* load & permutate scantables

       note: only wmv uses differnt ones

    */

    ff_init_scantable(s, &s->inter_scantable  , ff_zigzag_direct);

    ff_init_scantable(s, &s->intra_scantable  , ff_zigzag_direct);

    ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan);

    ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan);

    return 0;

}


static void yuv2yuvX_c(SwsContext *c, const int16_t *lumFilter,

                       const int16_t **lumSrc, int lumFilterSize,

                       const int16_t *chrFilter, const int16_t **chrUSrc,

                       const int16_t **chrVSrc,

                       int chrFilterSize, const int16_t **alpSrc,

                       uint8_t *dest, uint8_t *uDest, uint8_t *vDest,

                       uint8_t *aDest, int dstW, int chrDstW)

{

    //FIXME Optimize (just quickly written not optimized..)

    int i;

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

        int val=1<<18;

        int j;

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

            val += lumSrc[j][i] * lumFilter[j];

        dest[i]= av_clip_uint8(val>>19);

    }

    if (uDest)

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

            int u=1<<18;

            int v=1<<18;

            int j;

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

                u += chrUSrc[j][i] * chrFilter[j];

                v += chrVSrc[j][i] * chrFilter[j];

            }

            uDest[i]= av_clip_uint8(u>>19);

            vDest[i]= av_clip_uint8(v>>19);

        }

    if (CONFIG_SWSCALE_ALPHA && aDest)

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

            int val=1<<18;

            int j;

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

                val += alpSrc[j][i] * lumFilter[j];

            aDest[i]= av_clip_uint8(val>>19);

        }

}


static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,

                                   av_unused const uint8_t *buffer,

                                   av_unused uint32_t size)

{

    const struct MpegEncContext *s = avctx->priv_data;

    AVDXVAContext *ctx = avctx->hwaccel_context;

    struct dxva2_picture_context *ctx_pic =

        s->current_picture_ptr->hwaccel_picture_private;

    if (!DXVA_CONTEXT_VALID(avctx, ctx))

        return -1;

    assert(ctx_pic);

    fill_picture_parameters(avctx, ctx, s, &ctx_pic->pp);

    fill_quantization_matrices(avctx, ctx, s, &ctx_pic->qm);

    ctx_pic->slice_count    = 0;

    ctx_pic->bitstream_size = 0;

    ctx_pic->bitstream      = NULL;

    return 0;

}


static void avc_luma_vt_and_aver_dst_4x4_msa(const uint8_t *src,

                                             int32_t src_stride,

                                             uint8_t *dst, int32_t dst_stride)

{

    int16_t filt_const0 = 0xfb01;

    int16_t filt_const1 = 0x1414;

    int16_t filt_const2 = 0x1fb;

    v16u8 dst0, dst1, dst2, dst3;

    v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8;

    v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r;

    v16i8 src87_r, src2110, src4332, src6554, src8776;

    v8i16 out10, out32;

    v16i8 filt0, filt1, filt2;

    v16u8 res;

    filt0 = (v16i8) __msa_fill_h(filt_const0);

    filt1 = (v16i8) __msa_fill_h(filt_const1);

    filt2 = (v16i8) __msa_fill_h(filt_const2);

    LD_SB5(src, src_stride, src0, src1, src2, src3, src4);

    src += (5 * src_stride);

    ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3,

               src10_r, src21_r, src32_r, src43_r);

    ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332);

    XORI_B2_128_SB(src2110, src4332);

    LD_SB4(src, src_stride, src5, src6, src7, src8);

    ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7,

               src54_r, src65_r, src76_r, src87_r);

    ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776);

    XORI_B2_128_SB(src6554, src8776);

    out10 = DPADD_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2);

    out32 = DPADD_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2);

    SRARI_H2_SH(out10, out32, 5);

    SAT_SH2_SH(out10, out32, 7);

    LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3);

    res = PCKEV_XORI128_UB(out10, out32);

    ILVR_W2_UB(dst1, dst0, dst3, dst2, dst0, dst1);

    dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);

    dst0 = __msa_aver_u_b(res, dst0);

    ST4x4_UB(dst0, dst0, 0, 1, 2, 3, dst, dst_stride);

}


static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,

                               int *got_frame_ptr, AVPacket *avpkt)

{

    AVFrame *frame         = data;

    const uint8_t *buf     = avpkt->data;

    int buf_size           = avpkt->size;

    MP3On4DecodeContext *s = avctx->priv_data;

    MPADecodeContext *m;

    int fsize, len = buf_size, out_size = 0;

    uint32_t header;

    OUT_INT **out_samples;

    OUT_INT *outptr[2];

    int fr, ch, ret;

    /* get output buffer */

    frame->nb_samples = MPA_FRAME_SIZE;

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

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    out_samples = (OUT_INT **)frame->extended_data;

    // Discard too short frames

    if (buf_size < HEADER_SIZE)

        return AVERROR_INVALIDDATA;

    avctx->bit_rate = 0;

    ch = 0;

    for (fr = 0; fr < s->frames; fr++) {

        fsize = AV_RB16(buf) >> 4;

        fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);

        m     = s->mp3decctx[fr];

        assert(m != NULL);

        if (fsize < HEADER_SIZE) {

            av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");

            return AVERROR_INVALIDDATA;

        }

        header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header

        if (ff_mpa_check_header(header) < 0) // Bad header, discard block

            break;

        avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);

        if (ch + m->nb_channels > avctx->channels ||

            s->coff[fr] + m->nb_channels > avctx->channels) {

            av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "

                                        "channel count\n");

            return AVERROR_INVALIDDATA;

        }

        ch += m->nb_channels;

        outptr[0] = out_samples[s->coff[fr]];

        if (m->nb_channels > 1)

            outptr[1] = out_samples[s->coff[fr] + 1];

        if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0)

            return ret;

        out_size += ret;

        buf      += fsize;

        len      -= fsize;

        avctx->bit_rate += m->bit_rate;

    }

    /* update codec info */

    avctx->sample_rate = s->mp3decctx[0]->sample_rate;

    frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));

    *got_frame_ptr    = 1;

    return buf_size;

}


static int dxva2_h264_start_frame(AVCodecContext *avctx,

                                  av_unused const uint8_t *buffer,

                                  av_unused uint32_t size)

{

    const H264Context *h = avctx->priv_data;

    AVDXVAContext *ctx = avctx->hwaccel_context;

    struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private;

    if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||

        DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||

        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)

        return -1;

    assert(ctx_pic);

    /* Fill up DXVA_PicParams_H264 */

    fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);

    /* Fill up DXVA_Qmatrix_H264 */

    fill_scaling_lists(avctx, ctx, h, &ctx_pic->qm);

    ctx_pic->slice_count    = 0;

    ctx_pic->bitstream_size = 0;

    ctx_pic->bitstream      = NULL;

    return 0;

}


static inline void RENAME(yuv2yuvX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

				    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, long dstW, long chrDstW)

{

#ifdef HAVE_MMX

	if(uDest != NULL)

	{

		asm volatile(

				YSCALEYUV2YV12X(0, CHR_MMX_FILTER_OFFSET)

				:: "r" (&c->redDither),

				"r" (uDest), "p" (chrDstW)

				: "%"REG_a, "%"REG_d, "%"REG_S

			);

		asm volatile(

				YSCALEYUV2YV12X(4096, CHR_MMX_FILTER_OFFSET)

				:: "r" (&c->redDither),

				"r" (vDest), "p" (chrDstW)

				: "%"REG_a, "%"REG_d, "%"REG_S

			);

	}

	asm volatile(

			YSCALEYUV2YV12X(0, LUM_MMX_FILTER_OFFSET)

			:: "r" (&c->redDither),

			   "r" (dest), "p" (dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

		);

#else

#ifdef HAVE_ALTIVEC

yuv2yuvX_altivec_real(lumFilter, lumSrc, lumFilterSize,

		      chrFilter, chrSrc, chrFilterSize,

		      dest, uDest, vDest, dstW, chrDstW);

#else //HAVE_ALTIVEC

yuv2yuvXinC(lumFilter, lumSrc, lumFilterSize,

	    chrFilter, chrSrc, chrFilterSize,

	    dest, uDest, vDest, dstW, chrDstW);

#endif //!HAVE_ALTIVEC

#endif

}


static inline void dv_encode_video_segment(DVVideoContext *s,

                                           uint8_t *dif,

                                           const uint16_t *mb_pos_ptr)

{

    int mb_index, i, j, v;

    int mb_x, mb_y, c_offset, linesize;

    uint8_t*  y_ptr;

    uint8_t*  data;

    uint8_t*  ptr;

    int       do_edge_wrap;

    DCTELEM   block[64] __align8;

    DCTELEM   sblock[5*6][64] __align8;

    EncBlockInfo  enc_blks[5*6];

    PutBitContext pbs[5*6];

    PutBitContext* pb;

    EncBlockInfo* enc_blk;

    int       vs_bit_size = 0;

    int       qnos[5];

    enc_blk = &enc_blks[0];

    pb = &pbs[0];

    for(mb_index = 0; mb_index < 5; mb_index++) {

        v = *mb_pos_ptr++;

        mb_x = v & 0xff;

        mb_y = v >> 8;

        y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);

	c_offset = (s->sys->pix_fmt == PIX_FMT_YUV411P) ?

	           ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)) :

		   (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8));

	do_edge_wrap = 0;

	qnos[mb_index] = 15; /* No quantization */

        ptr = dif + mb_index*80 + 4;

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

            if (j < 4) {  /* Four Y blocks */

		/* NOTE: at end of line, the macroblock is handled as 420 */

		if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {

                    data = y_ptr + (j * 8);

                } else {

                    data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]);

                }

		linesize = s->picture.linesize[0];

            } else {      /* Cr and Cb blocks */

	        /* don't ask Fabrice why they inverted Cb and Cr ! */

	        data = s->picture.data[6 - j] + c_offset;

		linesize = s->picture.linesize[6 - j];

		if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))

		    do_edge_wrap = 1;

	    }

	    /* Everything is set up -- now just copy data -> DCT block */

	    if (do_edge_wrap) {  /* Edge wrap copy: 4x16 -> 8x8 */

		uint8_t* d;

		DCTELEM *b = block;

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

		   d = data + 8 * linesize;

		   b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3];

                   b[4] =    d[0]; b[5] =    d[1]; b[6] =    d[2]; b[7] =    d[3];

		   data += linesize;

		   b += 8;

		}

	    } else {             /* Simple copy: 8x8 -> 8x8 */

	        s->get_pixels(block, data, linesize);

	    }

            enc_blk->dct_mode = dv_guess_dct_mode(block);

	    enc_blk->mb = &sblock[mb_index*6+j][0];

	    enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0;

	    enc_blk->partial_bit_count = 0;

	    enc_blk->partial_bit_buffer = 0;

	    enc_blk->cur_ac = 1;

	    s->fdct[enc_blk->dct_mode](block);

	    dv_set_class_number(block, enc_blk,

	                        enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct,

				j/4*(j%2));

            init_put_bits(pb, ptr, block_sizes[j]/8);

	    put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024) >> 2));

	    put_bits(pb, 1, enc_blk->dct_mode);

	    put_bits(pb, 2, enc_blk->cno);

	    vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] +

	                   enc_blk->bit_size[2] + enc_blk->bit_size[3];

	    ++enc_blk;

	    ++pb;

	    ptr += block_sizes[j]/8;

        }

    }

    if (vs_total_ac_bits < vs_bit_size)

        dv_guess_qnos(&enc_blks[0], &qnos[0]);

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

       dif[i*80 + 3] = qnos[i];

    }

    /* First pass over individual cells only */

    for (j=0; j<5*6; j++)

       dv_encode_ac(&enc_blks[j], &pbs[j], 1);

    /* Second pass over each MB space */

    for (j=0; j<5*6; j++) {

       if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count)

           dv_encode_ac(&enc_blks[j], &pbs[(j/6)*6], 6);

    }

    /* Third and final pass over the whole vides segment space */

    for (j=0; j<5*6; j++) {

       if (enc_blks[j].cur_ac < 65 || enc_blks[j].partial_bit_count)

           dv_encode_ac(&enc_blks[j], &pbs[0], 6*5);

    }

    for (j=0; j<5*6; j++)

       flush_put_bits(&pbs[j]);

}


static double fade_gain(int curve, int64_t index, int range)

{

    double gain;

    gain = av_clipd(1.0 * index / range, 0, 1.0);

    switch (curve) {

    case QSIN:

        gain = sin(gain * M_PI / 2.0);

        break;

    case IQSIN:

        gain = 0.636943 * asin(gain);

        break;

    case ESIN:

        gain = 1.0 - cos(M_PI / 4.0 * (pow(2.0*gain - 1, 3) + 1));

        break;

    case HSIN:

        gain = (1.0 - cos(gain * M_PI)) / 2.0;

        break;

    case IHSIN:

        gain = 0.318471 * acos(1 - 2 * gain);

        break;

    case EXP:

        gain = pow(0.1, (1 - gain) * 5.0);

        break;

    case LOG:

        gain = av_clipd(0.0868589 * log(100000 * gain), 0, 1.0);

        break;

    case PAR:

        gain = 1 - sqrt(1 - gain);

        break;

    case IPAR:

        gain = (1 - (1 - gain) * (1 - gain));

        break;

    case QUA:

        gain *= gain;

        break;

    case CUB:

        gain = gain * gain * gain;

        break;

    case SQU:

        gain = sqrt(gain);

        break;

    case CBR:

        gain = cbrt(gain);

        break;

    case DESE:

        gain = gain <= 0.5 ? pow(2 * gain, 1/3.) / 2: 1 - pow(2 * (1 - gain), 1/3.) / 2;

        break;

    case DESI:

        gain = gain <= 0.5 ? pow(2 * gain, 3) / 2: 1 - pow(2 * (1 - gain), 3) / 2;

        break;

    }

    return gain;

}


static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {

    switch(avctx->colorspace) {

        case AVCOL_SPC_BT709:

            *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;

            break;

        case AVCOL_SPC_UNSPECIFIED:

            *matrix = NULL;

            break;

        case AVCOL_SPC_BT470BG:

        case AVCOL_SPC_SMPTE170M:

            *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;

            break;

        case AVCOL_SPC_SMPTE240M:

            *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;

            break;

        case AVCOL_SPC_BT2020_NCL:

            *matrix = kCVImageBufferYCbCrMatrix_ITU_R_2020;

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "Color space %s is not supported.\n", av_color_space_name(avctx->colorspace));

            return -1;

    }

    return 0;

}


static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)

{

    AVStream *fst;

    fst = av_mallocz(sizeof(AVStream));

    if (!fst)

        return NULL;

    if (copy) {

        fst->codec= avcodec_alloc_context();

        memcpy(fst->codec, codec, sizeof(AVCodecContext));

        if (codec->extradata_size) {

            fst->codec->extradata = av_malloc(codec->extradata_size);

            memcpy(fst->codec->extradata, codec->extradata,

                codec->extradata_size);

        }

    } else {

        /* live streams must use the actual feed's codec since it may be

         * updated later to carry extradata needed by the streams.

         */

        fst->codec = codec;

    }

    fst->priv_data = av_mallocz(sizeof(FeedData));

    fst->index = stream->nb_streams;

    av_set_pts_info(fst, 33, 1, 90000);

    fst->sample_aspect_ratio = (AVRational){0,1};

    stream->streams[stream->nb_streams++] = fst;

    return fst;

}


static void buffer_reserve(Buffer *buffer, size_t len)

{

    if ((buffer->capacity - buffer->offset) < len) {

	buffer->capacity += (len + 1024);

	buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);

	if (buffer->buffer == NULL) {

	    fprintf(stderr, "vnc: out of memory\n");

	    exit(1);

	}

    }

}


static void qmp_input_end_struct(Visitor *v, Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

    qmp_input_pop(qiv, errp);

}


MemoryRegionSection memory_region_find(MemoryRegion *mr,

                                       hwaddr addr, uint64_t size)

{

    MemoryRegionSection ret = { .mr = NULL };

    MemoryRegion *root;

    AddressSpace *as;

    AddrRange range;

    FlatView *view;

    FlatRange *fr;

    addr += mr->addr;

    for (root = mr; root->container; ) {

        root = root->container;

        addr += root->addr;

    }

    as = memory_region_to_address_space(root);

    if (!as) {

        return ret;

    }

    range = addrrange_make(int128_make64(addr), int128_make64(size));

    rcu_read_lock();

    view = atomic_rcu_read(&as->current_map);

    fr = flatview_lookup(view, range);

    if (!fr) {

        goto out;

    }

    while (fr > view->ranges && addrrange_intersects(fr[-1].addr, range)) {

        --fr;

    }

    ret.mr = fr->mr;

    ret.address_space = as;

    range = addrrange_intersection(range, fr->addr);

    ret.offset_within_region = fr->offset_in_region;

    ret.offset_within_region += int128_get64(int128_sub(range.start,

                                                        fr->addr.start));

    ret.size = range.size;

    ret.offset_within_address_space = int128_get64(range.start);

    ret.readonly = fr->readonly;

    memory_region_ref(ret.mr);

out:

    rcu_read_unlock();

    return ret;

}


static void vnc_colordepth(DisplayState *ds)

{

    int host_big_endian_flag;

    struct VncState *vs = ds->opaque;

#ifdef WORDS_BIGENDIAN

    host_big_endian_flag = 1;

#else

    host_big_endian_flag = 0;

#endif

    switch (ds_get_bits_per_pixel(ds)) {

        case 8:

            vs->depth = 1;

            vs->server_red_max = 7;

            vs->server_green_max = 7;

            vs->server_blue_max = 3;

            vs->server_red_shift = 5;

            vs->server_green_shift = 2;

            vs->server_blue_shift = 0;

            break;

        case 16:

            vs->depth = 2;

            vs->server_red_max = 31;

            vs->server_green_max = 63;

            vs->server_blue_max = 31;

            vs->server_red_shift = 11;

            vs->server_green_shift = 5;

            vs->server_blue_shift = 0;

            break;

        case 32:

            vs->depth = 4;

            vs->server_red_max = 255;

            vs->server_green_max = 255;

            vs->server_blue_max = 255;

            vs->server_red_shift = 16;

            vs->server_green_shift = 8;

            vs->server_blue_shift = 0;

            break;

        default:

            return;

    }

    if (vs->csock != -1 && vs->has_WMVi) {

        /* Sending a WMVi message to notify the client*/

        vnc_write_u8(vs, 0);  /* msg id */

        vnc_write_u8(vs, 0);

        vnc_write_u16(vs, 1); /* number of rects */

        vnc_framebuffer_update(vs, 0, 0, ds_get_width(ds), ds_get_height(ds), 0x574D5669);

        pixel_format_message(vs);

        vnc_flush(vs);

    } else {

        if (vs->pix_bpp == 4 && vs->depth == 4 &&

                host_big_endian_flag == vs->pix_big_endian &&

                vs->client_red_max == 0xff && vs->client_green_max == 0xff && vs->client_blue_max == 0xff &&

                vs->client_red_shift == 16 && vs->client_green_shift == 8 && vs->client_blue_shift == 0) {

            vs->write_pixels = vnc_write_pixels_copy;

            vs->send_hextile_tile = send_hextile_tile_32;

        } else if (vs->pix_bpp == 2 && vs->depth == 2 &&

                host_big_endian_flag == vs->pix_big_endian &&

                vs->client_red_max == 31 && vs->client_green_max == 63 && vs->client_blue_max == 31 &&

                vs->client_red_shift == 11 && vs->client_green_shift == 5 && vs->client_blue_shift == 0) {

            vs->write_pixels = vnc_write_pixels_copy;

            vs->send_hextile_tile = send_hextile_tile_16;

        } else if (vs->pix_bpp == 1 && vs->depth == 1 &&

                host_big_endian_flag == vs->pix_big_endian &&

                vs->client_red_max == 7 && vs->client_green_max == 7 && vs->client_blue_max == 3 &&

                vs->client_red_shift == 5 && vs->client_green_shift == 2 && vs->client_blue_shift == 0) {

            vs->write_pixels = vnc_write_pixels_copy;

            vs->send_hextile_tile = send_hextile_tile_8;

        } else {

            if (vs->depth == 4) {

                vs->send_hextile_tile = send_hextile_tile_generic_32;

            } else if (vs->depth == 2) {

                vs->send_hextile_tile = send_hextile_tile_generic_16;

            } else {

                vs->send_hextile_tile = send_hextile_tile_generic_8;

            }

            vs->write_pixels = vnc_write_pixels_generic;

        }

    }

}


int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)

{

    RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;

    MpegEncContext * const s = &r->s, * const s1 = &r1->s;

    int err;

    if (dst == src || !s1->context_initialized)

        return 0;

    if (s->height != s1->height || s->width != s1->width) {

        ff_MPV_common_end(s);

        s->height = s1->height;

        s->width  = s1->width;

        if ((err = ff_MPV_common_init(s)) < 0)

            return err;

        if ((err = rv34_decoder_realloc(r)) < 0)

            return err;

    }

    if ((err = ff_mpeg_update_thread_context(dst, src)))

        return err;

    r->cur_pts  = r1->cur_pts;

    r->last_pts = r1->last_pts;

    r->next_pts = r1->next_pts;

    memset(&r->si, 0, sizeof(r->si));

    /* necessary since it is it the condition checked for in decode_slice

     * to call ff_MPV_frame_start. cmp. comment at the end of decode_frame */

    s->current_picture_ptr = NULL;

    return 0;

}


static av_cold int flac_encode_init(AVCodecContext *avctx)

{

    int freq = avctx->sample_rate;

    int channels = avctx->channels;

    FlacEncodeContext *s = avctx->priv_data;

    int i, level;

    uint8_t *streaminfo;

    s->avctx = avctx;

    dsputil_init(&s->dsp, avctx);

    if (avctx->sample_fmt != SAMPLE_FMT_S16)

        return -1;

    if (channels < 1 || channels > FLAC_MAX_CHANNELS)

        return -1;

    s->channels = channels;

    /* find samplerate in table */

    if (freq < 1)

        return -1;

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

        if (freq == ff_flac_sample_rate_table[i]) {

            s->samplerate = ff_flac_sample_rate_table[i];

            s->sr_code[0] = i;

            s->sr_code[1] = 0;

            break;

        }

    }

    /* if not in table, samplerate is non-standard */

    if (i == 12) {

        if (freq % 1000 == 0 && freq < 255000) {

            s->sr_code[0] = 12;

            s->sr_code[1] = freq / 1000;

        } else if (freq % 10 == 0 && freq < 655350) {

            s->sr_code[0] = 14;

            s->sr_code[1] = freq / 10;

        } else if (freq < 65535) {

            s->sr_code[0] = 13;

            s->sr_code[1] = freq;

        } else {

            return -1;

        }

        s->samplerate = freq;

    }

    /* set compression option defaults based on avctx->compression_level */

    if (avctx->compression_level < 0)

        s->options.compression_level = 5;

    else

        s->options.compression_level = avctx->compression_level;

    av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", s->options.compression_level);

    level = s->options.compression_level;

    if (level > 12) {

        av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n",

               s->options.compression_level);

        return -1;

    }

    s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level];

    s->options.lpc_type      = ((int[]){ AV_LPC_TYPE_FIXED,    AV_LPC_TYPE_FIXED,    AV_LPC_TYPE_FIXED,

                                         AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON,

                                         AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON,

                                         AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON, AV_LPC_TYPE_LEVINSON,

                                         AV_LPC_TYPE_LEVINSON})[level];

    s->options.min_prediction_order = ((int[]){  2,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1})[level];

    s->options.max_prediction_order = ((int[]){  3,  4,  4,  6,  8,  8,  8,  8, 12, 12, 12, 32, 32})[level];

    s->options.prediction_order_method = ((int[]){ ORDER_METHOD_EST,    ORDER_METHOD_EST,    ORDER_METHOD_EST,

                                                   ORDER_METHOD_EST,    ORDER_METHOD_EST,    ORDER_METHOD_EST,

                                                   ORDER_METHOD_4LEVEL, ORDER_METHOD_LOG,    ORDER_METHOD_4LEVEL,

                                                   ORDER_METHOD_LOG,    ORDER_METHOD_SEARCH, ORDER_METHOD_LOG,

                                                   ORDER_METHOD_SEARCH})[level];

    s->options.min_partition_order = ((int[]){  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0})[level];

    s->options.max_partition_order = ((int[]){  2,  2,  3,  3,  3,  8,  8,  8,  8,  8,  8,  8,  8})[level];

    /* set compression option overrides from AVCodecContext */

#if LIBAVCODEC_VERSION_MAJOR < 53

    /* for compatibility with deprecated AVCodecContext.use_lpc */

    if (avctx->use_lpc == 0) {

        s->options.lpc_type = AV_LPC_TYPE_FIXED;

    } else if (avctx->use_lpc == 1) {

        s->options.lpc_type = AV_LPC_TYPE_LEVINSON;

    } else if (avctx->use_lpc > 1) {

        s->options.lpc_type   = AV_LPC_TYPE_CHOLESKY;

        s->options.lpc_passes = avctx->use_lpc - 1;

    }

#endif

    if (avctx->lpc_type > AV_LPC_TYPE_DEFAULT) {

        if (avctx->lpc_type > AV_LPC_TYPE_CHOLESKY) {

            av_log(avctx, AV_LOG_ERROR, "unknown lpc type: %d\n", avctx->lpc_type);

            return -1;

        }

        s->options.lpc_type = avctx->lpc_type;

        if (s->options.lpc_type == AV_LPC_TYPE_CHOLESKY) {

            if (avctx->lpc_passes < 0) {

                // default number of passes for Cholesky

                s->options.lpc_passes = 2;

            } else if (avctx->lpc_passes == 0) {

                av_log(avctx, AV_LOG_ERROR, "invalid number of lpc passes: %d\n",

                       avctx->lpc_passes);

                return -1;

            } else {

                s->options.lpc_passes = avctx->lpc_passes;

            }

        }

    }

    switch (s->options.lpc_type) {

    case AV_LPC_TYPE_NONE:

        av_log(avctx, AV_LOG_DEBUG, " lpc type: None\n");

        break;

    case AV_LPC_TYPE_FIXED:

        av_log(avctx, AV_LOG_DEBUG, " lpc type: Fixed pre-defined coefficients\n");

        break;

    case AV_LPC_TYPE_LEVINSON:

        av_log(avctx, AV_LOG_DEBUG, " lpc type: Levinson-Durbin recursion with Welch window\n");

        break;

    case AV_LPC_TYPE_CHOLESKY:

        av_log(avctx, AV_LOG_DEBUG, " lpc type: Cholesky factorization, %d pass%s\n",

               s->options.lpc_passes, s->options.lpc_passes==1?"":"es");

        break;

    }

    if (s->options.lpc_type == AV_LPC_TYPE_NONE) {

        s->options.min_prediction_order = 0;

    } else if (avctx->min_prediction_order >= 0) {

        if (s->options.lpc_type == AV_LPC_TYPE_FIXED) {

            if (avctx->min_prediction_order > MAX_FIXED_ORDER) {

                av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",

                       avctx->min_prediction_order);

                return -1;

            }

        } else if (avctx->min_prediction_order < MIN_LPC_ORDER ||

                   avctx->min_prediction_order > MAX_LPC_ORDER) {

            av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",

                   avctx->min_prediction_order);

            return -1;

        }

        s->options.min_prediction_order = avctx->min_prediction_order;

    }

    if (s->options.lpc_type == AV_LPC_TYPE_NONE) {

        s->options.max_prediction_order = 0;

    } else if (avctx->max_prediction_order >= 0) {

        if (s->options.lpc_type == AV_LPC_TYPE_FIXED) {

            if (avctx->max_prediction_order > MAX_FIXED_ORDER) {

                av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",

                       avctx->max_prediction_order);

                return -1;

            }

        } else if (avctx->max_prediction_order < MIN_LPC_ORDER ||

                   avctx->max_prediction_order > MAX_LPC_ORDER) {

            av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",

                   avctx->max_prediction_order);

            return -1;

        }

        s->options.max_prediction_order = avctx->max_prediction_order;

    }

    if (s->options.max_prediction_order < s->options.min_prediction_order) {

        av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",

               s->options.min_prediction_order, s->options.max_prediction_order);

        return -1;

    }

    av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n",

           s->options.min_prediction_order, s->options.max_prediction_order);

    if (avctx->prediction_order_method >= 0) {

        if (avctx->prediction_order_method > ORDER_METHOD_LOG) {

            av_log(avctx, AV_LOG_ERROR, "invalid prediction order method: %d\n",

                   avctx->prediction_order_method);

            return -1;

        }

        s->options.prediction_order_method = avctx->prediction_order_method;

    }

    switch (s->options.prediction_order_method) {

        case ORDER_METHOD_EST:    av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "estimate"); break;

        case ORDER_METHOD_2LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "2-level"); break;

        case ORDER_METHOD_4LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "4-level"); break;

        case ORDER_METHOD_8LEVEL: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "8-level"); break;

        case ORDER_METHOD_SEARCH: av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "full search"); break;

        case ORDER_METHOD_LOG:    av_log(avctx, AV_LOG_DEBUG, " order method: %s\n",

                                         "log search"); break;

    }

    if (avctx->min_partition_order >= 0) {

        if (avctx->min_partition_order > MAX_PARTITION_ORDER) {

            av_log(avctx, AV_LOG_ERROR, "invalid min partition order: %d\n",

                   avctx->min_partition_order);

            return -1;

        }

        s->options.min_partition_order = avctx->min_partition_order;

    }

    if (avctx->max_partition_order >= 0) {

        if (avctx->max_partition_order > MAX_PARTITION_ORDER) {

            av_log(avctx, AV_LOG_ERROR, "invalid max partition order: %d\n",

                   avctx->max_partition_order);

            return -1;

        }

        s->options.max_partition_order = avctx->max_partition_order;

    }

    if (s->options.max_partition_order < s->options.min_partition_order) {

        av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n",

               s->options.min_partition_order, s->options.max_partition_order);

        return -1;

    }

    av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n",

           s->options.min_partition_order, s->options.max_partition_order);

    if (avctx->frame_size > 0) {

        if (avctx->frame_size < FLAC_MIN_BLOCKSIZE ||

                avctx->frame_size > FLAC_MAX_BLOCKSIZE) {

            av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n",

                   avctx->frame_size);

            return -1;

        }

    } else {

        s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms);

    }

    s->max_blocksize = s->avctx->frame_size;

    av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", s->avctx->frame_size);

    /* set LPC precision */

    if (avctx->lpc_coeff_precision > 0) {

        if (avctx->lpc_coeff_precision > MAX_LPC_PRECISION) {

            av_log(avctx, AV_LOG_ERROR, "invalid lpc coeff precision: %d\n",

                   avctx->lpc_coeff_precision);

            return -1;

        }

        s->options.lpc_coeff_precision = avctx->lpc_coeff_precision;

    } else {

        /* default LPC precision */

        s->options.lpc_coeff_precision = 15;

    }

    av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n",

           s->options.lpc_coeff_precision);

    /* set maximum encoded frame size in verbatim mode */

    s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size,

                                                  s->channels, 16);

    /* initialize MD5 context */

    s->md5ctx = av_malloc(av_md5_size);

    if (!s->md5ctx)

    av_md5_init(s->md5ctx);

    streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);

    if (!streaminfo)

    write_streaminfo(s, streaminfo);

    avctx->extradata = streaminfo;

    avctx->extradata_size = FLAC_STREAMINFO_SIZE;

    s->frame_count   = 0;

    s->min_framesize = s->max_framesize;

    avctx->coded_frame = avcodec_alloc_frame();

    avctx->coded_frame->key_frame = 1;

    return 0;

}


static void init_mbr(BDRVVVFATState* s)

{

    /* TODO: if the files mbr.img and bootsect.img exist, use them */

    mbr_t* real_mbr=(mbr_t*)s->first_sectors;

    partition_t* partition = &(real_mbr->partition[0]);

    int lba;

    memset(s->first_sectors,0,512);

    /* Win NT Disk Signature */

    real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);

    partition->attributes=0x80; /* bootable */

    /* LBA is used when partition is outside the CHS geometry */

    lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);

    lba|= sector2CHS(s->bs, &partition->end_CHS,   s->sector_count);

    /*LBA partitions are identified only by start/length_sector_long not by CHS*/

    partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);

    partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);

    /* FAT12/FAT16/FAT32 */

    /* DOS uses different types when partition is LBA,

       probably to prevent older versions from using CHS on them */

    partition->fs_type= s->fat_type==12 ? 0x1:

                        s->fat_type==16 ? (lba?0xe:0x06):

                         /*fat_tyoe==32*/ (lba?0xc:0x0b);

    real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;

}


static void set_year_20xx(void)
{
    /* Set BCD mode */
    cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & ~REG_B_DM);
    cmos_write(RTC_REG_A, 0x76);
    cmos_write(RTC_YEAR, 0x11);
    cmos_write(RTC_CENTURY, 0x20);
    cmos_write(RTC_MONTH, 0x02);
    cmos_write(RTC_DAY_OF_MONTH, 0x02);
    cmos_write(RTC_HOURS, 0x02);
    cmos_write(RTC_MINUTES, 0x04);
    cmos_write(RTC_SECONDS, 0x58);
    cmos_write(RTC_REG_A, 0x26);
    g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
    g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
    g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
    g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
    /* Set a date in 2080 to ensure there is no year-2038 overflow.  */
    cmos_write(RTC_REG_A, 0x76);
    cmos_write(RTC_YEAR, 0x80);
    cmos_write(RTC_REG_A, 0x26);
    g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
    g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
    g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x80);
    g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);
    cmos_write(RTC_REG_A, 0x76);
    cmos_write(RTC_YEAR, 0x11);
    cmos_write(RTC_REG_A, 0x26);
    g_assert_cmpint(cmos_read(RTC_HOURS), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MINUTES), ==, 0x04);
    g_assert_cmpint(cmos_read(RTC_SECONDS), >=, 0x58);
    g_assert_cmpint(cmos_read(RTC_DAY_OF_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_MONTH), ==, 0x02);
    g_assert_cmpint(cmos_read(RTC_YEAR), ==, 0x11);
    g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20);