static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?

                        DCTELEM *block, int16_t *weight, DCTELEM *orig,

                        int n, int qscale){

    int16_t rem[64];

    DCTELEM d1[64];

    const int *qmat;

    const uint8_t *scantable= s->intra_scantable.scantable;

    const uint8_t *perm_scantable= s->intra_scantable.permutated;

//    unsigned int threshold1, threshold2;

//    int bias=0;

    int run_tab[65];

    int prev_run=0;

    int prev_level=0;

    int qmul, qadd, start_i, last_non_zero, i, dc;

    uint8_t * length;

    uint8_t * last_length;

    int lambda;

    int rle_index, run, q, sum;

#ifdef REFINE_STATS

static int count=0;

static int after_last=0;

static int to_zero=0;

static int from_zero=0;

static int raise=0;

static int lower=0;

static int messed_sign=0;

#endif

    if(basis[0][0] == 0)

        build_basis(s->dsp.idct_permutation);

    qmul= qscale*2;

    qadd= (qscale-1)|1;

    if (s->mb_intra) {

        if (!s->h263_aic) {

            if (n < 4)

                q = s->y_dc_scale;

            else

                q = s->c_dc_scale;

        } else{

            /* For AIC we skip quant/dequant of INTRADC */

            q = 1;

            qadd=0;

        }

        q <<= RECON_SHIFT-3;

        /* note: block[0] is assumed to be positive */

        dc= block[0]*q;

//        block[0] = (block[0] + (q >> 1)) / q;

        start_i = 1;

        qmat = s->q_intra_matrix[qscale];

//        if(s->mpeg_quant || s->out_format == FMT_MPEG1)

//            bias= 1<<(QMAT_SHIFT-1);

        length     = s->intra_ac_vlc_length;

        last_length= s->intra_ac_vlc_last_length;

    } else {

        dc= 0;

        start_i = 0;

        qmat = s->q_inter_matrix[qscale];

        length     = s->inter_ac_vlc_length;

        last_length= s->inter_ac_vlc_last_length;

    }

    last_non_zero = s->block_last_index[n];

#ifdef REFINE_STATS

{START_TIMER

#endif

    dc += (1<<(RECON_SHIFT-1));

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

        rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME  use orig dirrectly insteadof copying to rem[]

    }

#ifdef REFINE_STATS

STOP_TIMER("memset rem[]")}

#endif

    sum=0;

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

        int one= 36;

        int qns=4;

        int w;

        w= ABS(weight[i]) + qns*one;

        w= 15 + (48*qns*one + w/2)/w; // 16 .. 63

        weight[i] = w;

//        w=weight[i] = (63*qns + (w/2)) / w;

        assert(w>0);

        assert(w<(1<<6));

        sum += w*w;

    }

    lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);

#ifdef REFINE_STATS

{START_TIMER

#endif

    run=0;

    rle_index=0;

    for(i=start_i; i<=last_non_zero; i++){

        int j= perm_scantable[i];

        const int level= block[j];

        int coeff;

        if(level){

            if(level<0) coeff= qmul*level - qadd;

            else        coeff= qmul*level + qadd;

            run_tab[rle_index++]=run;

            run=0;

            s->dsp.add_8x8basis(rem, basis[j], coeff);

        }else{

            run++;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("init rem[]")

}

}

{START_TIMER

#endif

    for(;;){

        int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);

        int best_coeff=0;

        int best_change=0;

        int run2, best_unquant_change=0, analyze_gradient;

#ifdef REFINE_STATS

{START_TIMER

#endif

        analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3;

        if(analyze_gradient){

#ifdef REFINE_STATS

{START_TIMER

#endif

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

                int w= weight[i];

                d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);

            }

#ifdef REFINE_STATS

STOP_TIMER("rem*w*w")}

{START_TIMER

#endif

            s->dsp.fdct(d1);

#ifdef REFINE_STATS

STOP_TIMER("dct")}

#endif

        }

        if(start_i){

            const int level= block[0];

            int change, old_coeff;

            assert(s->mb_intra);

            old_coeff= q*level;

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff;

                new_coeff= q*new_level;

                if(new_coeff >= 2048 || new_coeff < 0)

                    continue;

                score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff);

                if(score<best_score){

                    best_score= score;

                    best_coeff= 0;

                    best_change= change;

                    best_unquant_change= new_coeff - old_coeff;

                }

            }

        }

        run=0;

        rle_index=0;

        run2= run_tab[rle_index++];

        prev_level=0;

        prev_run=0;

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

            int j= perm_scantable[i];

            const int level= block[j];

            int change, old_coeff;

            if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1)

                break;

            if(level){

                if(level<0) old_coeff= qmul*level - qadd;

                else        old_coeff= qmul*level + qadd;

                run2= run_tab[rle_index++]; //FIXME ! maybe after last

            }else{

                old_coeff=0;

                run2--;

                assert(run2>=0 || i >= last_non_zero );

            }

            for(change=-1; change<=1; change+=2){

                int new_level= level + change;

                int score, new_coeff, unquant_change;

                score=0;

                if(s->avctx->quantizer_noise_shaping < 2 && ABS(new_level) > ABS(level))

                   continue;

                if(new_level){

                    if(new_level<0) new_coeff= qmul*new_level - qadd;

                    else            new_coeff= qmul*new_level + qadd;

                    if(new_coeff >= 2048 || new_coeff <= -2048)

                        continue;

                    //FIXME check for overflow

                    if(level){

                        if(level < 63 && level > -63){

                            if(i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - length[UNI_AC_ENC_INDEX(run, level+64)];

                            else

                                score +=   last_length[UNI_AC_ENC_INDEX(run, new_level+64)]

                                         - last_length[UNI_AC_ENC_INDEX(run, level+64)];

                        }

                    }else{

                        assert(ABS(new_level)==1);

                        if(analyze_gradient){

                            int g= d1[ scantable[i] ];

                            if(g && (g^new_level) >= 0)

                                continue;

                        }

                        if(i < last_non_zero){

                            int next_i= i + run2 + 1;

                            int next_level= block[ perm_scantable[next_i] ] + 64;

                            if(next_level&(~127))

                                next_level= 0;

                            if(next_i < last_non_zero)

                                score +=   length[UNI_AC_ENC_INDEX(run, 65)]

                                         + length[UNI_AC_ENC_INDEX(run2, next_level)]

                                         - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                            else

                                score +=  length[UNI_AC_ENC_INDEX(run, 65)]

                                        + last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                        - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];

                        }else{

                            score += last_length[UNI_AC_ENC_INDEX(run, 65)];

                            if(prev_level){

                                score +=  length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                        - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                            }

                        }

                    }

                }else{

                    new_coeff=0;

                    assert(ABS(level)==1);

                    if(i < last_non_zero){

                        int next_i= i + run2 + 1;

                        int next_level= block[ perm_scantable[next_i] ] + 64;

                        if(next_level&(~127))

                            next_level= 0;

                        if(next_i < last_non_zero)

                            score +=   length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                        else

                            score +=   last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]

                                     - last_length[UNI_AC_ENC_INDEX(run2, next_level)]

                                     - length[UNI_AC_ENC_INDEX(run, 65)];

                    }else{

                        score += -last_length[UNI_AC_ENC_INDEX(run, 65)];

                        if(prev_level){

                            score +=  last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]

                                    - length[UNI_AC_ENC_INDEX(prev_run, prev_level)];

                        }

                    }

                }

                score *= lambda;

                unquant_change= new_coeff - old_coeff;

                assert((score < 100*lambda && score > -100*lambda) || lambda==0);

                score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);

                if(score<best_score){

                    best_score= score;

                    best_coeff= i;

                    best_change= change;

                    best_unquant_change= unquant_change;

                }

            }

            if(level){

                prev_level= level + 64;

                if(prev_level&(~127))

                    prev_level= 0;

                prev_run= run;

                run=0;

            }else{

                run++;

            }

        }

#ifdef REFINE_STATS

STOP_TIMER("iterative step")}

#endif

        if(best_change){

            int j= perm_scantable[ best_coeff ];

            block[j] += best_change;

            if(best_coeff > last_non_zero){

                last_non_zero= best_coeff;

                assert(block[j]);

#ifdef REFINE_STATS

after_last++;

#endif

            }else{

#ifdef REFINE_STATS

if(block[j]){

    if(block[j] - best_change){

        if(ABS(block[j]) > ABS(block[j] - best_change)){

            raise++;

        }else{

            lower++;

        }

    }else{

        from_zero++;

    }

}else{

    to_zero++;

}

#endif

                for(; last_non_zero>=start_i; last_non_zero--){

                    if(block[perm_scantable[last_non_zero]])

                        break;

                }

            }

#ifdef REFINE_STATS

count++;

if(256*256*256*64 % count == 0){

    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);

}

#endif

            run=0;

            rle_index=0;

            for(i=start_i; i<=last_non_zero; i++){

                int j= perm_scantable[i];

                const int level= block[j];

                 if(level){

                     run_tab[rle_index++]=run;

                     run=0;

                 }else{

                     run++;

                 }

            }

            s->dsp.add_8x8basis(rem, basis[j], best_unquant_change);

        }else{

            break;

        }

    }

#ifdef REFINE_STATS

if(last_non_zero>0){

STOP_TIMER("iterative search")

}

}

#endif

    return last_non_zero;

}


void *g_realloc(void * mem, size_t n_bytes)

{

    __coverity_negative_sink__(n_bytes);

    mem = realloc(mem, n_bytes == 0 ? 1 : n_bytes);

    if (!mem) __coverity_panic__();

    return mem;

}


av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)

{

    int i;

    ff_check_alignment();

#if CONFIG_ENCODERS

    if (avctx->bits_per_raw_sample == 10) {

        c->fdct    = ff_jpeg_fdct_islow_10;

        c->fdct248 = ff_fdct248_islow_10;

    } else {

        if(avctx->dct_algo==FF_DCT_FASTINT) {

            c->fdct    = ff_fdct_ifast;

            c->fdct248 = ff_fdct_ifast248;

        }

        else if(avctx->dct_algo==FF_DCT_FAAN) {

            c->fdct    = ff_faandct;

            c->fdct248 = ff_faandct248;

        }

        else {

            c->fdct    = ff_jpeg_fdct_islow_8; //slow/accurate/default

            c->fdct248 = ff_fdct248_islow_8;

        }

    }

#endif //CONFIG_ENCODERS

    if (avctx->bits_per_raw_sample == 10) {

        c->idct_put              = ff_simple_idct_put_10;

        c->idct_add              = ff_simple_idct_add_10;

        c->idct                  = ff_simple_idct_10;

        c->idct_permutation_type = FF_NO_IDCT_PERM;

    } else {

        if(avctx->idct_algo==FF_IDCT_INT){

            c->idct_put= ff_jref_idct_put;

            c->idct_add= ff_jref_idct_add;

            c->idct    = ff_j_rev_dct;

            c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;

        }else if((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER ) &&

                avctx->idct_algo==FF_IDCT_VP3){

            c->idct_put= ff_vp3_idct_put_c;

            c->idct_add= ff_vp3_idct_add_c;

            c->idct    = ff_vp3_idct_c;

            c->idct_permutation_type= FF_NO_IDCT_PERM;

        }else if(avctx->idct_algo==FF_IDCT_WMV2){

            c->idct_put= ff_wmv2_idct_put_c;

            c->idct_add= ff_wmv2_idct_add_c;

            c->idct    = ff_wmv2_idct_c;

            c->idct_permutation_type= FF_NO_IDCT_PERM;

        }else if(avctx->idct_algo==FF_IDCT_FAAN){

            c->idct_put= ff_faanidct_put;

            c->idct_add= ff_faanidct_add;

            c->idct    = ff_faanidct;

            c->idct_permutation_type= FF_NO_IDCT_PERM;

        }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) {

            c->idct_put= ff_ea_idct_put_c;

            c->idct_permutation_type= FF_NO_IDCT_PERM;

        }else{ //accurate/default

            c->idct_put = ff_simple_idct_put_8;

            c->idct_add = ff_simple_idct_add_8;

            c->idct     = ff_simple_idct_8;

            c->idct_permutation_type= FF_NO_IDCT_PERM;

        }

    }

    c->diff_pixels = diff_pixels_c;

    c->put_pixels_clamped = ff_put_pixels_clamped_c;

    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_c;

    c->add_pixels_clamped = ff_add_pixels_clamped_c;

    c->sum_abs_dctelem = sum_abs_dctelem_c;

    c->gmc1 = gmc1_c;

    c->gmc = ff_gmc_c;

    c->pix_sum = pix_sum_c;

    c->pix_norm1 = pix_norm1_c;

    c->fill_block_tab[0] = fill_block16_c;

    c->fill_block_tab[1] = fill_block8_c;

    /* TODO [0] 16  [1] 8 */

    c->pix_abs[0][0] = pix_abs16_c;

    c->pix_abs[0][1] = pix_abs16_x2_c;

    c->pix_abs[0][2] = pix_abs16_y2_c;

    c->pix_abs[0][3] = pix_abs16_xy2_c;

    c->pix_abs[1][0] = pix_abs8_c;

    c->pix_abs[1][1] = pix_abs8_x2_c;

    c->pix_abs[1][2] = pix_abs8_y2_c;

    c->pix_abs[1][3] = pix_abs8_xy2_c;

    c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c;

    c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c;

    c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c;

    c->put_tpel_pixels_tab[ 4] = put_tpel_pixels_mc01_c;

    c->put_tpel_pixels_tab[ 5] = put_tpel_pixels_mc11_c;

    c->put_tpel_pixels_tab[ 6] = put_tpel_pixels_mc21_c;

    c->put_tpel_pixels_tab[ 8] = put_tpel_pixels_mc02_c;

    c->put_tpel_pixels_tab[ 9] = put_tpel_pixels_mc12_c;

    c->put_tpel_pixels_tab[10] = put_tpel_pixels_mc22_c;

    c->avg_tpel_pixels_tab[ 0] = avg_tpel_pixels_mc00_c;

    c->avg_tpel_pixels_tab[ 1] = avg_tpel_pixels_mc10_c;

    c->avg_tpel_pixels_tab[ 2] = avg_tpel_pixels_mc20_c;

    c->avg_tpel_pixels_tab[ 4] = avg_tpel_pixels_mc01_c;

    c->avg_tpel_pixels_tab[ 5] = avg_tpel_pixels_mc11_c;

    c->avg_tpel_pixels_tab[ 6] = avg_tpel_pixels_mc21_c;

    c->avg_tpel_pixels_tab[ 8] = avg_tpel_pixels_mc02_c;

    c->avg_tpel_pixels_tab[ 9] = avg_tpel_pixels_mc12_c;

    c->avg_tpel_pixels_tab[10] = avg_tpel_pixels_mc22_c;

#define dspfunc(PFX, IDX, NUM) \

    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \

    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \

    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \

    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \

    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \

    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \

    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \

    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \

    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \

    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \

    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \

    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \

    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \

    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \

    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \

    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c

    dspfunc(put_qpel, 0, 16);

    dspfunc(put_no_rnd_qpel, 0, 16);

    dspfunc(avg_qpel, 0, 16);

    /* dspfunc(avg_no_rnd_qpel, 0, 16); */

    dspfunc(put_qpel, 1, 8);

    dspfunc(put_no_rnd_qpel, 1, 8);

    dspfunc(avg_qpel, 1, 8);

    /* dspfunc(avg_no_rnd_qpel, 1, 8); */

#undef dspfunc

#if CONFIG_MLP_DECODER || CONFIG_TRUEHD_DECODER

    ff_mlp_init(c, avctx);

#endif

#if CONFIG_WMV2_DECODER || CONFIG_VC1_DECODER

    ff_intrax8dsp_init(c,avctx);

#endif

    c->put_mspel_pixels_tab[0]= ff_put_pixels8x8_c;

    c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c;

    c->put_mspel_pixels_tab[2]= put_mspel8_mc20_c;

    c->put_mspel_pixels_tab[3]= put_mspel8_mc30_c;

    c->put_mspel_pixels_tab[4]= put_mspel8_mc02_c;

    c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c;

    c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c;

    c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c;

#define SET_CMP_FUNC(name) \

    c->name[0]= name ## 16_c;\

    c->name[1]= name ## 8x8_c;

    SET_CMP_FUNC(hadamard8_diff)

    c->hadamard8_diff[4]= hadamard8_intra16_c;

    c->hadamard8_diff[5]= hadamard8_intra8x8_c;

    SET_CMP_FUNC(dct_sad)

    SET_CMP_FUNC(dct_max)

#if CONFIG_GPL

    SET_CMP_FUNC(dct264_sad)

#endif

    c->sad[0]= pix_abs16_c;

    c->sad[1]= pix_abs8_c;

    c->sse[0]= sse16_c;

    c->sse[1]= sse8_c;

    c->sse[2]= sse4_c;

    SET_CMP_FUNC(quant_psnr)

    SET_CMP_FUNC(rd)

    SET_CMP_FUNC(bit)

    c->vsad[0]= vsad16_c;

    c->vsad[4]= vsad_intra16_c;

    c->vsad[5]= vsad_intra8_c;

    c->vsse[0]= vsse16_c;

    c->vsse[4]= vsse_intra16_c;

    c->vsse[5]= vsse_intra8_c;

    c->nsse[0]= nsse16_c;

    c->nsse[1]= nsse8_c;

#if CONFIG_DWT

    ff_dsputil_init_dwt(c);

#endif

    c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c;

    c->add_bytes= add_bytes_c;

    c->diff_bytes= diff_bytes_c;

    c->add_hfyu_median_prediction= add_hfyu_median_prediction_c;

    c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c;

    c->add_hfyu_left_prediction  = add_hfyu_left_prediction_c;

    c->add_hfyu_left_prediction_bgr32 = add_hfyu_left_prediction_bgr32_c;

    c->bswap_buf= bswap_buf;

    c->bswap16_buf = bswap16_buf;

    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {

        c->h263_h_loop_filter= h263_h_loop_filter_c;

        c->h263_v_loop_filter= h263_v_loop_filter_c;

    }

    if (CONFIG_VP3_DECODER) {

        c->vp3_h_loop_filter= ff_vp3_h_loop_filter_c;

        c->vp3_v_loop_filter= ff_vp3_v_loop_filter_c;

        c->vp3_idct_dc_add= ff_vp3_idct_dc_add_c;

    }

    c->h261_loop_filter= h261_loop_filter_c;

    c->try_8x8basis= try_8x8basis_c;

    c->add_8x8basis= add_8x8basis_c;

#if CONFIG_VORBIS_DECODER

    c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;

#endif

#if CONFIG_AC3_DECODER

    c->ac3_downmix = ff_ac3_downmix_c;

#endif

    c->vector_fmul = vector_fmul_c;

    c->vector_fmul_reverse = vector_fmul_reverse_c;

    c->vector_fmul_add = vector_fmul_add_c;

    c->vector_fmul_window = vector_fmul_window_c;

    c->vector_clipf = vector_clipf_c;

    c->scalarproduct_int16 = scalarproduct_int16_c;

    c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;

    c->apply_window_int16 = apply_window_int16_c;

    c->vector_clip_int32 = vector_clip_int32_c;

    c->scalarproduct_float = scalarproduct_float_c;

    c->butterflies_float = butterflies_float_c;

    c->butterflies_float_interleave = butterflies_float_interleave_c;

    c->vector_fmul_scalar = vector_fmul_scalar_c;

    c->vector_fmac_scalar = vector_fmac_scalar_c;

    c->shrink[0]= av_image_copy_plane;

    c->shrink[1]= ff_shrink22;

    c->shrink[2]= ff_shrink44;

    c->shrink[3]= ff_shrink88;

    c->prefetch= just_return;

    memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab));

    memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab));

#undef FUNC

#undef FUNCC

#define FUNC(f, depth) f ## _ ## depth

#define FUNCC(f, depth) f ## _ ## depth ## _c

#define dspfunc1(PFX, IDX, NUM, depth)\

    c->PFX ## _pixels_tab[IDX][0] = FUNCC(PFX ## _pixels ## NUM        , depth);\

    c->PFX ## _pixels_tab[IDX][1] = FUNCC(PFX ## _pixels ## NUM ## _x2 , depth);\

    c->PFX ## _pixels_tab[IDX][2] = FUNCC(PFX ## _pixels ## NUM ## _y2 , depth);\

    c->PFX ## _pixels_tab[IDX][3] = FUNCC(PFX ## _pixels ## NUM ## _xy2, depth)

#define dspfunc2(PFX, IDX, NUM, depth)\

    c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth);\

    c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth);\

    c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth);\

    c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth);\

    c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth);\

    c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth);\

    c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth);\

    c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth);\

    c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth);\

    c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth);\

    c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth);\

    c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth);\

    c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth);\

    c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth);\

    c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth);\

    c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)

#define BIT_DEPTH_FUNCS(depth, dct)\

    c->get_pixels                    = FUNCC(get_pixels   ## dct   , depth);\

    c->draw_edges                    = FUNCC(draw_edges            , depth);\

    c->emulated_edge_mc              = FUNC (ff_emulated_edge_mc   , depth);\

    c->clear_block                   = FUNCC(clear_block  ## dct   , depth);\

    c->clear_blocks                  = FUNCC(clear_blocks ## dct   , depth);\

    c->add_pixels8                   = FUNCC(add_pixels8  ## dct   , depth);\

    c->add_pixels4                   = FUNCC(add_pixels4  ## dct   , depth);\

    c->put_no_rnd_pixels_l2[0]       = FUNCC(put_no_rnd_pixels16_l2, depth);\

    c->put_no_rnd_pixels_l2[1]       = FUNCC(put_no_rnd_pixels8_l2 , depth);\

\

    c->put_h264_chroma_pixels_tab[0] = FUNCC(put_h264_chroma_mc8   , depth);\

    c->put_h264_chroma_pixels_tab[1] = FUNCC(put_h264_chroma_mc4   , depth);\

    c->put_h264_chroma_pixels_tab[2] = FUNCC(put_h264_chroma_mc2   , depth);\

    c->avg_h264_chroma_pixels_tab[0] = FUNCC(avg_h264_chroma_mc8   , depth);\

    c->avg_h264_chroma_pixels_tab[1] = FUNCC(avg_h264_chroma_mc4   , depth);\

    c->avg_h264_chroma_pixels_tab[2] = FUNCC(avg_h264_chroma_mc2   , depth);\

\

    dspfunc1(put       , 0, 16, depth);\

    dspfunc1(put       , 1,  8, depth);\

    dspfunc1(put       , 2,  4, depth);\

    dspfunc1(put       , 3,  2, depth);\

    dspfunc1(put_no_rnd, 0, 16, depth);\

    dspfunc1(put_no_rnd, 1,  8, depth);\

    dspfunc1(avg       , 0, 16, depth);\

    dspfunc1(avg       , 1,  8, depth);\

    dspfunc1(avg       , 2,  4, depth);\

    dspfunc1(avg       , 3,  2, depth);\

    dspfunc1(avg_no_rnd, 0, 16, depth);\

    dspfunc1(avg_no_rnd, 1,  8, depth);\

\

    dspfunc2(put_h264_qpel, 0, 16, depth);\

    dspfunc2(put_h264_qpel, 1,  8, depth);\

    dspfunc2(put_h264_qpel, 2,  4, depth);\

    dspfunc2(put_h264_qpel, 3,  2, depth);\

    dspfunc2(avg_h264_qpel, 0, 16, depth);\

    dspfunc2(avg_h264_qpel, 1,  8, depth);\

    dspfunc2(avg_h264_qpel, 2,  4, depth);

    switch (avctx->bits_per_raw_sample) {

    case 9:

        if (c->dct_bits == 32) {

            BIT_DEPTH_FUNCS(9, _32);

        } else {

            BIT_DEPTH_FUNCS(9, _16);

        }

        break;

    case 10:

        if (c->dct_bits == 32) {

            BIT_DEPTH_FUNCS(10, _32);

        } else {

            BIT_DEPTH_FUNCS(10, _16);

        }

        break;

    default:

        BIT_DEPTH_FUNCS(8, _16);

        break;

    }

    if (HAVE_MMX)        ff_dsputil_init_mmx   (c, avctx);

    if (ARCH_ARM)        ff_dsputil_init_arm   (c, avctx);

    if (HAVE_VIS)        ff_dsputil_init_vis   (c, avctx);

    if (ARCH_ALPHA)      ff_dsputil_init_alpha (c, avctx);

    if (ARCH_PPC)        ff_dsputil_init_ppc   (c, avctx);

    if (HAVE_MMI)        ff_dsputil_init_mmi   (c, avctx);

    if (ARCH_SH4)        ff_dsputil_init_sh4   (c, avctx);

    if (ARCH_BFIN)       ff_dsputil_init_bfin  (c, avctx);

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

        if(!c->put_2tap_qpel_pixels_tab[0][i])

            c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i];

        if(!c->avg_2tap_qpel_pixels_tab[0][i])

            c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i];

    }

    ff_init_scantable_permutation(c->idct_permutation,

                                  c->idct_permutation_type);

}


static int mpc7_decode_frame(AVCodecContext * avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    MPCContext *c = avctx->priv_data;

    GetBitContext gb;

    uint8_t *bits;

    int i, ch;

    int mb = -1;

    Band *bands = c->bands;

    int off;

    int bits_used, bits_avail;

    memset(bands, 0, sizeof(bands));

    if(buf_size <= 4){

        av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size);

    }

    bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE);

    c->dsp.bswap_buf((uint32_t*)bits, (const uint32_t*)(buf + 4), (buf_size - 4) >> 2);

    init_get_bits(&gb, bits, (buf_size - 4)* 8);

    skip_bits_long(&gb, buf[0]);

    /* read subband indexes */

    for(i = 0; i <= c->maxbands; i++){

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

            int t = 4;

            if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5;

            if(t == 4) bands[i].res[ch] = get_bits(&gb, 4);

            else bands[i].res[ch] = bands[i-1].res[ch] + t;

        }

        if(bands[i].res[0] || bands[i].res[1]){

            mb = i;

            if(c->MSS) bands[i].msf = get_bits1(&gb);

        }

    }

    /* get scale indexes coding method */

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

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

            if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1);

    /* get scale indexes */

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

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

            if(bands[i].res[ch]){

                bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i];

                bands[i].scf_idx[ch][0] = get_scale_idx(&gb, bands[i].scf_idx[ch][2]);

                switch(bands[i].scfi[ch]){

                case 0:

                    bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]);

                    bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]);

                    break;

                case 1:

                    bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]);

                    bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1];

                    break;

                case 2:

                    bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0];

                    bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]);

                    break;

                case 3:

                    bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0];

                    break;

                }

                c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2];

            }

        }

    }

    /* get quantizers */

    memset(c->Q, 0, sizeof(c->Q));

    off = 0;

    for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND)

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

            idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);

    ff_mpc_dequantize_and_synth(c, mb, data, 2);

    av_free(bits);

    bits_used = get_bits_count(&gb);

    bits_avail = (buf_size - 4) * 8;

    if(!buf[1] && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))){

        av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);

        return -1;

    }

    if(c->frames_to_skip){

        c->frames_to_skip--;

        *data_size = 0;

        return buf_size;

    }

    *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4;

    return buf_size;

}


void ff_h264_filter_mb(const H264Context *h, H264SliceContext *sl,

                       int mb_x, int mb_y,

                       uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr,

                       unsigned int linesize, unsigned int uvlinesize)

{

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

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

    const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;

    int first_vertical_edge_done = 0;

    int chroma = !(CONFIG_GRAY && (h->flags & AV_CODEC_FLAG_GRAY));

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

    int a = 52 + sl->slice_alpha_c0_offset - qp_bd_offset;

    int b = 52 + sl->slice_beta_offset - qp_bd_offset;

    if (FRAME_MBAFF(h)

            // and current and left pair do not have the same interlaced type

            && IS_INTERLACED(mb_type ^ sl->left_type[LTOP])

            // and left mb is in available to us

            && sl->left_type[LTOP]) {

        /* First vertical edge is different in MBAFF frames

         * There are 8 different bS to compute and 2 different Qp

         */

        DECLARE_ALIGNED(8, int16_t, bS)[8];

        int qp[2];

        int bqp[2];

        int rqp[2];

        int mb_qp, mbn0_qp, mbn1_qp;

        int i;

        first_vertical_edge_done = 1;

        if( IS_INTRA(mb_type) ) {

            AV_WN64A(&bS[0], 0x0004000400040004ULL);

            AV_WN64A(&bS[4], 0x0004000400040004ULL);

        } else {

            static const uint8_t offset[2][2][8]={

                {

                    {3+4*0, 3+4*0, 3+4*0, 3+4*0, 3+4*1, 3+4*1, 3+4*1, 3+4*1},

                    {3+4*2, 3+4*2, 3+4*2, 3+4*2, 3+4*3, 3+4*3, 3+4*3, 3+4*3},

                },{

                    {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},

                    {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},

                }

            };

            const uint8_t *off= offset[MB_FIELD(sl)][mb_y&1];

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

                int j= MB_FIELD(sl) ? i>>2 : i&1;

                int mbn_xy = sl->left_mb_xy[LEFT(j)];

                int mbn_type = sl->left_type[LEFT(j)];

                if( IS_INTRA( mbn_type ) )

                    bS[i] = 4;

                else{

                    bS[i] = 1 + !!(sl->non_zero_count_cache[12+8*(i>>1)] |

                         ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ?

                            (h->cbp_table[mbn_xy] & (((MB_FIELD(sl) ? (i&2) : (mb_y&1)) ? 8 : 2) << 12))

                                                                       :

                            h->non_zero_count[mbn_xy][ off[i] ]));

                }

            }

        }

        mb_qp   = h->cur_pic.qscale_table[mb_xy];

        mbn0_qp = h->cur_pic.qscale_table[sl->left_mb_xy[0]];

        mbn1_qp = h->cur_pic.qscale_table[sl->left_mb_xy[1]];

        qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;

        bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +

                   get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;

        rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) +

                   get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1;

        qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1;

        bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) +

                   get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1;

        rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) +

                   get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;

        /* Filter edge */

        ff_tlog(h->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);

        { int i; for (i = 0; i < 8; i++) ff_tlog(h->avctx, " bS[%d]:%d", i, bS[i]); ff_tlog(h->avctx, "\n"); }

        if (MB_FIELD(sl)) {

            filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0], a, b, 1 );

            filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1], a, b, 1 );

            if (chroma){

                if (CHROMA444(h)) {

                    filter_mb_mbaff_edgev ( h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );

                } else if (CHROMA422(h)) {

                    filter_mb_mbaff_edgecv(h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1);

                    filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1);

                    filter_mb_mbaff_edgecv(h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1);

                    filter_mb_mbaff_edgecv(h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1);

                }else{

                    filter_mb_mbaff_edgecv( h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );

                }

            }

        }else{

            filter_mb_mbaff_edgev ( h, img_y              , 2*  linesize, bS  , 2, qp [0], a, b, 1 );

            filter_mb_mbaff_edgev ( h, img_y  +   linesize, 2*  linesize, bS+1, 2, qp [1], a, b, 1 );

            if (chroma){

                if (CHROMA444(h)) {

                    filter_mb_mbaff_edgev ( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0], a, b, 1 );

                    filter_mb_mbaff_edgev ( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );

                }else{

                    filter_mb_mbaff_edgecv( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0], a, b, 1 );

                    filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1], a, b, 1 );

                }

            }

        }

    }

#if CONFIG_SMALL

    {

        int dir;

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

            filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize,

                          uvlinesize, mb_xy, mb_type, mvy_limit,

                          dir ? 0 : first_vertical_edge_done, a, b,

                          chroma, dir);

    }

#else

    filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, a, b, chroma, 0);

    filter_mb_dir(h, sl, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0,                        a, b, chroma, 1);

#endif

}


static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)

{

    int i;

    writer_print_section_header(w, SECTION_ID_STREAMS);

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

        if (selected_streams[i])

            show_stream(w, fmt_ctx, i, 0);

    writer_print_section_footer(w);

}


static av_always_inline void h264_loop_filter_strength_iteration_mmx2(int16_t bS[2][4][4], uint8_t nnz[40],

                                                                      int8_t ref[2][40],   int16_t mv[2][40][2],

                                                                      int bidir,   int edges, int step,

                                                                      int mask_mv, int dir)

{

        const x86_reg d_idx = dir ? -8 : -1;

        DECLARE_ALIGNED(8, const uint64_t, mask_dir) = dir ? 0 : 0xffffffffffffffffULL;

        int b_idx, edge;

        for( b_idx=12, edge=0; edge<edges; edge+=step, b_idx+=8*step ) {

            __asm__ volatile(

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

                ::"m"(mask_dir)

            );

            if(!(mask_mv & edge)) {

                if(bidir) {

                    __asm__ volatile(

                        "movd         (%1,%0), %%mm2 \n"

                        "punpckldq  40(%1,%0), %%mm2 \n" // { ref0[bn], ref1[bn] }

                        "pshufw $0x44,   (%1), %%mm0 \n" // { ref0[b], ref0[b] }

                        "pshufw $0x44, 40(%1), %%mm1 \n" // { ref1[b], ref1[b] }

                        "pshufw $0x4E, %%mm2, %%mm3 \n"

                        "psubb         %%mm2, %%mm0 \n" // { ref0[b]!=ref0[bn], ref0[b]!=ref1[bn] }

                        "psubb         %%mm3, %%mm1 \n" // { ref1[b]!=ref1[bn], ref1[b]!=ref0[bn] }

                        "1: \n"

                        "por           %%mm1, %%mm0 \n"

                        "movq      (%2,%0,4), %%mm1 \n"

                        "movq     8(%2,%0,4), %%mm2 \n"

                        "movq          %%mm1, %%mm3 \n"

                        "movq          %%mm2, %%mm4 \n"

                        "psubw          (%2), %%mm1 \n"

                        "psubw         8(%2), %%mm2 \n"

                        "psubw       160(%2), %%mm3 \n"

                        "psubw       168(%2), %%mm4 \n"

                        "packsswb      %%mm2, %%mm1 \n"

                        "packsswb      %%mm4, %%mm3 \n"

                        "paddb         %%mm6, %%mm1 \n"

                        "paddb         %%mm6, %%mm3 \n"

                        "psubusb       %%mm5, %%mm1 \n" // abs(mv[b] - mv[bn]) >= limit

                        "psubusb       %%mm5, %%mm3 \n"

                        "packsswb      %%mm3, %%mm1 \n"

                        "add $40, %0 \n"

                        "cmp $40, %0 \n"

                        "jl 1b \n"

                        "sub $80, %0 \n"

                        "pshufw $0x4E, %%mm1, %%mm1 \n"

                        "por           %%mm1, %%mm0 \n"

                        "pshufw $0x4E, %%mm0, %%mm1 \n"

                        "pminub        %%mm1, %%mm0 \n"

                        ::"r"(d_idx),

                          "r"(ref[0]+b_idx),

                          "r"(mv[0]+b_idx)

                    );

                } else {

                    __asm__ volatile(

                        "movd        (%1), %%mm0 \n"

                        "psubb    (%1,%0), %%mm0 \n" // ref[b] != ref[bn]

                        "movq        (%2), %%mm1 \n"

                        "movq       8(%2), %%mm2 \n"

                        "psubw  (%2,%0,4), %%mm1 \n"

                        "psubw 8(%2,%0,4), %%mm2 \n"

                        "packsswb   %%mm2, %%mm1 \n"

                        "paddb      %%mm6, %%mm1 \n"

                        "psubusb    %%mm5, %%mm1 \n" // abs(mv[b] - mv[bn]) >= limit

                        "packsswb   %%mm1, %%mm1 \n"

                        "por        %%mm1, %%mm0 \n"

                        ::"r"(d_idx),

                          "r"(ref[0]+b_idx),

                          "r"(mv[0]+b_idx)

                    );

                }

            }

            __asm__ volatile(

                "movd %0, %%mm1 \n"

                "por  %1, %%mm1 \n" // nnz[b] || nnz[bn]

                ::"m"(nnz[b_idx]),

                  "m"(nnz[b_idx+d_idx])

            );

            __asm__ volatile(

                "pminub    %%mm7, %%mm1 \n"

                "pminub    %%mm7, %%mm0 \n"

                "psllw        $1, %%mm1 \n"

                "pxor      %%mm2, %%mm2 \n"

                "pmaxub    %%mm0, %%mm1 \n"

                "punpcklbw %%mm2, %%mm1 \n"

                "movq      %%mm1, %0    \n"

                :"=m"(*bS[dir][edge])

                ::"memory"

            );

        }

}


static void intra_predict_hor_dc_8x8_msa(uint8_t *src, int32_t stride)

{

    uint8_t lp_cnt;

    uint32_t src0 = 0, src1 = 0;

    uint64_t out0, out1;

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

        src0 += src[lp_cnt * stride - 1];

        src1 += src[(4 + lp_cnt) * stride - 1];

    }

    src0 = (src0 + 2) >> 2;

    src1 = (src1 + 2) >> 2;

    out0 = src0 * 0x0101010101010101;

    out1 = src1 * 0x0101010101010101;

    for (lp_cnt = 4; lp_cnt--;) {

        SD(out0, src);

        SD(out1, (src + 4 * stride));

        src += stride;

    }

}


static int config_out_props(AVFilterLink *outlink)

{

    AVFilterContext *ctx = outlink->src;

    AVFilterLink *inlink = outlink->src->inputs[0];

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);

    TInterlaceContext *tinterlace = ctx->priv;

    int i;

    tinterlace->vsub = desc->log2_chroma_h;

    outlink->w = inlink->w;

    outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2?

        inlink->h*2 : inlink->h;

    if (tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2)

        outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio,

                                                av_make_q(2, 1));

    if (tinterlace->mode == MODE_PAD) {

        uint8_t black[4] = { 16, 128, 128, 16 };

        int i, ret;

        if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))

            black[0] = black[3] = 0;

        ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize,

                             outlink->w, outlink->h, outlink->format, 16);

        if (ret < 0)

            return ret;

        /* fill black picture with black */

        for (i = 0; i < 4 && tinterlace->black_data[i]; i++) {

            int h = i == 1 || i == 2 ? AV_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h) : outlink->h;

            memset(tinterlace->black_data[i], black[i],

                   tinterlace->black_linesize[i] * h);

        }

    }

    if ((tinterlace->flags & TINTERLACE_FLAG_VLPF

          || tinterlace->flags & TINTERLACE_FLAG_CVLPF)

            && !(tinterlace->mode == MODE_INTERLEAVE_TOP

              || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {

        av_log(ctx, AV_LOG_WARNING, "low_pass_filter flags ignored with mode %d\n",

                tinterlace->mode);

        tinterlace->flags &= ~TINTERLACE_FLAG_VLPF;

        tinterlace->flags &= ~TINTERLACE_FLAG_CVLPF;

    }

    tinterlace->preout_time_base = inlink->time_base;

    if (tinterlace->mode == MODE_INTERLACEX2) {

        tinterlace->preout_time_base.den *= 2;

        outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});

        outlink->time_base  = av_mul_q(inlink->time_base , (AVRational){1,2});

    } else if (tinterlace->mode == MODE_MERGEX2) {

        outlink->frame_rate = inlink->frame_rate;

        outlink->time_base  = inlink->time_base;

    } else if (tinterlace->mode != MODE_PAD) {

        outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});

        outlink->time_base  = av_mul_q(inlink->time_base , (AVRational){2,1});

    }

    for (i = 0; i<FF_ARRAY_ELEMS(standard_tbs); i++){

        if (!av_cmp_q(standard_tbs[i], outlink->time_base))

            break;

    }

    if (i == FF_ARRAY_ELEMS(standard_tbs) ||

        (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))

        outlink->time_base = tinterlace->preout_time_base;

    if (tinterlace->flags & TINTERLACE_FLAG_CVLPF) {

        tinterlace->lowpass_line = lowpass_line_complex_c;

        if (ARCH_X86)

            ff_tinterlace_init_x86(tinterlace);

    } else if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {

        tinterlace->lowpass_line = lowpass_line_c;

        if (ARCH_X86)

            ff_tinterlace_init_x86(tinterlace);

    }

    av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", tinterlace->mode,

           (tinterlace->flags & TINTERLACE_FLAG_CVLPF) ? "complex" :

           (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "linear" : "off",

           inlink->h, outlink->h);

    return 0;

}


static void rv40_v_weak_loop_filter(uint8_t *src, const int stride,

                                    const int filter_p1, const int filter_q1,

                                    const int alpha, const int beta,

                                    const int lim_p0q0, const int lim_q1,

                                    const int lim_p1)

{

    rv40_weak_loop_filter(src, 1, stride, filter_p1, filter_q1,

                          alpha, beta, lim_p0q0, lim_q1, lim_p1);

}


static int open_output_file(OptionsContext *o, const char *filename)

{

    AVFormatContext *oc;

    int i, j, err;

    AVOutputFormat *file_oformat;

    OutputFile *of;

    OutputStream *ost;

    InputStream  *ist;

    AVDictionary *unused_opts = NULL;

    AVDictionaryEntry *e = NULL;

    if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {

        o->stop_time = INT64_MAX;

        av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");

    }

    if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {

        int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;

        if (o->stop_time <= start_time) {

            av_log(NULL, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");

            exit_program(1);

        } else {

            o->recording_time = o->stop_time - start_time;

        }

    }

    GROW_ARRAY(output_files, nb_output_files);

    of = av_mallocz(sizeof(*of));

    if (!of)

        exit_program(1);

    output_files[nb_output_files - 1] = of;

    of->ost_index      = nb_output_streams;

    of->recording_time = o->recording_time;

    of->start_time     = o->start_time;

    of->limit_filesize = o->limit_filesize;

    of->shortest       = o->shortest;

    av_dict_copy(&of->opts, o->g->format_opts, 0);

    if (!strcmp(filename, "-"))

        filename = "pipe:";

    err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);

    if (!oc) {

        print_error(filename, err);

        exit_program(1);

    }

    of->ctx = oc;

    if (o->recording_time != INT64_MAX)

        oc->duration = o->recording_time;

    file_oformat= oc->oformat;

    oc->interrupt_callback = int_cb;

    /* create streams for all unlabeled output pads */

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

        FilterGraph *fg = filtergraphs[i];

        for (j = 0; j < fg->nb_outputs; j++) {

            OutputFilter *ofilter = fg->outputs[j];

            if (!ofilter->out_tmp || ofilter->out_tmp->name)

                continue;

            switch (ofilter->type) {

            case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;

            case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;

            case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;

            }

            init_output_filter(ofilter, o, oc);

        }

    }

    /* ffserver seeking with date=... needs a date reference */

    if (!strcmp(file_oformat->name, "ffm") &&

        av_strstart(filename, "http:", NULL)) {

        int err = parse_option(o, "metadata", "creation_time=now", options);

        if (err < 0) {

            print_error(filename, err);

            exit_program(1);

        }

    }

    if (!strcmp(file_oformat->name, "ffm") && !override_ffserver &&

        av_strstart(filename, "http:", NULL)) {

        int j;

        /* special case for files sent to ffserver: we get the stream

           parameters from ffserver */

        int err = read_ffserver_streams(o, oc, filename);

        if (err < 0) {

            print_error(filename, err);

            exit_program(1);

        }

        for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {

            ost = output_streams[j];

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

                ist = input_streams[i];

                if(ist->st->codec->codec_type == ost->st->codec->codec_type){

                    ost->sync_ist= ist;

                    ost->source_index= i;

                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");

                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");

                    ist->discard = 0;

                    ist->st->discard = ist->user_set_discard;

                    break;

                }

            }

            if(!ost->sync_ist){

                av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));

                exit_program(1);

            }

        }

    } else if (!o->nb_stream_maps) {

        char *subtitle_codec_name = NULL;

        /* pick the "best" stream of each type */

        /* video: highest resolution */

        if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) {

            int area = 0, idx = -1;

            int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);

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

                int new_area;

                ist = input_streams[i];

                new_area = ist->st->codec->width * ist->st->codec->height + 100000000*!!ist->st->codec_info_nb_frames;

                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))

                    new_area = 1;

                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&

                    new_area > area) {

                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))

                        continue;

                    area = new_area;

                    idx = i;

                }

            }

            if (idx >= 0)

                new_video_stream(o, oc, idx);

        }

        /* audio: most channels */

        if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) {

            int best_score = 0, idx = -1;

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

                int score;

                ist = input_streams[i];

                score = ist->st->codec->channels + 100000000*!!ist->st->codec_info_nb_frames;

                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&

                    score > best_score) {

                    best_score = score;

                    idx = i;

                }

            }

            if (idx >= 0)

                new_audio_stream(o, oc, idx);

        }

        /* subtitles: pick first */

        MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");

        if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) {

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

                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {

                    AVCodecDescriptor const *input_descriptor =

                        avcodec_descriptor_get(input_streams[i]->st->codec->codec_id);

                    AVCodecDescriptor const *output_descriptor = NULL;

                    AVCodec const *output_codec =

                        avcodec_find_encoder(oc->oformat->subtitle_codec);

                    int input_props = 0, output_props = 0;

                    if (output_codec)

                        output_descriptor = avcodec_descriptor_get(output_codec->id);

                    if (input_descriptor)

                        input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);

                    if (output_descriptor)

                        output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);

                    if (subtitle_codec_name ||

                        input_props & output_props ||

                        // Map dvb teletext which has neither property to any output subtitle encoder

                        input_descriptor && output_descriptor &&

                        (!input_descriptor->props ||

                         !output_descriptor->props)) {

                        new_subtitle_stream(o, oc, i);

                        break;

                    }

                }

        }

        /* Data only if codec id match */

        if (!o->data_disable ) {

            enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_DATA);

            for (i = 0; codec_id != AV_CODEC_ID_NONE && i < nb_input_streams; i++) {

                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_DATA

                    && input_streams[i]->st->codec->codec_id == codec_id )

                    new_data_stream(o, oc, i);

            }

        }

    } else {

        for (i = 0; i < o->nb_stream_maps; i++) {

            StreamMap *map = &o->stream_maps[i];

            if (map->disabled)

                continue;

            if (map->linklabel) {

                FilterGraph *fg;

                OutputFilter *ofilter = NULL;

                int j, k;

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

                    fg = filtergraphs[j];

                    for (k = 0; k < fg->nb_outputs; k++) {

                        AVFilterInOut *out = fg->outputs[k]->out_tmp;

                        if (out && !strcmp(out->name, map->linklabel)) {

                            ofilter = fg->outputs[k];

                            goto loop_end;

                        }

                    }

                }

loop_end:

                if (!ofilter) {

                    av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "

                           "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);

                    exit_program(1);

                }

                init_output_filter(ofilter, o, oc);

            } else {

                int src_idx = input_files[map->file_index]->ist_index + map->stream_index;

                ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];

                if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)

                    continue;

                if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)

                    continue;

                if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

                    continue;

                if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)

                    continue;

                ost = NULL;

                switch (ist->st->codec->codec_type) {

                case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;

                case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;

                case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;

                case AVMEDIA_TYPE_DATA:       ost = new_data_stream      (o, oc, src_idx); break;

                case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;

                case AVMEDIA_TYPE_UNKNOWN:

                    if (copy_unknown_streams) {

                        ost = new_unknown_stream   (o, oc, src_idx);

                        break;

                    }

                default:

                    av_log(NULL, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,

                           "Cannot map stream #%d:%d - unsupported type.\n",

                           map->file_index, map->stream_index);

                    if (!ignore_unknown_streams) {

                        av_log(NULL, AV_LOG_FATAL,

                               "If you want unsupported types ignored instead "

                               "of failing, please use the -ignore_unknown option\n"

                               "If you want them copied, please use -copy_unknown\n");

                        exit_program(1);

                    }

                }

                if (ost)

                    ost->sync_ist = input_streams[  input_files[map->sync_file_index]->ist_index

                                                  + map->sync_stream_index];

            }

        }

    }

    /* handle attached files */

    for (i = 0; i < o->nb_attachments; i++) {

        AVIOContext *pb;

        uint8_t *attachment;

        const char *p;

        int64_t len;

        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {

            av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",

                   o->attachments[i]);

            exit_program(1);

        }

        if ((len = avio_size(pb)) <= 0) {

            av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",

                   o->attachments[i]);

            exit_program(1);

        }

        if (!(attachment = av_malloc(len))) {

            av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",

                   o->attachments[i]);

            exit_program(1);

        }

        avio_read(pb, attachment, len);

        ost = new_attachment_stream(o, oc, -1);

        ost->stream_copy               = 1;

        ost->attachment_filename       = o->attachments[i];

        ost->finished                  = 1;

        ost->st->codec->extradata      = attachment;

        ost->st->codec->extradata_size = len;

        p = strrchr(o->attachments[i], '/');

        av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);

        avio_closep(&pb);

    }

    for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) { //for all streams of this output file

        AVDictionaryEntry *e;

        ost = output_streams[i];

        if ((ost->stream_copy || ost->attachment_filename)

            && (e = av_dict_get(o->g->codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))

            && (!e->key[5] || check_stream_specifier(oc, ost->st, e->key+6)))

            if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)

                exit_program(1);

    }

    if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {

        av_dump_format(oc, nb_output_files - 1, oc->filename, 1);

        av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);

        exit_program(1);

    }

    /* check if all codec options have been used */

    unused_opts = strip_specifiers(o->g->codec_opts);

    for (i = of->ost_index; i < nb_output_streams; i++) {

        e = NULL;

        while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e,

                                AV_DICT_IGNORE_SUFFIX)))

            av_dict_set(&unused_opts, e->key, NULL, 0);

    }

    e = NULL;

    while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {

        const AVClass *class = avcodec_get_class();

        const AVOption *option = av_opt_find(&class, e->key, NULL, 0,

                                             AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);

        const AVClass *fclass = avformat_get_class();

        const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,

                                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);

        if (!option || foption)

            continue;

        if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {

            av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "

                   "output file #%d (%s) is not an encoding option.\n", e->key,

                   option->help ? option->help : "", nb_output_files - 1,

                   filename);

            exit_program(1);

        }

        // gop_timecode is injected by generic code but not always used

        if (!strcmp(e->key, "gop_timecode"))

            continue;

        av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "

               "output file #%d (%s) has not been used for any stream. The most "

               "likely reason is either wrong type (e.g. a video option with "

               "no video streams) or that it is a private option of some encoder "

               "which was not actually used for any stream.\n", e->key,

               option->help ? option->help : "", nb_output_files - 1, filename);

    }

    av_dict_free(&unused_opts);

    /* set the encoding/decoding_needed flags */

    for (i = of->ost_index; i < nb_output_streams; i++) {

        OutputStream *ost = output_streams[i];

        ost->encoding_needed = !ost->stream_copy;

        if (ost->encoding_needed && ost->source_index >= 0) {

            InputStream *ist = input_streams[ost->source_index];

            ist->decoding_needed |= DECODING_FOR_OST;

        }

    }

    /* check filename in case of an image number is expected */

    if (oc->oformat->flags & AVFMT_NEEDNUMBER) {

        if (!av_filename_number_test(oc->filename)) {

            print_error(oc->filename, AVERROR(EINVAL));

            exit_program(1);

        }

    }

    if (!(oc->oformat->flags & AVFMT_NOSTREAMS) && !input_stream_potentially_available) {

        av_log(NULL, AV_LOG_ERROR,

               "No input streams but output needs an input stream\n");

        exit_program(1);

    }

    if (!(oc->oformat->flags & AVFMT_NOFILE)) {

        /* test if it already exists to avoid losing precious files */

        assert_file_overwrite(filename);

        /* open the file */

        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,

                              &oc->interrupt_callback,

                              &of->opts)) < 0) {

            print_error(filename, err);

            exit_program(1);

        }

    } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))

        assert_file_overwrite(filename);

    if (o->mux_preload) {

        av_dict_set_int(&of->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);

    }

    oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);

    /* copy metadata */

    for (i = 0; i < o->nb_metadata_map; i++) {

        char *p;

        int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);

        if (in_file_index >= nb_input_files) {

            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);

            exit_program(1);

        }

        copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,

                      in_file_index >= 0 ?

                      input_files[in_file_index]->ctx : NULL, o);

    }

    /* copy chapters */

    if (o->chapters_input_file >= nb_input_files) {

        if (o->chapters_input_file == INT_MAX) {

            /* copy chapters from the first input file that has them*/

            o->chapters_input_file = -1;

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

                if (input_files[i]->ctx->nb_chapters) {

                    o->chapters_input_file = i;

                    break;

                }

        } else {

            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",

                   o->chapters_input_file);

            exit_program(1);

        }

    }

    if (o->chapters_input_file >= 0)

        copy_chapters(input_files[o->chapters_input_file], of,

                      !o->metadata_chapters_manual);

    /* copy global metadata by default */

    if (!o->metadata_global_manual && nb_input_files){

        av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,

                     AV_DICT_DONT_OVERWRITE);

        if(o->recording_time != INT64_MAX)

            av_dict_set(&oc->metadata, "duration", NULL, 0);

        av_dict_set(&oc->metadata, "creation_time", NULL, 0);

    }

    if (!o->metadata_streams_manual)

        for (i = of->ost_index; i < nb_output_streams; i++) {

            InputStream *ist;

            if (output_streams[i]->source_index < 0)         /* this is true e.g. for attached files */

                continue;

            ist = input_streams[output_streams[i]->source_index];

            av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);

            if (!output_streams[i]->stream_copy) {

                av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0);

                if (ist->autorotate)

                    av_dict_set(&output_streams[i]->st->metadata, "rotate", NULL, 0);

            }

        }

    /* process manually set programs */

    for (i = 0; i < o->nb_program; i++) {

        const char *p = o->program[i].u.str;

        int progid = i+1;

        AVProgram *program;

        while(*p) {

            const char *p2 = av_get_token(&p, ":");

            char *key;

            if (!p2)

                break;

            if(*p) p++;

            key = av_get_token(&p2, "=");

            if (!key || !*p2)

                break;

            p2++;

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

                progid = strtol(p2, NULL, 0);

        }

        program = av_new_program(oc, progid);

        p = o->program[i].u.str;

        while(*p) {

            const char *p2 = av_get_token(&p, ":");

            char *key;

            if (!p2)

                break;

            if(*p) p++;

            key = av_get_token(&p2, "=");

            if (!key) {

                av_log(NULL, AV_LOG_FATAL,

                       "No '=' character in program string %s.\n",

                       p2);

                exit_program(1);

            }

            if (!*p2)

                exit_program(1);

            p2++;

            if (!strcmp(key, "title")) {

                av_dict_set(&program->metadata, "title", p2, 0);

            } else if (!strcmp(key, "program_num")) {

            } else if (!strcmp(key, "st")) {

                int st_num = strtol(p2, NULL, 0);

                av_program_add_stream_index(oc, progid, st_num);

            } else {

                av_log(NULL, AV_LOG_FATAL, "Unknown program key %s.\n", key);

                exit_program(1);

            }

        }

    }

    /* process manually set metadata */

    for (i = 0; i < o->nb_metadata; i++) {

        AVDictionary **m;

        char type, *val;

        const char *stream_spec;

        int index = 0, j, ret = 0;

        char now_time[256];

        val = strchr(o->metadata[i].u.str, '=');

        if (!val) {

            av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",

                   o->metadata[i].u.str);

            exit_program(1);

        }

        *val++ = 0;

        if (!strcmp(o->metadata[i].u.str, "creation_time") &&

            !strcmp(val, "now")) {

            time_t now = time(0);

            struct tm *ptm, tmbuf;

            ptm = localtime_r(&now, &tmbuf);

            if (ptm) {

                if (strftime(now_time, sizeof(now_time), "%Y-%m-%d %H:%M:%S", ptm))

                    val = now_time;

            }

        }

        parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);

        if (type == 's') {

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

                ost = output_streams[nb_output_streams - oc->nb_streams + j];

                if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {

                    av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);

                    if (!strcmp(o->metadata[i].u.str, "rotate")) {

                        ost->rotate_overridden = 1;

                    }

                } else if (ret < 0)

                    exit_program(1);

            }

        }

        else {

            switch (type) {

            case 'g':

                m = &oc->metadata;

                break;

            case 'c':

                if (index < 0 || index >= oc->nb_chapters) {

                    av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);

                    exit_program(1);

                }

                m = &oc->chapters[index]->metadata;

                break;

            case 'p':

                if (index < 0 || index >= oc->nb_programs) {

                    av_log(NULL, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);

                    exit_program(1);

                }

                m = &oc->programs[index]->metadata;

                break;

            default:

                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);

                exit_program(1);

            }

            av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);

        }

    }

    return 0;

}


static void vapic_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->no_user = 1;

    dc->reset   = vapic_reset;

    dc->vmsd    = &vmstate_vapic;

    dc->realize = vapic_realize;

}


AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)

{

    AVProbeData lpd = *pd;

    AVInputFormat *fmt1 = NULL, *fmt;

    int score, id3 = 0;

    if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {

        int id3len = ff_id3v2_tag_len(lpd.buf);

        if (lpd.buf_size > id3len + 16) {

            lpd.buf += id3len;

            lpd.buf_size -= id3len;

        }

        id3 = 1;

    }

    fmt = NULL;

    while ((fmt1 = av_iformat_next(fmt1))) {

        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))

            continue;

        score = 0;

        if (fmt1->read_probe) {

            score = fmt1->read_probe(&lpd);

        } else if (fmt1->extensions) {

            if (av_match_ext(lpd.filename, fmt1->extensions)) {

                score = 50;

            }

        }

        if (score > *score_max) {

            *score_max = score;

            fmt = fmt1;

        }else if (score == *score_max)

            fmt = NULL;

    }

    /* a hack for files with huge id3v2 tags -- try to guess by file extension. */

    if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) {

        while ((fmt = av_iformat_next(fmt)))

            if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {

                *score_max = AVPROBE_SCORE_MAX/4;

                break;

            }

    }

    return fmt;

}


static void v4l2_free_buffer(void *opaque, uint8_t *unused)

{

    V4L2Buffer* avbuf = opaque;

    V4L2m2mContext *s = buf_to_m2mctx(avbuf);

    atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel);

    if (s->reinit) {

        if (!atomic_load(&s->refcount))

            sem_post(&s->refsync);

        return;

    }

    if (avbuf->context->streamon) {

        ff_v4l2_buffer_enqueue(avbuf);

        return;

    }

    if (!atomic_load(&s->refcount))

        ff_v4l2_m2m_codec_end(s->avctx);

}


static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence)

{

    return avio_seek(s, offset + (offset & 1), whence);

}


static void ahci_start_dma(IDEDMA *dma, IDEState *s,

                           BlockCompletionFunc *dma_cb)

{

#ifdef DEBUG_AHCI

    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);

#endif

    DPRINTF(ad->port_no, "\n");

    s->io_buffer_offset = 0;

    dma_cb(s, 0);

}


rdt_new_context (void)

{

    PayloadContext *rdt = av_mallocz(sizeof(PayloadContext));

    avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);

    return rdt;

}


static void qpci_pc_config_writeb(QPCIBus *bus, int devfn, uint8_t offset, uint8_t value)

{

    outl(0xcf8, (1 << 31) | (devfn << 8) | offset);

    outb(0xcfc, value);

}


static void hpet_set_timer(HPETTimer *t)

{

    uint64_t diff;

    uint32_t wrap_diff;  /* how many ticks until we wrap? */

    uint64_t cur_tick = hpet_get_ticks();

    /* whenever new timer is being set up, make sure wrap_flag is 0 */

    t->wrap_flag = 0;

    diff = hpet_calculate_diff(t, cur_tick);

    /* hpet spec says in one-shot 32-bit mode, generate an interrupt when

     * counter wraps in addition to an interrupt with comparator match.

     */

    if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {

        wrap_diff = 0xffffffff - (uint32_t)cur_tick;

        if (wrap_diff < (uint32_t)diff) {

            diff = wrap_diff;

            t->wrap_flag = 1;

        }

    }

    qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)

                   + (int64_t)ticks_to_ns(diff));

}


static uint32_t set_allocation_state(sPAPRDRConnector *drc,

                                     sPAPRDRAllocationState state)

{

    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state);

    if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) {

        /* if there's no resource/device associated with the DRC, there's

         * no way for us to put it in an allocation state consistent with

         * being 'USABLE'. PAPR 2.7, 13.5.3.4 documents that this should

         * result in an RTAS return code of -3 / "no such indicator"

         */

        if (!drc->dev) {

            return RTAS_OUT_NO_SUCH_INDICATOR;

        }

    }

    if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) {

        drc->allocation_state = state;

        if (drc->awaiting_release &&

            drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {

            DPRINTFN("finalizing device removal");

            drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,

                         drc->detach_cb_opaque, NULL);

        }

    }

    return RTAS_OUT_SUCCESS;

}


int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)

{

    BaumDriverState *baum;

    CharDriverState *chr;

    brlapi_handle_t *handle;

#ifdef CONFIG_SDL

    SDL_SysWMinfo info;

#endif

    int tty;

    baum = g_malloc0(sizeof(BaumDriverState));

    baum->chr = chr = g_malloc0(sizeof(CharDriverState));

    chr->opaque = baum;

    chr->chr_write = baum_write;

    chr->chr_accept_input = baum_accept_input;

    chr->chr_close = baum_close;

    handle = g_malloc0(brlapi_getHandleSize());

    baum->brlapi = handle;

    baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);

    if (baum->brlapi_fd == -1) {

        brlapi_perror("baum_init: brlapi_openConnection");

        goto fail_handle;

    }

    baum->cellCount_timer = qemu_new_timer_ns(vm_clock, baum_cellCount_timer_cb, baum);

    if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {

        brlapi_perror("baum_init: brlapi_getDisplaySize");

        goto fail;

    }

#ifdef CONFIG_SDL

    memset(&info, 0, sizeof(info));

    SDL_VERSION(&info.version);

    if (SDL_GetWMInfo(&info))

        tty = info.info.x11.wmwindow;

    else

#endif

        tty = BRLAPI_TTY_DEFAULT;

    if (brlapi__enterTtyMode(handle, tty, NULL) == -1) {

        brlapi_perror("baum_init: brlapi_enterTtyMode");

        goto fail;

    }

    qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);

    qemu_chr_generic_open(chr);

    *_chr = chr;

    return 0;

fail:

    qemu_free_timer(baum->cellCount_timer);

    brlapi__closeConnection(handle);

fail_handle:

    g_free(handle);

    g_free(chr);

    g_free(baum);

    return -EIO;

}


static av_cold int ipvideo_decode_init(AVCodecContext *avctx)

{

    IpvideoContext *s = avctx->priv_data;

    s->avctx = avctx;

    s->is_16bpp = avctx->bits_per_coded_sample == 16;

    avctx->pix_fmt = s->is_16bpp ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_PAL8;

    ff_hpeldsp_init(&s->hdsp, avctx->flags);

    s->last_frame        = av_frame_alloc();

    s->second_last_frame = av_frame_alloc();

    s->cur_decode_frame  = av_frame_alloc();

    s->prev_decode_frame = av_frame_alloc();

    if (!s->last_frame || !s->second_last_frame ||

        !s->cur_decode_frame || !s->prev_decode_frame) {

        av_frame_free(&s->last_frame);

        av_frame_free(&s->second_last_frame);

        av_frame_free(&s->cur_decode_frame);

        av_frame_free(&s->prev_decode_frame);

        return AVERROR(ENOMEM);

    }

    s->cur_decode_frame->width   = avctx->width;

    s->prev_decode_frame->width  = avctx->width;

    s->cur_decode_frame->height  = avctx->height;

    s->prev_decode_frame->height = avctx->height;

    s->cur_decode_frame->format  = avctx->pix_fmt;

    s->prev_decode_frame->format = avctx->pix_fmt;

    ff_get_buffer(avctx, s->cur_decode_frame, 0);

    ff_get_buffer(avctx, s->prev_decode_frame, 0);

    return 0;

}


static int vvfat_open(BlockDriverState *bs, QDict *options, int flags)

{

    BDRVVVFATState *s = bs->opaque;

    int cyls, heads, secs;

    bool floppy;

    const char *dirname;

    QemuOpts *opts;

    Error *local_err = NULL;

    int ret;

#ifdef DEBUG

    vvv = s;

#endif

DLOG(if (stderr == NULL) {

    stderr = fopen("vvfat.log", "a");

    setbuf(stderr, NULL);

})

    opts = qemu_opts_create_nofail(&runtime_opts);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (error_is_set(&local_err)) {

        qerror_report_err(local_err);

        error_free(local_err);

        ret = -EINVAL;

        goto fail;

    }

    dirname = qemu_opt_get(opts, "dir");

    if (!dirname) {

        qerror_report(ERROR_CLASS_GENERIC_ERROR, "vvfat block driver requires "

                      "a 'dir' option");

        ret = -EINVAL;

        goto fail;

    }

    s->fat_type = qemu_opt_get_number(opts, "fat-type", 0);

    floppy = qemu_opt_get_bool(opts, "floppy", false);

    if (floppy) {

        /* 1.44MB or 2.88MB floppy.  2.88MB can be FAT12 (default) or FAT16. */

        if (!s->fat_type) {

            s->fat_type = 12;

            secs = 36;

            s->sectors_per_cluster = 2;

        } else {

            secs = s->fat_type == 12 ? 18 : 36;

            s->sectors_per_cluster = 1;

        }

        s->first_sectors_number = 1;

        cyls = 80;

        heads = 2;

    } else {

        /* 32MB or 504MB disk*/

        if (!s->fat_type) {

            s->fat_type = 16;

        }

        cyls = s->fat_type == 12 ? 64 : 1024;

        heads = 16;

        secs = 63;

    }

    switch (s->fat_type) {

    case 32:

	    fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. "

                "You are welcome to do so!\n");

        break;

    case 16:

    case 12:

        break;

    default:

        qerror_report(ERROR_CLASS_GENERIC_ERROR, "Valid FAT types are only "

                      "12, 16 and 32");

        ret = -EINVAL;

        goto fail;

    }

    s->bs = bs;

    /* LATER TODO: if FAT32, adjust */

    s->sectors_per_cluster=0x10;

    s->current_cluster=0xffffffff;

    s->first_sectors_number=0x40;

    /* read only is the default for safety */

    bs->read_only = 1;

    s->qcow = s->write_target = NULL;

    s->qcow_filename = NULL;

    s->fat2 = NULL;

    s->downcase_short_names = 1;

    fprintf(stderr, "vvfat %s chs %d,%d,%d\n",

            dirname, cyls, heads, secs);

    s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);

    if (qemu_opt_get_bool(opts, "rw", false)) {

        if (enable_write_target(s)) {

            ret = -EIO;

            goto fail;

        }

        bs->read_only = 0;

    }

    bs->total_sectors = cyls * heads * secs;

    if (init_directories(s, dirname, heads, secs)) {

        ret = -EIO;

        goto fail;

    }

    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;

    if (s->first_sectors_number == 0x40) {

        init_mbr(s, cyls, heads, secs);

    }

    //    assert(is_consistent(s));

    qemu_co_mutex_init(&s->lock);

    /* Disable migration when vvfat is used rw */

    if (s->qcow) {

        error_set(&s->migration_blocker,

                  QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,

                  "vvfat (rw)", bs->device_name, "live migration");

        migrate_add_blocker(s->migration_blocker);

    }

    ret = 0;

fail:

    qemu_opts_del(opts);

    return ret;

}


static int v4l2_try_start(AVCodecContext *avctx)

{

    V4L2m2mContext *s = avctx->priv_data;

    V4L2Context *const capture = &s->capture;

    V4L2Context *const output = &s->output;

    struct v4l2_selection selection;

    int ret;

    /* 1. start the output process */

    if (!output->streamon) {

        ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON);

        if (ret < 0) {

            av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON on output context\n");

            return ret;

        }

    }

    if (capture->streamon)

        return 0;

    /* 2. get the capture format */

    capture->format.type = capture->type;

    ret = ioctl(s->fd, VIDIOC_G_FMT, &capture->format);

    if (ret) {

        av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_FMT ioctl\n");

        return ret;

    }

    /* 2.1 update the AVCodecContext */

    avctx->pix_fmt = ff_v4l2_format_v4l2_to_avfmt(capture->format.fmt.pix_mp.pixelformat, AV_CODEC_ID_RAWVIDEO);

    capture->av_pix_fmt = avctx->pix_fmt;

    /* 3. set the crop parameters */

    selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    selection.r.height = avctx->coded_height;

    selection.r.width = avctx->coded_width;

    ret = ioctl(s->fd, VIDIOC_S_SELECTION, &selection);

    if (!ret) {

        ret = ioctl(s->fd, VIDIOC_G_SELECTION, &selection);

        if (ret) {

            av_log(avctx, AV_LOG_WARNING, "VIDIOC_G_SELECTION ioctl\n");

        } else {

            av_log(avctx, AV_LOG_DEBUG, "crop output %dx%d\n", selection.r.width, selection.r.height);

            /* update the size of the resulting frame */

            capture->height = selection.r.height;

            capture->width  = selection.r.width;

        }

    }

    /* 4. init the capture context now that we have the capture format */

    if (!capture->buffers) {

        ret = ff_v4l2_context_init(capture);

        if (ret) {

            av_log(avctx, AV_LOG_DEBUG, "can't request output buffers\n");

            return ret;

        }

    }

    /* 5. start the capture process */

    ret = ff_v4l2_context_set_status(capture, VIDIOC_STREAMON);

    if (ret) {

        av_log(avctx, AV_LOG_DEBUG, "VIDIOC_STREAMON, on capture context\n");

        return ret;

    }

    return 0;

}


static int vp3_decode_frame(AVCodecContext *avctx,

                            void *data, int *got_frame,

                            AVPacket *avpkt)

{

    const uint8_t *buf  = avpkt->data;

    int buf_size        = avpkt->size;

    Vp3DecodeContext *s = avctx->priv_data;

    GetBitContext gb;

    int i, ret;

    if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)

        return ret;

#if CONFIG_THEORA_DECODER

    if (s->theora && get_bits1(&gb)) {

        int type = get_bits(&gb, 7);

        skip_bits_long(&gb, 6*8); /* "theora" */

        if (s->avctx->active_thread_type&FF_THREAD_FRAME) {

            av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");

            return AVERROR_PATCHWELCOME;

        }

        if (type == 0) {

            vp3_decode_end(avctx);

            ret = theora_decode_header(avctx, &gb);

            if (ret < 0) {

                vp3_decode_end(avctx);

            } else

                ret = vp3_decode_init(avctx);

            return ret;

        } else if (type == 2) {

            ret = theora_decode_tables(avctx, &gb);

            if (ret < 0) {

                vp3_decode_end(avctx);

            } else

                ret = vp3_decode_init(avctx);

            return ret;

        }

        av_log(avctx, AV_LOG_ERROR,

               "Header packet passed to frame decoder, skipping\n");

        return -1;

    }

#endif

    s->keyframe = !get_bits1(&gb);

    if (!s->all_fragments) {

        av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");

        return -1;

    }

    if (!s->theora)

        skip_bits(&gb, 1);

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

        s->last_qps[i] = s->qps[i];

    s->nqps = 0;

    do {

        s->qps[s->nqps++] = get_bits(&gb, 6);

    } while (s->theora >= 0x030200 && s->nqps < 3 && get_bits1(&gb));

    for (i = s->nqps; i < 3; i++)

        s->qps[i] = -1;

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

        av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n",

               s->keyframe ? "key" : "", avctx->frame_number + 1, s->qps[0]);

    s->skip_loop_filter = !s->filter_limit_values[s->qps[0]] ||

                          avctx->skip_loop_filter >= (s->keyframe ? AVDISCARD_ALL

                                                                  : AVDISCARD_NONKEY);

    if (s->qps[0] != s->last_qps[0])

        init_loop_filter(s);

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

        // reinit all dequantizers if the first one changed, because

        // the DC of the first quantizer must be used for all matrices

        if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])

            init_dequantizer(s, i);

    if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)

        return buf_size;

    s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I

                                                : AV_PICTURE_TYPE_P;

    s->current_frame.f->key_frame = s->keyframe;

    if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0)

        goto error;

    if (!s->edge_emu_buffer)

        s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0]));

    if (s->keyframe) {

        if (!s->theora) {

            skip_bits(&gb, 4); /* width code */

            skip_bits(&gb, 4); /* height code */

            if (s->version) {

                s->version = get_bits(&gb, 5);

                if (avctx->frame_number == 0)

                    av_log(s->avctx, AV_LOG_DEBUG,

                           "VP version: %d\n", s->version);

            }

        }

        if (s->version || s->theora) {

            if (get_bits1(&gb))

                av_log(s->avctx, AV_LOG_ERROR,

                       "Warning, unsupported keyframe coding type?!\n");

            skip_bits(&gb, 2); /* reserved? */

        }

    } else {

        if (!s->golden_frame.f->data[0]) {

            av_log(s->avctx, AV_LOG_WARNING,

                   "vp3: first frame not a keyframe\n");

            s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;

            if (ff_thread_get_buffer(avctx, &s->golden_frame,

                                     AV_GET_BUFFER_FLAG_REF) < 0)

                goto error;

            ff_thread_release_buffer(avctx, &s->last_frame);

            if ((ret = ff_thread_ref_frame(&s->last_frame,

                                           &s->golden_frame)) < 0)

                goto error;

            ff_thread_report_progress(&s->last_frame, INT_MAX, 0);

        }

    }

    memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment));

    ff_thread_finish_setup(avctx);

    if (unpack_superblocks(s, &gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");

        goto error;

    }

    if (unpack_modes(s, &gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");

        goto error;

    }

    if (unpack_vectors(s, &gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");

        goto error;

    }

    if (unpack_block_qpis(s, &gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");

        goto error;

    }

    if (unpack_dct_coeffs(s, &gb)) {

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");

        goto error;

    }

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

        int height = s->height >> (i && s->chroma_y_shift);

        if (s->flipped_image)

            s->data_offset[i] = 0;

        else

            s->data_offset[i] = (height - 1) * s->current_frame.f->linesize[i];

    }

    s->last_slice_end = 0;

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

        render_slice(s, i);

    // filter the last row

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

        int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;

        apply_loop_filter(s, i, row, row + 1);

    }

    vp3_draw_horiz_band(s, s->height);

    /* output frame, offset as needed */

    if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)

        return ret;

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

        AVFrame *dst = data;

        int off = (s->offset_x >> (i && s->chroma_y_shift)) +

                  (s->offset_y >> (i && s->chroma_y_shift)) * dst->linesize[i];

        dst->data[i] += off;

    }

    *got_frame = 1;

    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {

        ret = update_frames(avctx);

        if (ret < 0)

            return ret;

    }

    return buf_size;

error:

    ff_thread_report_progress(&s->current_frame, INT_MAX, 0);

    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME))

        av_frame_unref(s->current_frame.f);

    return -1;

}


static void sysbus_fdc_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->props = sysbus_fdc_properties;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

}


static void gmc_motion(MpegEncContext *s,

                       uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,

                       uint8_t **ref_picture)

{

    uint8_t *ptr;

    int linesize, uvlinesize;

    const int a = s->sprite_warping_accuracy;

    int ox, oy;

    linesize   = s->linesize;

    uvlinesize = s->uvlinesize;

    ptr = ref_picture[0];

    ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +

         s->sprite_delta[0][1] * s->mb_y * 16;

    oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +

         s->sprite_delta[1][1] * s->mb_y * 16;

    s->mdsp.gmc(dest_y, ptr, linesize, 16,

                ox, oy,

                s->sprite_delta[0][0], s->sprite_delta[0][1],

                s->sprite_delta[1][0], s->sprite_delta[1][1],

                a + 1, (1 << (2 * a + 1)) - s->no_rounding,

                s->h_edge_pos, s->v_edge_pos);

    s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,

                ox + s->sprite_delta[0][0] * 8,

                oy + s->sprite_delta[1][0] * 8,

                s->sprite_delta[0][0], s->sprite_delta[0][1],

                s->sprite_delta[1][0], s->sprite_delta[1][1],

                a + 1, (1 << (2 * a + 1)) - s->no_rounding,

                s->h_edge_pos, s->v_edge_pos);

    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)

        return;

    ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +

         s->sprite_delta[0][1] * s->mb_y * 8;

    oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +

         s->sprite_delta[1][1] * s->mb_y * 8;

    ptr = ref_picture[1];

    s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,

                ox, oy,

                s->sprite_delta[0][0], s->sprite_delta[0][1],

                s->sprite_delta[1][0], s->sprite_delta[1][1],

                a + 1, (1 << (2 * a + 1)) - s->no_rounding,

                s->h_edge_pos >> 1, s->v_edge_pos >> 1);

    ptr = ref_picture[2];

    s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,

                ox, oy,

                s->sprite_delta[0][0], s->sprite_delta[0][1],

                s->sprite_delta[1][0], s->sprite_delta[1][1],

                a + 1, (1 << (2 * a + 1)) - s->no_rounding,

                s->h_edge_pos >> 1, s->v_edge_pos >> 1);

}


static av_cold int Faac_encode_init(AVCodecContext *avctx)

{

    FaacAudioContext *s = avctx->priv_data;

    faacEncConfigurationPtr faac_cfg;

    unsigned long samples_input, max_bytes_output;

    /* number of channels */

    if (avctx->channels < 1 || avctx->channels > 6)

        return -1;

    s->faac_handle = faacEncOpen(avctx->sample_rate,

                                 avctx->channels,

                                 &samples_input, &max_bytes_output);

    /* check faac version */

    faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle);

    if (faac_cfg->version != FAAC_CFG_VERSION) {

        av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version);

        faacEncClose(s->faac_handle);

        return -1;

    }

    /* put the options in the configuration struct */

    switch(avctx->profile) {

        case FF_PROFILE_AAC_MAIN:

            faac_cfg->aacObjectType = MAIN;

            break;

        case FF_PROFILE_UNKNOWN:

        case FF_PROFILE_AAC_LOW:

            faac_cfg->aacObjectType = LOW;

            break;

        case FF_PROFILE_AAC_SSR:

            faac_cfg->aacObjectType = SSR;

            break;

        case FF_PROFILE_AAC_LTP:

            faac_cfg->aacObjectType = LTP;

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n");

            faacEncClose(s->faac_handle);

            return -1;

    }

    faac_cfg->mpegVersion = MPEG4;

    faac_cfg->useTns = 0;

    faac_cfg->allowMidside = 1;

    faac_cfg->bitRate = avctx->bit_rate / avctx->channels;

    faac_cfg->bandWidth = avctx->cutoff;

    if(avctx->flags & CODEC_FLAG_QSCALE) {

        faac_cfg->bitRate = 0;

        faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA;

    }

    faac_cfg->outputFormat = 1;

    faac_cfg->inputFormat = FAAC_INPUT_16BIT;

    avctx->frame_size = samples_input / avctx->channels;

    avctx->coded_frame= avcodec_alloc_frame();

    avctx->coded_frame->key_frame= 1;

    /* Set decoder specific info */

    avctx->extradata_size = 0;

    if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {

        unsigned char *buffer = NULL;

        unsigned long decoder_specific_info_size;

        if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer,

                                           &decoder_specific_info_size)) {

            avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);

            avctx->extradata_size = decoder_specific_info_size;

            memcpy(avctx->extradata, buffer, avctx->extradata_size);

            faac_cfg->outputFormat = 0;

        }

#undef free

        free(buffer);

#define free please_use_av_free

    }

    if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {

        av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");

        return -1;

    }

    return 0;

}


av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)

{

    int n = 1 << nbits;

    int i;

    s->nbits    = nbits;

    s->inverse  = inverse;

    ff_init_ff_cos_tabs(nbits+2);

    s->costab = ff_cos_tabs[nbits+2];

    s->csc2 = av_malloc(n/2 * sizeof(FFTSample));

    if (ff_rdft_init(&s->rdft, nbits, inverse == DCT_III) < 0) {

        av_free(s->csc2);

        return -1;

    }

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

        s->csc2[i] = 0.5 / sin((M_PI / (2*n) * (2*i + 1)));

    switch(inverse) {

    case DCT_I  : s->dct_calc = ff_dct_calc_I_c; break;

    case DCT_II : s->dct_calc = ff_dct_calc_II_c ; break;

    case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;

    case DST_I  : s->dct_calc = ff_dst_calc_I_c; break;

    }

    if (inverse == DCT_II && nbits == 5)

        s->dct_calc = dct32_func;

    s->dct32 = dct32;

    if (HAVE_MMX)     ff_dct_init_mmx(s);

    return 0;

}


static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

    AVStream *st = c->fc->streams[c->fc->nb_streams-1];

    MOVStreamContext *sc = st->priv_data;

    int version = get_byte(pb);

    char language[4] = {0};

    unsigned lang;

    if (version > 1)

        return -1; /* unsupported */

    get_be24(pb); /* flags */

    if (version == 1) {

        get_be64(pb);

        get_be64(pb);

    } else {

        get_be32(pb); /* creation time */

        get_be32(pb); /* modification time */

    }

    sc->time_scale = get_be32(pb);

    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */

    lang = get_be16(pb); /* language */

    if (ff_mov_lang_to_iso639(lang, language))

        av_metadata_set(&st->metadata, "language", language);

    get_be16(pb); /* quality */

    return 0;

}