static av_always_inline void predict(PredictorState *ps, int *coef,

                                     int output_enable)

{

    const SoftFloat a     = { 1023410176, 0 };  // 61.0 / 64

    const SoftFloat alpha = {  973078528, 0 };  // 29.0 / 32

    SoftFloat e0, e1;

    SoftFloat pv;

    SoftFloat k1, k2;

    SoftFloat   r0 = ps->r0,     r1 = ps->r1;

    SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;

    SoftFloat var0 = ps->var0, var1 = ps->var1;

    SoftFloat tmp;

    if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {

        k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));

    }

    else {

        k1.mant = 0;

        k1.exp = 0;

    }

    if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {

        k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));

    }

    else {

        k2.mant = 0;

        k2.exp = 0;

    }

    tmp = av_mul_sf(k1, r0);

    pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));

    if (output_enable) {

        int shift = 28 - pv.exp;

        if (shift < 31)

            *coef += (pv.mant + (1 << (shift - 1))) >> shift;

    }

    e0 = av_int2sf(*coef, 2);

    e1 = av_sub_sf(e0, tmp);

    ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));

    tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));

    tmp.exp--;

    ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));

    ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));

    tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));

    tmp.exp--;

    ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));

    ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));

    ps->r0 = flt16_trunc(av_mul_sf(a, e0));

}


static OSStatus ffat_decode_callback(AudioConverterRef converter, UInt32 *nb_packets,

                                     AudioBufferList *data,

                                     AudioStreamPacketDescription **packets,

                                     void *inctx)

{

    AVCodecContext *avctx = inctx;

    ATDecodeContext *at = avctx->priv_data;

    if (at->eof) {

        *nb_packets = 0;

        if (packets) {

            *packets = &at->pkt_desc;

            at->pkt_desc.mDataByteSize = 0;

        }

        return 0;

    }

    av_packet_move_ref(&at->in_pkt, &at->new_in_pkt);

    at->new_in_pkt.data = 0;

    at->new_in_pkt.size = 0;

    if (!at->in_pkt.data) {

        *nb_packets = 0;

        return 1;

    }

    data->mNumberBuffers              = 1;

    data->mBuffers[0].mNumberChannels = 0;

    data->mBuffers[0].mDataByteSize   = at->in_pkt.size;

    data->mBuffers[0].mData           = at->in_pkt.data;

    *nb_packets = 1;

    if (packets) {

        *packets = &at->pkt_desc;

        at->pkt_desc.mDataByteSize = at->in_pkt.size;

    }

    return 0;

}


static int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)

{

    int i;

    int s;

    const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0);

    const vector unsigned char permclear = (vector unsigned char){255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0};

    vector unsigned char perm1 = vec_lvsl(0, pix1);

    vector unsigned char perm2 = vec_lvsl(0, pix2);

    vector unsigned char t1, t2, t3,t4, t5;

    vector unsigned int sum;

    vector signed int sumsqr;

    sum = (vector unsigned int)vec_splat_u32(0);

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

        /* Read potentially unaligned pixels into t1 and t2

           Since we're reading 16 pixels, and actually only want 8,

           mask out the last 8 pixels. The 0s don't change the sum. */

        vector unsigned char pix1l = vec_ld( 0, pix1);

        vector unsigned char pix1r = vec_ld(15, pix1);

        vector unsigned char pix2l = vec_ld( 0, pix2);

        vector unsigned char pix2r = vec_ld(15, pix2);

        t1 = vec_and(vec_perm(pix1l, pix1r, perm1), permclear);

        t2 = vec_and(vec_perm(pix2l, pix2r, perm2), permclear);

        /* Since we want to use unsigned chars, we can take advantage

           of the fact that abs(a-b)^2 = (a-b)^2. */

        /* Calculate abs differences vector */

        t3 = vec_max(t1, t2);

        t4 = vec_min(t1, t2);

        t5 = vec_sub(t3, t4);

        /* Square the values and add them to our sum */

        sum = vec_msum(t5, t5, sum);

        pix1 += line_size;

        pix2 += line_size;

    }

    /* Sum up the four partial sums, and put the result into s */

    sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);

    sumsqr = vec_splat(sumsqr, 3);

    vec_ste(sumsqr, 0, &s);

    return s;

}


av_cold void ff_vp8dsp_init_ppc(VP8DSPContext *c)

{

#if HAVE_ALTIVEC

    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))

        return;

    c->put_vp8_epel_pixels_tab[0][0][0] = put_vp8_pixels16_altivec;

    c->put_vp8_epel_pixels_tab[0][0][2] = put_vp8_epel16_h6_altivec;

    c->put_vp8_epel_pixels_tab[0][2][0] = put_vp8_epel16_v6_altivec;

    c->put_vp8_epel_pixels_tab[0][2][2] = put_vp8_epel16_h6v6_altivec;

    c->put_vp8_epel_pixels_tab[1][0][2] = put_vp8_epel8_h6_altivec;

    c->put_vp8_epel_pixels_tab[1][2][0] = put_vp8_epel8_v6_altivec;

    c->put_vp8_epel_pixels_tab[1][0][1] = put_vp8_epel8_h4_altivec;

    c->put_vp8_epel_pixels_tab[1][1][0] = put_vp8_epel8_v4_altivec;

    c->put_vp8_epel_pixels_tab[1][2][2] = put_vp8_epel8_h6v6_altivec;

    c->put_vp8_epel_pixels_tab[1][1][1] = put_vp8_epel8_h4v4_altivec;

    c->put_vp8_epel_pixels_tab[1][1][2] = put_vp8_epel8_h6v4_altivec;

    c->put_vp8_epel_pixels_tab[1][2][1] = put_vp8_epel8_h4v6_altivec;

    c->put_vp8_epel_pixels_tab[2][0][2] = put_vp8_epel4_h6_altivec;

    c->put_vp8_epel_pixels_tab[2][2][0] = put_vp8_epel4_v6_altivec;

    c->put_vp8_epel_pixels_tab[2][0][1] = put_vp8_epel4_h4_altivec;

    c->put_vp8_epel_pixels_tab[2][1][0] = put_vp8_epel4_v4_altivec;

    c->put_vp8_epel_pixels_tab[2][2][2] = put_vp8_epel4_h6v6_altivec;

    c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec;

    c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec;

    c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec;

#endif /* HAVE_ALTIVEC */

}


static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)

{

    Error *local_err = NULL;

    BDRVSheepdogState *s = bs->opaque;

    int ret, fd;

    uint32_t new_vid;

    SheepdogInode *inode;

    unsigned int datalen;

    DPRINTF("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " "

            "is_snapshot %d\n", sn_info->name, sn_info->id_str,

            s->name, sn_info->vm_state_size, s->is_snapshot);

    if (s->is_snapshot) {

        error_report("You can't create a snapshot of a snapshot VDI, "

                     "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);

        return -EINVAL;

    }

    DPRINTF("%s %s\n", sn_info->name, sn_info->id_str);

    s->inode.vm_state_size = sn_info->vm_state_size;

    s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;

    /* It appears that inode.tag does not require a NUL terminator,

     * which means this use of strncpy is ok.

     */

    strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));

    /* we don't need to update entire object */

    datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);

    /* refresh inode. */

    fd = connect_to_sdog(s, &local_err);

    if (fd < 0) {

        error_report("%s", error_get_pretty(local_err));;

        error_free(local_err);

        ret = fd;

        goto cleanup;

    }

    ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),

                       s->inode.nr_copies, datalen, 0, false, s->cache_flags);

    if (ret < 0) {

        error_report("failed to write snapshot's inode.");

        goto cleanup;

    }

    ret = do_sd_create(s, &new_vid, 1, &local_err);

    if (ret < 0) {

        error_report("%s", error_get_pretty(local_err));;

        error_free(local_err);

        error_report("failed to create inode for snapshot. %s",

                     strerror(errno));

        goto cleanup;

    }

    inode = (SheepdogInode *)g_malloc(datalen);

    ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),

                      s->inode.nr_copies, datalen, 0, s->cache_flags);

    if (ret < 0) {

        error_report("failed to read new inode info. %s", strerror(errno));

        goto cleanup;

    }

    memcpy(&s->inode, inode, datalen);

    DPRINTF("s->inode: name %s snap_id %x oid %x\n",

            s->inode.name, s->inode.snap_id, s->inode.vdi_id);

cleanup:

    closesocket(fd);

    return ret;

}


static int probe(AVProbeData *p)

{

    unsigned i, frames, checked = 0;

    if (p->buf_size < 22 || AV_RL16(p->buf) || AV_RL16(p->buf + 2) != 1)

        return 0;

    frames = AV_RL16(p->buf + 4);

    if (!frames)

        return 0;

    for (i = 0; i < frames && i * 16 + 22 <= p->buf_size; i++) {

        unsigned offset;

        if (AV_RL16(p->buf + 10 + i * 16) & ~1)

            return FFMIN(i, AVPROBE_SCORE_MAX / 4);

        if (p->buf[13 + i * 16])

            return FFMIN(i, AVPROBE_SCORE_MAX / 4);

        if (AV_RL32(p->buf + 14 + i * 16) < 40)

            return FFMIN(i, AVPROBE_SCORE_MAX / 4);

        offset = AV_RL32(p->buf + 18 + i * 16);

        if (offset < 22)

            return FFMIN(i, AVPROBE_SCORE_MAX / 4);

        if (offset + 8 > p->buf_size)

            continue;

        if (p->buf[offset] != 40 && AV_RB64(p->buf + offset) != PNGSIG)

            return FFMIN(i, AVPROBE_SCORE_MAX / 4);

        checked++;

    }

    if (checked < frames)

        return AVPROBE_SCORE_MAX / 4 + FFMIN(checked, 1);

    return AVPROBE_SCORE_MAX / 2 + 1;

}


int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc)

{

    inc_tb = av_mul_q(inc_tb, (AVRational) {inc, 1});

    if (av_cmp_q(inc_tb, ts_tb) < 0) {

        //increase step is too small for even 1 step to be representable

        return ts;

    } else {

        int64_t old = av_rescale_q(ts, ts_tb, inc_tb);

        int64_t old_ts = av_rescale_q(old, inc_tb, ts_tb);

        return av_rescale_q(old + 1, inc_tb, ts_tb) + (ts - old_ts);

    }

}


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

                                ptrdiff_t stride)

{

    avc_luma_hv_qrt_8w_msa(src - 2, src - (stride * 2), stride, dst, stride, 8);

}


static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceContext *sl)

{

    const int mb_x    = sl->mb_x;

    const int mb_y    = sl->mb_y;

    const int mb_xy   = sl->mb_xy;

    const int mb_type = h->cur_pic.mb_type[mb_xy];

    uint8_t *dest[3];

    int linesize;

    int i, j, p;

    const int *block_offset = &h->block_offset[0];

    const int transform_bypass = !SIMPLE && (sl->qscale == 0 && h->sps.transform_bypass);

    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & AV_CODEC_FLAG_GRAY)) ? 3 : 1;

    for (p = 0; p < plane_count; p++) {

        dest[p] = h->cur_pic.f->data[p] +

                  ((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16;

        h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT),

                         sl->linesize, 4);

    }

    h->list_counts[mb_xy] = sl->list_count;

    if (!SIMPLE && MB_FIELD(sl)) {

        linesize     = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize * 2;

        block_offset = &h->block_offset[48];

        if (mb_y & 1) // FIXME move out of this function?

            for (p = 0; p < 3; p++)

                dest[p] -= sl->linesize * 15;

        if (FRAME_MBAFF(h)) {

            int list;

            for (list = 0; list < sl->list_count; list++) {

                if (!USES_LIST(mb_type, list))

                    continue;

                if (IS_16X16(mb_type)) {

                    int8_t *ref = &sl->ref_cache[list][scan8[0]];

                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (sl->mb_y & 1), 1);

                } else {

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

                        int ref = sl->ref_cache[list][scan8[i]];

                        if (ref >= 0)

                            fill_rectangle(&sl->ref_cache[list][scan8[i]], 2, 2,

                                           8, (16 + ref) ^ (sl->mb_y & 1), 1);

                    }

                }

            }

        }

    } else {

        linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize;

    }

    if (!SIMPLE && IS_INTRA_PCM(mb_type)) {

        if (PIXEL_SHIFT) {

            const int bit_depth = h->sps.bit_depth_luma;

            GetBitContext gb;

            init_get_bits(&gb, sl->intra_pcm_ptr, 768 * bit_depth);

            for (p = 0; p < plane_count; p++)

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

                    uint16_t *tmp = (uint16_t *)(dest[p] + i * linesize);

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

                        tmp[j] = get_bits(&gb, bit_depth);

                }

        } else {

            for (p = 0; p < plane_count; p++)

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

                    memcpy(dest[p] + i * linesize,

                           sl->intra_pcm_ptr + p * 256 + i * 16, 16);

        }

    } else {

        if (IS_INTRA(mb_type)) {

            if (sl->deblocking_filter)

                xchg_mb_border(h, sl, dest[0], dest[1], dest[2], linesize,

                               linesize, 1, 1, SIMPLE, PIXEL_SHIFT);

            for (p = 0; p < plane_count; p++)

                hl_decode_mb_predict_luma(h, sl, mb_type, SIMPLE,

                                          transform_bypass, PIXEL_SHIFT,

                                          block_offset, linesize, dest[p], p);

            if (sl->deblocking_filter)

                xchg_mb_border(h, sl, dest[0], dest[1], dest[2], linesize,

                               linesize, 0, 1, SIMPLE, PIXEL_SHIFT);

        } else {

            FUNC(hl_motion_444)(h, sl, dest[0], dest[1], dest[2],

                      h->qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,

                      h->qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,

                      h->h264dsp.weight_h264_pixels_tab,

                      h->h264dsp.biweight_h264_pixels_tab);

        }

        for (p = 0; p < plane_count; p++)

            hl_decode_mb_idct_luma(h, sl, mb_type, SIMPLE, transform_bypass,

                                   PIXEL_SHIFT, block_offset, linesize,

                                   dest[p], p);

    }

}


static int parse_times(void *log_ctx, int64_t **times, int *nb_times,

                       const char *times_str)

{

    char *p;

    int i, ret = 0;

    char *times_str1 = av_strdup(times_str);

    char *saveptr = NULL;

    if (!times_str1)

        return AVERROR(ENOMEM);

#define FAIL(err) ret = err; goto end

    *nb_times = 1;

    for (p = times_str1; *p; p++)

        if (*p == ',')

            (*nb_times)++;

    *times = av_malloc(sizeof(**times) * *nb_times);

    if (!*times) {

        av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced times array\n");

        FAIL(AVERROR(ENOMEM));

    }

    p = times_str1;

    for (i = 0; i < *nb_times; i++) {

        int64_t t;

        char *tstr = av_strtok(p, ",", &saveptr);

        av_assert0(tstr);

        p = NULL;

        ret = av_parse_time(&t, tstr, 1);

        if (ret < 0) {

            av_log(log_ctx, AV_LOG_ERROR,

                   "Invalid time duration specification in %s\n", p);

            FAIL(AVERROR(EINVAL));

        }

        (*times)[i] = t;

        /* check on monotonicity */

        if (i && (*times)[i-1] > (*times)[i]) {

            av_log(log_ctx, AV_LOG_ERROR,

                   "Specified time %f is greater than the following time %f\n",

                   (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000);

            FAIL(AVERROR(EINVAL));

        }

    }

end:

    av_free(times_str1);

    return ret;

}


static void floor_fit(venc_context_t * venc, floor_t * fc, float * coeffs, int * posts, int samples) {

    int range = 255 / fc->multiplier + 1;

    int i;

    for (i = 0; i < fc->values; i++) {

        int position = fc->list[fc->list[i].sort].x;

        int begin = fc->list[fc->list[FFMAX(i-1, 0)].sort].x;

        int end   = fc->list[fc->list[FFMIN(i+1, fc->values - 1)].sort].x;

        int j;

        float average = 0;

        begin = (position + begin) / 2;

        end   = (position + end  ) / 2;

        assert(end <= samples);

        for (j = begin; j < end; j++) average += fabs(coeffs[j]);

        average /= end - begin;

        average /= 32; // MAGIC!

        for (j = 0; j < range; j++) if (floor1_inverse_db_table[j * fc->multiplier] > average) break;

        posts[fc->list[i].sort] = j;

    }

}


static void gen_spr_power8_fscr(CPUPPCState *env)

{

    spr_register_kvm(env, SPR_FSCR, "FSCR",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_FSCR, 0x00000000);

}


static int pcm_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    PCMDecode *s = avctx->priv_data;

    int sample_size, c, n, i;

    short *samples;

    const uint8_t *src, *src8, *src2[MAX_CHANNELS];

    uint8_t *dstu8;

    int16_t *dst_int16_t;

    int32_t *dst_int32_t;

    int64_t *dst_int64_t;

    uint16_t *dst_uint16_t;

    uint32_t *dst_uint32_t;

    samples = data;

    src = buf;

    if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) {

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

        return -1;

    }

    if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){

        av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n");

        return -1;

    }

    sample_size = av_get_bits_per_sample(avctx->codec_id)/8;

    /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */

    if (CODEC_ID_PCM_DVD == avctx->codec_id)

        /* 2 samples are interleaved per block in PCM_DVD */

        sample_size = avctx->bits_per_coded_sample * 2 / 8;

    else if (avctx->codec_id == CODEC_ID_PCM_LXF)

        /* we process 40-bit blocks per channel for LXF */

        sample_size = 5;

    if (sample_size == 0) {

        av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n");

        return AVERROR(EINVAL);

    }

    n = avctx->channels * sample_size;

    if(n && buf_size % n){

        if (buf_size < n) {

            av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n");

            return -1;

        }else

            buf_size -= buf_size % n;

    }

    buf_size= FFMIN(buf_size, *data_size/2);

    *data_size=0;

    n = buf_size/sample_size;

    switch(avctx->codec->id) {

    case CODEC_ID_PCM_U32LE:

        DECODE(uint32_t, le32, src, samples, n, 0, 0x80000000)

        break;

    case CODEC_ID_PCM_U32BE:

        DECODE(uint32_t, be32, src, samples, n, 0, 0x80000000)

        break;

    case CODEC_ID_PCM_S24LE:

        DECODE(int32_t, le24, src, samples, n, 8, 0)

        break;

    case CODEC_ID_PCM_S24BE:

        DECODE(int32_t, be24, src, samples, n, 8, 0)

        break;

    case CODEC_ID_PCM_U24LE:

        DECODE(uint32_t, le24, src, samples, n, 8, 0x800000)

        break;

    case CODEC_ID_PCM_U24BE:

        DECODE(uint32_t, be24, src, samples, n, 8, 0x800000)

        break;

    case CODEC_ID_PCM_S24DAUD:

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

          uint32_t v = bytestream_get_be24(&src);

          v >>= 4; // sync flags are here

          *samples++ = av_reverse[(v >> 8) & 0xff] +

                       (av_reverse[v & 0xff] << 8);

        }

        break;

    case CODEC_ID_PCM_S16LE_PLANAR:

        n /= avctx->channels;

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

            src2[c] = &src[c*n*2];

        for(;n>0;n--)

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

                *samples++ = bytestream_get_le16(&src2[c]);

        src = src2[avctx->channels-1];

        break;

    case CODEC_ID_PCM_U16LE:

        DECODE(uint16_t, le16, src, samples, n, 0, 0x8000)

        break;

    case CODEC_ID_PCM_U16BE:

        DECODE(uint16_t, be16, src, samples, n, 0, 0x8000)

        break;

    case CODEC_ID_PCM_S8:

        dstu8= (uint8_t*)samples;

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

            *dstu8++ = *src++ + 128;

        }

        samples= (short*)dstu8;

        break;

#if HAVE_BIGENDIAN

    case CODEC_ID_PCM_F64LE:

        DECODE(int64_t, le64, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_S32LE:

    case CODEC_ID_PCM_F32LE:

        DECODE(int32_t, le32, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_S16LE:

        DECODE(int16_t, le16, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_F64BE:

    case CODEC_ID_PCM_F32BE:

    case CODEC_ID_PCM_S32BE:

    case CODEC_ID_PCM_S16BE:

#else

    case CODEC_ID_PCM_F64BE:

        DECODE(int64_t, be64, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_F32BE:

    case CODEC_ID_PCM_S32BE:

        DECODE(int32_t, be32, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_S16BE:

        DECODE(int16_t, be16, src, samples, n, 0, 0)

        break;

    case CODEC_ID_PCM_F64LE:

    case CODEC_ID_PCM_F32LE:

    case CODEC_ID_PCM_S32LE:

    case CODEC_ID_PCM_S16LE:

#endif /* HAVE_BIGENDIAN */

    case CODEC_ID_PCM_U8:

        memcpy(samples, src, n*sample_size);

        src += n*sample_size;

        samples = (short*)((uint8_t*)data + n*sample_size);

        break;

    case CODEC_ID_PCM_ZORK:

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

            int x= *src++;

            if(x&128) x-= 128;

            else      x = -x;

            *samples++ = x << 8;

        }

        break;

    case CODEC_ID_PCM_ALAW:

    case CODEC_ID_PCM_MULAW:

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

            *samples++ = s->table[*src++];

        }

        break;

    case CODEC_ID_PCM_DVD:

        dst_int32_t = data;

        n /= avctx->channels;

        switch (avctx->bits_per_coded_sample) {

        case 20:

            while (n--) {

                c = avctx->channels;

                src8 = src + 4*c;

                while (c--) {

                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8   &0xf0) << 8);

                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ &0x0f) << 12);

                }

                src = src8;

            }

            break;

        case 24:

            while (n--) {

                c = avctx->channels;

                src8 = src + 4*c;

                while (c--) {

                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8);

                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8);

                }

                src = src8;

            }

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");

            return -1;

        }

        samples = (short *) dst_int32_t;

        break;

    case CODEC_ID_PCM_LXF:

        dst_int32_t = data;

        n /= avctx->channels;

        //unpack and de-planerize

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

            for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) {

                //extract low 20 bits and expand to 32 bits

                *dst_int32_t++ = (src8[2] << 28) | (src8[1] << 20) | (src8[0] << 12) |

                                 ((src8[2] & 0xF) << 8) | src8[1];

            }

            for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) {

                //extract high 20 bits and expand to 32 bits

                *dst_int32_t++ = (src8[4] << 24) | (src8[3] << 16) |

                                 ((src8[2] & 0xF0) << 8) | (src8[4] << 4) | (src8[3] >> 4);

            }

        }

        src += n * avctx->channels * 5;

        samples = (short *) dst_int32_t;

        break;

    default:

        return -1;

    }

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

    return src - buf;

}


int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,

                             int *got_sub_ptr,

                             AVPacket *avpkt)

{

    int i, ret = 0;

    if (!avpkt->data && avpkt->size) {

        av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");

        return AVERROR(EINVAL);

    }

    if (!avctx->codec)

        return AVERROR(EINVAL);

    if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {

        av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");

        return AVERROR(EINVAL);

    }

    *got_sub_ptr = 0;

    get_subtitle_defaults(sub);

    if ((avctx->codec->capabilities & AV_CODEC_CAP_DELAY) || avpkt->size) {

        AVPacket pkt_recoded;

        AVPacket tmp = *avpkt;

        int did_split = av_packet_split_side_data(&tmp);

        //apply_param_change(avctx, &tmp);

        if (did_split) {

            /* FFMIN() prevents overflow in case the packet wasn't allocated with

             * proper padding.

             * If the side data is smaller than the buffer padding size, the

             * remaining bytes should have already been filled with zeros by the

             * original packet allocation anyway. */

            memset(tmp.data + tmp.size, 0,

                   FFMIN(avpkt->size - tmp.size, AV_INPUT_BUFFER_PADDING_SIZE));

        }

        pkt_recoded = tmp;

        ret = recode_subtitle(avctx, &pkt_recoded, &tmp);

        if (ret < 0) {

            *got_sub_ptr = 0;

        } else {

            avctx->internal->pkt = &pkt_recoded;

            if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE)

                sub->pts = av_rescale_q(avpkt->pts,

                                        avctx->pkt_timebase, AV_TIME_BASE_Q);

            ret = avctx->codec->decode(avctx, sub, got_sub_ptr, &pkt_recoded);

            av_assert1((ret >= 0) >= !!*got_sub_ptr &&

                       !!*got_sub_ptr >= !!sub->num_rects);

            if (sub->num_rects && !sub->end_display_time && avpkt->duration &&

                avctx->pkt_timebase.num) {

                AVRational ms = { 1, 1000 };

                sub->end_display_time = av_rescale_q(avpkt->duration,

                                                     avctx->pkt_timebase, ms);

            }

            for (i = 0; i < sub->num_rects; i++) {

                if (sub->rects[i]->ass && !utf8_check(sub->rects[i]->ass)) {

                    av_log(avctx, AV_LOG_ERROR,

                           "Invalid UTF-8 in decoded subtitles text; "

                           "maybe missing -sub_charenc option\n");

                    avsubtitle_free(sub);

                    return AVERROR_INVALIDDATA;

                }

            }

            if (tmp.data != pkt_recoded.data) { // did we recode?

                /* prevent from destroying side data from original packet */

                pkt_recoded.side_data = NULL;

                pkt_recoded.side_data_elems = 0;

                av_packet_unref(&pkt_recoded);

            }

            if (avctx->codec_descriptor->props & AV_CODEC_PROP_BITMAP_SUB)

                sub->format = 0;

            else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB)

                sub->format = 1;

            avctx->internal->pkt = NULL;

        }

        if (did_split) {

            av_packet_free_side_data(&tmp);

            if(ret == tmp.size)

                ret = avpkt->size;

        }

        if (*got_sub_ptr)

            avctx->frame_number++;

    }

    return ret;

}


static int flv_write_packet(AVFormatContext *s, int stream_index,

                            const uint8_t *buf, int size, int64_t timestamp)

{

    ByteIOContext *pb = &s->pb;

    AVCodecContext *enc = &s->streams[stream_index]->codec;

    FLVContext *flv = s->priv_data;

    if (enc->codec_type == CODEC_TYPE_VIDEO) {

        FLVFrame *frame = av_malloc(sizeof(FLVFrame));

        frame->next = 0;

        frame->type = 9;

        frame->flags = 2; // choose h263

        frame->flags |= enc->coded_frame->key_frame ? 0x10 : 0x20; // add keyframe indicator

        frame->timestamp = timestamp;

        //frame->timestamp = ( ( flv->frameCount * (int64_t)FRAME_RATE_BASE * (int64_t)1000 ) / (int64_t)enc->frame_rate );

        //printf("%08x %f %f\n",frame->timestamp,(double)enc->frame_rate/(double)FRAME_RATE_BASE,1000*(double)FRAME_RATE_BASE/(double)enc->frame_rate);

        frame->size = size;

        frame->data = av_malloc(size);

        memcpy(frame->data,buf,size);

        flv->hasVideo = 1;

        InsertSorted(flv,frame);

        flv->frameCount ++;

    }

    else if (enc->codec_type == CODEC_TYPE_AUDIO) {

#ifdef CONFIG_MP3LAME

        if (enc->codec_id == CODEC_ID_MP3 ) {

            int c=0;

            for (;c<size;c++) {

                flv->audioFifo[(flv->audioOutPos+c)%AUDIO_FIFO_SIZE] = buf[c];

            }

            flv->audioSize += size;

            flv->audioOutPos += size;

            flv->audioOutPos %= AUDIO_FIFO_SIZE;

            if ( flv->initDelay == -1 ) {

                flv->initDelay = timestamp;

            }

            if ( flv->audioTime == -1 ) {

                flv->audioTime = timestamp;

//                flv->audioTime = ( ( ( flv->sampleCount - enc->delay ) * 8000 ) / flv->audioRate ) - flv->initDelay - 250;

//                if ( flv->audioTime < 0 ) {

//                    flv->audioTime = 0;

//                }

            }

        }

        for ( ; flv->audioSize >= 4 ; ) {

            int mp3FrameSize = 0;

            int mp3SampleRate = 0;

            int mp3IsMono = 0;

            int mp3SamplesPerFrame = 0;

            if ( mp3info(&flv->audioFifo[flv->audioInPos],&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {

                if ( flv->audioSize >= mp3FrameSize ) {

                    int soundFormat = 0x22;

                    int c=0;

                    FLVFrame *frame = av_malloc(sizeof(FLVFrame));

                    flv->audioRate = mp3SampleRate;

                    switch (mp3SampleRate) {

                        case    44100:

                            soundFormat |= 0x0C;

                            break;

                        case    22050:

                            soundFormat |= 0x08;

                            break;

                        case    11025:

                            soundFormat |= 0x04;

                            break;

                    }

                    if ( !mp3IsMono ) {

                        soundFormat |= 0x01;

                    }

                    frame->next = 0;

                    frame->type = 8;

                    frame->flags = soundFormat;

                    frame->timestamp = flv->audioTime;

                    frame->size = mp3FrameSize;

                    frame->data = av_malloc(mp3FrameSize);

                    for (;c<mp3FrameSize;c++) {

                        frame->data[c] = flv->audioFifo[(flv->audioInPos+c)%AUDIO_FIFO_SIZE];

                    }

                    flv->audioInPos += mp3FrameSize;

                    flv->audioSize -= mp3FrameSize;

                    flv->audioInPos %= AUDIO_FIFO_SIZE;

                    flv->sampleCount += mp3SamplesPerFrame;

                    // Reset audio for next round

                    flv->audioTime = -1;

                    // We got audio! Make sure we set this to the global flags on closure

                    flv->hasAudio = 1;

                    InsertSorted(flv,frame);

                }

                break;

            }

            flv->audioInPos ++;

            flv->audioSize --;

            flv->audioInPos %= AUDIO_FIFO_SIZE;

            // no audio in here!

            flv->audioTime = -1;

        }

#endif

    }

    Dump(flv,pb,128);

    put_flush_packet(pb);

    return 0;

}


void ahci_init(AHCIState *s, DeviceState *qdev, DMAContext *dma, int ports)

{

    qemu_irq *irqs;

    int i;

    s->dma = dma;

    s->ports = ports;

    s->dev = g_malloc0(sizeof(AHCIDevice) * ports);

    ahci_reg_init(s);

    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */

    memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", AHCI_MEM_BAR_SIZE);

    memory_region_init_io(&s->idp, &ahci_idp_ops, s, "ahci-idp", 32);

    irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);

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

        AHCIDevice *ad = &s->dev[i];

        ide_bus_new(&ad->port, qdev, i);

        ide_init2(&ad->port, irqs[i]);

        ad->hba = s;

        ad->port_no = i;

        ad->port.dma = &ad->dma;

        ad->port.dma->ops = &ahci_dma_ops;

        ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;

    }

}


static void put_psr(target_ulong val)

{

    env->psr = val & PSR_ICC;

    env->psref = (val & PSR_EF)? 1 : 0;

    env->psrpil = (val & PSR_PIL) >> 8;

#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY))

    cpu_check_irqs(env);

#endif

    env->psrs = (val & PSR_S)? 1 : 0;

    env->psrps = (val & PSR_PS)? 1 : 0;

#if !defined (TARGET_SPARC64)

    env->psret = (val & PSR_ET)? 1 : 0;

#endif

    set_cwp(val & PSR_CWP);

    env->cc_op = CC_OP_FLAGS;

}


void dsputil_init_ppc(void)

{

    // Common optimisations whether Altivec or not

    // ... pending ...

#if HAVE_ALTIVEC

    if (has_altivec()) {

        // Altivec specific optimisations

        pix_abs16x16 = pix_abs16x16_altivec;

        pix_abs8x8 = pix_abs8x8_altivec;

        pix_sum = pix_sum_altivec;

        diff_pixels = diff_pixels_altivec;

        get_pixels = get_pixels_altivec;

    } else

#endif

    {

        // Non-AltiVec PPC optimisations

        // ... pending ...

    }

}


int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,

                                 int64_t size)

{

    BDRVQcowState *s = bs->opaque;

    int chk = s->overlap_check & ~ign;

    int i, j;

    if (!size) {

        return 0;

    }

    if (chk & QCOW2_OL_MAIN_HEADER) {

        if (offset < s->cluster_size) {

            return QCOW2_OL_MAIN_HEADER;

        }

    }

    /* align range to test to cluster boundaries */

    size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);

    offset = start_of_cluster(s, offset);

    if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {

        if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {

            return QCOW2_OL_ACTIVE_L1;

        }

    }

    if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {

        if (overlaps_with(s->refcount_table_offset,

            s->refcount_table_size * sizeof(uint64_t))) {

            return QCOW2_OL_REFCOUNT_TABLE;

        }

    }

    if ((chk & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {

        if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {

            return QCOW2_OL_SNAPSHOT_TABLE;

        }

    }

    if ((chk & QCOW2_OL_INACTIVE_L1) && s->snapshots) {

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

            if (s->snapshots[i].l1_size &&

                overlaps_with(s->snapshots[i].l1_table_offset,

                s->snapshots[i].l1_size * sizeof(uint64_t))) {

                return QCOW2_OL_INACTIVE_L1;

            }

        }

    }

    if ((chk & QCOW2_OL_ACTIVE_L2) && s->l1_table) {

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

            if ((s->l1_table[i] & L1E_OFFSET_MASK) &&

                overlaps_with(s->l1_table[i] & L1E_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_ACTIVE_L2;

            }

        }

    }

    if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {

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

            if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&

                overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_REFCOUNT_BLOCK;

            }

        }

    }

    if ((chk & QCOW2_OL_INACTIVE_L2) && s->snapshots) {

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

            uint64_t l1_ofs = s->snapshots[i].l1_table_offset;

            uint32_t l1_sz  = s->snapshots[i].l1_size;

            uint64_t l1_sz2 = l1_sz * sizeof(uint64_t);

            uint64_t *l1 = g_malloc(l1_sz2);

            int ret;

            ret = bdrv_pread(bs->file, l1_ofs, l1, l1_sz2);

            if (ret < 0) {

                g_free(l1);

                return ret;

            }

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

                uint64_t l2_ofs = be64_to_cpu(l1[j]) & L1E_OFFSET_MASK;

                if (l2_ofs && overlaps_with(l2_ofs, s->cluster_size)) {

                    g_free(l1);

                    return QCOW2_OL_INACTIVE_L2;

                }

            }

            g_free(l1);

        }

    }

    return 0;

}


static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)

{

    char *config = NULL;

    switch (c->codec_id) {

        case AV_CODEC_ID_H264: {

            int mode = 1;

            if (fmt && fmt->oformat && fmt->oformat->priv_class &&

                av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0"))

                mode = 0;

            if (c->extradata_size) {

                config = extradata2psets(c);

            }

            av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n"

                                    "a=fmtp:%d packetization-mode=%d%s\r\n",

                                     payload_type,

                                     payload_type, mode, config ? config : "");

            break;

        }

        case AV_CODEC_ID_H263:

        case AV_CODEC_ID_H263P:

            /* a=framesize is required by 3GPP TS 26.234 (PSS). It

             * actually specifies the maximum video size, but we only know

             * the current size. This is required for playback on Android

             * stagefright and on Samsung bada. */

            if (!fmt || !fmt->oformat->priv_class ||

                !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190") ||

                c->codec_id == AV_CODEC_ID_H263P)

            av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n"

                                    "a=framesize:%d %d-%d\r\n",

                                    payload_type,

                                    payload_type, c->width, c->height);

            break;

        case AV_CODEC_ID_HEVC:

            if (c->extradata_size)

                av_log(NULL, AV_LOG_WARNING, "HEVC extradata not currently "

                                             "passed properly through SDP\n");

            av_strlcatf(buff, size, "a=rtpmap:%d H265/90000\r\n", payload_type);

            break;

        case AV_CODEC_ID_MPEG4:

            if (c->extradata_size) {

                config = extradata2config(c);

            }

            av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n"

                                    "a=fmtp:%d profile-level-id=1%s\r\n",

                                     payload_type,

                                     payload_type, config ? config : "");

            break;

        case AV_CODEC_ID_AAC:

            if (fmt && fmt->oformat->priv_class &&

                av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {

                config = latm_context2config(c);

                if (!config)

                    return NULL;

                av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"

                                        "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",

                                         payload_type, c->sample_rate, c->channels,

                                         payload_type, latm_context2profilelevel(c), config);

            } else {

                if (c->extradata_size) {

                    config = extradata2config(c);

                } else {

                    /* FIXME: maybe we can forge config information based on the

                     *        codec parameters...

                     */

                    av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");

                    return NULL;

                }

                if (!config) {

                    return NULL;

                }

                av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"

                                        "a=fmtp:%d profile-level-id=1;"

                                        "mode=AAC-hbr;sizelength=13;indexlength=3;"

                                        "indexdeltalength=3%s\r\n",

                                         payload_type, c->sample_rate, c->channels,

                                         payload_type, config);

            }

            break;

        case AV_CODEC_ID_PCM_S16BE:

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",

                                         payload_type,

                                         c->sample_rate, c->channels);

            break;

        case AV_CODEC_ID_PCM_MULAW:

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n",

                                         payload_type,

                                         c->sample_rate, c->channels);

            break;

        case AV_CODEC_ID_PCM_ALAW:

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n",

                                         payload_type,

                                         c->sample_rate, c->channels);

            break;

        case AV_CODEC_ID_AMR_NB:

            av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n"

                                    "a=fmtp:%d octet-align=1\r\n",

                                     payload_type, c->sample_rate, c->channels,

                                     payload_type);

            break;

        case AV_CODEC_ID_AMR_WB:

            av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n"

                                    "a=fmtp:%d octet-align=1\r\n",

                                     payload_type, c->sample_rate, c->channels,

                                     payload_type);

            break;

        case AV_CODEC_ID_VORBIS:

            if (c->extradata_size)

                config = xiph_extradata2config(c);

            else

                av_log(c, AV_LOG_ERROR, "Vorbis configuration info missing\n");

            if (!config)

                return NULL;

            av_strlcatf(buff, size, "a=rtpmap:%d vorbis/%d/%d\r\n"

                                    "a=fmtp:%d configuration=%s\r\n",

                                    payload_type, c->sample_rate, c->channels,

                                    payload_type, config);

            break;

        case AV_CODEC_ID_THEORA: {

            const char *pix_fmt;

            switch (c->pix_fmt) {

            case AV_PIX_FMT_YUV420P:

                pix_fmt = "YCbCr-4:2:0";

                break;

            case AV_PIX_FMT_YUV422P:

                pix_fmt = "YCbCr-4:2:2";

                break;

            case AV_PIX_FMT_YUV444P:

                pix_fmt = "YCbCr-4:4:4";

                break;

            default:

                av_log(c, AV_LOG_ERROR, "Unsupported pixel format.\n");

                return NULL;

            }

            if (c->extradata_size)

                config = xiph_extradata2config(c);

            else

                av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");

            if (!config)

                return NULL;

            av_strlcatf(buff, size, "a=rtpmap:%d theora/90000\r\n"

                                    "a=fmtp:%d delivery-method=inline; "

                                    "width=%d; height=%d; sampling=%s; "

                                    "configuration=%s\r\n",

                                    payload_type, payload_type,

                                    c->width, c->height, pix_fmt, config);

            break;

        }

        case AV_CODEC_ID_VP8:

            av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",

                                     payload_type);

            break;

        case AV_CODEC_ID_MJPEG:

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n",

                                         payload_type);

            break;

        case AV_CODEC_ID_ADPCM_G722:

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n",

                                         payload_type,

                                         8000, c->channels);

            break;

        case AV_CODEC_ID_ADPCM_G726: {

            if (payload_type >= RTP_PT_PRIVATE)

                av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n",

                                         payload_type,

                                         c->bits_per_coded_sample*8,

                                         c->sample_rate);

            break;

        }

        case AV_CODEC_ID_ILBC:

            av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"

                                    "a=fmtp:%d mode=%d\r\n",

                                     payload_type, c->sample_rate,

                                     payload_type, c->block_align == 38 ? 20 : 30);

            break;

        case AV_CODEC_ID_SPEEX:

            av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",

                                     payload_type, c->sample_rate);

            break;

        case AV_CODEC_ID_OPUS:

            /* The opus RTP draft says that all opus streams MUST be declared

               as stereo, to avoid negotiation failures. The actual number of

               channels can change on a packet-by-packet basis. The number of

               channels a receiver prefers to receive or a sender plans to send

               can be declared via fmtp parameters (both default to mono), but

               receivers MUST be able to receive and process stereo packets. */

            av_strlcatf(buff, size, "a=rtpmap:%d opus/48000/2\r\n",

                                     payload_type);

            if (c->channels == 2) {

                av_strlcatf(buff, size, "a=fmtp:%d sprop-stereo:1\r\n",

                                         payload_type);

            }

            break;

        default:

            /* Nothing special to do here... */

            break;

    }

    av_free(config);

    return buff;

}


static void compute_status(HTTPContext *c)

{

    HTTPContext *c1;

    FFStream *stream;

    char *p;

    time_t ti;

    int i, len;

    AVIOContext *pb;

    if (avio_open_dyn_buf(&pb) < 0) {

        /* XXX: return an error ? */

        c->buffer_ptr = c->buffer;

        c->buffer_end = c->buffer;

        return;

    }

    avio_printf(pb, "HTTP/1.0 200 OK\r\n");

    avio_printf(pb, "Content-type: %s\r\n", "text/html");

    avio_printf(pb, "Pragma: no-cache\r\n");

    avio_printf(pb, "\r\n");

    avio_printf(pb, "<title>%s Status</title>\n", program_name);

    if (c->stream->feed_filename[0])

        avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);

    avio_printf(pb, "\n");

    avio_printf(pb, "
%s Status
\n", program_name);

    /* format status */

    avio_printf(pb, "
Available Streams
\n");

    avio_printf(pb, "
\n");

    avio_printf(pb, "
PathServed
Conns
bytesFormatBit rate
kbits/sVideo
kbits/s
CodecAudio
kbits/s
CodecFeed\n");

    stream = first_stream;

    while (stream != NULL) {

        char sfilename[1024];

        char *eosf;

        if (stream->feed != stream) {

            av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);

            eosf = sfilename + strlen(sfilename);

            if (eosf - sfilename >= 4) {

                if (strcmp(eosf - 4, ".asf") == 0)

                    strcpy(eosf - 4, ".asx");

                else if (strcmp(eosf - 3, ".rm") == 0)

                    strcpy(eosf - 3, ".ram");

                else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {

                    /* generate a sample RTSP director if

                       unicast. Generate an SDP redirector if

                       multicast */

                    eosf = strrchr(sfilename, '.');

                    if (!eosf)

                        eosf = sfilename + strlen(sfilename);

                    if (stream->is_multicast)

                        strcpy(eosf, ".sdp");

                    else

                        strcpy(eosf, ".rtsp");

                }

            }

            avio_printf(pb, "
%s ",

                         sfilename, stream->filename);

            avio_printf(pb, " %d  ",

                        stream->conns_served);

            fmt_bytecount(pb, stream->bytes_served);

            switch(stream->stream_type) {

            case STREAM_TYPE_LIVE: {

                    int audio_bit_rate = 0;

                    int video_bit_rate = 0;

                    const char *audio_codec_name = "";

                    const char *video_codec_name = "";

                    const char *audio_codec_name_extra = "";

                    const char *video_codec_name_extra = "";

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

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

                        AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);

                        switch(st->codec->codec_type) {

                        case AVMEDIA_TYPE_AUDIO:

                            audio_bit_rate += st->codec->bit_rate;

                            if (codec) {

                                if (*audio_codec_name)

                                    audio_codec_name_extra = "...";

                                audio_codec_name = codec->name;

                            }

                            break;

                        case AVMEDIA_TYPE_VIDEO:

                            video_bit_rate += st->codec->bit_rate;

                            if (codec) {

                                if (*video_codec_name)

                                    video_codec_name_extra = "...";

                                video_codec_name = codec->name;

                            }

                            break;

                        case AVMEDIA_TYPE_DATA:

                            video_bit_rate += st->codec->bit_rate;

                            break;

                        default:

                            abort();

                        }

                    }

                    avio_printf(pb, " %s  %d  %d  %s %s  %d  %s %s",

                                 stream->fmt->name,

                                 stream->bandwidth,

                                 video_bit_rate / 1000, video_codec_name, video_codec_name_extra,

                                 audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);

                    if (stream->feed)

                        avio_printf(pb, "%s", stream->feed->filename);

                    else

                        avio_printf(pb, "%s", stream->feed_filename);

                    avio_printf(pb, "\n");

                }

                break;

            default:

                avio_printf(pb, " -  -  -  - \n");

                break;

            }

        }

        stream = stream->next;

    }

    avio_printf(pb, "
\n");

    stream = first_stream;

    while (stream != NULL) {

        if (stream->feed == stream) {

            avio_printf(pb, "
Feed %s
", stream->filename);

            if (stream->pid) {

                avio_printf(pb, "Running as pid %d.\n", stream->pid);

#if defined(linux) && !defined(CONFIG_NOCUTILS)

                {

                    FILE *pid_stat;

                    char ps_cmd[64];

                    /* This is somewhat linux specific I guess */

                    snprintf(ps_cmd, sizeof(ps_cmd),

                             "ps -o \"%%cpu,cputime\" --no-headers %d",

                             stream->pid);

                    pid_stat = popen(ps_cmd, "r");

                    if (pid_stat) {

                        char cpuperc[10];

                        char cpuused[64];

                        if (fscanf(pid_stat, "%10s %64s", cpuperc,

                                   cpuused) == 2) {

                            avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",

                                         cpuperc, cpuused);

                        }

                        fclose(pid_stat);

                    }

                }

#endif

                avio_printf(pb, "
");

            }

            avio_printf(pb, "

Streamtypekbits/scodecParameters\n");

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

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

                AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);

                const char *type = "unknown";

                char parameters[64];

                parameters[0] = 0;

                switch(st->codec->codec_type) {

                case AVMEDIA_TYPE_AUDIO:

                    type = "audio";

                    snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);

                    break;

                case AVMEDIA_TYPE_VIDEO:

                    type = "video";

                    snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,

                                st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);

                    break;

                default:

                    abort();

                }

                avio_printf(pb, "
%d%s%d%s%s\n",

                        i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);

            }

            avio_printf(pb, "
\n");

        }

        stream = stream->next;

    }

    /* connection status */

    avio_printf(pb, "
Connection Status
\n");

    avio_printf(pb, "Number of connections: %d / %d
\n",

                 nb_connections, nb_max_connections);

    avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k
\n",

                 current_bandwidth, max_bandwidth);

    avio_printf(pb, "
\n");

    avio_printf(pb, "
#FileIPProtoStateTarget bits/secActual bits/secBytes transferred\n");

    c1 = first_http_ctx;

    i = 0;

    while (c1 != NULL) {

        int bitrate;

        int j;

        bitrate = 0;

        if (c1->stream) {

            for (j = 0; j < c1->stream->nb_streams; j++) {

                if (!c1->stream->feed)

                    bitrate += c1->stream->streams[j]->codec->bit_rate;

                else if (c1->feed_streams[j] >= 0)

                    bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;

            }

        }

        i++;

        p = inet_ntoa(c1->from_addr.sin_addr);

        avio_printf(pb, "
%d%s%s%s%s%s",

                    i,

                    c1->stream ? c1->stream->filename : "",

                    c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",

                    p,

                    c1->protocol,

                    http_state[c1->state]);

        fmt_bytecount(pb, bitrate);

        avio_printf(pb, "");

        fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);

        avio_printf(pb, "");

        fmt_bytecount(pb, c1->data_count);

        avio_printf(pb, "\n");

        c1 = c1->next;

    }

    avio_printf(pb, "
\n");

    /* date */

    ti = time(NULL);

    p = ctime(&ti);

    avio_printf(pb, "
Generated at %s", p);

    avio_printf(pb, "\n\n");

    len = avio_close_dyn_buf(pb, &c->pb_buffer);

    c->buffer_ptr = c->pb_buffer;

    c->buffer_end = c->pb_buffer + len;

}


static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)

{

    ESPState *s = opaque;

    uint32_t saddr;

    saddr = (addr >> s->it_shift) & (ESP_REGS - 1);

    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],

            val);

    switch (saddr) {

    case ESP_TCLO:

    case ESP_TCMID:

        s->rregs[ESP_RSTAT] &= ~STAT_TC;

        break;

    case ESP_FIFO:

        if (s->do_cmd) {

            s->cmdbuf[s->cmdlen++] = val & 0xff;

        } else if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {

            uint8_t buf;

            buf = val & 0xff;

            s->ti_size--;

            fprintf(stderr, "esp: PIO data write not implemented\n");

        } else {

            s->ti_size++;

            s->ti_buf[s->ti_wptr++] = val & 0xff;

        }

        break;

    case ESP_CMD:

        s->rregs[saddr] = val;

        if (val & CMD_DMA) {

            s->dma = 1;

            /* Reload DMA counter.  */

            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];

            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];

        } else {

            s->dma = 0;

        }

        switch(val & CMD_CMD) {

        case CMD_NOP:

            DPRINTF("NOP (%2.2x)\n", val);

            break;

        case CMD_FLUSH:

            DPRINTF("Flush FIFO (%2.2x)\n", val);

            //s->ti_size = 0;

            s->rregs[ESP_RINTR] = INTR_FC;

            s->rregs[ESP_RSEQ] = 0;

            s->rregs[ESP_RFLAGS] = 0;

            break;

        case CMD_RESET:

            DPRINTF("Chip reset (%2.2x)\n", val);

            esp_reset(s);

            break;

        case CMD_BUSRESET:

            DPRINTF("Bus reset (%2.2x)\n", val);

            s->rregs[ESP_RINTR] = INTR_RST;

            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {

                esp_raise_irq(s);

            }

            break;

        case CMD_TI:

            handle_ti(s);

            break;

        case CMD_ICCS:

            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);

            write_response(s);

            break;

        case CMD_MSGACC:

            DPRINTF("Message Accepted (%2.2x)\n", val);

            write_response(s);

            s->rregs[ESP_RINTR] = INTR_DC;

            s->rregs[ESP_RSEQ] = 0;

            break;

        case CMD_SATN:

            DPRINTF("Set ATN (%2.2x)\n", val);

            break;

        case CMD_SELATN:

            DPRINTF("Set ATN (%2.2x)\n", val);

            handle_satn(s);

            break;

        case CMD_SELATNS:

            DPRINTF("Set ATN & stop (%2.2x)\n", val);

            handle_satn_stop(s);

            break;

        case CMD_ENSEL:

            DPRINTF("Enable selection (%2.2x)\n", val);

            break;

        default:

            DPRINTF("Unhandled ESP command (%2.2x)\n", val);

            break;

        }

        break;

    case ESP_WBUSID ... ESP_WSYNO:

        break;

    case ESP_CFG1:

        s->rregs[saddr] = val;

        break;

    case ESP_WCCF ... ESP_WTEST:

        break;

    case ESP_CFG2:

        s->rregs[saddr] = val & CFG2_MASK;

        break;

    case ESP_CFG3 ... ESP_RES4:

        s->rregs[saddr] = val;

        break;

    default:

        break;

    }

    s->wregs[saddr] = val;

}


int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,

                                FLACFrameInfo *fi)

{

    int bs_code, sr_code, bps_code;

    /* frame sync code */

    skip_bits(gb, 16);

    /* block size and sample rate codes */

    bs_code = get_bits(gb, 4);

    sr_code = get_bits(gb, 4);

    /* channels and decorrelation */

    fi->ch_mode = get_bits(gb, 4);

    if (fi->ch_mode < FLAC_MAX_CHANNELS) {

        fi->channels = fi->ch_mode + 1;

        fi->ch_mode = FLAC_CHMODE_INDEPENDENT;

    } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) {

        fi->channels = 2;

    } else {

        av_log(avctx, AV_LOG_ERROR, "invalid channel mode: %d\n", fi->ch_mode);

        return -1;

    }

    /* bits per sample */

    bps_code = get_bits(gb, 3);

    if (bps_code == 3 || bps_code == 7) {

        av_log(avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n",

               bps_code);

        return -1;

    }

    fi->bps = sample_size_table[bps_code];

    /* reserved bit */

    if (get_bits1(gb)) {

        av_log(avctx, AV_LOG_ERROR, "broken stream, invalid padding\n");

        return -1;

    }

    /* sample or frame count */

    if (get_utf8(gb) < 0) {

        av_log(avctx, AV_LOG_ERROR, "utf8 fscked\n");

        return -1;

    }

    /* blocksize */

    if (bs_code == 0) {

        av_log(avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n");

        return -1;

    } else if (bs_code == 6) {

        fi->blocksize = get_bits(gb, 8) + 1;

    } else if (bs_code == 7) {

        fi->blocksize = get_bits(gb, 16) + 1;

    } else {

        fi->blocksize = ff_flac_blocksize_table[bs_code];

    }

    /* sample rate */

    if (sr_code < 12) {

        fi->samplerate = ff_flac_sample_rate_table[sr_code];

    } else if (sr_code == 12) {

        fi->samplerate = get_bits(gb, 8) * 1000;

    } else if (sr_code == 13) {

        fi->samplerate = get_bits(gb, 16);

    } else if (sr_code == 14) {

        fi->samplerate = get_bits(gb, 16) * 10;

    } else {

        av_log(avctx, AV_LOG_ERROR, "illegal sample rate code %d\n",

               sr_code);

        return -1;

    }

    /* header CRC-8 check */

    skip_bits(gb, 8);

    if (av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, gb->buffer,

               get_bits_count(gb)/8)) {

        av_log(avctx, AV_LOG_ERROR, "header crc mismatch\n");

        return -1;

    }

    return 0;

}


static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)

{

    AVIOContext *dyn_cp;

    mkv_seekhead *seekhead = mkv->main_seekhead;

    ebml_master metaseek, seekentry;

    int64_t currentpos;

    int i;

    currentpos = avio_tell(pb);

    if (seekhead->reserved_size > 0) {

        if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0) {

            currentpos = -1;

            goto fail;

        }

    }

    if (start_ebml_master_crc32(pb, &dyn_cp, &metaseek, MATROSKA_ID_SEEKHEAD,

                                seekhead->reserved_size) < 0) {

        currentpos = -1;

        goto fail;

    }

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

        mkv_seekhead_entry *entry = &seekhead->entries[i];

        seekentry = start_ebml_master(dyn_cp, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE);

        put_ebml_id(dyn_cp, MATROSKA_ID_SEEKID);

        put_ebml_num(dyn_cp, ebml_id_size(entry->elementid), 0);

        put_ebml_id(dyn_cp, entry->elementid);

        put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos);

        end_ebml_master(dyn_cp, seekentry);

    }

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

    if (seekhead->reserved_size > 0) {

        uint64_t remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);

        put_ebml_void(pb, remaining);

        avio_seek(pb, currentpos, SEEK_SET);

        currentpos = seekhead->filepos;

    }

fail:

    av_freep(&mkv->main_seekhead->entries);

    av_freep(&mkv->main_seekhead);

    return currentpos;

}


static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,

                                unsigned int substr)

{

    SubStream *s = &m->substream[substr];

    unsigned int ch;

    if (s->param_presence_flags & PARAM_PRESENCE)

    if (get_bits1(gbp))

        s->param_presence_flags = get_bits(gbp, 8);

    if (s->param_presence_flags & PARAM_BLOCKSIZE)

        if (get_bits1(gbp)) {

            s->blocksize = get_bits(gbp, 9);

            if (s->blocksize > MAX_BLOCKSIZE) {

                av_log(m->avctx, AV_LOG_ERROR, "block size too large\n");

                s->blocksize = 0;

                return -1;

            }

        }

    if (s->param_presence_flags & PARAM_MATRIX)

        if (get_bits1(gbp)) {

            if (read_matrix_params(m, s, gbp) < 0)

                return -1;

        }

    if (s->param_presence_flags & PARAM_OUTSHIFT)

        if (get_bits1(gbp))

            for (ch = 0; ch <= s->max_matrix_channel; ch++) {

                s->output_shift[ch] = get_sbits(gbp, 4);

                dprintf(m->avctx, "output shift[%d] = %d\n",

                        ch, s->output_shift[ch]);

            }

    if (s->param_presence_flags & PARAM_QUANTSTEP)

        if (get_bits1(gbp))

            for (ch = 0; ch <= s->max_channel; ch++) {

                ChannelParams *cp = &m->channel_params[ch];

                s->quant_step_size[ch] = get_bits(gbp, 4);

                cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);

            }

    for (ch = s->min_channel; ch <= s->max_channel; ch++)

        if (get_bits1(gbp)) {

            if (read_channel_params(m, substr, gbp, ch) < 0)

                return -1;

        }

    return 0;

}


static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,

                                    unsigned size)

{

    PXA2xxPICState *s = (PXA2xxPICState *) opaque;

    switch (offset) {

    case ICIP:	/* IRQ Pending register */

        return s->int_pending[0] & ~s->is_fiq[0] & s->int_enabled[0];

    case ICIP2:	/* IRQ Pending register 2 */

        return s->int_pending[1] & ~s->is_fiq[1] & s->int_enabled[1];

    case ICMR:	/* Mask register */

        return s->int_enabled[0];

    case ICMR2:	/* Mask register 2 */

        return s->int_enabled[1];

    case ICLR:	/* Level register */

        return s->is_fiq[0];

    case ICLR2:	/* Level register 2 */

        return s->is_fiq[1];

    case ICCR:	/* Idle mask */

        return (s->int_idle == 0);

    case ICFP:	/* FIQ Pending register */

        return s->int_pending[0] & s->is_fiq[0] & s->int_enabled[0];

    case ICFP2:	/* FIQ Pending register 2 */

        return s->int_pending[1] & s->is_fiq[1] & s->int_enabled[1];

    case ICPR:	/* Pending register */

        return s->int_pending[0];

    case ICPR2:	/* Pending register 2 */

        return s->int_pending[1];

    case IPR0  ... IPR31:

        return s->priority[0  + ((offset - IPR0 ) >> 2)];

    case IPR32 ... IPR39:

        return s->priority[32 + ((offset - IPR32) >> 2)];

    case ICHP:	/* Highest Priority register */

        return pxa2xx_pic_highest(s);

    default:

        printf("%s: Bad register offset " REG_FMT "\n", __FUNCTION__, offset);

        return 0;

    }

}


static inline void gen_op_addl_A0_seg(DisasContext *s, int reg)

{

    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUX86State, segs[reg].base));

    if (CODE64(s)) {

        tcg_gen_ext32u_tl(cpu_A0, cpu_A0);

        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);

    } else {

        tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);

        tcg_gen_ext32u_tl(cpu_A0, cpu_A0);

    }

}


void vm_start(void)

{

    if (!vm_running) {

        cpu_enable_ticks();

        vm_running = 1;

        vm_state_notify(1, 0);

        qemu_rearm_alarm_timer(alarm_timer);

        resume_all_vcpus();

    }

}


static int raw_pread(BlockDriverState *bs, int64_t offset,

                     uint8_t *buf, int count)

{

    BDRVRawState *s = bs->opaque;

    int size, ret, shift, sum;

    sum = 0;

    if (s->aligned_buf != NULL)  {

        if (offset & 0x1ff) {

            /* align offset on a 512 bytes boundary */

            shift = offset & 0x1ff;

            size = (shift + count + 0x1ff) & ~0x1ff;

            if (size > ALIGNED_BUFFER_SIZE)

                size = ALIGNED_BUFFER_SIZE;

            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);

            if (ret < 0)

                return ret;

            size = 512 - shift;

            if (size > count)

                size = count;

            memcpy(buf, s->aligned_buf + shift, size);

            buf += size;

            offset += size;

            count -= size;

            sum += size;

            if (count == 0)

                return sum;

        }

        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {

            /* read on aligned buffer */

            while (count) {

                size = (count + 0x1ff) & ~0x1ff;

                if (size > ALIGNED_BUFFER_SIZE)

                    size = ALIGNED_BUFFER_SIZE;

                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);

                if (ret < 0) {

                    return ret;

                } else if (ret == 0) {

                    fprintf(stderr, "raw_pread: read beyond end of file\n");

                    abort();

                }

                size = ret;

                if (size > count)

                    size = count;

                memcpy(buf, s->aligned_buf, size);

                buf += size;

                offset += size;

                count -= size;

                sum += size;

            }

            return sum;

        }

    }

    return raw_pread_aligned(bs, offset, buf, count) + sum;

}


address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *xlat,

                                 hwaddr *plen, bool resolve_subpage)

{

    MemoryRegionSection *section;

    Int128 diff, diff_page;

    section = address_space_lookup_region(d, addr, resolve_subpage);

    /* Compute offset within MemoryRegionSection */

    addr -= section->offset_within_address_space;

    /* Compute offset within MemoryRegion */

    *xlat = addr + section->offset_within_region;

    diff_page = int128_make64(((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr);

    diff = int128_sub(section->mr->size, int128_make64(addr));

    diff = int128_min(diff, diff_page);

    *plen = int128_get64(int128_min(diff, int128_make64(*plen)));

    return section;

}


void checkasm_report(const char *name, ...)

{

    static int prev_checked, prev_failed, max_length;

    if (state.num_checked > prev_checked) {

        print_cpu_name();

        if (*name) {

            int pad_length = max_length;

            va_list arg;

            fprintf(stderr, " - ");

            va_start(arg, name);

            pad_length -= vfprintf(stderr, name, arg);

            va_end(arg);

            fprintf(stderr, "%*c", FFMAX(pad_length, 0) + 2, '[');

        } else

            fprintf(stderr, " - %-*s [", max_length, state.current_func->name);

        if (state.num_failed == prev_failed)

            color_printf(COLOR_GREEN, "OK");

        else

            color_printf(COLOR_RED, "FAILED");

        fprintf(stderr, "]\n");

        prev_checked = state.num_checked;

        prev_failed  = state.num_failed;

    } else if (!state.cpu_flag) {

        int length;

        /* Calculate the amount of padding required to make the output vertically aligned */

        if (*name) {

            va_list arg;

            va_start(arg, name);

            length = vsnprintf(NULL, 0, name, arg);

            va_end(arg);

        } else

            length = strlen(state.current_func->name);

        if (length > max_length)

            max_length = length;

    }

}


static int rtp_new_av_stream(HTTPContext *c,

                             int stream_index, struct sockaddr_in *dest_addr,

                             HTTPContext *rtsp_c)

{

    AVFormatContext *ctx;

    AVStream *st;

    char *ipaddr;

    URLContext *h = NULL;

    uint8_t *dummy_buf;

    int max_packet_size;

    /* now we can open the relevant output stream */

    ctx = avformat_alloc_context();

    if (!ctx)

        return -1;

    ctx->oformat = av_guess_format("rtp", NULL, NULL);

    st = av_mallocz(sizeof(AVStream));

    if (!st)

        goto fail;

    ctx->nb_streams = 1;

    ctx->streams[0] = st;

    if (!c->stream->feed ||

        c->stream->feed == c->stream)

        memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));

    else

        memcpy(st,

               c->stream->feed->streams[c->stream->feed_streams[stream_index]],

               sizeof(AVStream));

    st->priv_data = NULL;

    /* build destination RTP address */

    ipaddr = inet_ntoa(dest_addr->sin_addr);

    switch(c->rtp_protocol) {

    case RTSP_LOWER_TRANSPORT_UDP:

    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:

        /* RTP/UDP case */

        /* XXX: also pass as parameter to function ? */

        if (c->stream->is_multicast) {

            int ttl;

            ttl = c->stream->multicast_ttl;

            if (!ttl)

                ttl = 16;

            snprintf(ctx->filename, sizeof(ctx->filename),

                     "rtp://%s:%d?multicast=1&ttl=%d",

                     ipaddr, ntohs(dest_addr->sin_port), ttl);

        } else {

            snprintf(ctx->filename, sizeof(ctx->filename),

                     "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));

        }

        if (url_open(&h, ctx->filename, URL_WRONLY) < 0)

            goto fail;

        c->rtp_handles[stream_index] = h;

        max_packet_size = url_get_max_packet_size(h);

        break;

    case RTSP_LOWER_TRANSPORT_TCP:

        /* RTP/TCP case */

        c->rtsp_c = rtsp_c;

        max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;

        break;

    default:

        goto fail;

    }

    http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",

             ipaddr, ntohs(dest_addr->sin_port),

             c->stream->filename, stream_index, c->protocol);

    /* normally, no packets should be output here, but the packet size may be checked */

    if (url_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {

        /* XXX: close stream */

        goto fail;

    }

    av_set_parameters(ctx, NULL);

    if (av_write_header(ctx) < 0) {

    fail:

        if (h)

            url_close(h);

        av_free(ctx);

        return -1;

    }

    avio_close_dyn_buf(ctx->pb, &dummy_buf);

    av_free(dummy_buf);

    c->rtp_ctx[stream_index] = ctx;

    return 0;

}


float32 HELPER(ucf64_muls)(float32 a, float32 b, CPUUniCore32State *env)

{

    return float32_mul(a, b, &env->ucf64.fp_status);

}


static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend,

                                  Error **errp)

{

    const char *device = qemu_opt_get(opts, "path");

    if (device == NULL) {

        error_setg(errp, "chardev: serial/tty: no device path given");

        return;

    }

    backend->serial = g_new0(ChardevHostdev, 1);

    backend->serial->device = g_strdup(device);

}


static void *rcu_update_perf_test(void *arg)

{

    long long n_updates_local = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;

    atomic_inc(&nthreadsrunning);

    while (goflag == GOFLAG_INIT) {

        g_usleep(1000);

    }

    while (goflag == GOFLAG_RUN) {

        synchronize_rcu();

        n_updates_local++;

    }

    atomic_add(&n_updates, n_updates_local);

    rcu_unregister_thread();

    return NULL;

}


static int tpm_passthrough_unix_transfer(TPMPassthruState *tpm_pt,

                                         const TPMLocality *locty_data)

{

    return tpm_passthrough_unix_tx_bufs(tpm_pt,

                                        locty_data->w_buffer.buffer,

                                        locty_data->w_offset,

                                        locty_data->r_buffer.buffer,

                                        locty_data->r_buffer.size);

}


static void lsi_transfer_data(SCSIRequest *req, uint32_t len)

{

    LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);

    int out;

    if (s->waiting == 1 || !s->current || req->hba_private != s->current ||

        (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {

        if (lsi_queue_req(s, req, len)) {

            return;

        }

    }

    out = (s->sstat1 & PHASE_MASK) == PHASE_DO;

    /* host adapter (re)connected */

    DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len);

    s->current->dma_len = len;

    s->command_complete = 1;

    if (s->waiting) {

        if (s->waiting == 1 || s->dbc == 0) {

            lsi_resume_script(s);

        } else {

            lsi_do_dma(s, out);

        }

    }

}


void tlb_set_page(CPUArchState *env, target_ulong vaddr,

                  hwaddr paddr, int prot,

                  int mmu_idx, target_ulong size)

{

    MemoryRegionSection *section;

    unsigned int index;

    target_ulong address;

    target_ulong code_address;

    uintptr_t addend;

    CPUTLBEntry *te;

    hwaddr iotlb;

    assert(size >= TARGET_PAGE_SIZE);

    if (size != TARGET_PAGE_SIZE) {

        tlb_add_large_page(env, vaddr, size);

    }

    section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);

#if defined(DEBUG_TLB)

    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx

           " prot=%x idx=%d pd=0x%08lx\n",

           vaddr, paddr, prot, mmu_idx, pd);

#endif

    address = vaddr;

    if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {

        /* IO memory case */

        address |= TLB_MMIO;

        addend = 0;

    } else {

        /* TLB_MMIO for rom/romd handled below */

        addend = (uintptr_t)memory_region_get_ram_ptr(section->mr)

        + memory_region_section_addr(section, paddr);

    }

    code_address = address;

    iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, prot,

                                            &address);

    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);

    env->iotlb[mmu_idx][index] = iotlb - vaddr;

    te = &env->tlb_table[mmu_idx][index];

    te->addend = addend - vaddr;

    if (prot & PAGE_READ) {

        te->addr_read = address;

    } else {

        te->addr_read = -1;

    }

    if (prot & PAGE_EXEC) {

        te->addr_code = code_address;

    } else {

        te->addr_code = -1;

    }

    if (prot & PAGE_WRITE) {

        if ((memory_region_is_ram(section->mr) && section->readonly)

            || memory_region_is_romd(section->mr)) {

            /* Write access calls the I/O callback.  */

            te->addr_write = address | TLB_MMIO;

        } else if (memory_region_is_ram(section->mr)

                   && !cpu_physical_memory_is_dirty(

                           section->mr->ram_addr

                           + memory_region_section_addr(section, paddr))) {

            te->addr_write = address | TLB_NOTDIRTY;

        } else {

            te->addr_write = address;

        }

    } else {

        te->addr_write = -1;

    }

}


void memory_region_set_address(MemoryRegion *mr, hwaddr addr)

{

    MemoryRegion *parent = mr->parent;

    int priority = mr->priority;

    bool may_overlap = mr->may_overlap;

    if (addr == mr->addr || !parent) {

        mr->addr = addr;

        return;

    }

    memory_region_transaction_begin();

    memory_region_ref(mr);

    memory_region_del_subregion(parent, mr);

    if (may_overlap) {

        memory_region_add_subregion_overlap(parent, addr, mr, priority);

    } else {

        memory_region_add_subregion(parent, addr, mr);

    }

    memory_region_unref(mr);

    memory_region_transaction_commit();

}


void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size)

{

    int i;

    unsigned char __align8 vector128[8] =

      { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };

    movq_m2r(*vector128, mm1);

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

        movq_m2r(*(block), mm0);

        packsswb_m2r(*(block + 4), mm0);

        block += 8;

        paddb_r2r(mm1, mm0);

        movq_r2m(mm0, *pixels);

        pixels += line_size;

    }

}


static void gd_mouse_mode_change(Notifier *notify, void *data)

{

    gd_update_cursor(container_of(notify, GtkDisplayState, mouse_mode_notifier),

                     FALSE);

}


static void loop_filter(H264Context *h, int start_x, int end_x){

    MpegEncContext * const s = &h->s;

    uint8_t  *dest_y, *dest_cb, *dest_cr;

    int linesize, uvlinesize, mb_x, mb_y;

    const int end_mb_y= s->mb_y + FRAME_MBAFF;

    const int old_slice_type= h->slice_type;

    const int pixel_shift = h->pixel_shift;

    if(h->deblocking_filter) {

        for(mb_x= start_x; mb_x<end_x; mb_x++){

            for(mb_y=end_mb_y - FRAME_MBAFF; mb_y<= end_mb_y; mb_y++){

                int mb_xy, mb_type;

                mb_xy = h->mb_xy = mb_x + mb_y*s->mb_stride;

                h->slice_num= h->slice_table[mb_xy];

                mb_type= s->current_picture.mb_type[mb_xy];

                h->list_count= h->list_counts[mb_xy];

                if(FRAME_MBAFF)

                    h->mb_mbaff = h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);

                s->mb_x= mb_x;

                s->mb_y= mb_y;

                dest_y  = s->current_picture.data[0] + ((mb_x << pixel_shift) + mb_y * s->linesize  ) * 16;

                dest_cb = s->current_picture.data[1] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * 8;

                dest_cr = s->current_picture.data[2] + ((mb_x << pixel_shift) + mb_y * s->uvlinesize) * 8;

                    //FIXME simplify above

                if (MB_FIELD) {

                    linesize   = h->mb_linesize   = s->linesize * 2;

                    uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;

                    if(mb_y&1){ //FIXME move out of this function?

                        dest_y -= s->linesize*15;

                        dest_cb-= s->uvlinesize*7;

                        dest_cr-= s->uvlinesize*7;

                    }

                } else {

                    linesize   = h->mb_linesize   = s->linesize;

                    uvlinesize = h->mb_uvlinesize = s->uvlinesize;

                }

                backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0);

                if(fill_filter_caches(h, mb_type))

                    continue;

                h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);

                h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);

                if (FRAME_MBAFF) {

                    ff_h264_filter_mb     (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);

                } else {

                    ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);

                }

            }

        }

    }

    h->slice_type= old_slice_type;

    s->mb_x= 0;

    s->mb_y= end_mb_y - FRAME_MBAFF;

    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);

    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);

}


static int to_integer(char *p, int len)

{

    int ret;

    char *q = av_malloc(sizeof(char) * len);

    if (!q) return -1;

    strncpy(q, p, len);

    ret = atoi(q);

    av_free(q);

    return ret;

}


void checkasm_check_blend(void)

{

    uint8_t *top1 = av_malloc(BUF_SIZE);

    uint8_t *top2 = av_malloc(BUF_SIZE);

    uint8_t *bot1 = av_malloc(BUF_SIZE);

    uint8_t *bot2 = av_malloc(BUF_SIZE);

    uint8_t *dst1 = av_malloc(BUF_SIZE);

    uint8_t *dst2 = av_malloc(BUF_SIZE);

    FilterParams param = {

        .opacity = 1.0,

    };

#define check_and_report(name, val)               \

    param.mode = val;                             \

    ff_blend_init(&param, 0);                     \

    if (check_func(param.blend, #name))           \

        check_blend_func();

    check_and_report(addition, BLEND_ADDITION)

    check_and_report(addition128, BLEND_ADDITION128)

    check_and_report(and, BLEND_AND)

    check_and_report(average, BLEND_AVERAGE)

    check_and_report(darken, BLEND_DARKEN)

    check_and_report(difference128, BLEND_DIFFERENCE128)

    check_and_report(hardmix, BLEND_HARDMIX)

    check_and_report(lighten, BLEND_LIGHTEN)

    check_and_report(multiply, BLEND_MULTIPLY)

    check_and_report(or, BLEND_OR)

    check_and_report(phoenix, BLEND_PHOENIX)

    check_and_report(screen, BLEND_SCREEN)

    check_and_report(subtract, BLEND_SUBTRACT)

    check_and_report(xor, BLEND_XOR)

    check_and_report(difference, BLEND_DIFFERENCE)

    check_and_report(extremity, BLEND_EXTREMITY)

    check_and_report(negation, BLEND_NEGATION)

    report("8bit");

    av_freep(&top1);

    av_freep(&top2);

    av_freep(&bot1);

    av_freep(&bot2);

    av_freep(&dst1);

    av_freep(&dst2);

}


qemu_irq *armv7m_init(int flash_size, int sram_size,

                      const char *kernel_filename, const char *cpu_model)

{

    CPUState *env;

    DeviceState *nvic;

    /* FIXME: make this local state.  */

    static qemu_irq pic[64];

    qemu_irq *cpu_pic;

    uint32_t pc;

    int image_size;

    uint64_t entry;

    uint64_t lowaddr;

    int i;

    int big_endian;

    flash_size *= 1024;

    sram_size *= 1024;

    if (!cpu_model)

	cpu_model = "cortex-m3";

    env = cpu_init(cpu_model);

    if (!env) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

#if 0

    /* > 32Mb SRAM gets complicated because it overlaps the bitband area.

       We don't have proper commandline options, so allocate half of memory

       as SRAM, up to a maximum of 32Mb, and the rest as code.  */

    if (ram_size > (512 + 32) * 1024 * 1024)

        ram_size = (512 + 32) * 1024 * 1024;

    sram_size = (ram_size / 2) & TARGET_PAGE_MASK;

    if (sram_size > 32 * 1024 * 1024)

        sram_size = 32 * 1024 * 1024;

    code_size = ram_size - sram_size;

#endif

    /* Flash programming is done via the SCU, so pretend it is ROM.  */

    cpu_register_physical_memory(0, flash_size,

                                 qemu_ram_alloc(flash_size) | IO_MEM_ROM);

    cpu_register_physical_memory(0x20000000, sram_size,

                                 qemu_ram_alloc(sram_size) | IO_MEM_RAM);

    armv7m_bitband_init();

    nvic = qdev_create(NULL, "armv7m_nvic");

    env->v7m.nvic = nvic;

    qdev_init(nvic);

    cpu_pic = arm_pic_init_cpu(env);

    sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);

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

        pic[i] = qdev_get_gpio_in(nvic, i);

    }

#ifdef TARGET_WORDS_BIGENDIAN

    big_endian = 1;

#else

    big_endian = 0;

#endif

    image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL,

                          big_endian, ELF_MACHINE, 1);

    if (image_size < 0) {

        image_size = load_image_targphys(kernel_filename, 0, flash_size);

	lowaddr = 0;

    }

    if (image_size < 0) {

        fprintf(stderr, "qemu: could not load kernel '%s'\n",

                kernel_filename);

        exit(1);

    }

    /* If the image was loaded at address zero then assume it is a

       regular ROM image and perform the normal CPU reset sequence.

       Otherwise jump directly to the entry point.  */

    if (lowaddr == 0) {

	env->regs[13] = ldl_phys(0);

	pc = ldl_phys(4);

    } else {

	pc = entry;

    }

    env->thumb = pc & 1;

    env->regs[15] = pc & ~1;

    /* Hack to map an additional page of ram at the top of the address

       space.  This stops qemu complaining about executing code outside RAM

       when returning from an exception.  */

    cpu_register_physical_memory(0xfffff000, 0x1000,

                                 qemu_ram_alloc(0x1000) | IO_MEM_RAM);

    return pic;

}


static int svq3_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             AVPacket *avpkt)

{

    SVQ3Context *svq3 = avctx->priv_data;

    H264Context *h = &svq3->h;

    MpegEncContext *s = &h->s;

    int buf_size = avpkt->size;

    int m, mb_type, left;

    uint8_t *buf;

    /* special case for last picture */

    if (buf_size == 0) {

        if (s->next_picture_ptr && !s->low_delay) {

            *(AVFrame *) data = *(AVFrame *) &s->next_picture;

            s->next_picture_ptr = NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    s->mb_x = s->mb_y = h->mb_xy = 0;

    if (svq3->watermark_key) {

        svq3->buf = av_fast_realloc(svq3->buf, &svq3->buf_size,

                                    buf_size+FF_INPUT_BUFFER_PADDING_SIZE);

        if (!svq3->buf)

            return AVERROR(ENOMEM);

        memcpy(svq3->buf, avpkt->data, buf_size);

        buf = svq3->buf;

    } else {

        buf = avpkt->data;

    }

    init_get_bits(&s->gb, buf, 8*buf_size);

    if (svq3_decode_slice_header(avctx))

        return -1;

    s->pict_type = h->slice_type;

    s->picture_number = h->slice_num;

    if (avctx->debug&FF_DEBUG_PICT_INFO){

        av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",

               av_get_picture_type_char(s->pict_type), svq3->halfpel_flag, svq3->thirdpel_flag,

               s->adaptive_quant, s->qscale, h->slice_num);

    }

    /* for skipping the frame */

    s->current_picture.pict_type = s->pict_type;

    s->current_picture.key_frame = (s->pict_type == AV_PICTURE_TYPE_I);

    /* Skip B-frames if we do not have reference frames. */

    if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B)

        return 0;

    if (  (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B)

        ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I)

        || avctx->skip_frame >= AVDISCARD_ALL)

        return 0;

    if (s->next_p_frame_damaged) {

        if (s->pict_type == AV_PICTURE_TYPE_B)

            return 0;

        else

            s->next_p_frame_damaged = 0;

    }

    if (ff_h264_frame_start(h) < 0)

        return -1;

    if (s->pict_type == AV_PICTURE_TYPE_B) {

        h->frame_num_offset = (h->slice_num - h->prev_frame_num);

        if (h->frame_num_offset < 0) {

            h->frame_num_offset += 256;

        }

        if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) {

            av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n");

            return -1;

        }

    } else {

        h->prev_frame_num = h->frame_num;

        h->frame_num = h->slice_num;

        h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num);

        if (h->prev_frame_num_offset < 0) {

            h->prev_frame_num_offset += 256;

        }

    }

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

        int i;

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

            int j;

            for (j = -1; j < 4; j++)

                h->ref_cache[m][scan8[0] + 8*i + j]= 1;

            if (i < 3)

                h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE;

        }

    }

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

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

            h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;

            if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits &&

                ((get_bits_count(&s->gb) & 7) == 0 || show_bits(&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) {

                skip_bits(&s->gb, svq3->next_slice_index - get_bits_count(&s->gb));

                s->gb.size_in_bits = 8*buf_size;

                if (svq3_decode_slice_header(avctx))

                    return -1;

                /* TODO: support s->mb_skip_run */

            }

            mb_type = svq3_get_ue_golomb(&s->gb);

            if (s->pict_type == AV_PICTURE_TYPE_I) {

                mb_type += 8;

            } else if (s->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4) {

                mb_type += 4;

            }

            if (mb_type > 33 || svq3_decode_mb(svq3, mb_type)) {

                av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);

                return -1;

            }

            if (mb_type != 0) {

                ff_h264_hl_decode_mb (h);

            }

            if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay) {

                s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =

                    (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;

            }

        }

        ff_draw_horiz_band(s, 16*s->mb_y, 16);

    }

    left = buf_size*8 - get_bits_count(&s->gb);

    if (s->mb_y != s->mb_height || s->mb_x != s->mb_width) {

        av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, s->mb_y, s->mb_x, left);

        //av_hex_dump(stderr, buf+buf_size-8, 8);

    }

    if (left < 0) {

        av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);

        return -1;

    }

    MPV_frame_end(s);

    if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {

        *(AVFrame *) data = *(AVFrame *) &s->current_picture;

    } else {

        *(AVFrame *) data = *(AVFrame *) &s->last_picture;

    }

    /* Do not output the last pic after seeking. */

    if (s->last_picture_ptr || s->low_delay) {

        *data_size = sizeof(AVFrame);

    }

    return buf_size;

}


int mpeg4_decode_video_packet_header(MpegEncContext *s)

{

    int mb_num_bits= av_log2(s->mb_num - 1) + 1;

    int header_extension=0, mb_num, len;

    /* is there enough space left for a video packet + header */

    if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1;

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

        if(get_bits1(&s->gb)) break;

    }

    if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){

        av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");

        return -1;

    }

    if(s->shape != RECT_SHAPE){

        header_extension= get_bits1(&s->gb);

        //FIXME more stuff here

    }

    mb_num= get_bits(&s->gb, mb_num_bits);

    if(mb_num>=s->mb_num){

        av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);

        return -1;

    }

    s->mb_x= mb_num % s->mb_width;

    s->mb_y= mb_num / s->mb_width;

    if(s->shape != BIN_ONLY_SHAPE){

        int qscale= get_bits(&s->gb, s->quant_precision);

        if(qscale)

            s->chroma_qscale=s->qscale= qscale;

    }

    if(s->shape == RECT_SHAPE){

        header_extension= get_bits1(&s->gb);

    }

    if(header_extension){

        int time_incr=0;

        while (get_bits1(&s->gb) != 0)

            time_incr++;

        check_marker(&s->gb, "before time_increment in video packed header");

        skip_bits(&s->gb, s->time_increment_bits); /* time_increment */

        check_marker(&s->gb, "before vop_coding_type in video packed header");

        skip_bits(&s->gb, 2); /* vop coding type */

        //FIXME not rect stuff here

        if(s->shape != BIN_ONLY_SHAPE){

            skip_bits(&s->gb, 3); /* intra dc vlc threshold */

//FIXME don't just ignore everything

            if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){

                mpeg4_decode_sprite_trajectory(s, &s->gb);

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

            }

            //FIXME reduced res stuff here

            if (s->pict_type != AV_PICTURE_TYPE_I) {

                int f_code = get_bits(&s->gb, 3);       /* fcode_for */

                if(f_code==0){

                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n");

                }

            }

            if (s->pict_type == AV_PICTURE_TYPE_B) {

                int b_code = get_bits(&s->gb, 3);

                if(b_code==0){

                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n");

                }

            }

        }

    }

    //FIXME new-pred stuff

    return 0;

}


static void opt_video_rc_override_string(char *arg)

{

    video_rc_override_string = arg;

}


av_cold int ff_dvvideo_init(AVCodecContext *avctx)

{

    DVVideoContext *s = avctx->priv_data;

    DSPContext dsp;

    static int done = 0;

    int i, j;

    if (!done) {

        VLC dv_vlc;

        uint16_t new_dv_vlc_bits[NB_DV_VLC*2];

        uint8_t  new_dv_vlc_len[NB_DV_VLC*2];

        uint8_t  new_dv_vlc_run[NB_DV_VLC*2];

        int16_t  new_dv_vlc_level[NB_DV_VLC*2];

        done = 1;

        /* it's faster to include sign bit in a generic VLC parsing scheme */

        for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {

            new_dv_vlc_bits[j]  = dv_vlc_bits[i];

            new_dv_vlc_len[j]   = dv_vlc_len[i];

            new_dv_vlc_run[j]   = dv_vlc_run[i];

            new_dv_vlc_level[j] = dv_vlc_level[i];

            if (dv_vlc_level[i]) {

                new_dv_vlc_bits[j] <<= 1;

                new_dv_vlc_len[j]++;

                j++;

                new_dv_vlc_bits[j]  = (dv_vlc_bits[i] << 1) | 1;

                new_dv_vlc_len[j]   =  dv_vlc_len[i] + 1;

                new_dv_vlc_run[j]   =  dv_vlc_run[i];

                new_dv_vlc_level[j] = -dv_vlc_level[i];

            }

        }

        /* NOTE: as a trick, we use the fact the no codes are unused

           to accelerate the parsing of partial codes */

        init_vlc(&dv_vlc, TEX_VLC_BITS, j,

                 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);

        assert(dv_vlc.table_size == 1184);

        for (i = 0; i < dv_vlc.table_size; i++){

            int code = dv_vlc.table[i][0];

            int len  = dv_vlc.table[i][1];

            int level, run;

            if (len < 0){ //more bits needed

                run   = 0;

                level = code;

            } else {

                run   = new_dv_vlc_run  [code] + 1;

                level = new_dv_vlc_level[code];

            }

            ff_dv_rl_vlc[i].len   = len;

            ff_dv_rl_vlc[i].level = level;

            ff_dv_rl_vlc[i].run   = run;

        }

        ff_free_vlc(&dv_vlc);

    }

    /* Generic DSP setup */

    ff_dsputil_init(&dsp, avctx);

    ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);

    s->get_pixels = dsp.get_pixels;

    s->ildct_cmp = dsp.ildct_cmp[5];

    /* 88DCT setup */

    s->fdct[0]     = dsp.fdct;

    s->idct_put[0] = dsp.idct_put;

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

       s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];

    /* 248DCT setup */

    s->fdct[1]     = dsp.fdct248;

    s->idct_put[1] = ff_simple_idct248_put;  // FIXME: need to add it to DSP

    if (avctx->lowres){

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

            int j = ff_zigzag248_direct[i];

            s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];

        }

    }else

        memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);

    avctx->coded_frame = &s->picture;

    s->avctx = avctx;

    avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;

    return 0;

}