QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,

                                  QCryptoCipherMode mode,

                                  const uint8_t *key, size_t nkey,

                                  Error **errp)

{

    QCryptoCipher *cipher;

    QCryptoCipherNettle *ctx;

    uint8_t *rfbkey;

    switch (mode) {

    case QCRYPTO_CIPHER_MODE_ECB:

    case QCRYPTO_CIPHER_MODE_CBC:

    case QCRYPTO_CIPHER_MODE_XTS:

    case QCRYPTO_CIPHER_MODE_CTR:

        break;

    default:

        error_setg(errp, "Unsupported cipher mode %s",

                   QCryptoCipherMode_lookup[mode]);

        return NULL;

    }

    if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {

        return NULL;

    }

    cipher = g_new0(QCryptoCipher, 1);

    cipher->alg = alg;

    cipher->mode = mode;

    ctx = g_new0(QCryptoCipherNettle, 1);

    switch (alg) {

    case QCRYPTO_CIPHER_ALG_DES_RFB:

        ctx->ctx = g_new0(struct des_ctx, 1);

        rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);

        des_set_key(ctx->ctx, rfbkey);

        g_free(rfbkey);

        ctx->alg_encrypt_native = des_encrypt_native;

        ctx->alg_decrypt_native = des_decrypt_native;

        ctx->alg_encrypt_wrapper = des_encrypt_wrapper;

        ctx->alg_decrypt_wrapper = des_decrypt_wrapper;

        ctx->blocksize = DES_BLOCK_SIZE;

        break;

    case QCRYPTO_CIPHER_ALG_AES_128:

    case QCRYPTO_CIPHER_ALG_AES_192:

    case QCRYPTO_CIPHER_ALG_AES_256:

        ctx->ctx = g_new0(QCryptoNettleAES, 1);

        if (mode == QCRYPTO_CIPHER_MODE_XTS) {

            ctx->ctx_tweak = g_new0(QCryptoNettleAES, 1);

            nkey /= 2;

            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc,

                                nkey, key);

            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec,

                                nkey, key);

            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->enc,

                                nkey, key + nkey);

            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->dec,

                                nkey, key + nkey);

        } else {

            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc,

                                nkey, key);

            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec,

                                nkey, key);

        }

        ctx->alg_encrypt_native = aes_encrypt_native;

        ctx->alg_decrypt_native = aes_decrypt_native;

        ctx->alg_encrypt_wrapper = aes_encrypt_wrapper;

        ctx->alg_decrypt_wrapper = aes_decrypt_wrapper;

        ctx->blocksize = AES_BLOCK_SIZE;

        break;

    case QCRYPTO_CIPHER_ALG_CAST5_128:

        ctx->ctx = g_new0(struct cast128_ctx, 1);

        if (mode == QCRYPTO_CIPHER_MODE_XTS) {

            ctx->ctx_tweak = g_new0(struct cast128_ctx, 1);

            nkey /= 2;

            cast5_set_key(ctx->ctx, nkey, key);

            cast5_set_key(ctx->ctx_tweak, nkey, key + nkey);

        } else {

            cast5_set_key(ctx->ctx, nkey, key);

        }

        ctx->alg_encrypt_native = cast128_encrypt_native;

        ctx->alg_decrypt_native = cast128_decrypt_native;

        ctx->alg_encrypt_wrapper = cast128_encrypt_wrapper;

        ctx->alg_decrypt_wrapper = cast128_decrypt_wrapper;

        ctx->blocksize = CAST128_BLOCK_SIZE;

        break;

    case QCRYPTO_CIPHER_ALG_SERPENT_128:

    case QCRYPTO_CIPHER_ALG_SERPENT_192:

    case QCRYPTO_CIPHER_ALG_SERPENT_256:

        ctx->ctx = g_new0(struct serpent_ctx, 1);

        if (mode == QCRYPTO_CIPHER_MODE_XTS) {

            ctx->ctx_tweak = g_new0(struct serpent_ctx, 1);

            nkey /= 2;

            serpent_set_key(ctx->ctx, nkey, key);

            serpent_set_key(ctx->ctx_tweak, nkey, key + nkey);

        } else {

            serpent_set_key(ctx->ctx, nkey, key);

        }

        ctx->alg_encrypt_native = serpent_encrypt_native;

        ctx->alg_decrypt_native = serpent_decrypt_native;

        ctx->alg_encrypt_wrapper = serpent_encrypt_wrapper;

        ctx->alg_decrypt_wrapper = serpent_decrypt_wrapper;

        ctx->blocksize = SERPENT_BLOCK_SIZE;

        break;

    case QCRYPTO_CIPHER_ALG_TWOFISH_128:

    case QCRYPTO_CIPHER_ALG_TWOFISH_192:

    case QCRYPTO_CIPHER_ALG_TWOFISH_256:

        ctx->ctx = g_new0(struct twofish_ctx, 1);

        if (mode == QCRYPTO_CIPHER_MODE_XTS) {

            ctx->ctx_tweak = g_new0(struct twofish_ctx, 1);

            nkey /= 2;

            twofish_set_key(ctx->ctx, nkey, key);

            twofish_set_key(ctx->ctx_tweak, nkey, key + nkey);

        } else {

            twofish_set_key(ctx->ctx, nkey, key);

        }

        ctx->alg_encrypt_native = twofish_encrypt_native;

        ctx->alg_decrypt_native = twofish_decrypt_native;

        ctx->alg_encrypt_wrapper = twofish_encrypt_wrapper;

        ctx->alg_decrypt_wrapper = twofish_decrypt_wrapper;

        ctx->blocksize = TWOFISH_BLOCK_SIZE;

        break;

    default:

        error_setg(errp, "Unsupported cipher algorithm %s",

                   QCryptoCipherAlgorithm_lookup[alg]);

        goto error;

    }

    if (mode == QCRYPTO_CIPHER_MODE_XTS &&

        ctx->blocksize != XTS_BLOCK_SIZE) {

        error_setg(errp, "Cipher block size %zu must equal XTS block size %d",

                   ctx->blocksize, XTS_BLOCK_SIZE);

        goto error;

    }

    ctx->iv = g_new0(uint8_t, ctx->blocksize);

    cipher->opaque = ctx;

    return cipher;

 error:

    g_free(cipher);

    g_free(ctx);

    return NULL;

}


static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)

{

    int64_t pos = avio_tell(pb);

    avio_wb32(pb, 0); /* size */

    ffio_wfourcc(pb, "minf");

    if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)

        mov_write_vmhd_tag(pb);

    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)

        mov_write_smhd_tag(pb);

    else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {

        if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {

            mov_write_gmhd_tag(pb, track);

        } else {

            mov_write_nmhd_tag(pb);

        }

    } else if (track->tag == MKTAG('r','t','p',' ')) {

        mov_write_hmhd_tag(pb);

    } else if (track->tag == MKTAG('t','m','c','d')) {

        mov_write_gmhd_tag(pb, track);

    }

    if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */

        mov_write_hdlr_tag(pb, NULL);

    mov_write_dinf_tag(pb);

    mov_write_stbl_tag(pb, track);

    return update_size(pb, pos);

}


static int qsv_decode_init(AVCodecContext *avctx, QSVContext *q)

{

    const AVPixFmtDescriptor *desc;

    mfxSession session = NULL;

    int iopattern = 0;

    mfxVideoParam param = { { 0 } };

    int frame_width  = avctx->coded_width;

    int frame_height = avctx->coded_height;

    int ret;

    desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);

    if (!desc)

        return AVERROR_BUG;

    if (!q->async_fifo) {

        q->async_fifo = av_fifo_alloc((1 + q->async_depth) *

                                      (sizeof(mfxSyncPoint*) + sizeof(QSVFrame*)));

        if (!q->async_fifo)

            return AVERROR(ENOMEM);

    }

    if (avctx->pix_fmt == AV_PIX_FMT_QSV && avctx->hwaccel_context) {

        AVQSVContext *user_ctx = avctx->hwaccel_context;

        session           = user_ctx->session;

        iopattern         = user_ctx->iopattern;

        q->ext_buffers    = user_ctx->ext_buffers;

        q->nb_ext_buffers = user_ctx->nb_ext_buffers;

    }

    if (avctx->hw_frames_ctx) {

        AVHWFramesContext    *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;

        AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;

        if (!iopattern) {

            if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)

                iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY;

            else if (frames_hwctx->frame_type & MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET)

                iopattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;

        }

        frame_width  = frames_hwctx->surfaces[0].Info.Width;

        frame_height = frames_hwctx->surfaces[0].Info.Height;

    }

    if (!iopattern)

        iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY;

    q->iopattern = iopattern;

    ret = qsv_init_session(avctx, q, session, avctx->hw_frames_ctx);

    if (ret < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error initializing an MFX session\n");

        return ret;

    }

    ret = ff_qsv_codec_id_to_mfx(avctx->codec_id);

    if (ret < 0)

        return ret;

    param.mfx.CodecId      = ret;

    param.mfx.CodecProfile = ff_qsv_profile_to_mfx(avctx->codec_id, avctx->profile);

    param.mfx.CodecLevel   = avctx->level == FF_LEVEL_UNKNOWN ? MFX_LEVEL_UNKNOWN : avctx->level;

    param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;

    param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;

    param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;

    param.mfx.FrameInfo.FourCC         = q->fourcc;

    param.mfx.FrameInfo.Width          = frame_width;

    param.mfx.FrameInfo.Height         = frame_height;

    param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;

    switch (avctx->field_order) {

    case AV_FIELD_PROGRESSIVE:

        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;

        break;

    case AV_FIELD_TT:

        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;

        break;

    case AV_FIELD_BB:

        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_BFF;

        break;

    default:

        param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_UNKNOWN;

        break;

    }

    param.IOPattern   = q->iopattern;

    param.AsyncDepth  = q->async_depth;

    param.ExtParam    = q->ext_buffers;

    param.NumExtParam = q->nb_ext_buffers;

    ret = MFXVideoDECODE_Init(q->session, &param);

    if (ret < 0)

        return ff_qsv_print_error(avctx, ret,

                                  "Error initializing the MFX video decoder");

    q->frame_info = param.mfx.FrameInfo;

    return 0;

}


static void ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,

                             const uint8_t *table)

{

    int i;

    int j;

    int out = 0;

    int c;

    int t;

    /* first line contain absolute values, other lines contain deltas */

    while (out < width){

        c = ir2_get_code(&ctx->gb);

        if(c > 0x80) { /* we have a run */

            c -= 0x80;

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

                dst[out++] = 0x80;

        } else { /* copy two values from table */

            dst[out++] = table[c * 2];

            dst[out++] = table[(c * 2) + 1];

        }

    }

    dst += stride;

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

        out = 0;

        while (out < width){

            c = ir2_get_code(&ctx->gb);

            if(c > 0x80) { /* we have a skip */

                c -= 0x80;

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

                    dst[out] = dst[out - stride];

                    out++;

                }

            } else { /* add two deltas from table */

                t = dst[out - stride] + (table[c * 2] - 128);

                CLAMP_TO_BYTE(t);

                dst[out] = t;

                out++;

                t = dst[out - stride] + (table[(c * 2) + 1] - 128);

                CLAMP_TO_BYTE(t);

                dst[out] = t;

                out++;

            }

        }

        dst += stride;

    }

}


int kvm_arm_sync_mpstate_to_kvm(ARMCPU *cpu)

{

    if (cap_has_mp_state) {

        struct kvm_mp_state mp_state = {

            .mp_state =

            cpu->powered_off ? KVM_MP_STATE_STOPPED : KVM_MP_STATE_RUNNABLE

        };

        int ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &mp_state);

        if (ret) {

            fprintf(stderr, "%s: failed to set MP_STATE %d/%s\n",

                    __func__, ret, strerror(-ret));

            return -1;

        }

    }

    return 0;

}


void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext *ctx,

                                                bool assign, bool set_handler)

{

    if (assign && set_handler) {

        aio_set_event_notifier(ctx, &vq->host_notifier, true,

                               virtio_queue_host_notifier_read);

    } else {

        aio_set_event_notifier(ctx, &vq->host_notifier, true, NULL);

    }

    if (!assign) {

        /* Test and clear notifier before after disabling event,

         * in case poll callback didn't have time to run. */

        virtio_queue_host_notifier_read(&vq->host_notifier);

    }

}


av_cold int swr_init(struct SwrContext *s){

    int ret;

    char l1[1024], l2[1024];

    clear_context(s);

    if(s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){

        av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);

        return AVERROR(EINVAL);

    }

    if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){

        av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);

        return AVERROR(EINVAL);

    }

    s->out.ch_count  = s-> user_out_ch_count;

    s-> in.ch_count  = s->  user_in_ch_count;

    s->used_ch_count = s->user_used_ch_count;

    s-> in_ch_layout = s-> user_in_ch_layout;

    s->out_ch_layout = s->user_out_ch_layout;

    if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) {

        av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout);

        s->in_ch_layout = 0;

    }

    if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) {

        av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout);

        s->out_ch_layout = 0;

    }

    switch(s->engine){

#if CONFIG_LIBSOXR

        case SWR_ENGINE_SOXR: s->resampler = &swri_soxr_resampler; break;

#endif

        case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;

        default:

            av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");

            return AVERROR(EINVAL);

    }

    if(!s->used_ch_count)

        s->used_ch_count= s->in.ch_count;

    if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){

        av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");

        s-> in_ch_layout= 0;

    }

    if(!s-> in_ch_layout)

        s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);

    if(!s->out_ch_layout)

        s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);

    s->rematrix= s->out_ch_layout  !=s->in_ch_layout || s->rematrix_volume!=1.0 ||

                 s->rematrix_custom;

    if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){

        if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_S16P){

            s->int_sample_fmt= AV_SAMPLE_FMT_S16P;

        }else if(   av_get_planar_sample_fmt(s-> in_sample_fmt) == AV_SAMPLE_FMT_S32P

                 && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P

                 && !s->rematrix

                 && s->engine != SWR_ENGINE_SOXR){

            s->int_sample_fmt= AV_SAMPLE_FMT_S32P;

        }else if(av_get_planar_sample_fmt(s->in_sample_fmt) <= AV_SAMPLE_FMT_FLTP){

            s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;

        }else{

            av_log(s, AV_LOG_DEBUG, "Using double precision mode\n");

            s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;

        }

    }

    if(   s->int_sample_fmt != AV_SAMPLE_FMT_S16P

        &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P

        &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP

        &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){

        av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, S16/S32/FLT/DBL is supported\n", av_get_sample_fmt_name(s->int_sample_fmt));

        return AVERROR(EINVAL);

    }

    set_audiodata_fmt(&s-> in, s-> in_sample_fmt);

    set_audiodata_fmt(&s->out, s->out_sample_fmt);

    if (s->firstpts_in_samples != AV_NOPTS_VALUE) {

        if (!s->async && s->min_compensation >= FLT_MAX/2)

            s->async = 1;

        s->firstpts =

        s->outpts   = s->firstpts_in_samples * s->out_sample_rate;

    } else

        s->firstpts = AV_NOPTS_VALUE;

    if (s->async) {

        if (s->min_compensation >= FLT_MAX/2)

            s->min_compensation = 0.001;

        if (s->async > 1.0001) {

            s->max_soft_compensation = s->async / (double) s->in_sample_rate;

        }

    }

    if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){

        s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby);

        if (!s->resample) {

            av_log(s, AV_LOG_ERROR, "Failed to initilaize resampler\n");

            return AVERROR(ENOMEM);

        }

    }else

        s->resampler->free(&s->resample);

    if(    s->int_sample_fmt != AV_SAMPLE_FMT_S16P

        && s->int_sample_fmt != AV_SAMPLE_FMT_S32P

        && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP

        && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP

        && s->resample){

        av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n");

        return -1;

    }

#define RSC 1 //FIXME finetune

    if(!s-> in.ch_count)

        s-> in.ch_count= av_get_channel_layout_nb_channels(s-> in_ch_layout);

    if(!s->used_ch_count)

        s->used_ch_count= s->in.ch_count;

    if(!s->out.ch_count)

        s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);

    if(!s-> in.ch_count){

        av_assert0(!s->in_ch_layout);

        av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");

        return -1;

    }

    av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout);

    av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout);

    if (s->out_ch_layout && s->out.ch_count != av_get_channel_layout_nb_channels(s->out_ch_layout)) {

        av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches specified channel count %d\n", l2, s->out.ch_count);

        return AVERROR(EINVAL);

    }

    if (s->in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s->in_ch_layout)) {

        av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_count);

        return AVERROR(EINVAL);

    }

    if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) {

        av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "

               "but there is not enough information to do it\n", l1, l2);

        return -1;

    }

av_assert0(s->used_ch_count);

av_assert0(s->out.ch_count);

    s->resample_first= RSC*s->out.ch_count/s->in.ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;

    s->in_buffer= s->in;

    s->silence  = s->in;

    s->drop_temp= s->out;

    if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){

        s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,

                                                   s-> in_sample_fmt, s-> in.ch_count, NULL, 0);

        return 0;

    }

    s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,

                                             s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);

    s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,

                                             s->int_sample_fmt, s->out.ch_count, NULL, 0);

    if (!s->in_convert || !s->out_convert)

        return AVERROR(ENOMEM);

    s->postin= s->in;

    s->preout= s->out;

    s->midbuf= s->in;

    if(s->channel_map){

        s->postin.ch_count=

        s->midbuf.ch_count= s->used_ch_count;

        if(s->resample)

            s->in_buffer.ch_count= s->used_ch_count;

    }

    if(!s->resample_first){

        s->midbuf.ch_count= s->out.ch_count;

        if(s->resample)

            s->in_buffer.ch_count = s->out.ch_count;

    }

    set_audiodata_fmt(&s->postin, s->int_sample_fmt);

    set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);

    set_audiodata_fmt(&s->preout, s->int_sample_fmt);

    if(s->resample){

        set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);

    }

    if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)

        return ret;

    if(s->rematrix || s->dither.method)

        return swri_rematrix_init(s);

    return 0;

}


static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_num)

{

    MpegEncContext *s  = &v->s;

    int mb_cbp         = v->cbp[s->mb_x - s->mb_stride],

        block_cbp      = mb_cbp      >> (block_num * 4), bottom_cbp,

        mb_is_intra    = v->is_intra[s->mb_x - s->mb_stride],

        block_is_intra = mb_is_intra >> (block_num * 4), bottom_is_intra;

    int idx, linesize  = block_num > 3 ? s->uvlinesize : s->linesize, ttblk;

    uint8_t *dst;

    if (block_num > 3) {

        dst      = s->dest[block_num - 3];

    } else {

        dst      = s->dest[0] + (block_num & 1) * 8 + ((block_num & 2) * 4 - 8) * linesize;

    }

    if (s->mb_y != s->end_mb_y || block_num < 2) {

        int16_t (*mv)[2];

        int mv_stride;

        if (block_num > 3) {

            bottom_cbp      = v->cbp[s->mb_x]      >> (block_num * 4);

            bottom_is_intra = v->is_intra[s->mb_x] >> (block_num * 4);

            mv              = &v->luma_mv[s->mb_x - s->mb_stride];

            mv_stride       = s->mb_stride;

        } else {

            bottom_cbp      = (block_num < 2) ? (mb_cbp               >> ((block_num + 2) * 4))

                                              : (v->cbp[s->mb_x]      >> ((block_num - 2) * 4));

            bottom_is_intra = (block_num < 2) ? (mb_is_intra          >> ((block_num + 2) * 4))

                                              : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));

            mv_stride       = s->b8_stride;

            mv              = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];

        }

        if (bottom_is_intra & 1 || block_is_intra & 1 ||

            mv[0][0] != mv[mv_stride][0] || mv[0][1] != mv[mv_stride][1]) {

            v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);

        } else {

            idx = ((bottom_cbp >> 2) | block_cbp) & 3;

            if (idx == 3) {

                v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);

            } else if (idx) {

                if (idx == 1)

                    v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);

                else

                    v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);

            }

        }

    }

    dst -= 4 * linesize;

    ttblk = (v->ttblk[s->mb_x - s->mb_stride] >> (block_num * 4)) & 0xF;

    if (ttblk == TT_4X4 || ttblk == TT_8X4) {

        idx = (block_cbp | (block_cbp >> 2)) & 3;

        if (idx == 3) {

            v->vc1dsp.vc1_v_loop_filter8(dst, linesize, v->pq);

        } else if (idx) {

            if (idx == 1)

                v->vc1dsp.vc1_v_loop_filter4(dst + 4, linesize, v->pq);

            else

                v->vc1dsp.vc1_v_loop_filter4(dst,     linesize, v->pq);

        }

    }

}


int main(void)

{

    int x = 0;

    int i, j;

    AVLFG state;

    av_lfg_init(&state, 0xdeadbeef);

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

        START_TIMER

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

            //av_log(NULL, AV_LOG_ERROR, "%X\n", av_lfg_get(&state));

            x += av_lfg_get(&state);

        }

        STOP_TIMER("624 calls of av_lfg_get");

    }

    av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x);

    /* BMG usage example */

    {

        double mean   = 1000;

        double stddev = 53;

        av_lfg_init(&state, 42);

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

            double bmg_out[2];

            av_bmg_get(&state, bmg_out);

            av_log(NULL, AV_LOG_INFO,

                   "%f\n%f\n",

                   bmg_out[0] * stddev + mean,

                   bmg_out[1] * stddev + mean);

        }

    }

    return 0;

}


enum CodecID codec_get_id(const CodecTag *tags, unsigned int tag)

{

    while (tags->id != 0) {

        if(   toupper((tag >> 0)&0xFF) == toupper((tags->tag >> 0)&0xFF)

           && toupper((tag >> 8)&0xFF) == toupper((tags->tag >> 8)&0xFF)

           && toupper((tag >>16)&0xFF) == toupper((tags->tag >>16)&0xFF)

           && toupper((tag >>24)&0xFF) == toupper((tags->tag >>24)&0xFF))

            return tags->id;

        tags++;

    }

    return CODEC_ID_NONE;

}


static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const int16_t *_block,

                                        ptrdiff_t stride)

{

    int i;

    pixel *pix = (pixel*)_pix;

    const dctcoef *block = (const dctcoef*)_block;

    stride >>= sizeof(pixel)-1;

    pix -= stride;

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

        pixel v = pix[0];

        pix[1*stride]= v += block[0];

        pix[2*stride]= v += block[4];

        pix[3*stride]= v += block[8];

        pix[4*stride]= v +  block[12];

        pix++;

        block++;

    }

}


static void pci_bridge_cleanup_alias(MemoryRegion *alias,

                                     MemoryRegion *parent_space)

{

    memory_region_del_subregion(parent_space, alias);

    memory_region_destroy(alias);

}


static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
{
    const AVHWAccel *hwaccel = avctx->hwaccel;
    int override_dimensions = 1;
    int ret;
    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
        if ((ret = av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) < 0 || avctx->pix_fmt<0) {
            av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
            return AVERROR(EINVAL);
        }
        if (frame->width <= 0 || frame->height <= 0) {
            frame->width  = FFMAX(avctx->width,  AV_CEIL_RSHIFT(avctx->coded_width,  avctx->lowres));
            frame->height = FFMAX(avctx->height, AV_CEIL_RSHIFT(avctx->coded_height, avctx->lowres));
            override_dimensions = 0;
        }
        if (frame->data[0] || frame->data[1] || frame->data[2] || frame->data[3]) {
            av_log(avctx, AV_LOG_ERROR, "pic->data[*]!=NULL in get_buffer_internal\n");
            return AVERROR(EINVAL);
        }
    }
    ret = ff_decode_frame_props(avctx, frame);
        return ret;
    if (hwaccel) {
        if (hwaccel->alloc_frame) {
            ret = hwaccel->alloc_frame(avctx, frame);
            goto end;
        }
    } else
        avctx->sw_pix_fmt = avctx->pix_fmt;
    ret = avctx->get_buffer2(avctx, frame, flags);
    if (ret >= 0)
        validate_avframe_allocation(avctx, frame);
end:
    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions &&
        !(avctx->codec->caps_internal & FF_CODEC_CAP_EXPORTS_CROPPING)) {
        frame->width  = avctx->width;
        frame->height = avctx->height;
    }
    return ret;
}


void pcie_host_mmcfg_init(PCIExpressHost *e, uint32_t size)

{

    assert(!(size & (size - 1)));       /* power of 2 */

    assert(size >= PCIE_MMCFG_SIZE_MIN);

    assert(size <= PCIE_MMCFG_SIZE_MAX);

    e->size = size;

    memory_region_init_io(&e->mmio, OBJECT(e), &pcie_mmcfg_ops, e,

                          "pcie-mmcfg", e->size);

}


static void update_sse_status(CPUX86State *env)

{

    int rnd_type;

    /* set rounding mode */

    switch (env->mxcsr & SSE_RC_MASK) {

    default:

    case SSE_RC_NEAR:

        rnd_type = float_round_nearest_even;

        break;

    case SSE_RC_DOWN:

        rnd_type = float_round_down;

        break;

    case SSE_RC_UP:

        rnd_type = float_round_up;

        break;

    case SSE_RC_CHOP:

        rnd_type = float_round_to_zero;

        break;

    }

    set_float_rounding_mode(rnd_type, &env->sse_status);

    /* set denormals are zero */

    set_flush_inputs_to_zero((env->mxcsr & SSE_DAZ) ? 1 : 0, &env->sse_status);

    /* set flush to zero */

    set_flush_to_zero((env->mxcsr & SSE_FZ) ? 1 : 0, &env->fp_status);

}


static int adts_aac_probe(AVProbeData *p)

{

    int max_frames = 0, first_frames = 0;

    int fsize, frames;

    uint8_t *buf0 = p->buf;

    uint8_t *buf2;

    uint8_t *buf;

    uint8_t *end = buf0 + p->buf_size - 7;

    buf = buf0;

    for(; buf < end; buf= buf2+1) {

        buf2 = buf;

        for(frames = 0; buf2 < end; frames++) {

            uint32_t header = AV_RB16(buf2);

            if((header&0xFFF6) != 0xFFF0)

                break;

            fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF;

            if(fsize < 7)

                break;

            buf2 += fsize;

        }

        max_frames = FFMAX(max_frames, frames);

        if(buf == buf0)

            first_frames= frames;

    }

    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;

    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;

    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;

    else if(max_frames>=1) return 1;

    else                   return 0;

}


static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc,

                                              Error **errp)

{

    char *handshake_end;

    ssize_t ret;

    /* Typical HTTP headers from novnc are 512 bytes, so limiting

     * total header size to 4096 is easily enough. */

    size_t want = 4096 - ioc->encinput.offset;

    buffer_reserve(&ioc->encinput, want);

    ret = qio_channel_read(ioc->master,

                           (char *)buffer_end(&ioc->encinput), want, errp);

    if (ret < 0) {

        return -1;

    }

    ioc->encinput.offset += ret;

    handshake_end = g_strstr_len((char *)ioc->encinput.buffer,

                                 ioc->encinput.offset,

                                 QIO_CHANNEL_WEBSOCK_HANDSHAKE_END);

    if (!handshake_end) {

        if (ioc->encinput.offset >= 4096) {

            error_setg(errp,

                       "End of headers not found in first 4096 bytes");

            return -1;

        } else {

            return 0;

        }

    }

    *handshake_end = '\0';

    if (qio_channel_websock_handshake_process(ioc,

                                              (char *)ioc->encinput.buffer,

                                              errp) < 0) {

        return -1;

    }

    buffer_advance(&ioc->encinput,

                   handshake_end - (char *)ioc->encinput.buffer +

                   strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_END));

    return 1;

}


static int decode_init_mp3on4(AVCodecContext * avctx)

{

    MP3On4DecodeContext *s = avctx->priv_data;

    MPEG4AudioConfig cfg;

    int i;

    if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) {

        av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");

        return -1;

    }

    avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size);

    if (!cfg.chan_config || cfg.chan_config > 7) {

        av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");

        return -1;

    }

    s->frames = mp3Frames[cfg.chan_config];

    s->coff = chan_offset[cfg.chan_config];

    avctx->channels = ff_mpeg4audio_channels[cfg.chan_config];

    avctx->channel_layout = chan_layout[cfg.chan_config];

    if (cfg.sample_rate < 16000)

        s->syncword = 0xffe00000;

    else

        s->syncword = 0xfff00000;

    /* Init the first mp3 decoder in standard way, so that all tables get builded

     * We replace avctx->priv_data with the context of the first decoder so that

     * decode_init() does not have to be changed.

     * Other decoders will be initialized here copying data from the first context

     */

    // Allocate zeroed memory for the first decoder context

    s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));

    // Put decoder context in place to make init_decode() happy

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

    decode_init(avctx);

    // Restore mp3on4 context pointer

    avctx->priv_data = s;

    s->mp3decctx[0]->adu_mode = 1; // Set adu mode

    /* Create a separate codec/context for each frame (first is already ok).

     * Each frame is 1 or 2 channels - up to 5 frames allowed

     */

    for (i = 1; i < s->frames; i++) {

        s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));

        if (!s->mp3decctx[i])

        s->mp3decctx[i]->adu_mode = 1;

        s->mp3decctx[i]->avctx = avctx;

        s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;

    }

    /* Allocate buffer for multi-channel output if needed */

    if (s->frames > 1) {

        s->decoded_buf = av_malloc(MPA_FRAME_SIZE * MPA_MAX_CHANNELS *

                                   sizeof(*s->decoded_buf));

        if (!s->decoded_buf)

    }

    return 0;

alloc_fail:

    decode_close_mp3on4(avctx);

    return AVERROR(ENOMEM);

}


void avdevice_register_all(void)

{

    static int inited;

    if (inited)

        return;

    inited = 1;

    /* devices */

    REGISTER_MUXDEMUX (AUDIO_BEOS, audio_beos);

    REGISTER_DEMUXER  (BKTR, bktr);

    REGISTER_DEMUXER  (DV1394, dv1394);

    REGISTER_MUXDEMUX (OSS, oss);

    REGISTER_DEMUXER  (V4L2, v4l2);

    REGISTER_DEMUXER  (V4L, v4l);

    REGISTER_DEMUXER  (X11_GRAB_DEVICE, x11_grab_device);

    /* external libraries */

    REGISTER_DEMUXER  (LIBDC1394, libdc1394);

}


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

{

    ASFContext *asf = s->priv_data;

    ASFStream *asf_st = 0;

    ByteIOContext *pb = &s->pb;

    static int pc = 0;

    for (;;) {

	int rsize = 0;

	if (asf->packet_size_left < FRAME_HEADER_SIZE

	    || asf->packet_segments < 0) {

	    //asf->packet_size_left <= asf->packet_padsize) {

	    int ret;

	    //printf("PACKETLEFTSIZE  %d\n", asf->packet_size_left);

            /* fail safe */

            if (asf->packet_size_left)

		url_fskip(pb, asf->packet_size_left);

            if (asf->packet_padsize)

		url_fskip(pb, asf->packet_padsize);

	    ret = asf_get_packet(s);

	    //printf("READ ASF PACKET  %d   r:%d   c:%d\n", ret, asf->packet_size_left, pc++);

	    if (ret < 0)

		return -EIO;

            asf->packet_time_start = 0;

            continue;

	}

	if (asf->packet_time_start == 0) {

            int num;

	    if (--asf->packet_segments < 0)

		continue;

	    /* read frame header */

	    num = get_byte(pb);

	    rsize++;

	    asf->packet_key_frame = (num & 0x80) >> 7;

	    asf->stream_index = asf->asfid2avid[num & 0x7f];

	    if (asf->stream_index < 0)

	    {

		/* unhandled packet (should not happen) */

		url_fskip(pb, asf->packet_frag_size);

		asf->packet_size_left -= asf->packet_frag_size;

		printf("ff asf skip %d  %d\n", asf->packet_frag_size, num &0x7f);

                continue;

	    }

	    asf->asf_st = s->streams[asf->stream_index]->priv_data;

	    //printf("ASFST  %p    %d <> %d\n", asf->asf_st, asf->stream_index, num & 0x7f);

	    // sequence should be ignored!

	    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);

	    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);

	    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);

	    if (asf->packet_replic_size > 1) {

                // it should be always at least 8 bytes - FIXME validate

		asf->packet_obj_size = get_le32(pb);

		asf->packet_frag_timestamp = get_le32(pb); // timestamp

		rsize += asf->packet_replic_size; // FIXME - check validity

	    } else {

		// multipacket - frag_offset is beginig timestamp

		asf->packet_time_start = asf->packet_frag_offset;

                asf->packet_frag_offset = 0;

		asf->packet_frag_timestamp = asf->packet_timestamp;

		if (asf->packet_replic_size == 1) {

		    asf->packet_time_delta = get_byte(pb);

		    rsize++;

		}

	    }

	    if (asf->packet_flags & 0x01) {

		DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal

		//printf("Fragsize %d\n", asf->packet_frag_size);

	    } else {

		asf->packet_frag_size = asf->packet_size_left - rsize;

		//printf("Using rest  %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);

	    }

	    if (asf->packet_replic_size == 1)

	    {

		asf->packet_multi_size = asf->packet_frag_size;

		if (asf->packet_multi_size > asf->packet_size_left)

		{

		    asf->packet_segments = 0;

                    continue;

		}

	    }

#undef DO_2BITS

	    asf->packet_size_left -= rsize;

	    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);

	}

	asf_st = asf->asf_st;

	if ((asf->packet_frag_offset != asf_st->frag_offset

	     || (asf->packet_frag_offset

		 && asf->packet_seq != asf_st->seq)) // seq should be ignored

	   ) {

	    /* cannot continue current packet: free it */

	    // FIXME better check if packet was already allocated

	    printf("ff asf parser skips: %d - %d     o:%d - %d    %d %d   fl:%d\n",

		   asf_st->pkt.size,

		   asf->packet_obj_size,

		   asf->packet_frag_offset, asf_st->frag_offset,

		   asf->packet_seq, asf_st->seq, asf->packet_frag_size);

	    if (asf_st->pkt.size)

		av_free_packet(&asf_st->pkt);

	    asf_st->frag_offset = 0;

	    if (asf->packet_frag_offset != 0) {

		url_fskip(pb, asf->packet_frag_size);

		printf("ff asf parser skiping %db\n", asf->packet_frag_size);

		asf->packet_size_left -= asf->packet_frag_size;

		continue;

	    }

	}

	if (asf->packet_replic_size == 1) {

	    // frag_offset is here used as the begining timestamp

	    asf->packet_frag_timestamp = asf->packet_time_start;

	    asf->packet_time_start += asf->packet_time_delta;

	    asf->packet_obj_size = asf->packet_frag_size = get_byte(pb);

	    asf->packet_size_left--;

            asf->packet_multi_size--;

	    if (asf->packet_multi_size < asf->packet_obj_size)

	    {

		asf->packet_time_start = 0;

		url_fskip(pb, asf->packet_multi_size);

		asf->packet_size_left -= asf->packet_multi_size;

                continue;

	    }

	    asf->packet_multi_size -= asf->packet_obj_size;

	    //printf("COMPRESS size  %d  %d  %d   ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size);

	}

	if (asf_st->frag_offset == 0) {

	    /* new packet */

	    av_new_packet(&asf_st->pkt, asf->packet_obj_size);

	    asf_st->seq = asf->packet_seq;

	    asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll;

	    asf_st->pkt.stream_index = asf->stream_index;

	    if (asf->packet_key_frame)

		asf_st->pkt.flags |= PKT_FLAG_KEY;

	}

	/* read data */

	//printf("READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",

	//       asf->packet_size, asf_st->pkt.size, asf->packet_frag_offset,

	//       asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);

	asf->packet_size_left -= asf->packet_frag_size;

	if (asf->packet_size_left < 0)

            continue;

	get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset,

		   asf->packet_frag_size);

	asf_st->frag_offset += asf->packet_frag_size;

	/* test if whole packet is read */

	if (asf_st->frag_offset == asf_st->pkt.size) {

	    /* return packet */

	    if (asf_st->ds_span > 1) {

		/* packet descrambling */

		char* newdata = av_malloc(asf_st->pkt.size);

		if (newdata) {

		    int offset = 0;

		    while (offset < asf_st->pkt.size) {

			int off = offset / asf_st->ds_chunk_size;

			int row = off / asf_st->ds_span;

			int col = off % asf_st->ds_span;

			int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;

			//printf("off:%d  row:%d  col:%d  idx:%d\n", off, row, col, idx);

			memcpy(newdata + offset,

			       asf_st->pkt.data + idx * asf_st->ds_chunk_size,

			       asf_st->ds_chunk_size);

			offset += asf_st->ds_chunk_size;

		    }

		    av_free(asf_st->pkt.data);

		    asf_st->pkt.data = newdata;

		}

	    }

	    asf_st->frag_offset = 0;

	    memcpy(pkt, &asf_st->pkt, sizeof(AVPacket));

	    //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size);

	    asf_st->pkt.size = 0;

	    asf_st->pkt.data = 0;

	    break; // packet completed

	}

    }

    return 0;

}


static int qdm2_decode_frame(AVCodecContext *avctx,

            void *data, int *data_size,

            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    QDM2Context *s = avctx->priv_data;

    int16_t *out = data;

    int i;

    if(!buf)

        return 0;

    if(buf_size < s->checksum_size)

        return -1;

    av_log(avctx, AV_LOG_DEBUG, "decode(%d): %p[%d] -> %p[%d]\n",

       buf_size, buf, s->checksum_size, data, *data_size);

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

        if (qdm2_decode(s, buf, out) < 0)

            return -1;

        out += s->channels * s->frame_size;

    }

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

    return s->checksum_size;

}


static av_cold int xcbgrab_read_header(AVFormatContext *s)

{

    XCBGrabContext *c = s->priv_data;

    int screen_num, ret;

    const xcb_setup_t *setup;

    char *display_name = av_strdup(s->filename);

    if (s->filename) {

        if (!display_name)

            return AVERROR(ENOMEM);

        if (!sscanf(s->filename, "%[^+]+%d,%d", display_name, &c->x, &c->y)) {

            *display_name = 0;

            sscanf(s->filename, "+%d,%d", &c->x, &c->y);

        }

    }

    c->conn = xcb_connect(display_name, &screen_num);

    av_freep(&display_name);

    if ((ret = xcb_connection_has_error(c->conn))) {

        av_log(s, AV_LOG_ERROR, "Cannot open display %s, error %d.\n",

               s->filename ? s->filename : "default", ret);

        return AVERROR(EIO);

    }

    setup = xcb_get_setup(c->conn);

    c->screen = get_screen(setup, screen_num);

    if (!c->screen) {

        av_log(s, AV_LOG_ERROR, "The screen %d does not exist.\n",

               screen_num);

        xcbgrab_read_close(s);

        return AVERROR(EIO);

    }

#if CONFIG_LIBXCB_SHM

    c->segment = xcb_generate_id(c->conn);

#endif

    ret = create_stream(s);

    if (ret < 0) {

        xcbgrab_read_close(s);

        return ret;

    }

#if CONFIG_LIBXCB_SHM

    c->has_shm = check_shm(c->conn);

#endif

#if CONFIG_LIBXCB_XFIXES

    if (c->draw_mouse) {

        if (!(c->draw_mouse = check_xfixes(c->conn))) {

            av_log(s, AV_LOG_WARNING,

                   "XFixes not available, cannot draw the mouse.\n");

        }

        if (c->bpp < 24) {

            avpriv_report_missing_feature(s, "%d bits per pixel screen",

                                          c->bpp);

            c->draw_mouse = 0;

        }

    }

#endif

    if (c->show_region)

        setup_window(s);

    return 0;

}


H264_CHROMA_MC(put_       , op_put)

H264_CHROMA_MC(avg_       , op_avg)

#undef op_avg

#undef op_put

#define H264_LOWPASS(OPNAME, OP, OP2) \

static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int h=2;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

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

    {\

        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\

        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\

        dst+=dstStride;\

        src+=srcStride;\

    }\

}\

\

static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int w=2;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    for(i=0; i<w; i++)\

    {\

        const int srcB= src[-2*srcStride];\

        const int srcA= src[-1*srcStride];\

        const int src0= src[0 *srcStride];\

        const int src1= src[1 *srcStride];\

        const int src2= src[2 *srcStride];\

        const int src3= src[3 *srcStride];\

        const int src4= src[4 *srcStride];\

        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\

        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\

        dst++;\

        src++;\

    }\

}\

\

static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\

    const int h=2;\

    const int w=2;\

    const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    src -= 2*srcStride;\

    for(i=0; i<h+5; i++)\

    {\

        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\

        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\

        tmp+=tmpStride;\

        src+=srcStride;\

    }\

    tmp -= tmpStride*(h+5-2);\

    for(i=0; i<w; i++)\

    {\

        const int tmpB= tmp[-2*tmpStride] - pad;\

        const int tmpA= tmp[-1*tmpStride] - pad;\

        const int tmp0= tmp[0 *tmpStride] - pad;\

        const int tmp1= tmp[1 *tmpStride] - pad;\

        const int tmp2= tmp[2 *tmpStride] - pad;\

        const int tmp3= tmp[3 *tmpStride] - pad;\

        const int tmp4= tmp[4 *tmpStride] - pad;\

        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\

        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\

        dst++;\

        tmp++;\

    }\

}\

static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int h=4;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

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

    {\

        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\

        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\

        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\

        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\

        dst+=dstStride;\

        src+=srcStride;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int w=4;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    for(i=0; i<w; i++)\

    {\

        const int srcB= src[-2*srcStride];\

        const int srcA= src[-1*srcStride];\

        const int src0= src[0 *srcStride];\

        const int src1= src[1 *srcStride];\

        const int src2= src[2 *srcStride];\

        const int src3= src[3 *srcStride];\

        const int src4= src[4 *srcStride];\

        const int src5= src[5 *srcStride];\

        const int src6= src[6 *srcStride];\

        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\

        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\

        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\

        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\

        dst++;\

        src++;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\

    const int h=4;\

    const int w=4;\

    const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    src -= 2*srcStride;\

    for(i=0; i<h+5; i++)\

    {\

        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\

        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\

        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]) + pad;\

        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]) + pad;\

        tmp+=tmpStride;\

        src+=srcStride;\

    }\

    tmp -= tmpStride*(h+5-2);\

    for(i=0; i<w; i++)\

    {\

        const int tmpB= tmp[-2*tmpStride] - pad;\

        const int tmpA= tmp[-1*tmpStride] - pad;\

        const int tmp0= tmp[0 *tmpStride] - pad;\

        const int tmp1= tmp[1 *tmpStride] - pad;\

        const int tmp2= tmp[2 *tmpStride] - pad;\

        const int tmp3= tmp[3 *tmpStride] - pad;\

        const int tmp4= tmp[4 *tmpStride] - pad;\

        const int tmp5= tmp[5 *tmpStride] - pad;\

        const int tmp6= tmp[6 *tmpStride] - pad;\

        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\

        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\

        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\

        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\

        dst++;\

        tmp++;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int h=8;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

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

    {\

        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\

        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]));\

        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]));\

        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]));\

        OP(dst[4], (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]));\

        OP(dst[5], (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]));\

        OP(dst[6], (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]));\

        OP(dst[7], (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]));\

        dst+=dstStride;\

        src+=srcStride;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\

    const int w=8;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    for(i=0; i<w; i++)\

    {\

        const int srcB= src[-2*srcStride];\

        const int srcA= src[-1*srcStride];\

        const int src0= src[0 *srcStride];\

        const int src1= src[1 *srcStride];\

        const int src2= src[2 *srcStride];\

        const int src3= src[3 *srcStride];\

        const int src4= src[4 *srcStride];\

        const int src5= src[5 *srcStride];\

        const int src6= src[6 *srcStride];\

        const int src7= src[7 *srcStride];\

        const int src8= src[8 *srcStride];\

        const int src9= src[9 *srcStride];\

        const int src10=src[10*srcStride];\

        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\

        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\

        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\

        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\

        OP(dst[4*dstStride], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\

        OP(dst[5*dstStride], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\

        OP(dst[6*dstStride], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\

        OP(dst[7*dstStride], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\

        dst++;\

        src++;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *p_dst, pixeltmp *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\

    const int h=8;\

    const int w=8;\

    const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\

    INIT_CLIP\

    int i;\

    pixel *dst = (pixel*)p_dst;\

    pixel *src = (pixel*)p_src;\

    dstStride >>= sizeof(pixel)-1;\

    srcStride >>= sizeof(pixel)-1;\

    src -= 2*srcStride;\

    for(i=0; i<h+5; i++)\

    {\

        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]) + pad;\

        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]) + pad;\

        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]) + pad;\

        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]) + pad;\

        tmp[4]= (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]) + pad;\

        tmp[5]= (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]) + pad;\

        tmp[6]= (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]) + pad;\

        tmp[7]= (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]) + pad;\

        tmp+=tmpStride;\

        src+=srcStride;\

    }\

    tmp -= tmpStride*(h+5-2);\

    for(i=0; i<w; i++)\

    {\

        const int tmpB= tmp[-2*tmpStride] - pad;\

        const int tmpA= tmp[-1*tmpStride] - pad;\

        const int tmp0= tmp[0 *tmpStride] - pad;\

        const int tmp1= tmp[1 *tmpStride] - pad;\

        const int tmp2= tmp[2 *tmpStride] - pad;\

        const int tmp3= tmp[3 *tmpStride] - pad;\

        const int tmp4= tmp[4 *tmpStride] - pad;\

        const int tmp5= tmp[5 *tmpStride] - pad;\

        const int tmp6= tmp[6 *tmpStride] - pad;\

        const int tmp7= tmp[7 *tmpStride] - pad;\

        const int tmp8= tmp[8 *tmpStride] - pad;\

        const int tmp9= tmp[9 *tmpStride] - pad;\

        const int tmp10=tmp[10*tmpStride] - pad;\

        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\

        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\

        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\

        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\

        OP2(dst[4*dstStride], (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));\

        OP2(dst[5*dstStride], (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));\

        OP2(dst[6*dstStride], (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));\

        OP2(dst[7*dstStride], (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));\

        dst++;\

        tmp++;\

    }\

}\

\

static void FUNC(OPNAME ## h264_qpel16_v_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\

    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\

    src += 8*srcStride;\

    dst += 8*dstStride;\

    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\

}\

\

static void FUNC(OPNAME ## h264_qpel16_h_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\

    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\

    src += 8*srcStride;\

    dst += 8*dstStride;\

    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\

}\

\

static void FUNC(OPNAME ## h264_qpel16_hv_lowpass)(uint8_t *dst, pixeltmp *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\

    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\

    src += 8*srcStride;\

    dst += 8*dstStride;\

    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\

    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\

}\

#define H264_MC(OPNAME, SIZE) \

static av_unused void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc00)(uint8_t *dst, uint8_t *src, int stride){\

    FUNCC(OPNAME ## pixels ## SIZE)(dst, src, stride, SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc10)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t half[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src, half, stride, stride, SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc20)(uint8_t *dst, uint8_t *src, int stride){\

    FUNC(OPNAME ## h264_qpel ## SIZE ## _h_lowpass)(dst, src, stride, stride);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc30)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t half[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src+sizeof(pixel), half, stride, stride, SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc01)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t half[SIZE*SIZE*sizeof(pixel)];\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid, half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc02)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(OPNAME ## h264_qpel ## SIZE ## _v_lowpass)(dst, full_mid, stride, SIZE*sizeof(pixel));\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc03)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t half[SIZE*SIZE*sizeof(pixel)];\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid+SIZE*sizeof(pixel), half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc11)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc31)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\

    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc13)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc33)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\

    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, int stride){\

    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\

    FUNC(OPNAME ## h264_qpel ## SIZE ## _hv_lowpass)(dst, tmp, src, stride, SIZE*sizeof(pixel), stride);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc21)(uint8_t *dst, uint8_t *src, int stride){\

    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\

    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, int stride){\

    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\

    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc12)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

\

static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc32)(uint8_t *dst, uint8_t *src, int stride){\

    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\

    pixeltmp tmp[SIZE*(SIZE+5)*sizeof(pixel)];\

    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\

    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\

    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\

    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\

    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\

    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\

}\

#define op_avg(a, b)  a = (((a)+CLIP(((b) + 16)>>5)+1)>>1)

//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)

#define op_put(a, b)  a = CLIP(((b) + 16)>>5)

#define op2_avg(a, b)  a = (((a)+CLIP(((b) + 512)>>10)+1)>>1)

#define op2_put(a, b)  a = CLIP(((b) + 512)>>10)

H264_LOWPASS(put_       , op_put, op2_put)

H264_LOWPASS(avg_       , op_avg, op2_avg)

H264_MC(put_, 2)

H264_MC(put_, 4)

H264_MC(put_, 8)

H264_MC(put_, 16)

H264_MC(avg_, 4)

H264_MC(avg_, 8)

H264_MC(avg_, 16)

#undef op_avg

#undef op_put

#undef op2_avg

#undef op2_put

#if BIT_DEPTH == 8

#   define put_h264_qpel8_mc00_8_c  ff_put_pixels8x8_8_c

#   define avg_h264_qpel8_mc00_8_c  ff_avg_pixels8x8_8_c

#   define put_h264_qpel16_mc00_8_c ff_put_pixels16x16_8_c

#   define avg_h264_qpel16_mc00_8_c ff_avg_pixels16x16_8_c

#elif BIT_DEPTH == 9

#   define put_h264_qpel8_mc00_9_c  ff_put_pixels8x8_9_c

#   define avg_h264_qpel8_mc00_9_c  ff_avg_pixels8x8_9_c

#   define put_h264_qpel16_mc00_9_c ff_put_pixels16x16_9_c

#   define avg_h264_qpel16_mc00_9_c ff_avg_pixels16x16_9_c

#elif BIT_DEPTH == 10

#   define put_h264_qpel8_mc00_10_c  ff_put_pixels8x8_10_c

#   define avg_h264_qpel8_mc00_10_c  ff_avg_pixels8x8_10_c

#   define put_h264_qpel16_mc00_10_c ff_put_pixels16x16_10_c

#   define avg_h264_qpel16_mc00_10_c ff_avg_pixels16x16_10_c

#elif BIT_DEPTH == 12

#   define put_h264_qpel8_mc00_12_c  ff_put_pixels8x8_12_c

#   define avg_h264_qpel8_mc00_12_c  ff_avg_pixels8x8_12_c

#   define put_h264_qpel16_mc00_12_c ff_put_pixels16x16_12_c

#   define avg_h264_qpel16_mc00_12_c ff_avg_pixels16x16_12_c

#elif BIT_DEPTH == 14

#   define put_h264_qpel8_mc00_14_c  ff_put_pixels8x8_14_c

#   define avg_h264_qpel8_mc00_14_c  ff_avg_pixels8x8_14_c

#   define put_h264_qpel16_mc00_14_c ff_put_pixels16x16_14_c

#   define avg_h264_qpel16_mc00_14_c ff_avg_pixels16x16_14_c

#endif

void FUNCC(ff_put_pixels8x8)(uint8_t *dst, uint8_t *src, int stride) {

    FUNCC(put_pixels8)(dst, src, stride, 8);

}


yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,

                      int lumFilterSize, const int16_t *chrFilter,

                      const int16_t **chrUSrc, const int16_t **chrVSrc,

                      int chrFilterSize, const int16_t **alpSrc,

                      uint16_t *dest, uint16_t *uDest, uint16_t *vDest,

                      uint16_t *aDest, int dstW, int chrDstW,

                      int big_endian, int output_bits)

{

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

    int i;

    int shift = 11 + 16 - output_bits;

#define output_pixel(pos, val) \

    if (big_endian) { \

        if (output_bits == 16) { \

            AV_WB16(pos, av_clip_uint16(val >> shift)); \

        } else { \

            AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \

        } \

    } else { \

        if (output_bits == 16) { \

            AV_WL16(pos, av_clip_uint16(val >> shift)); \

        } else { \

            AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \

        } \

    }

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

        int val = 1 << (26-output_bits);

        int j;

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

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

        output_pixel(&dest[i], val);

    }

    if (uDest) {

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

            int u = 1 << (26-output_bits);

            int v = 1 << (26-output_bits);

            int j;

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

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

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

            }

            output_pixel(&uDest[i], u);

            output_pixel(&vDest[i], v);

        }

    }

    if (CONFIG_SWSCALE_ALPHA && aDest) {

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

            int val = 1 << (26-output_bits);

            int j;

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

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

            output_pixel(&aDest[i], val);

        }

    }

#undef output_pixel

}


void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){

    MpegEncContext * const s = &h->s;

    int b8_stride = h->b8_stride;

    int b4_stride = h->b_stride;

    int mb_xy = h->mb_xy;

    int mb_type_col[2];

    const int16_t (*l1mv0)[2], (*l1mv1)[2];

    const int8_t *l1ref0, *l1ref1;

    const int is_b8x8 = IS_8X8(*mb_type);

    unsigned int sub_mb_type;

    int i8, i4;

    assert(h->ref_list[1][0].reference&3);

#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)

    if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL

        if(!IS_INTERLACED(*mb_type)){                    //     AFR/FR    -> AFL/FL

            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;

            b8_stride = 0;

        }else{

            mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity

        }

        goto single_col;

    }else{                                               // AFL/AFR/FR/FL -> AFR/FR

        if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR

            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;

            mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];

            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride];

            b8_stride *= 3;

            b4_stride *= 6;

            sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

            if(    (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)

                && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA)

                && !is_b8x8){

                *mb_type   |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */

            }else{

                *mb_type   |= MB_TYPE_8x8|MB_TYPE_L0L1;

            }

        }else{                                           //     AFR/FR    -> AFR/FR

single_col:

            mb_type_col[0] =

            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];

            if(IS_8X8(mb_type_col[0]) && !h->sps.direct_8x8_inference_flag){

                /* FIXME save sub mb types from previous frames (or derive from MVs)

                * so we know exactly what block size to use */

                sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */

                *mb_type   |= MB_TYPE_8x8|MB_TYPE_L0L1;

            }else if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){

                sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

                *mb_type   |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */

            }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){

                sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

                *mb_type   |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16));

            }else{

                sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

                *mb_type   |= MB_TYPE_8x8|MB_TYPE_L0L1;

            }

        }

    }

    l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];

    l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];

    l1ref0 = &h->ref_list[1][0].ref_index [0][h->mb2b8_xy[mb_xy]];

    l1ref1 = &h->ref_list[1][0].ref_index [1][h->mb2b8_xy[mb_xy]];

    if(!b8_stride){

        if(s->mb_y&1){

            l1ref0 += h->b8_stride;

            l1ref1 += h->b8_stride;

            l1mv0  +=  2*b4_stride;

            l1mv1  +=  2*b4_stride;

        }

    }

    if(h->direct_spatial_mv_pred){

        int ref[2];

        int mv[2][2];

        int list;

        /* FIXME interlacing + spatial direct uses wrong colocated block positions */

        /* ref = min(neighbors) */

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

            int refa = h->ref_cache[list][scan8[0] - 1];

            int refb = h->ref_cache[list][scan8[0] - 8];

            int refc = h->ref_cache[list][scan8[0] - 8 + 4];

            if(refc == PART_NOT_AVAILABLE)

                refc = h->ref_cache[list][scan8[0] - 8 - 1];

            ref[list] = FFMIN3((unsigned)refa, (unsigned)refb, (unsigned)refc);

            if(ref[list] >= 0){

                pred_motion(h, 0, 4, list, ref[list], &mv[list][0], &mv[list][1]);

            }else{

                int mask= ~(MB_TYPE_L0 << (2*list));

                mv[list][0] = mv[list][1] = 0;

                ref[list] = -1;

                if(!is_b8x8)

                    *mb_type &= mask;

                sub_mb_type &= mask;

            }

        }

        if(ref[0] < 0 && ref[1] < 0){

            ref[0] = ref[1] = 0;

            if(!is_b8x8)

                *mb_type |= MB_TYPE_L0L1;

            sub_mb_type |= MB_TYPE_L0L1;

        }

        if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){

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

                int x8 = i8&1;

                int y8 = i8>>1;

                int xy8 = x8+y8*b8_stride;

                int xy4 = 3*x8+y8*b4_stride;

                int a,b;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1);

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1);

                if(!IS_INTRA(mb_type_col[y8]) && !h->ref_list[1][0].long_ref

                   && (   (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1)

                       || (l1ref0[xy8]  < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[xy4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){

                    a=b=0;

                    if(ref[0] > 0)

                        a= pack16to32(mv[0][0],mv[0][1]);

                    if(ref[1] > 0)

                        b= pack16to32(mv[1][0],mv[1][1]);

                }else{

                    a= pack16to32(mv[0][0],mv[0][1]);

                    b= pack16to32(mv[1][0],mv[1][1]);

                }

                fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4);

                fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4);

            }

        }else if(IS_16X16(*mb_type)){

            int a,b;

            fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);

            fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);

            if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref

               && (   (l1ref0[0] == 0 && FFABS(l1mv0[0][0]) <= 1 && FFABS(l1mv0[0][1]) <= 1)

                   || (l1ref0[0]  < 0 && l1ref1[0] == 0 && FFABS(l1mv1[0][0]) <= 1 && FFABS(l1mv1[0][1]) <= 1

                       && (h->x264_build>33 || !h->x264_build)))){

                a=b=0;

                if(ref[0] > 0)

                    a= pack16to32(mv[0][0],mv[0][1]);

                if(ref[1] > 0)

                    b= pack16to32(mv[1][0],mv[1][1]);

            }else{

                a= pack16to32(mv[0][0],mv[0][1]);

                b= pack16to32(mv[1][0],mv[1][1]);

            }

            fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);

            fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);

        }else{

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

                const int x8 = i8&1;

                const int y8 = i8>>1;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mv[0][0],mv[0][1]), 4);

                fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mv[1][0],mv[1][1]), 4);

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1);

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1);

                /* col_zero_flag */

                if(!IS_INTRA(mb_type_col[0]) && !h->ref_list[1][0].long_ref && (   l1ref0[x8 + y8*b8_stride] == 0

                                              || (l1ref0[x8 + y8*b8_stride] < 0 && l1ref1[x8 + y8*b8_stride] == 0

                                                  && (h->x264_build>33 || !h->x264_build)))){

                    const int16_t (*l1mv)[2]= l1ref0[x8 + y8*b8_stride] == 0 ? l1mv0 : l1mv1;

                    if(IS_SUB_8X8(sub_mb_type)){

                        const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride];

                        if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){

                            if(ref[0] == 0)

                                fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);

                            if(ref[1] == 0)

                                fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);

                        }

                    }else

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

                        const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride];

                        if(FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1){

                            if(ref[0] == 0)

                                *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0;

                            if(ref[1] == 0)

                                *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0;

                        }

                    }

                }

            }

        }

    }else{ /* direct temporal mv pred */

        const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]};

        const int *dist_scale_factor = h->dist_scale_factor;

        int ref_offset= 0;

        if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){

            map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];

            map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];

            dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];

        }

        if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0]))

            ref_offset += 16;

        if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){

            int y_shift  = 2*!IS_INTERLACED(*mb_type);

            assert(h->sps.direct_8x8_inference_flag);

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

                const int x8 = i8&1;

                const int y8 = i8>>1;

                int ref0, scale;

                const int16_t (*l1mv)[2]= l1mv0;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);

                if(IS_INTRA(mb_type_col[y8])){

                    fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);

                    fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);

                    continue;

                }

                ref0 = l1ref0[x8 + y8*b8_stride];

                if(ref0 >= 0)

                    ref0 = map_col_to_list0[0][ref0 + ref_offset];

                else{

                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];

                    l1mv= l1mv1;

                }

                scale = dist_scale_factor[ref0];

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);

                {

                    const int16_t *mv_col = l1mv[x8*3 + y8*b4_stride];

                    int my_col = (mv_col[1]<<y_shift)/2;

                    int mx = (scale * mv_col[0] + 128) >> 8;

                    int my = (scale * my_col + 128) >> 8;

                    fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);

                    fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-my_col), 4);

                }

            }

            return;

        }

        /* one-to-one mv scaling */

        if(IS_16X16(*mb_type)){

            int ref, mv0, mv1;

            fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);

            if(IS_INTRA(mb_type_col[0])){

                ref=mv0=mv1=0;

            }else{

                const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]

                                                : map_col_to_list0[1][l1ref1[0] + ref_offset];

                const int scale = dist_scale_factor[ref0];

                const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];

                int mv_l0[2];

                mv_l0[0] = (scale * mv_col[0] + 128) >> 8;

                mv_l0[1] = (scale * mv_col[1] + 128) >> 8;

                ref= ref0;

                mv0= pack16to32(mv_l0[0],mv_l0[1]);

                mv1= pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]);

            }

            fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);

            fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);

            fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);

        }else{

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

                const int x8 = i8&1;

                const int y8 = i8>>1;

                int ref0, scale;

                const int16_t (*l1mv)[2]= l1mv0;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);

                if(IS_INTRA(mb_type_col[0])){

                    fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);

                    fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);

                    continue;

                }

                ref0 = l1ref0[x8 + y8*b8_stride];

                if(ref0 >= 0)

                    ref0 = map_col_to_list0[0][ref0 + ref_offset];

                else{

                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];

                    l1mv= l1mv1;

                }

                scale = dist_scale_factor[ref0];

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);

                if(IS_SUB_8X8(sub_mb_type)){

                    const int16_t *mv_col = l1mv[x8*3 + y8*3*b4_stride];

                    int mx = (scale * mv_col[0] + 128) >> 8;

                    int my = (scale * mv_col[1] + 128) >> 8;

                    fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4);

                    fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4);

                }else

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

                    const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*b4_stride];

                    int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]];

                    mv_l0[0] = (scale * mv_col[0] + 128) >> 8;

                    mv_l0[1] = (scale * mv_col[1] + 128) >> 8;

                    *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] =

                        pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]);

                }

            }

        }

    }

}


static void avc_luma_mid_and_aver_dst_4x4_msa(const uint8_t *src,

                                              int32_t src_stride,

                                              uint8_t *dst, int32_t dst_stride)

{

    v16i8 src0, src1, src2, src3, src4;

    v16i8 mask0, mask1, mask2;

    v8i16 hz_out0, hz_out1, hz_out2, hz_out3;

    v8i16 hz_out4, hz_out5, hz_out6, hz_out7, hz_out8;

    v8i16 res0, res1, res2, res3;

    v16u8 dst0, dst1, dst2, dst3;

    v16u8 tmp0, tmp1, tmp2, tmp3;

    LD_SB3(&luma_mask_arr[48], 16, mask0, mask1, mask2);

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

    src += (5 * src_stride);

    XORI_B5_128_SB(src0, src1, src2, src3, src4);

    hz_out0 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src0, src1,

                                                          mask0, mask1, mask2);

    hz_out2 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src2, src3,

                                                          mask0, mask1, mask2);

    PCKOD_D2_SH(hz_out0, hz_out0, hz_out2, hz_out2, hz_out1, hz_out3);

    hz_out4 = AVC_HORZ_FILTER_SH(src4, src4, mask0, mask1, mask2);

    LD_SB4(src, src_stride, src0, src1, src2, src3);

    XORI_B4_128_SB(src0, src1, src2, src3);

    hz_out5 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src0, src1,

                                                          mask0, mask1, mask2);

    hz_out7 = AVC_XOR_VSHF_B_AND_APPLY_6TAP_HORIZ_FILT_SH(src2, src3,

                                                          mask0, mask1, mask2);

    PCKOD_D2_SH(hz_out5, hz_out5, hz_out7, hz_out7, hz_out6, hz_out8);

    res0 = AVC_CALC_DPADD_H_6PIX_2COEFF_R_SH(hz_out0, hz_out1, hz_out2,

                                             hz_out3, hz_out4, hz_out5);

    res1 = AVC_CALC_DPADD_H_6PIX_2COEFF_R_SH(hz_out1, hz_out2, hz_out3,

                                             hz_out4, hz_out5, hz_out6);

    res2 = AVC_CALC_DPADD_H_6PIX_2COEFF_R_SH(hz_out2, hz_out3, hz_out4,

                                             hz_out5, hz_out6, hz_out7);

    res3 = AVC_CALC_DPADD_H_6PIX_2COEFF_R_SH(hz_out3, hz_out4, hz_out5,

                                             hz_out6, hz_out7, hz_out8);

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

    tmp0 = PCKEV_XORI128_UB(res0, res1);

    tmp1 = PCKEV_XORI128_UB(res2, res3);

    PCKEV_D2_UB(dst1, dst0, dst3, dst2, tmp2, tmp3);

    AVER_UB2_UB(tmp0, tmp2, tmp1, tmp3, tmp0, tmp1);

    ST4x4_UB(tmp0, tmp1, 0, 2, 0, 2, dst, dst_stride);

}


static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,

                                                    DCTELEM *block, int n,

                                                    int qscale,

                                                    int index_bits,

                                                    int level_bias,

                                                    int level_shift)

{

    int i, j, index1, index2, len;

    int level, component, sign;

    const uint8_t *weight_matrix;

    OPEN_READER(bs, &ctx->gb);

    if (n&2) {

        component = 1 + (n&1);

        weight_matrix = ctx->cid_table->chroma_weight;

    } else {

        component = 0;

        weight_matrix = ctx->cid_table->luma_weight;

    }

    UPDATE_CACHE(bs, &ctx->gb);

    GET_VLC(len, bs, &ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);

    if (len) {

        level = GET_CACHE(bs, &ctx->gb);

        LAST_SKIP_BITS(bs, &ctx->gb, len);

        sign  = ~level >> 31;

        level = (NEG_USR32(sign ^ level, len) ^ sign) - sign;

        ctx->last_dc[component] += level;

    }

    block[0] = ctx->last_dc[component];

    //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]);

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

        UPDATE_CACHE(bs, &ctx->gb);

        GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,

                DNXHD_VLC_BITS, 2);

        //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index1);

        level = ctx->cid_table->ac_level[index1];

        if (!level) { /* EOB */

            //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n");

            break;

        }

        sign = SHOW_SBITS(bs, &ctx->gb, 1);

        SKIP_BITS(bs, &ctx->gb, 1);

        if (ctx->cid_table->ac_index_flag[index1]) {

            level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 6;

            SKIP_BITS(bs, &ctx->gb, index_bits);

        }

        if (ctx->cid_table->ac_run_flag[index1]) {

            UPDATE_CACHE(bs, &ctx->gb);

            GET_VLC(index2, bs, &ctx->gb, ctx->run_vlc.table,

                    DNXHD_VLC_BITS, 2);

            i += ctx->cid_table->run[index2];

        }

        if (i > 63) {

            av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);

            break;

        }

        j = ctx->scantable.permutated[i];

        //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j);

        //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weight %d\n", level, weight_matrix[i]);

        level = (2*level+1) * qscale * weight_matrix[i];

        if (level_bias < 32 || weight_matrix[i] != level_bias)

            level += level_bias;

        level >>= level_shift;

        //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level);

        block[j] = (level^sign) - sign;

    }

    CLOSE_READER(bs, &ctx->gb);

}


static VideoState *stream_open(const char *filename, AVInputFormat *iformat)

{

    VideoState *is;

    is = av_mallocz(sizeof(VideoState));

    if (!is)

        return NULL;

    av_strlcpy(is->filename, filename, sizeof(is->filename));

    is->iformat = iformat;

    is->ytop    = 0;

    is->xleft   = 0;

    /* start video display */

    is->pictq_mutex = SDL_CreateMutex();

    is->pictq_cond  = SDL_CreateCond();

    is->subpq_mutex = SDL_CreateMutex();

    is->subpq_cond  = SDL_CreateCond();

    packet_queue_init(&is->videoq);

    packet_queue_init(&is->audioq);

    packet_queue_init(&is->subtitleq);

    is->continue_read_thread = SDL_CreateCond();

    //FIXME: use a cleaner way to signal obsolete external clock...

    update_external_clock_pts(is, (double)AV_NOPTS_VALUE);

    update_external_clock_speed(is, 1.0);

    is->audio_current_pts_drift = -av_gettime() / 1000000.0;

    is->video_current_pts_drift = is->audio_current_pts_drift;

    is->audio_clock_serial = -1;

    is->video_clock_serial = -1;

    is->av_sync_type = av_sync_type;

    is->read_tid     = SDL_CreateThread(read_thread, is);

    if (!is->read_tid) {

        av_free(is);

        return NULL;

    }

    return is;

}


int ff_mjpeg_encode_stuffing(MpegEncContext *s)

{

    int i;

    PutBitContext *pbc = &s->pb;

    int mb_y = s->mb_y - !s->mb_x;

    int ret;

    MJpegContext *m;

    m = s->mjpeg_ctx;

    if (s->huffman == HUFFMAN_TABLE_OPTIMAL) {

        ff_mjpeg_build_optimal_huffman(m);

        // Replace the VLCs with the optimal ones.

        // The default ones may be used for trellis during quantization.

        ff_init_uni_ac_vlc(m->huff_size_ac_luminance,   m->uni_ac_vlc_len);

        ff_init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len);

        s->intra_ac_vlc_length      =

        s->intra_ac_vlc_last_length = m->uni_ac_vlc_len;

        s->intra_chroma_ac_vlc_length      =

        s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;

    }

    ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,

                                   s->pred, s->intra_matrix, s->chroma_intra_matrix);

    ff_mjpeg_encode_picture_frame(s);

    ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100,

                                            put_bits_count(&s->pb) / 4 + 1000);

    if (ret < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n");

        goto fail;

    }

    ff_mjpeg_escape_FF(pbc, s->esc_pos);

    if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height)

        put_marker(pbc, RST0 + (mb_y&7));

    s->esc_pos = put_bits_count(pbc) >> 3;

fail:

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

        s->last_dc[i] = 128 << s->intra_dc_precision;

    return ret;

}


void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)

{

    void (*start_frame)(AVFilterLink *, AVFilterBufferRef *);

    AVFilterPad *dst = link->dstpad;

    FF_DPRINTF_START(NULL, start_frame); ff_dprintf_link(NULL, link, 0); dprintf(NULL, " "); ff_dprintf_ref(NULL, picref, 1);

    if (!(start_frame = dst->start_frame))

        start_frame = avfilter_default_start_frame;

    /* prepare to copy the picture if it has insufficient permissions */

    if ((dst->min_perms & picref->perms) != dst->min_perms ||

         dst->rej_perms & picref->perms) {

        av_log(link->dst, AV_LOG_DEBUG,

                "frame copy needed (have perms %x, need %x, reject %x)\n",

                picref->perms,

                link->dstpad->min_perms, link->dstpad->rej_perms);

        link->cur_buf = avfilter_get_video_buffer(link, dst->min_perms, link->w, link->h);

        link->src_buf = picref;

        avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);

    }

    else

        link->cur_buf = picref;

    start_frame(link, link->cur_buf);

}