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

{

    SegmentContext *seg = s->priv_data;

    AVFormatContext *oc = seg->avf;

    AVStream *st = s->streams[pkt->stream_index];

    int64_t end_pts = seg->recording_time * seg->number;

    int ret, can_split = 1;

    if (!oc)

        return AVERROR(EINVAL);

    if (seg->has_video) {

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

                    pkt->flags & AV_PKT_FLAG_KEY;

    }

    if (can_split && av_compare_ts(pkt->pts, st->time_base, end_pts,

                                   AV_TIME_BASE_Q) >= 0) {

        av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n",

               pkt->stream_index, pkt->pts);

        ret = segment_end(oc, seg->individual_header_trailer);

        if (!ret)

            ret = segment_start(s, seg->individual_header_trailer);

        if (ret)

            goto fail;

        oc = seg->avf;

        if (seg->list) {

            if (seg->list_type == LIST_HLS) {

                if ((ret = segment_hls_window(s, 0)) < 0)

                    goto fail;

            } else {

                avio_printf(seg->pb, "%s\n", oc->filename);

                avio_flush(seg->pb);

                if (seg->size && !(seg->number % seg->size)) {

                    avio_closep(&seg->pb);

                    if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,

                                          &s->interrupt_callback, NULL)) < 0)

                        goto fail;

                }

            }

        }

    }

    ret = ff_write_chained(oc, pkt->stream_index, pkt, s);

fail:

    if (ret < 0)

        seg_free_context(seg);

    return ret;

}


avs_decode_frame(AVCodecContext * avctx,

                 void *data, int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    const uint8_t *buf_end = avpkt->data + avpkt->size;

    int buf_size = avpkt->size;

    AvsContext *const avs = avctx->priv_data;

    AVFrame *picture = data;

    AVFrame *const p =  &avs->picture;

    const uint8_t *table, *vect;

    uint8_t *out;

    int i, j, x, y, stride, vect_w = 3, vect_h = 3;

    AvsVideoSubType sub_type;

    AvsBlockType type;

    GetBitContext change_map;

    if (avctx->reget_buffer(avctx, p)) {

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

        return -1;

    }

    p->reference = 3;

    p->pict_type = AV_PICTURE_TYPE_P;

    p->key_frame = 0;

    out = avs->picture.data[0];

    stride = avs->picture.linesize[0];

    if (buf_end - buf < 4)

        return AVERROR_INVALIDDATA;

    sub_type = buf[0];

    type = buf[1];

    buf += 4;

    if (type == AVS_PALETTE) {

        int first, last;

        uint32_t *pal = (uint32_t *) avs->picture.data[1];

        first = AV_RL16(buf);

        last = first + AV_RL16(buf + 2);

        if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first))

            return AVERROR_INVALIDDATA;

        buf += 4;

        for (i=first; i<last; i++, buf+=3) {

            pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2);

            pal[i] |= 0xFFU << 24 | (pal[i] >> 6) & 0x30303;

        }

        sub_type = buf[0];

        type = buf[1];

        buf += 4;

    }

    if (type != AVS_VIDEO)

        return -1;

    switch (sub_type) {

    case AVS_I_FRAME:

        p->pict_type = AV_PICTURE_TYPE_I;

        p->key_frame = 1;

    case AVS_P_FRAME_3X3:

        vect_w = 3;

        vect_h = 3;

        break;

    case AVS_P_FRAME_2X2:

        vect_w = 2;

        vect_h = 2;

        break;

    case AVS_P_FRAME_2X3:

        vect_w = 2;

        vect_h = 3;

        break;

    default:

      return -1;

    }

    if (buf_end - buf < 256 * vect_w * vect_h)

        return AVERROR_INVALIDDATA;

    table = buf + (256 * vect_w * vect_h);

    if (sub_type != AVS_I_FRAME) {

        int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h);

        if (buf_end - table < map_size)

            return AVERROR_INVALIDDATA;

        init_get_bits(&change_map, table, map_size * 8);

        table += map_size;

    }

    for (y=0; y<198; y+=vect_h) {

        for (x=0; x<318; x+=vect_w) {

            if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) {

                if (buf_end - table < 1)

                    return AVERROR_INVALIDDATA;

                vect = &buf[*table++ * (vect_w * vect_h)];

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

                    out[(y + 0) * stride + x + j] = vect[(0 * vect_w) + j];

                    out[(y + 1) * stride + x + j] = vect[(1 * vect_w) + j];

                    if (vect_h == 3)

                        out[(y + 2) * stride + x + j] =

                            vect[(2 * vect_w) + j];

                }

            }

        }

        if (sub_type != AVS_I_FRAME)

            align_get_bits(&change_map);

    }

    *picture   = avs->picture;

    *got_frame = 1;

    return buf_size;

}


int av_asrc_buffer_add_buffer(AVFilterContext *ctx,

                              uint8_t *buf, int buf_size, int sample_rate,

                              int sample_fmt, int64_t channel_layout, int planar,

                              int64_t pts, int av_unused flags)

{

    uint8_t *data[8];

    int linesize[8];

    int nb_channels = av_get_channel_layout_nb_channels(channel_layout),

        nb_samples  = buf_size / nb_channels / av_get_bytes_per_sample(sample_fmt);

    av_samples_fill_arrays(data, linesize,

                           buf, nb_channels, nb_samples,

                           sample_fmt, 16);

    return av_asrc_buffer_add_samples(ctx,

                                      data, linesize, nb_samples,

                                      sample_rate,

                                      sample_fmt, channel_layout, planar,

                                      pts, flags);

}


static int vmdaudio_decode_frame(AVCodecContext *avctx,

                                 void *data, int *data_size,

                                 AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    VmdAudioContext *s = avctx->priv_data;

    int block_type, silent_chunks;

    unsigned char *output_samples = (unsigned char *)data;

    if (buf_size < 16) {

        av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");

        *data_size = 0;

        return buf_size;

    }

    block_type = buf[6];

    if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {

        av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);

        return AVERROR(EINVAL);

    }

    buf      += 16;

    buf_size -= 16;

    silent_chunks = 0;

    if (block_type == BLOCK_TYPE_INITIAL) {

        uint32_t flags = AV_RB32(buf);

        silent_chunks  = av_popcount(flags);

        buf      += 4;

        buf_size -= 4;

    } else if (block_type == BLOCK_TYPE_SILENCE) {

        silent_chunks = 1;

        buf_size = 0; // should already be zero but set it just to be sure

    }

    /* ensure output buffer is large enough */

    if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps)

        return -1;

    *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size);

    return avpkt->size;

}


static void ps_decorrelate_c(INTFLOAT (*out)[2], INTFLOAT (*delay)[2],

                             INTFLOAT (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],

                             const INTFLOAT phi_fract[2], const INTFLOAT (*Q_fract)[2],

                             const INTFLOAT *transient_gain,

                             INTFLOAT g_decay_slope,

                             int len)

{

    static const INTFLOAT a[] = { Q31(0.65143905753106f),

                               Q31(0.56471812200776f),

                               Q31(0.48954165955695f) };

    INTFLOAT ag[PS_AP_LINKS];

    int m, n;

    for (m = 0; m < PS_AP_LINKS; m++)

        ag[m] = AAC_MUL30(a[m], g_decay_slope);

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

        INTFLOAT in_re = AAC_MSUB30(delay[n][0], phi_fract[0], delay[n][1], phi_fract[1]);

        INTFLOAT in_im = AAC_MADD30(delay[n][0], phi_fract[1], delay[n][1], phi_fract[0]);

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

            INTFLOAT a_re                = AAC_MUL31(ag[m], in_re);

            INTFLOAT a_im                = AAC_MUL31(ag[m], in_im);

            INTFLOAT link_delay_re       = ap_delay[m][n+2-m][0];

            INTFLOAT link_delay_im       = ap_delay[m][n+2-m][1];

            INTFLOAT fractional_delay_re = Q_fract[m][0];

            INTFLOAT fractional_delay_im = Q_fract[m][1];

            INTFLOAT apd_re = in_re;

            INTFLOAT apd_im = in_im;

            in_re = AAC_MSUB30(link_delay_re, fractional_delay_re,

                    link_delay_im, fractional_delay_im);

            in_re -= a_re;

            in_im = AAC_MADD30(link_delay_re, fractional_delay_im,

                    link_delay_im, fractional_delay_re);

            in_im -= a_im;

            ap_delay[m][n+5][0] = apd_re + AAC_MUL31(ag[m], in_re);

            ap_delay[m][n+5][1] = apd_im + AAC_MUL31(ag[m], in_im);

        }

        out[n][0] = AAC_MUL16(transient_gain[n], in_re);

        out[n][1] = AAC_MUL16(transient_gain[n], in_im);

    }

}


void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,

                  uint8_t ce, uint8_t wp, uint8_t gnd)

{

    NANDFlashState *s = (NANDFlashState *) dev;

    s->cle = cle;

    s->ale = ale;

    s->ce = ce;

    s->wp = wp;

    s->gnd = gnd;

    if (wp)

        s->status |= NAND_IOSTATUS_UNPROTCT;

    else

        s->status &= ~NAND_IOSTATUS_UNPROTCT;

}


static int parse_presentation_segment(AVCodecContext *avctx,
                                      const uint8_t *buf, int buf_size,
                                      int64_t pts)
{
    PGSSubContext *ctx = avctx->priv_data;
    int i, state, ret;
    const uint8_t *buf_end = buf + buf_size;
    // Video descriptor
    int w = bytestream_get_be16(&buf);
    int h = bytestream_get_be16(&buf);
    uint16_t object_index;
    ctx->presentation.pts = pts;
    av_dlog(avctx, "Video Dimensions %dx%d\n",
            w, h);
    ret = ff_set_dimensions(avctx, w, h);
    if (ret < 0)
        return ret;
    /* Skip 1 bytes of unknown, frame rate */
    buf++;
    // Composition descriptor
    ctx->presentation.id_number = bytestream_get_be16(&buf);
    /*
     * state is a 2 bit field that defines pgs epoch boundaries
     * 00 - Normal, previously defined objects and palettes are still valid
     * 01 - Acquisition point, previous objects and palettes can be released
     * 10 - Epoch start, previous objects and palettes can be released
     * 11 - Epoch continue, previous objects and palettes can be released
     *
     * reserved 6 bits discarded
     */
    state = bytestream_get_byte(&buf) >> 6;
    if (state != 0) {
        flush_cache(avctx);
    /*
     * skip palette_update_flag (0x80),
     */
    buf += 1;
    ctx->presentation.palette_id = bytestream_get_byte(&buf);
    ctx->presentation.object_count = bytestream_get_byte(&buf);
    if (ctx->presentation.object_count > MAX_OBJECT_REFS) {
        av_log(avctx, AV_LOG_ERROR,
               "Invalid number of presentation objects %d\n",
               ctx->presentation.object_count);
        ctx->presentation.object_count = 2;
        if (avctx->err_recognition & AV_EF_EXPLODE) {
    for (i = 0; i < ctx->presentation.object_count; i++)
    {
        ctx->presentation.objects[i].id = bytestream_get_be16(&buf);
        ctx->presentation.objects[i].window_id = bytestream_get_byte(&buf);
        ctx->presentation.objects[i].composition_flag = bytestream_get_byte(&buf);
        ctx->presentation.objects[i].x = bytestream_get_be16(&buf);
        ctx->presentation.objects[i].y = bytestream_get_be16(&buf);
        // If cropping
        if (ctx->presentation.objects[i].composition_flag & 0x80) {
            ctx->presentation.objects[i].crop_x = bytestream_get_be16(&buf);
            ctx->presentation.objects[i].crop_y = bytestream_get_be16(&buf);
            ctx->presentation.objects[i].crop_w = bytestream_get_be16(&buf);
            ctx->presentation.objects[i].crop_h = bytestream_get_be16(&buf);
        av_dlog(avctx, "Subtitle Placement x=%d, y=%d\n",
                ctx->presentation.objects[i].x, ctx->presentation.objects[i].y);
        if (ctx->presentation.objects[i].x > avctx->width ||
            ctx->presentation.objects[i].y > avctx->height) {
            av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n",
                   ctx->presentation.objects[i].x,
                   ctx->presentation.objects[i].y,
                    avctx->width, avctx->height);
            ctx->presentation.objects[i].x = 0;
            ctx->presentation.objects[i].y = 0;
            if (avctx->err_recognition & AV_EF_EXPLODE) {
    return 0;


PROTO4(_pack_2ch_)

PROTO4(_pack_6ch_)

PROTO4(_unpack_2ch_)

av_cold void swri_audio_convert_init_x86(struct AudioConvert *ac,

                                 enum AVSampleFormat out_fmt,

                                 enum AVSampleFormat in_fmt,

                                 int channels){

    int mm_flags = av_get_cpu_flags();

    ac->simd_f= NULL;

//FIXME add memcpy case

#define MULTI_CAPS_FUNC(flag, cap) \

    if (mm_flags & flag) {\

        if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\

            ac->simd_f =  ff_int16_to_int32_a_ ## cap;\

        if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\

            ac->simd_f =  ff_int32_to_int16_a_ ## cap;\

    }

MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx)

MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2)

    if(mm_flags & AV_CPU_FLAG_MMX) {

        if(channels == 6) {

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_6ch_float_to_float_a_mmx;

        }

    }

    if(mm_flags & AV_CPU_FLAG_SSE2) {

        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)

            ac->simd_f =  ff_int32_to_float_a_sse2;

        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P)

            ac->simd_f =  ff_int16_to_float_a_sse2;

        if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP)

            ac->simd_f =  ff_float_to_int32_a_sse2;

        if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)

            ac->simd_f =  ff_float_to_int16_a_sse2;

        if(channels == 2) {

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_2ch_int32_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S16P)

                ac->simd_f =  ff_pack_2ch_int16_to_int16_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_S16P)

                ac->simd_f =  ff_pack_2ch_int16_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_2ch_int32_to_int16_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32)

                ac->simd_f =  ff_unpack_2ch_int32_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_int16_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S32)

                ac->simd_f =  ff_unpack_2ch_int32_to_int16_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_2ch_int32_to_float_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)

                ac->simd_f =  ff_pack_2ch_float_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S16P)

                ac->simd_f =  ff_pack_2ch_int16_to_float_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_FLTP)

                ac->simd_f =  ff_pack_2ch_float_to_int16_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S32)

                ac->simd_f =  ff_unpack_2ch_int32_to_float_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_FLT)

                ac->simd_f =  ff_unpack_2ch_float_to_int32_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_float_a_sse2;

            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_FLT)

                ac->simd_f =  ff_unpack_2ch_float_to_int16_a_sse2;

        }

    }

    if(mm_flags & AV_CPU_FLAG_SSSE3) {

        if(channels == 2) {

            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_int16_a_ssse3;

            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_int32_a_ssse3;

            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S16)

                ac->simd_f =  ff_unpack_2ch_int16_to_float_a_ssse3;

        }

    }

    if(mm_flags & AV_CPU_FLAG_SSE4) {

        if(channels == 6) {

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_6ch_float_to_float_a_sse4;

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_6ch_int32_to_float_a_sse4;

            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)

                ac->simd_f =  ff_pack_6ch_float_to_int32_a_sse4;

        }

    }

    if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) {

        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)

            ac->simd_f =  ff_int32_to_float_a_avx;

        if(channels == 6) {

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_6ch_float_to_float_a_avx;

            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)

                ac->simd_f =  ff_pack_6ch_int32_to_float_a_avx;

            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)

                ac->simd_f =  ff_pack_6ch_float_to_int32_a_avx;

        }

    }

}


static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)

{

    FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail);

    if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)

        FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail);

    ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4 - ctx->min_padding) * 8;

    ctx->qscale = 1;

    ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2

    return 0;

 fail:

    return -1;

}


void qemu_system_killed(int signal, pid_t pid)

{

    shutdown_signal = signal;

    shutdown_pid = pid;

    no_shutdown = 0;

    /* Cannot call qemu_system_shutdown_request directly because

     * we are in a signal handler.

     */

    shutdown_requested = 1;

    qemu_notify_event();

}


static int qemu_chr_open_tty(QemuOpts *opts, CharDriverState **_chr)

{

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

    CharDriverState *chr;

    int fd;

    TFR(fd = qemu_open(filename, O_RDWR | O_NONBLOCK));

    if (fd < 0) {

        return -errno;

    }

    tty_serial_init(fd, 115200, 'N', 8, 1);

    chr = qemu_chr_open_fd(fd, fd);

    chr->chr_ioctl = tty_serial_ioctl;

    chr->chr_close = qemu_chr_close_tty;

    *_chr = chr;

    return 0;

}


static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)

{

    USBHubState *s = (USBHubState *)dev;

    int ret;

    switch(p->pid) {

    case USB_TOKEN_IN:

        if (p->devep == 1) {

            USBHubPort *port;

            unsigned int status;

            uint8_t buf[4];

            int i, n;

            n = (NUM_PORTS + 1 + 7) / 8;

            if (p->iov.size == 1) { /* FreeBSD workaround */

                n = 1;

            } else if (n > p->iov.size) {

                return USB_RET_BABBLE;

            }

            status = 0;

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

                port = &s->ports[i];

                if (port->wPortChange)

                    status |= (1 << (i + 1));

            }

            if (status != 0) {

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

                    buf[i] = status >> (8 * i);

                }

                usb_packet_copy(p, buf, n);

                ret = n;

            } else {

                ret = USB_RET_NAK; /* usb11 11.13.1 */

            }

        } else {

            goto fail;

        }

        break;

    case USB_TOKEN_OUT:

    default:

    fail:

        ret = USB_RET_STALL;

        break;

    }

    return ret;

}


static char *vio_format_dev_name(VIOsPAPRDevice *dev)

{

    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);

    char *name;

    /* Device tree style name device@reg */

    if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) {

        return NULL;

    }

    return name;

}


static int load_option_rom(const char *oprom, target_phys_addr_t start,

                           target_phys_addr_t end)

{

    int size;

    char *filename;

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, oprom);

    if (filename) {

        size = get_image_size(filename);

        if (size > 0 && start + size > end) {

            fprintf(stderr, "Not enough space to load option rom '%s'\n",

                    oprom);

            exit(1);

        }

        size = load_image_targphys(filename, start, end - start);

        qemu_free(filename);

    } else {

        size = -1;

    }

    if (size < 0) {

        fprintf(stderr, "Could not load option rom '%s'\n", oprom);

        exit(1);

    }

    /* Round up optiom rom size to the next 2k boundary */

    size = (size + 2047) & ~2047;

    option_rom_setup_reset(start, size);

    return size;

}


static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,

                                                 BlockDriverState *bs,

                                                 QDict *options,

                                                 int flags,

                                                 const BdrvChildRole *role,

                                                 QDict *parent_options,

                                                 int parent_flags)

{

    assert(bs != NULL);

    BlockReopenQueueEntry *bs_entry;

    BdrvChild *child;

    QDict *old_options, *explicit_options;

    if (bs_queue == NULL) {

        bs_queue = g_new0(BlockReopenQueue, 1);

        QSIMPLEQ_INIT(bs_queue);

    }

    if (!options) {

        options = qdict_new();

    }

    /*

     * Precedence of options:

     * 1. Explicitly passed in options (highest)

     * 2. Set in flags (only for top level)

     * 3. Retained from explicitly set options of bs

     * 4. Inherited from parent node

     * 5. Retained from effective options of bs

     */

    if (!parent_options) {

        /*

         * Any setting represented by flags is always updated. If the

         * corresponding QDict option is set, it takes precedence. Otherwise

         * the flag is translated into a QDict option. The old setting of bs is

         * not considered.

         */

        update_options_from_flags(options, flags);

    }

    /* Old explicitly set values (don't overwrite by inherited value) */

    old_options = qdict_clone_shallow(bs->explicit_options);

    bdrv_join_options(bs, options, old_options);

    QDECREF(old_options);

    explicit_options = qdict_clone_shallow(options);

    /* Inherit from parent node */

    if (parent_options) {

        assert(!flags);

        role->inherit_options(&flags, options, parent_flags, parent_options);

    }

    /* Old values are used for options that aren't set yet */

    old_options = qdict_clone_shallow(bs->options);

    bdrv_join_options(bs, options, old_options);

    QDECREF(old_options);

    /* bdrv_open() masks this flag out */

    flags &= ~BDRV_O_PROTOCOL;

    QLIST_FOREACH(child, &bs->children, next) {

        QDict *new_child_options;

        char *child_key_dot;

        /* reopen can only change the options of block devices that were

         * implicitly created and inherited options. For other (referenced)

         * block devices, a syntax like "backing.foo" results in an error. */

        if (child->bs->inherits_from != bs) {

            continue;

        }

        child_key_dot = g_strdup_printf("%s.", child->name);

        qdict_extract_subqdict(options, &new_child_options, child_key_dot);

        g_free(child_key_dot);

        bdrv_reopen_queue_child(bs_queue, child->bs, new_child_options, 0,

                                child->role, options, flags);

    }

    bs_entry = g_new0(BlockReopenQueueEntry, 1);

    QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);

    bs_entry->state.bs = bs;

    bs_entry->state.options = options;

    bs_entry->state.explicit_options = explicit_options;

    bs_entry->state.flags = flags;

    return bs_queue;

}


static void xilinx_axidma_init(Object *obj)

{

    XilinxAXIDMA *s = XILINX_AXI_DMA(obj);

    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    Error *errp = NULL;

    object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,

                             (Object **) &s->tx_dev, NULL);

    object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM);

    object_property_add_child(OBJECT(s), "axistream-connected-target",

                              (Object *)&s->rx_data_dev, &errp);

    assert_no_error(errp);

    sysbus_init_irq(sbd, &s->streams[0].irq);

    sysbus_init_irq(sbd, &s->streams[1].irq);

    memory_region_init_io(&s->iomem, &axidma_ops, s,

                          "xlnx.axi-dma", R_MAX * 4 * 2);

    sysbus_init_mmio(sbd, &s->iomem);

}


void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)

{

    TranslationBlock *tb;

    CPUState *saved_env;

    unsigned long pc;

    int ret;

    /* XXX: hack to restore env in all cases, even if not called from

       generated code */

    saved_env = env;

    env = cpu_single_env;

    D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__,

	     env->pc, env->debug1, retaddr);

    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);

    if (unlikely(ret)) {

        if (retaddr) {

            /* now we have a real cpu fault */

            pc = (unsigned long)retaddr;

            tb = tb_find_pc(pc);

            if (tb) {

                /* the PC is inside the translated code. It means that we have

                   a virtual CPU fault */

                cpu_restore_state(tb, env, pc);

		/* Evaluate flags after retranslation.  */

                helper_top_evaluate_flags();

            }

        }

        cpu_loop_exit(env);

    }

    env = saved_env;

}


static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)

{

    DiracContext *s     = avctx->priv_data;

    DiracFrame *picture = data;

    uint8_t *buf        = pkt->data;

    int buf_size        = pkt->size;

    int i, data_unit_size, buf_idx = 0;

    /* release unused frames */

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

        if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) {

            avctx->release_buffer(avctx, &s->all_frames[i].avframe);

            memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));

        }

    s->current_picture = NULL;

    *data_size = 0;

    /* end of stream, so flush delayed pics */

    if (buf_size == 0)

        return get_delayed_pic(s, (AVFrame *)data, data_size);

    for (;;) {

        /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6

          [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646

          BBCD start code search */

        for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) {

            if (buf[buf_idx  ] == 'B' && buf[buf_idx+1] == 'B' &&

                buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D')

                break;

        }

        /* BBCD found or end of data */

        if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size)

            break;

        data_unit_size = AV_RB32(buf+buf_idx+5);

        if (buf_idx + data_unit_size > buf_size || !data_unit_size) {

            if(buf_idx + data_unit_size > buf_size)

            av_log(s->avctx, AV_LOG_ERROR,

                   "Data unit with size %d is larger than input buffer, discarding\n",

                   data_unit_size);

            buf_idx += 4;

            continue;

        }

        /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */

        if (dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size))

        {

            av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n");

            return -1;

        }

        buf_idx += data_unit_size;

    }

    if (!s->current_picture)

        return 0;

    if (s->current_picture->avframe.display_picture_number > s->frame_number) {

        DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);

        s->current_picture->avframe.reference |= DELAYED_PIC_REF;

        if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {

            int min_num = s->delay_frames[0]->avframe.display_picture_number;

            /* Too many delayed frames, so we display the frame with the lowest pts */

            av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");

            delayed_frame = s->delay_frames[0];

            for (i = 1; s->delay_frames[i]; i++)

                if (s->delay_frames[i]->avframe.display_picture_number < min_num)

                    min_num = s->delay_frames[i]->avframe.display_picture_number;

            delayed_frame = remove_frame(s->delay_frames, min_num);

            add_frame(s->delay_frames, MAX_DELAY, s->current_picture);

        }

        if (delayed_frame) {

            delayed_frame->avframe.reference ^= DELAYED_PIC_REF;

            *(AVFrame*)data = delayed_frame->avframe;

            *data_size = sizeof(AVFrame);

        }

    } else if (s->current_picture->avframe.display_picture_number == s->frame_number) {

        /* The right frame at the right time :-) */

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

        *data_size = sizeof(AVFrame);

    }

    if (*data_size)

        s->frame_number = picture->avframe.display_picture_number + 1;

    return buf_idx;

}


int vfio_spapr_create_window(VFIOContainer *container,

                             MemoryRegionSection *section,

                             hwaddr *pgsize)

{

    int ret;

    IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);

    unsigned pagesize = memory_region_iommu_get_min_page_size(iommu_mr);

    unsigned entries, pages;

    struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) };

    /*

     * FIXME: For VFIO iommu types which have KVM acceleration to

     * avoid bouncing all map/unmaps through qemu this way, this

     * would be the right place to wire that up (tell the KVM

     * device emulation the VFIO iommu handles to use).

     */

    create.window_size = int128_get64(section->size);

    create.page_shift = ctz64(pagesize);

    /*

     * SPAPR host supports multilevel TCE tables, there is some

     * heuristic to decide how many levels we want for our table:

     * 0..64 = 1; 65..4096 = 2; 4097..262144 = 3; 262145.. = 4

     */

    entries = create.window_size >> create.page_shift;

    pages = MAX((entries * sizeof(uint64_t)) / getpagesize(), 1);

    pages = MAX(pow2ceil(pages) - 1, 1); /* Round up */

    create.levels = ctz64(pages) / 6 + 1;

    ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create);

    if (ret) {

        error_report("Failed to create a window, ret = %d (%m)", ret);

        return -errno;

    }

    if (create.start_addr != section->offset_within_address_space) {

        vfio_spapr_remove_window(container, create.start_addr);

        error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64,

                     section->offset_within_address_space,

                     (uint64_t)create.start_addr);

        return -EINVAL;

    }

    trace_vfio_spapr_create_window(create.page_shift,

                                   create.window_size,

                                   create.start_addr);

    *pgsize = pagesize;

    return 0;

}


main(

    int argc,

    char *argv[]

) {

    GMainLoop *loop;

    GIOChannel *channel_stdin;

    char *qemu_host;

    char *qemu_port;

    VCardEmulOptions *command_line_options = NULL;

    char *cert_names[MAX_CERTS];

    char *emul_args = NULL;

    int cert_count = 0;

    int c, sock;

    if (socket_init() != 0)

        return 1;

    while ((c = getopt(argc, argv, "c:e:pd:")) != -1) {

        switch (c) {

        case 'c':

            if (cert_count >= MAX_CERTS) {

                printf("too many certificates (max = %d)\n", MAX_CERTS);

                exit(5);

            }

            cert_names[cert_count++] = optarg;

            break;

        case 'e':

            emul_args = optarg;

            break;

        case 'p':

            print_usage();

            exit(4);

            break;

        case 'd':

            verbose = get_id_from_string(optarg, 1);

            break;

        }

    }

    if (argc - optind != 2) {

        print_usage();

        exit(4);

    }

    if (cert_count > 0) {

        char *new_args;

        int len, i;

        /* if we've given some -c options, we clearly we want do so some

         * software emulation.  add that emulation now. this is NSS Emulator

         * specific */

        if (emul_args == NULL) {

            emul_args = (char *)"db=\"/etc/pki/nssdb\"";

        }

#define SOFT_STRING ",soft=(,Virtual Reader,CAC,,"

             /* 2 == close paren & null */

        len = strlen(emul_args) + strlen(SOFT_STRING) + 2;

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

            len += strlen(cert_names[i])+1; /* 1 == comma */

        }

        new_args = g_malloc(len);

        strcpy(new_args, emul_args);

        strcat(new_args, SOFT_STRING);

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

            strcat(new_args, cert_names[i]);

            strcat(new_args, ",");

        }

        strcat(new_args, ")");

        emul_args = new_args;

    }

    if (emul_args) {

        command_line_options = vcard_emul_options(emul_args);

    }

    qemu_host = g_strdup(argv[argc - 2]);

    qemu_port = g_strdup(argv[argc - 1]);

    sock = connect_to_qemu(qemu_host, qemu_port);

    if (sock == -1) {

        fprintf(stderr, "error opening socket, exiting.\n");

        exit(5);

    }

    socket_to_send = g_byte_array_new();

    qemu_mutex_init(&socket_to_send_lock);

    qemu_mutex_init(&pending_reader_lock);

    qemu_cond_init(&pending_reader_condition);

    vcard_emul_init(command_line_options);

    loop = g_main_loop_new(NULL, true);

    printf("> ");

    fflush(stdout);

#ifdef _WIN32

    channel_stdin = g_io_channel_win32_new_fd(STDIN_FILENO);

#else

    channel_stdin = g_io_channel_unix_new(STDIN_FILENO);

#endif

    g_io_add_watch(channel_stdin, G_IO_IN, do_command, NULL);

#ifdef _WIN32

    channel_socket = g_io_channel_win32_new_socket(sock);

#else

    channel_socket = g_io_channel_unix_new(sock);

#endif

    g_io_channel_set_encoding(channel_socket, NULL, NULL);

    /* we buffer ourself for thread safety reasons */

    g_io_channel_set_buffered(channel_socket, FALSE);

    /* Send init message, Host responds (and then we send reader attachments) */

    VSCMsgInit init = {

        .version = htonl(VSCARD_VERSION),

        .magic = VSCARD_MAGIC,

        .capabilities = {0}

    };

    send_msg(VSC_Init, 0, &init, sizeof(init));

    g_main_loop_run(loop);

    g_main_loop_unref(loop);

    g_io_channel_unref(channel_stdin);

    g_io_channel_unref(channel_socket);

    g_byte_array_free(socket_to_send, TRUE);

    closesocket(sock);

    return 0;

}


static void test_visitor_in_wrong_type(TestInputVisitorData *data,

                                       const void *unused)

{

    TestStruct *p = NULL;

    Visitor *v;

    strList *q = NULL;

    int64_t i;

    Error *err = NULL;

    /* Make sure arrays and structs cannot be confused */

    v = visitor_input_test_init(data, "[]");

    visit_type_TestStruct(v, NULL, &p, &err);

    error_free_or_abort(&err);

    g_assert(!p);

    v = visitor_input_test_init(data, "{}");

    visit_type_strList(v, NULL, &q, &err);

    error_free_or_abort(&err);

    assert(!q);

    /* Make sure primitives and struct cannot be confused */

    v = visitor_input_test_init(data, "1");

    visit_type_TestStruct(v, NULL, &p, &err);

    error_free_or_abort(&err);

    g_assert(!p);

    v = visitor_input_test_init(data, "{}");

    visit_type_int(v, NULL, &i, &err);

    error_free_or_abort(&err);

    /* Make sure primitives and arrays cannot be confused */

    v = visitor_input_test_init(data, "1");

    visit_type_strList(v, NULL, &q, &err);

    error_free_or_abort(&err);

    assert(!q);

    v = visitor_input_test_init(data, "[]");

    visit_type_int(v, NULL, &i, &err);

    error_free_or_abort(&err);

}


static int buffered_close(void *opaque)

{

    MigrationState *s = opaque;

    DPRINTF("closing\n");

    s->xfer_limit = INT_MAX;

    while (!qemu_file_get_error(s->file) && s->buffer_size) {

        buffered_flush(s);

    }

    return migrate_fd_close(s);

}


static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f)

{

    int64_t completed_sector_sum = 0;

    BlkMigDevState *bmds;

    int progress;

    int ret = 0;

    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {

        if (bmds->bulk_completed == 0) {

            if (mig_save_device_bulk(mon, f, bmds) == 1) {

                /* completed bulk section for this device */

                bmds->bulk_completed = 1;

            }

            completed_sector_sum += bmds->completed_sectors;

            ret = 1;

            break;

        } else {

            completed_sector_sum += bmds->completed_sectors;

        }

    }

    if (block_mig_state.total_sector_sum != 0) {

        progress = completed_sector_sum * 100 /

                   block_mig_state.total_sector_sum;

    } else {

        progress = 100;

    }

    if (progress != block_mig_state.prev_progress) {

        block_mig_state.prev_progress = progress;

        qemu_put_be64(f, (progress << BDRV_SECTOR_BITS)

                         | BLK_MIG_FLAG_PROGRESS);

        monitor_printf(mon, "Completed %d %%\r", progress);

        monitor_flush(mon);

    }

    return ret;

}


static void vfio_msi_enable(VFIOPCIDevice *vdev)

{

    int ret, i;

    vfio_disable_interrupts(vdev);

    vdev->nr_vectors = msi_nr_vectors_allocated(&vdev->pdev);

retry:

    vdev->msi_vectors = g_malloc0(vdev->nr_vectors * sizeof(VFIOMSIVector));

    for (i = 0; i < vdev->nr_vectors; i++) {

        VFIOMSIVector *vector = &vdev->msi_vectors[i];

        MSIMessage msg = msi_get_message(&vdev->pdev, i);

        vector->vdev = vdev;

        vector->virq = -1;

        vector->use = true;

        if (event_notifier_init(&vector->interrupt, 0)) {

            error_report("vfio: Error: event_notifier_init failed");

        }

        qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),

                            vfio_msi_interrupt, NULL, vector);

        /*

         * Attempt to enable route through KVM irqchip,

         * default to userspace handling if unavailable.

         */

        vfio_add_kvm_msi_virq(vector, &msg, false);

    }

    /* Set interrupt type prior to possible interrupts */

    vdev->interrupt = VFIO_INT_MSI;

    ret = vfio_enable_vectors(vdev, false);

    if (ret) {

        if (ret < 0) {

            error_report("vfio: Error: Failed to setup MSI fds: %m");

        } else if (ret != vdev->nr_vectors) {

            error_report("vfio: Error: Failed to enable %d "

                         "MSI vectors, retry with %d", vdev->nr_vectors, ret);

        }

        for (i = 0; i < vdev->nr_vectors; i++) {

            VFIOMSIVector *vector = &vdev->msi_vectors[i];

            if (vector->virq >= 0) {

                vfio_remove_kvm_msi_virq(vector);

            }

            qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),

                                NULL, NULL, NULL);

            event_notifier_cleanup(&vector->interrupt);

        }

        g_free(vdev->msi_vectors);

        if (ret > 0 && ret != vdev->nr_vectors) {

            vdev->nr_vectors = ret;

            goto retry;

        }

        vdev->nr_vectors = 0;

        /*

         * Failing to setup MSI doesn't really fall within any specification.

         * Let's try leaving interrupts disabled and hope the guest figures

         * out to fall back to INTx for this device.

         */

        error_report("vfio: Error: Failed to enable MSI");

        vdev->interrupt = VFIO_INT_NONE;

        return;

    }

    trace_vfio_msi_enable(vdev->vbasedev.name, vdev->nr_vectors);

}


build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)

{

    int madt_start = table_data->len;

    const MemMapEntry *memmap = guest_info->memmap;

    const int *irqmap = guest_info->irqmap;

    AcpiMultipleApicTable *madt;

    AcpiMadtGenericDistributor *gicd;

    AcpiMadtGenericMsiFrame *gic_msi;

    int i;

    madt = acpi_data_push(table_data, sizeof *madt);

    gicd = acpi_data_push(table_data, sizeof *gicd);

    gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;

    gicd->length = sizeof(*gicd);

    gicd->base_address = memmap[VIRT_GIC_DIST].base;

    for (i = 0; i < guest_info->smp_cpus; i++) {

        AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,

                                                     sizeof *gicc);

        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));

        gicc->type = ACPI_APIC_GENERIC_INTERRUPT;

        gicc->length = sizeof(*gicc);

        if (guest_info->gic_version == 2) {

            gicc->base_address = memmap[VIRT_GIC_CPU].base;

        }

        gicc->cpu_interface_number = i;

        gicc->arm_mpidr = armcpu->mp_affinity;

        gicc->uid = i;

        gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);

    }

    if (guest_info->gic_version == 3) {

        AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,

                                                         sizeof *gicr);

        gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;

        gicr->length = sizeof(*gicr);

        gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);

        gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);

    } else {

        gic_msi = acpi_data_push(table_data, sizeof *gic_msi);

        gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;

        gic_msi->length = sizeof(*gic_msi);

        gic_msi->gic_msi_frame_id = 0;

        gic_msi->base_address = cpu_to_le64(memmap[VIRT_GIC_V2M].base);

        gic_msi->flags = cpu_to_le32(1);

        gic_msi->spi_count = cpu_to_le16(NUM_GICV2M_SPIS);

        gic_msi->spi_base = cpu_to_le16(irqmap[VIRT_GIC_V2M] + ARM_SPI_BASE);

    }

    build_header(linker, table_data,

                 (void *)(table_data->data + madt_start), "APIC",

                 table_data->len - madt_start, 3, NULL, NULL);

}


void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)

{

    uint8_t *ptr;

    MemoryRegionSection *section;

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

    if (!memory_region_is_ram(section->mr) || section->readonly) {

        addr = memory_region_section_addr(section, addr);

        if (memory_region_is_ram(section->mr)) {

            section = &phys_sections[phys_section_rom];

        }

        io_mem_write(section->mr, addr, val, 4);

    } else {

        unsigned long addr1 = (memory_region_get_ram_addr(section->mr)

                               & TARGET_PAGE_MASK)

            + memory_region_section_addr(section, addr);

        ptr = qemu_get_ram_ptr(addr1);

        stl_p(ptr, val);

        if (unlikely(in_migration)) {

            if (!cpu_physical_memory_is_dirty(addr1)) {

                /* invalidate code */

                tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);

                /* set dirty bit */

                cpu_physical_memory_set_dirty_flags(

                    addr1, (0xff & ~CODE_DIRTY_FLAG));

            }

        }

    }

}


static void compare_pri_rs_finalize(SocketReadState *pri_rs)

{

    CompareState *s = container_of(pri_rs, CompareState, pri_rs);

    if (packet_enqueue(s, PRIMARY_IN)) {

        trace_colo_compare_main("primary: unsupported packet in");

        compare_chr_send(s,

                         pri_rs->buf,

                         pri_rs->packet_len,

                         pri_rs->vnet_hdr_len);

    } else {

        /* compare connection */

        g_queue_foreach(&s->conn_list, colo_compare_connection, s);

    }

}


static int opt_default(const char *opt, const char *arg){

    int type;

    const AVOption *o= NULL;

    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};

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

        const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);

        if(o2)

            o = av_set_string(avctx_opts[type], opt, arg);

    }

    if(!o)

        o = av_set_string(avformat_opts, opt, arg);

    if(!o)

        o = av_set_string(sws_opts, opt, arg);

    if(!o){

        if(opt[0] == 'a')

            o = av_set_string(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg);

        else if(opt[0] == 'v')

            o = av_set_string(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg);

        else if(opt[0] == 's')

            o = av_set_string(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg);

    }

    if(!o)

        return -1;

//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));

    //FIXME we should always use avctx_opts, ... for storing options so there wont be any need to keep track of whats set over this

    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));

    opt_names[opt_name_count++]= o->name;

#ifdef CONFIG_FFM_MUXER

    /* disable generate of real time pts in ffm (need to be supressed anyway) */

    if(avctx_opts[0]->flags & CODEC_FLAG_BITEXACT)

        ffm_nopts = 1;

#endif

    if(avctx_opts[0]->debug)

        av_log_set_level(AV_LOG_DEBUG);

    return 0;

}


static void test_qemu_strtoul_overflow(void)

{

    const char *str = "99999999999999999999999999999999999999999999";

    char f = 'X';

    const char *endptr = &f;

    unsigned long res = 999;

    int err;

    err = qemu_strtoul(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, -ERANGE);

    g_assert_cmpint(res, ==, ULONG_MAX);

    g_assert(endptr == str + strlen(str));

}


int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)

{

    Property *prop;

    int ret;

    prop = qdev_prop_find(dev, name);

    if (!prop) {

        fprintf(stderr, "property \"%s.%s\" not found\n",

                dev->info->name, name);

        return -1;

    }

    if (!prop->info->parse) {

        fprintf(stderr, "property \"%s.%s\" has no parser\n",

                dev->info->name, name);

        return -1;

    }

    ret = prop->info->parse(dev, prop, value);

    if (ret < 0) {

        switch (ret) {

        case -EEXIST:

            fprintf(stderr, "property \"%s.%s\": \"%s\" is already in use\n",

                    dev->info->name, name, value);

            break;

        default:

        case -EINVAL:

            fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n",

                    dev->info->name, name, value);

            break;

        case -ENOENT:

            fprintf(stderr, "property \"%s.%s\": could not find \"%s\"\n",

                    dev->info->name, name, value);

            break;

        }

        return -1;

    }

    return 0;

}


uint32_t ldub_phys(target_phys_addr_t addr)

{

    uint8_t val;

    cpu_physical_memory_read(addr, &val, 1);

    return val;

}


static int get_physical_address_data(CPUState *env,

                                     target_phys_addr_t *physical, int *prot,

                                     target_ulong address, int rw, int mmu_idx)

{

    unsigned int i;

    uint64_t context;

    int is_user = (mmu_idx == MMU_USER_IDX ||

                   mmu_idx == MMU_USER_SECONDARY_IDX);

    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */

        *physical = ultrasparc_truncate_physical(address);

        *prot = PAGE_READ | PAGE_WRITE;

        return 0;

    }

    switch(mmu_idx) {

    case MMU_USER_IDX:

    case MMU_KERNEL_IDX:

        context = env->dmmu.mmu_primary_context & 0x1fff;

        break;

    case MMU_USER_SECONDARY_IDX:

    case MMU_KERNEL_SECONDARY_IDX:

        context = env->dmmu.mmu_secondary_context & 0x1fff;

        break;

    case MMU_NUCLEUS_IDX:

    default:

        context = 0;

        break;

    }

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

        // ctx match, vaddr match, valid?

        if (ultrasparc_tag_match(&env->dtlb[i],

                                 address, context, physical)) {

            // access ok?

            if (((env->dtlb[i].tte & 0x4) && is_user) ||

                (!(env->dtlb[i].tte & 0x2) && (rw == 1))) {

                uint8_t fault_type = 0;

                if ((env->dtlb[i].tte & 0x4) && is_user) {

                    fault_type |= 1; /* privilege violation */

                }

                if (env->dmmu.sfsr & 1) /* Fault status register */

                    env->dmmu.sfsr = 2; /* overflow (not read before

                                             another fault) */

                env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;

                env->dmmu.sfsr |= (fault_type << 7);

                env->dmmu.sfar = address; /* Fault address register */

                env->exception_index = TT_DFAULT;

#ifdef DEBUG_MMU

                printf("DFAULT at 0x%" PRIx64 "\n", address);

#endif

                return 1;

            }

            *prot = PAGE_READ;

            if (env->dtlb[i].tte & 0x2)

                *prot |= PAGE_WRITE;

            TTE_SET_USED(env->dtlb[i].tte);

            return 0;

        }

    }

#ifdef DEBUG_MMU

    printf("DMISS at 0x%" PRIx64 "\n", address);

#endif

    env->dmmu.tag_access = (address & ~0x1fffULL) | context;

    env->exception_index = TT_DMISS;

    return 1;

}


static void vfio_pci_reset(DeviceState *dev)

{

    PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);

    VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);

    if (!vdev->reset_works) {

        return;

    }

    if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {

        error_report("vfio: Error unable to reset physical device "

                     "(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,

                     vdev->host.bus, vdev->host.slot, vdev->host.function);

    }

}


void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)

{

    unsigned int i;

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

        const TCGProfile *orig = &tcg_ctxs[i]->prof;

        if (counters) {

            PROF_ADD(prof, orig, tb_count1);

            PROF_ADD(prof, orig, tb_count);

            PROF_ADD(prof, orig, op_count);

            PROF_MAX(prof, orig, op_count_max);

            PROF_ADD(prof, orig, temp_count);

            PROF_MAX(prof, orig, temp_count_max);

            PROF_ADD(prof, orig, del_op_count);

            PROF_ADD(prof, orig, code_in_len);

            PROF_ADD(prof, orig, code_out_len);

            PROF_ADD(prof, orig, search_out_len);

            PROF_ADD(prof, orig, interm_time);

            PROF_ADD(prof, orig, code_time);

            PROF_ADD(prof, orig, la_time);

            PROF_ADD(prof, orig, opt_time);

            PROF_ADD(prof, orig, restore_count);

            PROF_ADD(prof, orig, restore_time);

        }

        if (table) {

            int i;

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

                PROF_ADD(prof, orig, table_op_count[i]);

            }

        }

    }

}


static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)

{

    char *pix_fmts;

    OutputStream *ost = ofilter->ost;

    OutputFile    *of = output_files[ost->file_index];

    AVFilterContext *last_filter = out->filter_ctx;

    int pad_idx = out->pad_idx;

    int ret;

    char name[255];

    snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);

    ret = avfilter_graph_create_filter(&ofilter->filter,

                                       avfilter_get_by_name("buffersink"),

                                       name, NULL, NULL, fg->graph);

    if (ret < 0)

        return ret;

    if (!hw_device_ctx && (ofilter->width || ofilter->height)) {

        char args[255];

        AVFilterContext *filter;

        snprintf(args, sizeof(args), "%d:%d:0x%X",

                 ofilter->width, ofilter->height,

                 (unsigned)ost->sws_flags);

        snprintf(name, sizeof(name), "scaler for output stream %d:%d",

                 ost->file_index, ost->index);

        if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),

                                                name, args, NULL, fg->graph)) < 0)

            return ret;

        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)

            return ret;

        last_filter = filter;

        pad_idx = 0;

    }

    if ((pix_fmts = choose_pix_fmts(ofilter))) {

        AVFilterContext *filter;

        snprintf(name, sizeof(name), "pixel format for output stream %d:%d",

                 ost->file_index, ost->index);

        ret = avfilter_graph_create_filter(&filter,

                                           avfilter_get_by_name("format"),

                                           "format", pix_fmts, NULL, fg->graph);

        av_freep(&pix_fmts);

        if (ret < 0)

            return ret;

        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)

            return ret;

        last_filter = filter;

        pad_idx     = 0;

    }

    if (ost->frame_rate.num) {

        AVFilterContext *fps;

        char args[255];

        snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,

                 ost->frame_rate.den);

        snprintf(name, sizeof(name), "fps for output stream %d:%d",

                 ost->file_index, ost->index);

        ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),

                                           name, args, NULL, fg->graph);

        if (ret < 0)

            return ret;

        ret = avfilter_link(last_filter, pad_idx, fps, 0);

        if (ret < 0)

            return ret;

        last_filter = fps;

        pad_idx = 0;

    }

    snprintf(name, sizeof(name), "trim for output stream %d:%d",

             ost->file_index, ost->index);

    ret = insert_trim(of->start_time, of->recording_time,

                      &last_filter, &pad_idx, name);

    if (ret < 0)

        return ret;

    if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)

        return ret;

    return 0;

}


static void vfio_exitfn(PCIDevice *pdev)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);

    VFIOGroup *group = vdev->vbasedev.group;

    vfio_unregister_err_notifier(vdev);

    pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);

    vfio_disable_interrupts(vdev);

    if (vdev->intx.mmap_timer) {

        timer_free(vdev->intx.mmap_timer);

    }

    vfio_teardown_msi(vdev);

    vfio_unmap_bars(vdev);

    g_free(vdev->emulated_config_bits);

    g_free(vdev->rom);

    vfio_put_device(vdev);

    vfio_put_group(group);

}


static void FUNCC(pred4x4_left_dc)(uint8_t *_src, const uint8_t *topright, int _stride){

    pixel *src = (pixel*)_src;

    int stride = _stride/sizeof(pixel);

    const int dc= (  src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2;

    ((pixel4*)(src+0*stride))[0]=

    ((pixel4*)(src+1*stride))[0]=

    ((pixel4*)(src+2*stride))[0]=

    ((pixel4*)(src+3*stride))[0]= PIXEL_SPLAT_X4(dc);

}


static void decode_nal_sei_decoded_picture_hash(HEVCContext *s)

{

    int cIdx, i;

    uint8_t hash_type;

    //uint16_t picture_crc;

    //uint32_t picture_checksum;

    GetBitContext *gb = &s->HEVClc->gb;

    hash_type = get_bits(gb, 8);

    for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {

        if (hash_type == 0) {

            s->is_md5 = 1;

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

                s->md5[cIdx][i] = get_bits(gb, 8);

        } else if (hash_type == 1) {

            // picture_crc = get_bits(gb, 16);

            skip_bits(gb, 16);

        } else if (hash_type == 2) {

            // picture_checksum = get_bits(gb, 32);

            skip_bits(gb, 32);

        }

    }

}


static av_cold void dcadec_flush(AVCodecContext *avctx)

{

    DCAContext *s = avctx->priv_data;

    ff_dca_core_flush(&s->core);

    ff_dca_xll_flush(&s->xll);

    ff_dca_lbr_flush(&s->lbr);

    s->core_residual_valid = 0;

}


static int amf_parse_object(AVFormatContext *s, AVStream *astream,

                            AVStream *vstream, const char *key,

                            int64_t max_pos, int depth)

{

    AVCodecContext *acodec, *vcodec;

    FLVContext *flv = s->priv_data;

    AVIOContext *ioc;

    AMFDataType amf_type;

    char str_val[256];

    double num_val;

    num_val  = 0;

    ioc      = s->pb;

    amf_type = avio_r8(ioc);

    switch (amf_type) {

    case AMF_DATA_TYPE_NUMBER:

        num_val = av_int2double(avio_rb64(ioc));

        break;

    case AMF_DATA_TYPE_BOOL:

        num_val = avio_r8(ioc);

        break;

    case AMF_DATA_TYPE_STRING:

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

            return -1;

        break;

    case AMF_DATA_TYPE_OBJECT:

        if ((vstream || astream) && key &&

            !strcmp(KEYFRAMES_TAG, key) && depth == 1)

            if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,

                                      max_pos) < 0)

                return -1;

        while (avio_tell(ioc) < max_pos - 2 &&

               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)

            if (amf_parse_object(s, astream, vstream, str_val, max_pos,

                                 depth + 1) < 0)

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

        if (avio_r8(ioc) != AMF_END_OF_OBJECT)

            return -1;

        break;

    case AMF_DATA_TYPE_NULL:

    case AMF_DATA_TYPE_UNDEFINED:

    case AMF_DATA_TYPE_UNSUPPORTED:

        break;     // these take up no additional space

    case AMF_DATA_TYPE_MIXEDARRAY:

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

        while (avio_tell(ioc) < max_pos - 2 &&

               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)

            // this is the only case in which we would want a nested

            // parse to not skip over the object

            if (amf_parse_object(s, astream, vstream, str_val, max_pos,

                                 depth + 1) < 0)

                return -1;

        if (avio_r8(ioc) != AMF_END_OF_OBJECT)

            return -1;

        break;

    case AMF_DATA_TYPE_ARRAY:

    {

        unsigned int arraylen, i;

        arraylen = avio_rb32(ioc);

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

            if (amf_parse_object(s, NULL, NULL, NULL, max_pos,

                                 depth + 1) < 0)

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

    }

    break;

    case AMF_DATA_TYPE_DATE:

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

        break;

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

        return -1;

    }

    // only look for metadata values when we are not nested and key != NULL

    if (depth == 1 && key) {

        acodec = astream ? astream->codec : NULL;

        vcodec = vstream ? vstream->codec : NULL;

        if (amf_type == AMF_DATA_TYPE_NUMBER ||

            amf_type == AMF_DATA_TYPE_BOOL) {

            if (!strcmp(key, "duration"))

                s->duration = num_val * AV_TIME_BASE;

            else if (!strcmp(key, "videodatarate") && vcodec &&

                     0 <= (int)(num_val * 1024.0))

                vcodec->bit_rate = num_val * 1024.0;

            else if (!strcmp(key, "audiodatarate") && acodec &&

                     0 <= (int)(num_val * 1024.0))

                acodec->bit_rate = num_val * 1024.0;

            else if (!strcmp(key, "datastream")) {

                AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA);

                if (!st)

                    return AVERROR(ENOMEM);

                st->codec->codec_id = AV_CODEC_ID_TEXT;

            } else if (flv->trust_metadata) {

                if (!strcmp(key, "videocodecid") && vcodec) {

                    flv_set_video_codec(s, vstream, num_val, 0);

                } else if (!strcmp(key, "audiocodecid") && acodec) {

                    int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;

                    flv_set_audio_codec(s, astream, acodec, id);

                } else if (!strcmp(key, "audiosamplerate") && acodec) {

                    acodec->sample_rate = num_val;

                } else if (!strcmp(key, "audiosamplesize") && acodec) {

                    acodec->bits_per_coded_sample = num_val;

                } else if (!strcmp(key, "stereo") && acodec) {

                    acodec->channels       = num_val + 1;

                    acodec->channel_layout = acodec->channels == 2 ?

                                             AV_CH_LAYOUT_STEREO :

                                             AV_CH_LAYOUT_MONO;

                } else if (!strcmp(key, "width") && vcodec) {

                    vcodec->width = num_val;

                } else if (!strcmp(key, "height") && vcodec) {

                    vcodec->height = num_val;

                }

            }

        }

        if (!strcmp(key, "duration")        ||

            !strcmp(key, "filesize")        ||

            !strcmp(key, "width")           ||

            !strcmp(key, "height")          ||

            !strcmp(key, "videodatarate")   ||

            !strcmp(key, "framerate")       ||

            !strcmp(key, "videocodecid")    ||

            !strcmp(key, "audiodatarate")   ||

            !strcmp(key, "audiosamplerate") ||

            !strcmp(key, "audiosamplesize") ||

            !strcmp(key, "stereo")          ||

            !strcmp(key, "audiocodecid")    ||

            !strcmp(key, "datastream"))

            return 0;

        if (amf_type == AMF_DATA_TYPE_BOOL) {

            av_strlcpy(str_val, num_val > 0 ? "true" : "false",

                       sizeof(str_val));

            av_dict_set(&s->metadata, key, str_val, 0);

        } else if (amf_type == AMF_DATA_TYPE_NUMBER) {

            snprintf(str_val, sizeof(str_val), "%.f", num_val);

            av_dict_set(&s->metadata, key, str_val, 0);

        } else if (amf_type == AMF_DATA_TYPE_STRING)

            av_dict_set(&s->metadata, key, str_val, 0);

    }

    return 0;

}


static int check(AVIOContext *pb, int64_t pos, int64_t *out_pos)

{

    MPADecodeHeader mh = { 0 };

    int i;

    uint32_t header;

    int64_t off = 0;

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

        off = avio_seek(pb, pos + mh.frame_size, SEEK_SET);

        if (off < 0)

            break;

        header = avio_rb32(pb);

        if (ff_mpa_check_header(header) < 0 ||

            avpriv_mpegaudio_decode_header(&mh, header))

            break;

        out_pos[i] = off;

    }

    return i;

}


int av_read_play(AVFormatContext *s)

{

    if (s->iformat->read_play)

        return s->iformat->read_play(s);

    if (s->pb && s->pb->read_pause)

        return av_url_read_fpause(s->pb, 0);

    return AVERROR(ENOSYS);

}


int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length,

                         HEVCNAL *nal)

{

    int i, si, di;

    uint8_t *dst;

    if (s)

        nal->skipped_bytes = 0;

#define STARTCODE_TEST                                                  \

        if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {     \

            if (src[i + 2] != 3) {                                      \

                /* startcode, so we must be past the end */             \

                length = i;                                             \

            }                                                           \

            break;                                                      \

        }

#if HAVE_FAST_UNALIGNED

#define FIND_FIRST_ZERO                                                 \

        if (i > 0 && !src[i])                                           \

            i--;                                                        \

        while (src[i])                                                  \

            i++

#if HAVE_FAST_64BIT

    for (i = 0; i + 1 < length; i += 9) {

        if (!((~AV_RN64A(src + i) &

               (AV_RN64A(src + i) - 0x0100010001000101ULL)) &

              0x8000800080008080ULL))

            continue;

        FIND_FIRST_ZERO;

        STARTCODE_TEST;

        i -= 7;

    }

#else

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

        if (!((~AV_RN32A(src + i) &

               (AV_RN32A(src + i) - 0x01000101U)) &

              0x80008080U))

            continue;

        FIND_FIRST_ZERO;

        STARTCODE_TEST;

        i -= 3;

    }

#endif /* HAVE_FAST_64BIT */

#else

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

        if (src[i])

            continue;

        if (i > 0 && src[i - 1] == 0)

            i--;

        STARTCODE_TEST;

    }

#endif /* HAVE_FAST_UNALIGNED */

    if (i >= length - 1) { // no escaped 0

        nal->data     =

        nal->raw_data = src;

        nal->size     =

        nal->raw_size = length;

        return length;

    }

    av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size,

                   length + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!nal->rbsp_buffer)

        return AVERROR(ENOMEM);

    dst = nal->rbsp_buffer;

    memcpy(dst, src, i);

    si = di = i;

    while (si + 2 < length) {

        // remove escapes (very rare 1:2^22)

        if (src[si + 2] > 3) {

            dst[di++] = src[si++];

            dst[di++] = src[si++];

        } else if (src[si] == 0 && src[si + 1] == 0) {

            if (src[si + 2] == 3) { // escape

                dst[di++] = 0;

                dst[di++] = 0;

                si       += 3;

                if (s && nal->skipped_bytes_pos) {

                    nal->skipped_bytes++;

                    if (nal->skipped_bytes_pos_size < nal->skipped_bytes) {

                        nal->skipped_bytes_pos_size *= 2;

                        av_assert0(nal->skipped_bytes_pos_size >= nal->skipped_bytes);

                        av_reallocp_array(&nal->skipped_bytes_pos,

                                nal->skipped_bytes_pos_size,

                                sizeof(*nal->skipped_bytes_pos));

                        if (!nal->skipped_bytes_pos) {

                            nal->skipped_bytes_pos_size = 0;

                            return AVERROR(ENOMEM);

                        }

                    }

                    if (nal->skipped_bytes_pos)

                        nal->skipped_bytes_pos[nal->skipped_bytes-1] = di - 1;

                }

                continue;

            } else // next start code

                goto nsc;

        }

        dst[di++] = src[si++];

    }

    while (si < length)

        dst[di++] = src[si++];

nsc:

    memset(dst + di, 0, AV_INPUT_BUFFER_PADDING_SIZE);

    nal->data = dst;

    nal->size = di;

    nal->raw_data = src;

    nal->raw_size = si;

    return si;

}


static int tiff_decode_tag(TiffContext *s, const uint8_t *start,

                           const uint8_t *buf, const uint8_t *end_buf)

{

    unsigned tag, type, count, off, value = 0;

    int i, j;

    int ret;

    uint32_t *pal;

    const uint8_t *rp, *gp, *bp;

    double *dp;

    if (end_buf - buf < 12)

        return -1;

    tag = tget_short(&buf, s->le);

    type = tget_short(&buf, s->le);

    count = tget_long(&buf, s->le);

    off = tget_long(&buf, s->le);

    if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {

        av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",

               type);

        return 0;

    }

    if (count == 1) {

        switch (type) {

        case TIFF_BYTE:

        case TIFF_SHORT:

            buf -= 4;

            value = tget(&buf, type, s->le);

            buf = NULL;

            break;

        case TIFF_LONG:

            value = off;

            buf = NULL;

            break;

        case TIFF_STRING:

            if (count <= 4) {

                buf -= 4;

                break;

            }

        default:

            value = UINT_MAX;

            buf = start + off;

        }

    } else {

        if (count <= 4 && type_sizes[type] * count <= 4) {

            buf -= 4;

        } else {

            buf = start + off;

        }

    }

    if (buf && (buf < start || buf > end_buf)) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Tag referencing position outside the image\n");

        return -1;

    }

    switch (tag) {

    case TIFF_WIDTH:

        s->width = value;

        break;

    case TIFF_HEIGHT:

        s->height = value;

        break;

    case TIFF_BPP:

        s->bppcount = count;

        if (count > 4) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "This format is not supported (bpp=%d, %d components)\n",

                   s->bpp, count);

            return -1;

        }

        if (count == 1)

            s->bpp = value;

        else {

            switch (type) {

            case TIFF_BYTE:

                s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) +

                         ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);

                break;

            case TIFF_SHORT:

            case TIFF_LONG:

                s->bpp = 0;

                for (i = 0; i < count && buf < end_buf; i++)

                    s->bpp += tget(&buf, type, s->le);

                break;

            default:

                s->bpp = -1;

            }

        }

        break;

    case TIFF_SAMPLES_PER_PIXEL:

        if (count != 1) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Samples per pixel requires a single value, many provided\n");

            return AVERROR_INVALIDDATA;

        }

        if (s->bppcount == 1)

            s->bpp *= value;

        s->bppcount = value;

        break;

    case TIFF_COMPR:

        s->compr = value;

        s->predictor = 0;

        switch (s->compr) {

        case TIFF_RAW:

        case TIFF_PACKBITS:

        case TIFF_LZW:

        case TIFF_CCITT_RLE:

            break;

        case TIFF_G3:

        case TIFF_G4:

            s->fax_opts = 0;

            break;

        case TIFF_DEFLATE:

        case TIFF_ADOBE_DEFLATE:

#if CONFIG_ZLIB

            break;

#else

            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");

            return -1;

#endif

        case TIFF_JPEG:

        case TIFF_NEWJPEG:

            av_log(s->avctx, AV_LOG_ERROR,

                   "JPEG compression is not supported\n");

            return -1;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",

                   s->compr);

            return -1;

        }

        break;

    case TIFF_ROWSPERSTRIP:

        if (type == TIFF_LONG && value == UINT_MAX)

            value = s->avctx->height;

        if (value < 1) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Incorrect value of rows per strip\n");

            return -1;

        }

        s->rps = value;

        break;

    case TIFF_STRIP_OFFS:

        if (count == 1) {

            s->stripdata = NULL;

            s->stripoff = value;

        } else

            s->stripdata = start + off;

        s->strips = count;

        if (s->strips == 1)

            s->rps = s->height;

        s->sot = type;

        if (s->stripdata > end_buf) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Tag referencing position outside the image\n");

            return -1;

        }

        break;

    case TIFF_STRIP_SIZE:

        if (count == 1) {

            s->stripsizes = NULL;

            s->stripsize = value;

            s->strips = 1;

        } else {

            s->stripsizes = start + off;

        }

        s->strips = count;

        s->sstype = type;

        if (s->stripsizes > end_buf) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Tag referencing position outside the image\n");

            return -1;

        }

        break;

    case TIFF_TILE_BYTE_COUNTS:

    case TIFF_TILE_LENGTH:

    case TIFF_TILE_OFFSETS:

    case TIFF_TILE_WIDTH:

        av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");

        return AVERROR_PATCHWELCOME;

        break;

    case TIFF_PREDICTOR:

        s->predictor = value;

        break;

    case TIFF_INVERT:

        switch (value) {

        case 0:

            s->invert = 1;

            break;

        case 1:

            s->invert = 0;

            break;

        case 2:

        case 3:

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n",

                   value);

            return -1;

        }

        break;

    case TIFF_FILL_ORDER:

        if (value < 1 || value > 2) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Unknown FillOrder value %d, trying default one\n", value);

            value = 1;

        }

        s->fill_order = value - 1;

        break;

    case TIFF_PAL:

        pal = (uint32_t *) s->palette;

        off = type_sizes[type];

        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)

            return -1;

        rp = buf;

        gp = buf + count / 3 * off;

        bp = buf + count / 3 * off * 2;

        off = (type_sizes[type] - 1) << 3;

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

            j = 0xff << 24;

            j |= (tget(&rp, type, s->le) >> off) << 16;

            j |= (tget(&gp, type, s->le) >> off) << 8;

            j |=  tget(&bp, type, s->le) >> off;

            pal[i] = j;

        }

        s->palette_is_set = 1;

        break;

    case TIFF_PLANAR:

        if (value == 2) {

            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");

            return -1;

        }

        break;

    case TIFF_T4OPTIONS:

        if (s->compr == TIFF_G3)

            s->fax_opts = value;

        break;

    case TIFF_T6OPTIONS:

        if (s->compr == TIFF_G4)

            s->fax_opts = value;

        break;

#define ADD_METADATA(count, name, sep)\

    if (ret = add_metadata(&buf, count, type, name, sep, s) < 0) {\

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

        return ret;\

    }

    case TIFF_MODEL_PIXEL_SCALE:

        ADD_METADATA(count, "ModelPixelScaleTag", NULL);

        break;

    case TIFF_MODEL_TRANSFORMATION:

        ADD_METADATA(count, "ModelTransformationTag", NULL);

        break;

    case TIFF_MODEL_TIEPOINT:

        ADD_METADATA(count, "ModelTiepointTag", NULL);

        break;

    case TIFF_GEO_KEY_DIRECTORY:

        ADD_METADATA(1, "GeoTIFF_Version", NULL);

        ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");

        s->geotag_count   = tget_short(&buf, s->le);

        if (s->geotag_count > count / 4 - 1) {

            s->geotag_count = count / 4 - 1;

            av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");

        }

        s->geotags = av_mallocz(sizeof(TiffGeoTag) * s->geotag_count);

        if (!s->geotags) {

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

            return AVERROR(ENOMEM);

        }

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

            s->geotags[i].key    = tget_short(&buf, s->le);

            s->geotags[i].type   = tget_short(&buf, s->le);

            s->geotags[i].count  = tget_short(&buf, s->le);

            if (!s->geotags[i].type)

                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, tget_short(&buf, s->le));

            else

                s->geotags[i].offset = tget_short(&buf, s->le);

        }

        break;

    case TIFF_GEO_DOUBLE_PARAMS:

        dp = av_malloc(count * sizeof(double));

        if (!dp) {

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

            return AVERROR(ENOMEM);

        }

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

            dp[i] = tget_double(&buf, s->le);

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

            if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {

                if (s->geotags[i].count == 0

                    || s->geotags[i].offset + s->geotags[i].count > count) {

                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);

                } else {

                    char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");

                    if (!ap) {

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

                        av_freep(&dp);

                        return AVERROR(ENOMEM);

                    }

                    s->geotags[i].val = ap;

                }

            }

        }

        av_freep(&dp);

        break;

    case TIFF_GEO_ASCII_PARAMS:

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

            if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {

                if (s->geotags[i].count == 0

                    || s->geotags[i].offset +  s->geotags[i].count > count) {

                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);

                } else {

                    char *ap = av_malloc(s->geotags[i].count);

                    if (!ap) {

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

                        return AVERROR(ENOMEM);

                    }

                    memcpy(ap, &buf[s->geotags[i].offset], s->geotags[i].count);

                    ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte

                    s->geotags[i].val = ap;

                }

            }

        }

        break;

    default:

        av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",

               tag, tag);

    }

    return 0;

}


static int bit_allocation(IMCContext *q, IMCChannel *chctx,

                          int stream_format_code, int freebits, int flag)

{

    int i, j;

    const float limit = -1.e20;

    float highest = 0.0;

    int indx;

    int t1 = 0;

    int t2 = 1;

    float summa = 0.0;

    int iacc = 0;

    int summer = 0;

    int rres, cwlen;

    float lowest = 1.e10;

    int low_indx = 0;

    float workT[32];

    int flg;

    int found_indx = 0;

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

        highest = FFMAX(highest, chctx->flcoeffs1[i]);

    for (i = 0; i < BANDS - 1; i++)

        chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]);

    chctx->flcoeffs4[BANDS - 1] = limit;

    highest = highest * 0.25;

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

        indx = -1;

        if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i])

            indx = 0;

        if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i])

            indx = 1;

        if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i])

            indx = 2;

        if (indx == -1)

            return AVERROR_INVALIDDATA;

        chctx->flcoeffs4[i] += xTab[(indx * 2 + (chctx->flcoeffs1[i] < highest)) * 2 + flag];

    }

    if (stream_format_code & 0x2) {

        chctx->flcoeffs4[0] = limit;

        chctx->flcoeffs4[1] = limit;

        chctx->flcoeffs4[2] = limit;

        chctx->flcoeffs4[3] = limit;

    }

    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) {

        iacc  += chctx->bandWidthT[i];

        summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];

    }

    if (!iacc)

        return AVERROR_INVALIDDATA;

    chctx->bandWidthT[BANDS - 1] = 0;

    summa = (summa * 0.5 - freebits) / iacc;

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

        rres = summer - freebits;

        if ((rres >= -8) && (rres <= 8))

            break;

        summer = 0;

        iacc   = 0;

        for (j = (stream_format_code & 0x2) ? 4 : 0; j < BANDS; j++) {

            cwlen = av_clipf(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);

            chctx->bitsBandT[j] = cwlen;

            summer += chctx->bandWidthT[j] * cwlen;

            if (cwlen > 0)

                iacc += chctx->bandWidthT[j];

        }

        flg = t2;

        t2 = 1;

        if (freebits < summer)

            t2 = -1;

        if (i == 0)

            flg = t2;

        if (flg != t2)

            t1++;

        summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;

    }

    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS; i++) {

        for (j = band_tab[i]; j < band_tab[i + 1]; j++)

            chctx->CWlengthT[j] = chctx->bitsBandT[i];

    }

    if (freebits > summer) {

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

            workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20

                                              : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);

        }

        highest = 0.0;

        do {

            if (highest <= -1.e20)

                break;

            found_indx = 0;

            highest = -1.e20;

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

                if (workT[i] > highest) {

                    highest = workT[i];

                    found_indx = i;

                }

            }

            if (highest > -1.e20) {

                workT[found_indx] -= 2.0;

                if (++chctx->bitsBandT[found_indx] == 6)

                    workT[found_indx] = -1.e20;

                for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) {

                    chctx->CWlengthT[j]++;

                    summer++;

                }

            }

        } while (freebits > summer);

    }

    if (freebits < summer) {

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

            workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] + 1.585)

                                       : 1.e20;

        }

        if (stream_format_code & 0x2) {

            workT[0] = 1.e20;

            workT[1] = 1.e20;

            workT[2] = 1.e20;

            workT[3] = 1.e20;

        }

        while (freebits < summer) {

            lowest   = 1.e10;

            low_indx = 0;

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

                if (workT[i] < lowest) {

                    lowest   = workT[i];

                    low_indx = i;

                }

            }

            // if (lowest >= 1.e10)

            //     break;

            workT[low_indx] = lowest + 2.0;

            if (!--chctx->bitsBandT[low_indx])

                workT[low_indx] = 1.e20;

            for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) {

                if (chctx->CWlengthT[j] > 0) {

                    chctx->CWlengthT[j]--;

                    summer--;

                }

            }

        }

    }

    return 0;

}


static av_cold int g722_decode_init(AVCodecContext * avctx)

{

    G722Context *c = avctx->priv_data;

    if (avctx->channels != 1) {

        av_log(avctx, AV_LOG_ERROR, "Only mono tracks are allowed.\n");

        return AVERROR_INVALIDDATA;

    }

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    c->band[0].scale_factor = 8;

    c->band[1].scale_factor = 2;

    c->prev_samples_pos = 22;

    avcodec_get_frame_defaults(&c->frame);

    avctx->coded_frame = &c->frame;

    return 0;

}


static int handle_packet(MpegTSContext *ts, const uint8_t *packet)

{

    AVFormatContext *s = ts->stream;

    MpegTSFilter *tss;

    int len, pid, cc, cc_ok, afc, is_start;

    const uint8_t *p, *p_end;

    int64_t pos;

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

    if(pid && discard_pid(ts, pid))

        return 0;

    is_start = packet[1] & 0x40;

    tss = ts->pids[pid];

    if (ts->auto_guess && tss == NULL && is_start) {

        add_pes_stream(ts, pid, -1, 0);

        tss = ts->pids[pid];

    }

    if (!tss)

        return 0;

    /* continuity check (currently not used) */

    cc = (packet[3] & 0xf);

    cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));

    tss->last_cc = cc;

    /* skip adaptation field */

    afc = (packet[3] >> 4) & 3;

    p = packet + 4;

    if (afc == 0) /* reserved value */

        return 0;

    if (afc == 2) /* adaptation field only */

        return 0;

    if (afc == 3) {

        /* skip adapation field */

        p += p[0] + 1;

    }

    /* if past the end of packet, ignore */

    p_end = packet + TS_PACKET_SIZE;

    if (p >= p_end)

        return 0;

    pos = url_ftell(ts->stream->pb);

    ts->pos47= pos % ts->raw_packet_size;

    if (tss->type == MPEGTS_SECTION) {

        if (is_start) {

            /* pointer field present */

            len = *p++;

            if (p + len > p_end)

                return 0;

            if (len && cc_ok) {

                /* write remaining section bytes */

                write_section_data(s, tss,

                                   p, len, 0);

                /* check whether filter has been closed */

                if (!ts->pids[pid])

                    return 0;

            }

            p += len;

            if (p < p_end) {

                write_section_data(s, tss,

                                   p, p_end - p, 1);

            }

        } else {

            if (cc_ok) {

                write_section_data(s, tss,

                                   p, p_end - p, 0);

            }

        }

    } else {

        int ret;

        // Note: The position here points actually behind the current packet.

        if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,

                                            pos - ts->raw_packet_size)) < 0)

            return ret;

    }

    return 0;

}


static void buffer_release(void *opaque, uint8_t *data)

{

    *(uint8_t*)opaque = 0;

}


static void float_to_int16_3dnow(int16_t *dst, const float *src, int len){

    // not bit-exact: pf2id uses different rounding than C and SSE

    int i;

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

        asm volatile(

            "pf2id       %1, %%mm0 \n\t"

            "pf2id       %2, %%mm1 \n\t"

            "packssdw %%mm1, %%mm0 \n\t"

            "movq     %%mm0, %0    \n\t"

            :"=m"(dst[i])

            :"m"(src[i]), "m"(src[i+2])

        );

    }

    asm volatile("femms");

}


static int add_shorts_metadata(const uint8_t **buf, int count, const char *name,

                               const char *sep, TiffContext *s)

{

    char *ap;

    int i;

    int *sp = av_malloc(count * sizeof(int));

    if (!sp)

        return AVERROR(ENOMEM);

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

        sp[i] = tget_short(buf, s->le);

    ap = shorts2str(sp, count, sep);

    av_freep(&sp);

    if (!ap)

        return AVERROR(ENOMEM);

    av_dict_set(&s->picture.metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);

    return 0;

}


int ff_mjpeg_decode_sos(MJpegDecodeContext *s,

                        const uint8_t *mb_bitmask, const AVFrame *reference)

{

    int len, nb_components, i, h, v, predictor, point_transform;

    int index, id;

    const int block_size= s->lossless ? 1 : 8;

    int ilv, prev_shift;

    /* XXX: verify len field validity */

    len = get_bits(&s->gb, 16);

    nb_components = get_bits(&s->gb, 8);

    if (nb_components == 0 || nb_components > MAX_COMPONENTS){

        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: nb_components (%d) unsupported\n", nb_components);

        return -1;

    }

    if (len != 6+2*nb_components)

    {

        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);

        return -1;

    }

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

        id = get_bits(&s->gb, 8) - 1;

        av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);

        /* find component index */

        for(index=0;index<s->nb_components;index++)

            if (id == s->component_id[index])

                break;

        if (index == s->nb_components)

        {

            av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index);

            return -1;

        }

        /* Metasoft MJPEG codec has Cb and Cr swapped */

        if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J')

            && nb_components == 3 && s->nb_components == 3 && i)

            index = 3 - i;

        if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == PIX_FMT_GBR24P)

            index = (i+2)%3;

        s->comp_index[i] = index;

        s->nb_blocks[i] = s->h_count[index] * s->v_count[index];

        s->h_scount[i] = s->h_count[index];

        s->v_scount[i] = s->v_count[index];

        s->dc_index[i] = get_bits(&s->gb, 4);

        s->ac_index[i] = get_bits(&s->gb, 4);

        if (s->dc_index[i] <  0 || s->ac_index[i] < 0 ||

            s->dc_index[i] >= 4 || s->ac_index[i] >= 4)

            goto out_of_range;

        if (!s->vlcs[0][s->dc_index[i]].table || !s->vlcs[1][s->ac_index[i]].table)

            goto out_of_range;

    }

    predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */

    ilv= get_bits(&s->gb, 8);    /* JPEG Se / JPEG-LS ILV */

    if(s->avctx->codec_tag != AV_RL32("CJPG")){

        prev_shift = get_bits(&s->gb, 4); /* Ah */

        point_transform= get_bits(&s->gb, 4); /* Al */

    }else

        prev_shift= point_transform= 0;

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

        s->last_dc[i] = 1024;

    if (nb_components > 1) {

        /* interleaved stream */

        s->mb_width  = (s->width  + s->h_max * block_size - 1) / (s->h_max * block_size);

        s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);

    } else if(!s->ls) { /* skip this for JPEG-LS */

        h = s->h_max / s->h_scount[0];

        v = s->v_max / s->v_scount[0];

        s->mb_width  = (s->width  + h * block_size - 1) / (h * block_size);

        s->mb_height = (s->height + v * block_size - 1) / (v * block_size);

        s->nb_blocks[0] = 1;

        s->h_scount[0] = 1;

        s->v_scount[0] = 1;

    }

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

        av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n", s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "",

               predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod,

               s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components);

    /* mjpeg-b can have padding bytes between sos and image data, skip them */

    for (i = s->mjpb_skiptosod; i > 0; i--)

        skip_bits(&s->gb, 8);

    if(s->lossless){

        av_assert0(s->picture_ptr == &s->picture);

        if(CONFIG_JPEGLS_DECODER && s->ls){

//            for(){

//            reset_ls_coding_parameters(s, 0);

            if(ff_jpegls_decode_picture(s, predictor, point_transform, ilv) < 0)

                return -1;

        }else{

            if(s->rgb){

                if(ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform) < 0)

                    return -1;

            }else{

                if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0)

                    return -1;

            }

        }

    }else{

        if(s->progressive && predictor) {

            av_assert0(s->picture_ptr == &s->picture);

            if(mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, point_transform) < 0)

                return -1;

        } else {

            if(mjpeg_decode_scan(s, nb_components, prev_shift, point_transform,

                                 mb_bitmask, reference) < 0)

                return -1;

        }

    }

    if (s->yuv421) {

        uint8_t *line = s->picture_ptr->data[2];

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

            for (index = s->width - 1; index; index--)

                line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1;

            line += s->linesize[2];

        }

    } else if (s->yuv442) {

        uint8_t *dst = &((uint8_t *)s->picture_ptr->data[2])[(s->height - 1) * s->linesize[2]];

        for (i = s->height - 1; i; i--) {

            uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[2])[i / 2 * s->linesize[2]];

            uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[2])[(i + 1) / 2 * s->linesize[2]];

            if (src1 == src2) {

                memcpy(dst, src1, s->width);

            } else {

                for (index = 0; index < s->width; index++)

                    dst[index] = (src1[index] + src2[index]) >> 1;

            }

            dst -= s->linesize[2];

        }

    }

    emms_c();

    return 0;

 out_of_range:

    av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");

    return -1;

}


static int is_intra_more_likely(MpegEncContext *s){

    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;

    if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) return 1; //no previous frame available -> use spatial prediction

    undamaged_count=0;

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

        const int mb_xy= s->mb_index2xy[i];

        const int error= s->error_status_table[mb_xy];

        if(!((error&DC_ERROR) && (error&MV_ERROR)))

            undamaged_count++;

    }

    if(s->codec_id == CODEC_ID_H264){

        H264Context *h= (void*)s;

        if (h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0])

            return 1;

    }

    if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction

    //prevent dsp.sad() check, that requires access to the image

    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)

        return 1;

    skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs

    is_intra_likely=0;

    j=0;

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

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

            int error;

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

            error= s->error_status_table[mb_xy];

            if((error&DC_ERROR) && (error&MV_ERROR))

                continue; //skip damaged

            j++;

            if((j%skip_amount) != 0) continue; //skip a few to speed things up

            if(s->pict_type==AV_PICTURE_TYPE_I){

                uint8_t *mb_ptr     = s->current_picture.f.data[0] + mb_x*16 + mb_y*16*s->linesize;

                uint8_t *last_mb_ptr= s->last_picture.f.data   [0] + mb_x*16 + mb_y*16*s->linesize;

                if (s->avctx->codec_id == CODEC_ID_H264) {

                    // FIXME

                } else {

                    ff_thread_await_progress((AVFrame *) s->last_picture_ptr,

                                             mb_y, 0);

                }

                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);

                // FIXME need await_progress() here

                is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);

            }else{

                if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))

                   is_intra_likely++;

                else

                   is_intra_likely--;

            }

        }

    }

//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);

    return is_intra_likely > 0;

}


I2CAdapter *omap_i2c_create(uint64_t addr)

{

    OMAPI2C *s = g_malloc0(sizeof(*s));

    I2CAdapter *i2c = (I2CAdapter *)s;

    uint16_t data;

    s->addr = addr;

    i2c->send = omap_i2c_send;

    i2c->recv = omap_i2c_recv;

    /* verify the mmio address by looking for a known signature */

    memread(addr + OMAP_I2C_REV, &data, 2);

    g_assert_cmphex(data, ==, 0x34);

    return i2c;

}