static int initFilter(int16_t **outFilter, int32_t **filterPos,

                      int *outFilterSize, int xInc, int srcW, int dstW,

                      int filterAlign, int one, int flags, int cpu_flags,

                      SwsVector *srcFilter, SwsVector *dstFilter,

                      double param[2], int is_horizontal)

{

    int i;

    int filterSize;

    int filter2Size;

    int minFilterSize;

    int64_t *filter    = NULL;

    int64_t *filter2   = NULL;

    const int64_t fone = 1LL << 54;

    int ret            = -1;

    emms_c(); // FIXME should not be required but IS (even for non-MMX versions)

    // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end

    FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW + 3) * sizeof(**filterPos), fail);

    if (FFABS(xInc - 0x10000) < 10) { // unscaled

        int i;

        filterSize = 1;

        FF_ALLOCZ_OR_GOTO(NULL, filter,

                          dstW * sizeof(*filter) * filterSize, fail);

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

            filter[i * filterSize] = fone;

            (*filterPos)[i]        = i;

        }

    } else if (flags & SWS_POINT) { // lame looking point sampling mode

        int i;

        int xDstInSrc;

        filterSize = 1;

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = xInc / 2 - 0x8000;

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

            int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;

            (*filterPos)[i] = xx;

            filter[i]       = fone;

            xDstInSrc      += xInc;

        }

    } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||

               (flags & SWS_FAST_BILINEAR)) { // bilinear upscale

        int i;

        int xDstInSrc;

        filterSize = 2;

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = xInc / 2 - 0x8000;

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

            int xx = (xDstInSrc - ((filterSize - 1) << 15) + (1 << 15)) >> 16;

            int j;

            (*filterPos)[i] = xx;

            // bilinear upscale / linear interpolate / area averaging

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

                int64_t coeff = fone - FFABS((xx << 16) - xDstInSrc) *

                                (fone >> 16);

                if (coeff < 0)

                    coeff = 0;

                filter[i * filterSize + j] = coeff;

                xx++;

            }

            xDstInSrc += xInc;

        }

    } else {

        int64_t xDstInSrc;

        int sizeFactor;

        if (flags & SWS_BICUBIC)

            sizeFactor = 4;

        else if (flags & SWS_X)

            sizeFactor = 8;

        else if (flags & SWS_AREA)

            sizeFactor = 1;     // downscale only, for upscale it is bilinear

        else if (flags & SWS_GAUSS)

            sizeFactor = 8;     // infinite ;)

        else if (flags & SWS_LANCZOS)

            sizeFactor = param[0] != SWS_PARAM_DEFAULT ? ceil(2 * param[0]) : 6;

        else if (flags & SWS_SINC)

            sizeFactor = 20;    // infinite ;)

        else if (flags & SWS_SPLINE)

            sizeFactor = 20;    // infinite ;)

        else if (flags & SWS_BILINEAR)

            sizeFactor = 2;

        else {

            sizeFactor = 0;     // GCC warning killer

            assert(0);

        }

        if (xInc <= 1 << 16)

            filterSize = 1 + sizeFactor;    // upscale

        else

            filterSize = 1 + (sizeFactor * srcW + dstW - 1) / dstW;

        filterSize = FFMIN(filterSize, srcW - 2);

        filterSize = FFMAX(filterSize, 1);

        FF_ALLOC_OR_GOTO(NULL, filter,

                         dstW * sizeof(*filter) * filterSize, fail);

        xDstInSrc = xInc - 0x10000;

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

            int xx = (xDstInSrc - ((filterSize - 2) << 16)) / (1 << 17);

            int j;

            (*filterPos)[i] = xx;

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

                int64_t d = (FFABS(((int64_t)xx << 17) - xDstInSrc)) << 13;

                double floatd;

                int64_t coeff;

                if (xInc > 1 << 16)

                    d = d * dstW / srcW;

                floatd = d * (1.0 / (1 << 30));

                if (flags & SWS_BICUBIC) {

                    int64_t B = (param[0] != SWS_PARAM_DEFAULT ? param[0] :   0) * (1 << 24);

                    int64_t C = (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1 << 24);

                    if (d >= 1LL << 31) {

                        coeff = 0.0;

                    } else {

                        int64_t dd  = (d  * d) >> 30;

                        int64_t ddd = (dd * d) >> 30;

                        if (d < 1LL << 30)

                            coeff =  (12 * (1 << 24) -  9 * B - 6 * C) * ddd +

                                    (-18 * (1 << 24) + 12 * B + 6 * C) *  dd +

                                      (6 * (1 << 24) -  2 * B)         * (1 << 30);

                        else

                            coeff =      (-B -  6 * C) * ddd +

                                      (6 * B + 30 * C) * dd  +

                                    (-12 * B - 48 * C) * d   +

                                      (8 * B + 24 * C) * (1 << 30);

                    }

                    coeff *= fone >> (30 + 24);

                }

#if 0

                else if (flags & SWS_X) {

                    double p  = param ? param * 0.01 : 0.3;

                    coeff     = d ? sin(d * M_PI) / (d * M_PI) : 1.0;

                    coeff    *= pow(2.0, -p * d * d);

                }

#endif

                else if (flags & SWS_X) {

                    double A = param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0;

                    double c;

                    if (floatd < 1.0)

                        c = cos(floatd * M_PI);

                    else

                        c = -1.0;

                    if (c < 0.0)

                        c = -pow(-c, A);

                    else

                        c = pow(c, A);

                    coeff = (c * 0.5 + 0.5) * fone;

                } else if (flags & SWS_AREA) {

                    int64_t d2 = d - (1 << 29);

                    if (d2 * xInc < -(1LL << (29 + 16)))

                        coeff = 1.0 * (1LL << (30 + 16));

                    else if (d2 * xInc < (1LL << (29 + 16)))

                        coeff = -d2 * xInc + (1LL << (29 + 16));

                    else

                        coeff = 0.0;

                    coeff *= fone >> (30 + 16);

                } else if (flags & SWS_GAUSS) {

                    double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;

                    coeff = (pow(2.0, -p * floatd * floatd)) * fone;

                } else if (flags & SWS_SINC) {

                    coeff = (d ? sin(floatd * M_PI) / (floatd * M_PI) : 1.0) * fone;

                } else if (flags & SWS_LANCZOS) {

                    double p = param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0;

                    coeff = (d ? sin(floatd * M_PI) * sin(floatd * M_PI / p) /

                             (floatd * floatd * M_PI * M_PI / p) : 1.0) * fone;

                    if (floatd > p)

                        coeff = 0;

                } else if (flags & SWS_BILINEAR) {

                    coeff = (1 << 30) - d;

                    if (coeff < 0)

                        coeff = 0;

                    coeff *= fone >> 30;

                } else if (flags & SWS_SPLINE) {

                    double p = -2.196152422706632;

                    coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;

                } else {

                    coeff = 0.0; // GCC warning killer

                    assert(0);

                }

                filter[i * filterSize + j] = coeff;

                xx++;

            }

            xDstInSrc += 2 * xInc;

        }

    }

    /* apply src & dst Filter to filter -> filter2

     * av_free(filter);

     */

    assert(filterSize > 0);

    filter2Size = filterSize;

    if (srcFilter)

        filter2Size += srcFilter->length - 1;

    if (dstFilter)

        filter2Size += dstFilter->length - 1;

    assert(filter2Size > 0);

    FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size * dstW * sizeof(*filter2), fail);

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

        int j, k;

        if (srcFilter) {

            for (k = 0; k < srcFilter->length; k++) {

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

                    filter2[i * filter2Size + k + j] +=

                        srcFilter->coeff[k] * filter[i * filterSize + j];

            }

        } else {

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

                filter2[i * filter2Size + j] = filter[i * filterSize + j];

        }

        // FIXME dstFilter

        (*filterPos)[i] += (filterSize - 1) / 2 - (filter2Size - 1) / 2;

    }

    av_freep(&filter);

    /* try to reduce the filter-size (step1 find size and shift left) */

    // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not).

    minFilterSize = 0;

    for (i = dstW - 1; i >= 0; i--) {

        int min = filter2Size;

        int j;

        int64_t cutOff = 0.0;

        /* get rid of near zero elements on the left by shifting left */

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

            int k;

            cutOff += FFABS(filter2[i * filter2Size]);

            if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)

                break;

            /* preserve monotonicity because the core can't handle the

             * filter otherwise */

            if (i < dstW - 1 && (*filterPos)[i] >= (*filterPos)[i + 1])

                break;

            // move filter coefficients left

            for (k = 1; k < filter2Size; k++)

                filter2[i * filter2Size + k - 1] = filter2[i * filter2Size + k];

            filter2[i * filter2Size + k - 1] = 0;

            (*filterPos)[i]++;

        }

        cutOff = 0;

        /* count near zeros on the right */

        for (j = filter2Size - 1; j > 0; j--) {

            cutOff += FFABS(filter2[i * filter2Size + j]);

            if (cutOff > SWS_MAX_REDUCE_CUTOFF * fone)

                break;

            min--;

        }

        if (min > minFilterSize)

            minFilterSize = min;

    }

    if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) {

        // we can handle the special case 4, so we don't want to go the full 8

        if (minFilterSize < 5)

            filterAlign = 4;

        /* We really don't want to waste our time doing useless computation, so

         * fall back on the scalar C code for very small filters.

         * Vectorizing is worth it only if you have a decent-sized vector. */

        if (minFilterSize < 3)

            filterAlign = 1;

    }

    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {

        // special case for unscaled vertical filtering

        if (minFilterSize == 1 && filterAlign == 2)

            filterAlign = 1;

    }

    assert(minFilterSize > 0);

    filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));

    assert(filterSize > 0);

    filter = av_malloc(filterSize * dstW * sizeof(*filter));

    if (filterSize >= MAX_FILTER_SIZE * 16 /

                      ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter)

        goto fail;

    *outFilterSize = filterSize;

    if (flags & SWS_PRINT_INFO)

        av_log(NULL, AV_LOG_VERBOSE,

               "SwScaler: reducing / aligning filtersize %d -> %d\n",

               filter2Size, filterSize);

    /* try to reduce the filter-size (step2 reduce it) */

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

        int j;

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

            if (j >= filter2Size)

                filter[i * filterSize + j] = 0;

            else

                filter[i * filterSize + j] = filter2[i * filter2Size + j];

            if ((flags & SWS_BITEXACT) && j >= minFilterSize)

                filter[i * filterSize + j] = 0;

        }

    }

    // FIXME try to align filterPos if possible

    // fix borders

    if (is_horizontal) {

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

            int j;

            if ((*filterPos)[i] < 0) {

                // move filter coefficients left to compensate for filterPos

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

                    int left = FFMAX(j + (*filterPos)[i], 0);

                    filter[i * filterSize + left] += filter[i * filterSize + j];

                    filter[i * filterSize + j]     = 0;

                }

                (*filterPos)[i] = 0;

            }

            if ((*filterPos)[i] + filterSize > srcW) {

                int shift = (*filterPos)[i] + filterSize - srcW;

                // move filter coefficients right to compensate for filterPos

                for (j = filterSize - 2; j >= 0; j--) {

                    int right = FFMIN(j + shift, filterSize - 1);

                    filter[i * filterSize + right] += filter[i * filterSize + j];

                    filter[i * filterSize + j]      = 0;

                }

                (*filterPos)[i] = srcW - filterSize;

            }

        }

    }

    // Note the +1 is for the MMX scaler which reads over the end

    /* align at 16 for AltiVec (needed by hScale_altivec_real) */

    FF_ALLOCZ_OR_GOTO(NULL, *outFilter,

                      *outFilterSize * (dstW + 3) * sizeof(int16_t), fail);

    /* normalize & store in outFilter */

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

        int j;

        int64_t error = 0;

        int64_t sum   = 0;

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

            sum += filter[i * filterSize + j];

        }

        sum = (sum + one / 2) / one;

        for (j = 0; j < *outFilterSize; j++) {

            int64_t v = filter[i * filterSize + j] + error;

            int intV  = ROUNDED_DIV(v, sum);

            (*outFilter)[i * (*outFilterSize) + j] = intV;

            error                                  = v - intV * sum;

        }

    }

    (*filterPos)[dstW + 0] =

    (*filterPos)[dstW + 1] =

    (*filterPos)[dstW + 2] = (*filterPos)[dstW - 1]; /* the MMX/SSE scaler will

                                                      * read over the end */

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

        int k = (dstW - 1) * (*outFilterSize) + i;

        (*outFilter)[k + 1 * (*outFilterSize)] =

        (*outFilter)[k + 2 * (*outFilterSize)] =

        (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k];

    }

    ret = 0;

fail:

    av_free(filter);

    av_free(filter2);

    return ret;

}


static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)[32][2], int is34)

{

    int e, b, k;

    INTFLOAT (*H11)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H11;

    INTFLOAT (*H12)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H12;

    INTFLOAT (*H21)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H21;

    INTFLOAT (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;

    int8_t *opd_hist = ps->opd_hist;

    int8_t *ipd_hist = ps->ipd_hist;

    int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];

    int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf;

    int8_t (*icc_mapped)[PS_MAX_NR_IIDICC] = icc_mapped_buf;

    int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf;

    int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf;

    const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;

    TABLE_CONST INTFLOAT (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;

    //Remapping

    if (ps->num_env_old) {

        memcpy(H11[0][0], H11[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[0][0][0]));

        memcpy(H11[1][0], H11[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H11[1][0][0]));

        memcpy(H12[0][0], H12[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[0][0][0]));

        memcpy(H12[1][0], H12[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H12[1][0][0]));

        memcpy(H21[0][0], H21[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[0][0][0]));

        memcpy(H21[1][0], H21[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H21[1][0][0]));

        memcpy(H22[0][0], H22[0][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[0][0][0]));

        memcpy(H22[1][0], H22[1][ps->num_env_old], PS_MAX_NR_IIDICC*sizeof(H22[1][0][0]));

    }

    if (is34) {

        remap34(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1);

        remap34(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1);

        if (ps->enable_ipdopd) {

            remap34(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0);

            remap34(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0);

        }

        if (!ps->is34bands_old) {

            map_val_20_to_34(H11[0][0]);

            map_val_20_to_34(H11[1][0]);

            map_val_20_to_34(H12[0][0]);

            map_val_20_to_34(H12[1][0]);

            map_val_20_to_34(H21[0][0]);

            map_val_20_to_34(H21[1][0]);

            map_val_20_to_34(H22[0][0]);

            map_val_20_to_34(H22[1][0]);

            ipdopd_reset(ipd_hist, opd_hist);

        }

    } else {

        remap20(&iid_mapped, ps->iid_par, ps->nr_iid_par, ps->num_env, 1);

        remap20(&icc_mapped, ps->icc_par, ps->nr_icc_par, ps->num_env, 1);

        if (ps->enable_ipdopd) {

            remap20(&ipd_mapped, ps->ipd_par, ps->nr_ipdopd_par, ps->num_env, 0);

            remap20(&opd_mapped, ps->opd_par, ps->nr_ipdopd_par, ps->num_env, 0);

        }

        if (ps->is34bands_old) {

            map_val_34_to_20(H11[0][0]);

            map_val_34_to_20(H11[1][0]);

            map_val_34_to_20(H12[0][0]);

            map_val_34_to_20(H12[1][0]);

            map_val_34_to_20(H21[0][0]);

            map_val_34_to_20(H21[1][0]);

            map_val_34_to_20(H22[0][0]);

            map_val_34_to_20(H22[1][0]);

            ipdopd_reset(ipd_hist, opd_hist);

        }

    }

    //Mixing

    for (e = 0; e < ps->num_env; e++) {

        for (b = 0; b < NR_PAR_BANDS[is34]; b++) {

            INTFLOAT h11, h12, h21, h22;

            h11 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][0];

            h12 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][1];

            h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2];

            h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3];

            if (!PS_BASELINE && ps->enable_ipdopd && b < NR_IPDOPD_BANDS[is34]) {

                //The spec say says to only run this smoother when enable_ipdopd

                //is set but the reference decoder appears to run it constantly

                INTFLOAT h11i, h12i, h21i, h22i;

                INTFLOAT ipd_adj_re, ipd_adj_im;

                int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b];

                int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b];

                INTFLOAT opd_re = pd_re_smooth[opd_idx];

                INTFLOAT opd_im = pd_im_smooth[opd_idx];

                INTFLOAT ipd_re = pd_re_smooth[ipd_idx];

                INTFLOAT ipd_im = pd_im_smooth[ipd_idx];

                opd_hist[b] = opd_idx & 0x3F;

                ipd_hist[b] = ipd_idx & 0x3F;

                ipd_adj_re = AAC_MADD30(opd_re, ipd_re, opd_im, ipd_im);

                ipd_adj_im = AAC_MSUB30(opd_im, ipd_re, opd_re, ipd_im);

                h11i = AAC_MUL30(h11,  opd_im);

                h11  = AAC_MUL30(h11,  opd_re);

                h12i = AAC_MUL30(h12,  ipd_adj_im);

                h12  = AAC_MUL30(h12,  ipd_adj_re);

                h21i = AAC_MUL30(h21,  opd_im);

                h21  = AAC_MUL30(h21,  opd_re);

                h22i = AAC_MUL30(h22,  ipd_adj_im);

                h22  = AAC_MUL30(h22,  ipd_adj_re);

                H11[1][e+1][b] = h11i;

                H12[1][e+1][b] = h12i;

                H21[1][e+1][b] = h21i;

                H22[1][e+1][b] = h22i;

            }

            H11[0][e+1][b] = h11;

            H12[0][e+1][b] = h12;

            H21[0][e+1][b] = h21;

            H22[0][e+1][b] = h22;

        }

        for (k = 0; k < NR_BANDS[is34]; k++) {

            LOCAL_ALIGNED_16(INTFLOAT, h, [2], [4]);

            LOCAL_ALIGNED_16(INTFLOAT, h_step, [2], [4]);

            int start = ps->border_position[e];

            int stop  = ps->border_position[e+1];

            INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1);

#if USE_FIXED

            width = FFMIN(2U*width, INT_MAX);

#endif

            b = k_to_i[k];

            h[0][0] = H11[0][e][b];

            h[0][1] = H12[0][e][b];

            h[0][2] = H21[0][e][b];

            h[0][3] = H22[0][e][b];

            if (!PS_BASELINE && ps->enable_ipdopd) {

            //Is this necessary? ps_04_new seems unchanged

            if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) {

                h[1][0] = -H11[1][e][b];

                h[1][1] = -H12[1][e][b];

                h[1][2] = -H21[1][e][b];

                h[1][3] = -H22[1][e][b];

            } else {

                h[1][0] = H11[1][e][b];

                h[1][1] = H12[1][e][b];

                h[1][2] = H21[1][e][b];

                h[1][3] = H22[1][e][b];

            }

            }

            //Interpolation

            h_step[0][0] = AAC_MSUB31_V3(H11[0][e+1][b], h[0][0], width);

            h_step[0][1] = AAC_MSUB31_V3(H12[0][e+1][b], h[0][1], width);

            h_step[0][2] = AAC_MSUB31_V3(H21[0][e+1][b], h[0][2], width);

            h_step[0][3] = AAC_MSUB31_V3(H22[0][e+1][b], h[0][3], width);

            if (!PS_BASELINE && ps->enable_ipdopd) {

                h_step[1][0] = AAC_MSUB31_V3(H11[1][e+1][b], h[1][0], width);

                h_step[1][1] = AAC_MSUB31_V3(H12[1][e+1][b], h[1][1], width);

                h_step[1][2] = AAC_MSUB31_V3(H21[1][e+1][b], h[1][2], width);

                h_step[1][3] = AAC_MSUB31_V3(H22[1][e+1][b], h[1][3], width);

            }

            ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](

                l[k] + 1 + start, r[k] + 1 + start,

                h, h_step, stop - start);

        }

    }

}


int coroutine_fn bdrv_co_preadv(BlockDriverState *bs,

    int64_t offset, unsigned int bytes, QEMUIOVector *qiov,

    BdrvRequestFlags flags)

{

    BlockDriver *drv = bs->drv;

    BdrvTrackedRequest req;

    uint64_t align = bs->request_alignment;

    uint8_t *head_buf = NULL;

    uint8_t *tail_buf = NULL;

    QEMUIOVector local_qiov;

    bool use_local_qiov = false;

    int ret;

    if (!drv) {

        return -ENOMEDIUM;

    }

    ret = bdrv_check_byte_request(bs, offset, bytes);

    if (ret < 0) {

        return ret;

    }

    /* Don't do copy-on-read if we read data before write operation */

    if (bs->copy_on_read && !(flags & BDRV_REQ_NO_SERIALISING)) {

        flags |= BDRV_REQ_COPY_ON_READ;

    }

    /* Align read if necessary by padding qiov */

    if (offset & (align - 1)) {

        head_buf = qemu_blockalign(bs, align);

        qemu_iovec_init(&local_qiov, qiov->niov + 2);

        qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1));

        qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);

        use_local_qiov = true;

        bytes += offset & (align - 1);

        offset = offset & ~(align - 1);

    }

    if ((offset + bytes) & (align - 1)) {

        if (!use_local_qiov) {

            qemu_iovec_init(&local_qiov, qiov->niov + 1);

            qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);

            use_local_qiov = true;

        }

        tail_buf = qemu_blockalign(bs, align);

        qemu_iovec_add(&local_qiov, tail_buf,

                       align - ((offset + bytes) & (align - 1)));

        bytes = ROUND_UP(bytes, align);

    }

    tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ);

    ret = bdrv_aligned_preadv(bs, &req, offset, bytes, align,

                              use_local_qiov ? &local_qiov : qiov,

                              flags);

    tracked_request_end(&req);

    if (use_local_qiov) {

        qemu_iovec_destroy(&local_qiov);

        qemu_vfree(head_buf);

        qemu_vfree(tail_buf);

    }

    return ret;

}


static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg,

                                  bool msix)

{

    int virq;

    if ((msix && !VFIO_ALLOW_KVM_MSIX) ||

        (!msix && !VFIO_ALLOW_KVM_MSI) || !msg) {

        return;

    }

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

        return;

    }

    virq = kvm_irqchip_add_msi_route(kvm_state, *msg);

    if (virq < 0) {

        event_notifier_cleanup(&vector->kvm_interrupt);

        return;

    }

    if (kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt,

                                       NULL, virq) < 0) {

        kvm_irqchip_release_virq(kvm_state, virq);

        event_notifier_cleanup(&vector->kvm_interrupt);

        return;

    }

    vector->virq = virq;

}


void bios_linker_loader_add_pointer(BIOSLinker *linker,

                                    const char *dest_file,

                                    const char *src_file,

                                    void *pointer,

                                    uint8_t pointer_size)

{

    BiosLinkerLoaderEntry entry;

    const BiosLinkerFileEntry *file = bios_linker_find_file(linker, dest_file);

    ptrdiff_t offset = (gchar *)pointer - file->blob->data;

    assert(offset >= 0);

    assert(offset + pointer_size <= file->blob->len);

    memset(&entry, 0, sizeof entry);

    strncpy(entry.pointer.dest_file, dest_file,

            sizeof entry.pointer.dest_file - 1);

    strncpy(entry.pointer.src_file, src_file,

            sizeof entry.pointer.src_file - 1);

    entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);

    entry.pointer.offset = cpu_to_le32(offset);

    entry.pointer.size = pointer_size;

    assert(pointer_size == 1 || pointer_size == 2 ||

           pointer_size == 4 || pointer_size == 8);

    g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);

}


yuv2yuvX_altivec_real(SwsContext *c,

                      const int16_t *lumFilter, const int16_t **lumSrc,

                      int lumFilterSize, const int16_t *chrFilter,

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

                      int chrFilterSize, const int16_t **alpSrc,

                      uint8_t *dest, uint8_t *uDest,

                      uint8_t *vDest, uint8_t *aDest,

                      int dstW, int chrDstW)

{

    const vector signed int vini = {(1 << 18), (1 << 18), (1 << 18), (1 << 18)};

    register int i, j;

    {

        DECLARE_ALIGNED(16, int, val)[dstW];

        for (i = 0; i < (dstW -7); i+=4) {

            vec_st(vini, i << 2, val);

        }

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

            val[i] = (1 << 18);

        }

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

            vector signed short l1, vLumFilter = vec_ld(j << 1, lumFilter);

            vector unsigned char perm, perm0 = vec_lvsl(j << 1, lumFilter);

            vLumFilter = vec_perm(vLumFilter, vLumFilter, perm0);

            vLumFilter = vec_splat(vLumFilter, 0); // lumFilter[j] is loaded 8 times in vLumFilter

            perm = vec_lvsl(0, lumSrc[j]);

            l1 = vec_ld(0, lumSrc[j]);

            for (i = 0; i < (dstW - 7); i+=8) {

                int offset = i << 2;

                vector signed short l2 = vec_ld((i << 1) + 16, lumSrc[j]);

                vector signed int v1 = vec_ld(offset, val);

                vector signed int v2 = vec_ld(offset + 16, val);

                vector signed short ls = vec_perm(l1, l2, perm); // lumSrc[j][i] ... lumSrc[j][i+7]

                vector signed int i1 = vec_mule(vLumFilter, ls);

                vector signed int i2 = vec_mulo(vLumFilter, ls);

                vector signed int vf1 = vec_mergeh(i1, i2);

                vector signed int vf2 = vec_mergel(i1, i2); // lumSrc[j][i] * lumFilter[j] ... lumSrc[j][i+7] * lumFilter[j]

                vector signed int vo1 = vec_add(v1, vf1);

                vector signed int vo2 = vec_add(v2, vf2);

                vec_st(vo1, offset, val);

                vec_st(vo2, offset + 16, val);

                l1 = l2;

            }

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

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

            }

        }

        altivec_packIntArrayToCharArray(val, dest, dstW);

    }

    if (uDest != 0) {

        DECLARE_ALIGNED(16, int, u)[chrDstW];

        DECLARE_ALIGNED(16, int, v)[chrDstW];

        for (i = 0; i < (chrDstW -7); i+=4) {

            vec_st(vini, i << 2, u);

            vec_st(vini, i << 2, v);

        }

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

            u[i] = (1 << 18);

            v[i] = (1 << 18);

        }

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

            vector signed short l1, l1_V, vChrFilter = vec_ld(j << 1, chrFilter);

            vector unsigned char perm, perm0 = vec_lvsl(j << 1, chrFilter);

            vChrFilter = vec_perm(vChrFilter, vChrFilter, perm0);

            vChrFilter = vec_splat(vChrFilter, 0); // chrFilter[j] is loaded 8 times in vChrFilter

            perm = vec_lvsl(0, chrUSrc[j]);

            l1 = vec_ld(0, chrUSrc[j]);

            l1_V = vec_ld(0, chrVSrc[j]);

            for (i = 0; i < (chrDstW - 7); i+=8) {

                int offset = i << 2;

                vector signed short l2 = vec_ld((i << 1) + 16, chrUSrc[j]);

                vector signed short l2_V = vec_ld((i << 1) + 16, chrVSrc[j]);

                vector signed int v1 = vec_ld(offset, u);

                vector signed int v2 = vec_ld(offset + 16, u);

                vector signed int v1_V = vec_ld(offset, v);

                vector signed int v2_V = vec_ld(offset + 16, v);

                vector signed short ls = vec_perm(l1, l2, perm); // chrUSrc[j][i] ... chrUSrc[j][i+7]

                vector signed short ls_V = vec_perm(l1_V, l2_V, perm); // chrVSrc[j][i] ... chrVSrc[j][i]

                vector signed int i1 = vec_mule(vChrFilter, ls);

                vector signed int i2 = vec_mulo(vChrFilter, ls);

                vector signed int i1_V = vec_mule(vChrFilter, ls_V);

                vector signed int i2_V = vec_mulo(vChrFilter, ls_V);

                vector signed int vf1 = vec_mergeh(i1, i2);

                vector signed int vf2 = vec_mergel(i1, i2); // chrUSrc[j][i] * chrFilter[j] ... chrUSrc[j][i+7] * chrFilter[j]

                vector signed int vf1_V = vec_mergeh(i1_V, i2_V);

                vector signed int vf2_V = vec_mergel(i1_V, i2_V); // chrVSrc[j][i] * chrFilter[j] ... chrVSrc[j][i+7] * chrFilter[j]

                vector signed int vo1 = vec_add(v1, vf1);

                vector signed int vo2 = vec_add(v2, vf2);

                vector signed int vo1_V = vec_add(v1_V, vf1_V);

                vector signed int vo2_V = vec_add(v2_V, vf2_V);

                vec_st(vo1, offset, u);

                vec_st(vo2, offset + 16, u);

                vec_st(vo1_V, offset, v);

                vec_st(vo2_V, offset + 16, v);

                l1 = l2;

                l1_V = l2_V;

            }

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

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

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

            }

        }

        altivec_packIntArrayToCharArray(u, uDest, chrDstW);

        altivec_packIntArrayToCharArray(v, vDest, chrDstW);

    }

}


static int fmod_init_out (HWVoiceOut *hw, audsettings_t *as)

{

    int bits16, mode, channel;

    FMODVoiceOut *fmd = (FMODVoiceOut *) hw;

    audsettings_t obt_as = *as;

    mode = aud_to_fmodfmt (as->fmt, as->nchannels == 2 ? 1 : 0);

    fmd->fmod_sample = FSOUND_Sample_Alloc (

        FSOUND_FREE,            /* index */

        conf.nb_samples,        /* length */

        mode,                   /* mode */

        as->freq,               /* freq */

        255,                    /* volume */

        128,                    /* pan */

        255                     /* priority */

        );

    if (!fmd->fmod_sample) {

        fmod_logerr2 ("DAC", "Failed to allocate FMOD sample\n");

        return -1;

    }

    channel = FSOUND_PlaySoundEx (FSOUND_FREE, fmd->fmod_sample, 0, 1);

    if (channel < 0) {

        fmod_logerr2 ("DAC", "Failed to start playing sound\n");

        FSOUND_Sample_Free (fmd->fmod_sample);

        return -1;

    }

    fmd->channel = channel;

    /* FMOD always operates on little endian frames? */

    obt_as.endianness = 0;

    audio_pcm_init_info (&hw->info, &obt_as);

    bits16 = (mode & FSOUND_16BITS) != 0;

    hw->samples = conf.nb_samples;

    return 0;

}


void blk_dev_change_media_cb(BlockBackend *blk, bool load)

{

    if (blk->dev_ops && blk->dev_ops->change_media_cb) {

        bool tray_was_closed = !blk_dev_is_tray_open(blk);

        blk->dev_ops->change_media_cb(blk->dev_opaque, load);

        if (tray_was_closed) {

            /* tray open */

            qapi_event_send_device_tray_moved(blk_name(blk),

                                              true, &error_abort);

        }

        if (load) {

            /* tray close */

            qapi_event_send_device_tray_moved(blk_name(blk),

                                              false, &error_abort);

        }

    }

}


static void chr_read(void *opaque, const void *buf, size_t size)

{

    VirtIORNG *vrng = opaque;

    size_t len;

    int offset;

    if (!is_guest_ready(vrng)) {

        return;

    }

    offset = 0;

    while (offset < size) {

        if (!pop_an_elem(vrng)) {

            break;

        }

        len = iov_from_buf(vrng->elem.in_sg, vrng->elem.in_num,

                           0, buf + offset, size - offset);

        offset += len;

        virtqueue_push(vrng->vq, &vrng->elem, len);

        vrng->popped = false;

    }

    virtio_notify(&vrng->vdev, vrng->vq);

    /*

     * Lastly, if we had multiple elems queued by the guest, and we

     * didn't have enough data to fill them all, indicate we want more

     * data.

     */

    len = pop_an_elem(vrng);

    if (len) {

        rng_backend_request_entropy(vrng->rng, size, chr_read, vrng);

    }

}


void cpu_loop(CPUX86State *env)

{

    CPUState *cs = CPU(x86_env_get_cpu(env));

    int trapnr;

    abi_ulong pc;

    target_siginfo_t info;

    for(;;) {

        cpu_exec_start(cs);

        trapnr = cpu_x86_exec(cs);

        cpu_exec_end(cs);

        switch(trapnr) {

        case 0x80:

            /* linux syscall from int $0x80 */

            env->regs[R_EAX] = do_syscall(env,

                                          env->regs[R_EAX],

                                          env->regs[R_EBX],

                                          env->regs[R_ECX],

                                          env->regs[R_EDX],

                                          env->regs[R_ESI],

                                          env->regs[R_EDI],

                                          env->regs[R_EBP],

                                          0, 0);

            break;

#ifndef TARGET_ABI32

        case EXCP_SYSCALL:

            /* linux syscall from syscall instruction */

            env->regs[R_EAX] = do_syscall(env,

                                          env->regs[R_EAX],

                                          env->regs[R_EDI],

                                          env->regs[R_ESI],

                                          env->regs[R_EDX],

                                          env->regs[10],

                                          env->regs[8],

                                          env->regs[9],

                                          0, 0);

            break;

#endif

        case EXCP0B_NOSEG:

        case EXCP0C_STACK:

            info.si_signo = TARGET_SIGBUS;

            info.si_errno = 0;

            info.si_code = TARGET_SI_KERNEL;

            info._sifields._sigfault._addr = 0;

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP0D_GPF:

            /* XXX: potential problem if ABI32 */

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_fault(env);

            } else

#endif

            {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SI_KERNEL;

                info._sifields._sigfault._addr = 0;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP0E_PAGE:

            info.si_signo = TARGET_SIGSEGV;

            info.si_errno = 0;

            if (!(env->error_code & 1))

                info.si_code = TARGET_SEGV_MAPERR;

            else

                info.si_code = TARGET_SEGV_ACCERR;

            info._sifields._sigfault._addr = env->cr[2];

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP00_DIVZ:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                /* division by zero */

                info.si_signo = TARGET_SIGFPE;

                info.si_errno = 0;

                info.si_code = TARGET_FPE_INTDIV;

                info._sifields._sigfault._addr = env->eip;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP01_DB:

        case EXCP03_INT3:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                info.si_signo = TARGET_SIGTRAP;

                info.si_errno = 0;

                if (trapnr == EXCP01_DB) {

                    info.si_code = TARGET_TRAP_BRKPT;

                    info._sifields._sigfault._addr = env->eip;

                } else {

                    info.si_code = TARGET_SI_KERNEL;

                    info._sifields._sigfault._addr = 0;

                }

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP04_INTO:

        case EXCP05_BOUND:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SI_KERNEL;

                info._sifields._sigfault._addr = 0;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP06_ILLOP:

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_ILLOPN;

            info._sifields._sigfault._addr = env->eip;

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP_INTERRUPT:

            /* just indicate that signals should be handled asap */

            break;

        case EXCP_DEBUG:

            {

                int sig;

                sig = gdb_handlesig(cs, TARGET_SIGTRAP);

                if (sig)

                  {

                    info.si_signo = sig;

                    info.si_errno = 0;

                    info.si_code = TARGET_TRAP_BRKPT;

                    queue_signal(env, info.si_signo, &info);

                  }

            }

            break;

        default:

            pc = env->segs[R_CS].base + env->eip;

            EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",

                      (long)pc, trapnr);

            abort();

        }

        process_pending_signals(env);

    }

}


void kqemu_flush(CPUState *env, int global)

{

    LOG_INT("kqemu_flush:\n");

    nb_pages_to_flush = KQEMU_FLUSH_ALL;

}


static inline void gen_evmergelohi(DisasContext *ctx)

{

    if (unlikely(!ctx->spe_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

#if defined(TARGET_PPC64)

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);

    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);

    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

#else

    if (rD(ctx->opcode) == rA(ctx->opcode)) {

        TCGv_i32 tmp = tcg_temp_new_i32();

        tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);

        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);

        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);

        tcg_temp_free_i32(tmp);

    } else {

        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);

        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    }

#endif

}


gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,

                               bool search_pc)

{

    CPUState *cs = CPU(cpu);

    CPUMIPSState *env = &cpu->env;

    DisasContext ctx;

    target_ulong pc_start;

    uint16_t *gen_opc_end;

    CPUBreakpoint *bp;

    int j, lj = -1;

    int num_insns;

    int max_insns;

    int insn_bytes;

    int is_slot;

    if (search_pc)

        qemu_log("search pc %d\n", search_pc);

    pc_start = tb->pc;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    ctx.pc = pc_start;

    ctx.saved_pc = -1;

    ctx.singlestep_enabled = cs->singlestep_enabled;

    ctx.insn_flags = env->insn_flags;

    ctx.CP0_Config1 = env->CP0_Config1;

    ctx.tb = tb;

    ctx.bstate = BS_NONE;

    ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;

    ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;

    ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;

    ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;

    ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;

    /* Restore delay slot state from the tb context.  */

    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */

    ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);

    restore_cpu_state(env, &ctx);

#ifdef CONFIG_USER_ONLY

        ctx.mem_idx = MIPS_HFLAG_UM;

#else

        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;

#endif

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0)

        max_insns = CF_COUNT_MASK;

    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);

    gen_tb_start();

    while (ctx.bstate == BS_NONE) {

        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {

            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {

                if (bp->pc == ctx.pc) {

                    save_cpu_state(&ctx, 1);

                    ctx.bstate = BS_BRANCH;

                    gen_helper_0e0i(raise_exception, EXCP_DEBUG);

                    /* Include the breakpoint location or the tb won't

                     * be flushed when it must be.  */

                    ctx.pc += 4;

                    goto done_generating;

                }

            }

        }

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j)

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

            }

            tcg_ctx.gen_opc_pc[lj] = ctx.pc;

            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;

            gen_opc_btarget[lj] = ctx.btarget;

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = num_insns;

        }

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))

            gen_io_start();

        is_slot = ctx.hflags & MIPS_HFLAG_BMASK;

        if (!(ctx.hflags & MIPS_HFLAG_M16)) {

            ctx.opcode = cpu_ldl_code(env, ctx.pc);

            insn_bytes = 4;

            decode_opc(env, &ctx);

        } else if (ctx.insn_flags & ASE_MICROMIPS) {

            ctx.opcode = cpu_lduw_code(env, ctx.pc);

            insn_bytes = decode_micromips_opc(env, &ctx);

        } else if (ctx.insn_flags & ASE_MIPS16) {

            ctx.opcode = cpu_lduw_code(env, ctx.pc);

            insn_bytes = decode_mips16_opc(env, &ctx);

        } else {

            generate_exception(&ctx, EXCP_RI);

            ctx.bstate = BS_STOP;

            break;

        }

        if (ctx.hflags & MIPS_HFLAG_BMASK) {

            if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |

                                MIPS_HFLAG_FBNSLOT))) {

                /* force to generate branch as there is neither delay nor

                   forbidden slot */

                is_slot = 1;

            }

        }

        if (is_slot) {

            gen_branch(&ctx, insn_bytes);

        }

        ctx.pc += insn_bytes;

        num_insns++;

        /* Execute a branch and its delay slot as a single instruction.

           This is what GDB expects and is consistent with what the

           hardware does (e.g. if a delay slot instruction faults, the

           reported PC is the PC of the branch).  */

        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {

            break;

        }

        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)

            break;

        if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {

            break;

        }

        if (num_insns >= max_insns)

            break;

        if (singlestep)

            break;

    }

    if (tb->cflags & CF_LAST_IO) {

        gen_io_end();

    }

    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {

        save_cpu_state(&ctx, ctx.bstate == BS_NONE);

        gen_helper_0e0i(raise_exception, EXCP_DEBUG);

    } else {

        switch (ctx.bstate) {

        case BS_STOP:

            gen_goto_tb(&ctx, 0, ctx.pc);

            break;

        case BS_NONE:

            save_cpu_state(&ctx, 0);

            gen_goto_tb(&ctx, 0, ctx.pc);

            break;

        case BS_EXCP:

            tcg_gen_exit_tb(0);

            break;

        case BS_BRANCH:

        default:

            break;

        }

    }

done_generating:

    gen_tb_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        lj++;

        while (lj <= j)

            tcg_ctx.gen_opc_instr_start[lj++] = 0;

    } else {

        tb->size = ctx.pc - pc_start;

        tb->icount = num_insns;

    }

#ifdef DEBUG_DISAS

    LOG_DISAS("\n");

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

        log_target_disas(env, pc_start, ctx.pc - pc_start, 0);

        qemu_log("\n");

    }

#endif

}


static inline void gen_movs(DisasContext *s, int ot)

{

    gen_string_movl_A0_ESI(s);

    gen_op_ld_T0_A0(ot + s->mem_index);

    gen_string_movl_A0_EDI(s);

    gen_op_st_T0_A0(ot + s->mem_index);

    gen_op_movl_T0_Dshift[ot]();

#ifdef TARGET_X86_64

    if (s->aflag == 2) {

        gen_op_addq_ESI_T0();

        gen_op_addq_EDI_T0();

    } else

#endif

    if (s->aflag) {

        gen_op_addl_ESI_T0();

        gen_op_addl_EDI_T0();

    } else {

        gen_op_addw_ESI_T0();

        gen_op_addw_EDI_T0();

    }

}


static int udp_read(URLContext *h, uint8_t *buf, int size)

{

    UDPContext *s = h->priv_data;

    int ret;

    int avail;

#if HAVE_PTHREADS

    if (s->fifo) {

        pthread_mutex_lock(&s->mutex);

        do {

            avail = av_fifo_size(s->fifo);

            if (avail) { // >=size) {

                uint8_t tmp[4];

                pthread_mutex_unlock(&s->mutex);

                av_fifo_generic_read(s->fifo, tmp, 4, NULL);

                avail= AV_RL32(tmp);

                if(avail > size){

                    av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");

                    avail= size;

                }

                av_fifo_generic_read(s->fifo, buf, avail, NULL);

                av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);

                return avail;

            } else if(s->circular_buffer_error){

                pthread_mutex_unlock(&s->mutex);

                return s->circular_buffer_error;

            } else if(h->flags & AVIO_FLAG_NONBLOCK) {

                pthread_mutex_unlock(&s->mutex);

                return AVERROR(EAGAIN);

            }

            else {

                pthread_cond_wait(&s->cond, &s->mutex);

            }

        } while( 1);

    }

#endif

    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {

        ret = ff_network_wait_fd(s->udp_fd, 0);

        if (ret < 0)

            return ret;

    }

    ret = recv(s->udp_fd, buf, size, 0);

    return ret < 0 ? ff_neterrno() : ret;

}


static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,

                                    MSIMessage msg)

{

    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);

    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    VirtQueue *vq = virtio_vector_first_queue(vdev, vector);

    int ret, index, unmasked = 0;

    while (vq) {

        index = virtio_get_queue_index(vq);

        if (!virtio_queue_get_num(vdev, index)) {

            break;

        }

        ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);

        if (ret < 0) {

            goto undo;

        }

        vq = virtio_vector_next_queue(vq);

        ++unmasked;

    }

    return 0;

undo:

    vq = virtio_vector_first_queue(vdev, vector);

    while (vq && --unmasked >= 0) {

        index = virtio_get_queue_index(vq);

        virtio_pci_vq_vector_mask(proxy, index, vector);

        vq = virtio_vector_next_queue(vq);

    }

    return ret;

}


static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)

{

    VirtIOPCIProxy *proxy = opaque;

    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    hwaddr pa;

    switch (addr) {

    case VIRTIO_PCI_GUEST_FEATURES:

        /* Guest does not negotiate properly?  We have to assume nothing. */

        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {

            val = virtio_bus_get_vdev_bad_features(&proxy->bus);

        }

        virtio_set_features(vdev, val);

        break;

    case VIRTIO_PCI_QUEUE_PFN:

        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;

        if (pa == 0) {

            virtio_pci_stop_ioeventfd(proxy);

            virtio_reset(vdev);

            msix_unuse_all_vectors(&proxy->pci_dev);

        }

        else

            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);

        break;

    case VIRTIO_PCI_QUEUE_SEL:

        if (val < VIRTIO_PCI_QUEUE_MAX)

            vdev->queue_sel = val;

        break;

    case VIRTIO_PCI_QUEUE_NOTIFY:

        if (val < VIRTIO_PCI_QUEUE_MAX) {

            virtio_queue_notify(vdev, val);

        }

        break;

    case VIRTIO_PCI_STATUS:

        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {

            virtio_pci_stop_ioeventfd(proxy);

        }

        virtio_set_status(vdev, val & 0xFF);

        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {

            virtio_pci_start_ioeventfd(proxy);

        }

        if (vdev->status == 0) {

            virtio_reset(vdev);

            msix_unuse_all_vectors(&proxy->pci_dev);

        }

        /* Linux before 2.6.34 drives the device without enabling

           the PCI device bus master bit. Enable it automatically

           for the guest. This is a PCI spec violation but so is

           initiating DMA with bus master bit clear. */

        if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {

            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,

                                     proxy->pci_dev.config[PCI_COMMAND] |

                                     PCI_COMMAND_MASTER, 1);

        }

        /* Linux before 2.6.34 sets the device as OK without enabling

           the PCI device bus master bit. In this case we need to disable

           some safety checks. */

        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&

            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {

            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;

        }

        break;

    case VIRTIO_MSI_CONFIG_VECTOR:

        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);

        /* Make it possible for guest to discover an error took place. */

        if (msix_vector_use(&proxy->pci_dev, val) < 0)

            val = VIRTIO_NO_VECTOR;

        vdev->config_vector = val;

        break;

    case VIRTIO_MSI_QUEUE_VECTOR:

        msix_vector_unuse(&proxy->pci_dev,

                          virtio_queue_vector(vdev, vdev->queue_sel));

        /* Make it possible for guest to discover an error took place. */

        if (msix_vector_use(&proxy->pci_dev, val) < 0)

            val = VIRTIO_NO_VECTOR;

        virtio_queue_set_vector(vdev, vdev->queue_sel, val);

        break;

    default:

        error_report("%s: unexpected address 0x%x value 0x%x",

                     __func__, addr, val);

        break;

    }

}


void tcg_register_helper(void *func, const char *name)

{

    TCGContext *s = &tcg_ctx;

    GHashTable *table = s->helpers;

    if (table == NULL) {

        /* Use g_direct_hash/equal for direct pointer comparisons on func.  */

        table = g_hash_table_new(NULL, NULL);

        s->helpers = table;

    }

    g_hash_table_insert(table, (gpointer)func, (gpointer)name);

}


static void nvdimm_init(Object *obj)

{

    object_property_add(obj, "label-size", "int",

                        nvdimm_get_label_size, nvdimm_set_label_size, NULL,

                        NULL, NULL);

}


char *g_strdup_vprintf(const char *format, va_list ap)

{

    char ch, *s;

    size_t len;

    __coverity_string_null_sink__(format);

    __coverity_string_size_sink__(format);

    ch = *format;

    ch = *(char *)ap;

    s = __coverity_alloc_nosize__();

    __coverity_writeall__(s);

    __coverity_mark_as_afm_allocated__(s, AFM_free);

    return len;

}


static void randomize_loopfilter_buffers(int bidx, int lineoff, int str,

                                         int bit_depth, int dir,

                                         int* E, int* F, int* H, int* I,

                                         uint8_t *buf0, uint8_t *buf1)

{

    uint32_t mask = (1 << bit_depth) - 1;

    int off = dir ? lineoff : lineoff * 16;

    int istride = dir ? 1 : 16;

    int jstride = dir ? str : 1;

    int i, j;

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

        int idx = off + i * istride, p0, q0;

        setpx(idx,  0, q0 = rnd() & mask);

        setsx(idx, -1, p0 = q0, E[bidx] >> 2);

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

            setsx(idx, -1 - j, p0, F[bidx]);

            setsx(idx, j, q0, F[bidx]);

        }

    }

    for (i = 2; i < 4; i++) /* flat8 */ {

        int idx = off + i * istride, p0, q0;

        setpx(idx,  0, q0 = rnd() & mask);

        setsx(idx, -1, p0 = q0, E[bidx] >> 2);

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

            setsx(idx, -1 - j, p0, F[bidx]);

            setsx(idx, j, q0, F[bidx]);

        }

        for (j = 4; j < 8; j++) {

            setpx(idx, -1 - j, rnd() & mask);

            setpx(idx, j, rnd() & mask);

        }

    }

    for (i = 4; i < 6; i++) /* regular */ {

        int idx = off + i * istride, p2, p1, p0, q0, q1, q2;

        setpx(idx,  0, q0 = rnd() & mask);

        setsx(idx,  1, q1 = q0, I[bidx]);

        setsx(idx,  2, q2 = q1, I[bidx]);

        setsx(idx,  3, q2,      I[bidx]);

        setsx(idx, -1, p0 = q0, E[bidx] >> 2);

        setsx(idx, -2, p1 = p0, I[bidx]);

        setsx(idx, -3, p2 = p1, I[bidx]);

        setsx(idx, -4, p2,      I[bidx]);

        for (j = 4; j < 8; j++) {

            setpx(idx, -1 - j, rnd() & mask);

            setpx(idx, j, rnd() & mask);

        }

    }

    for (i = 6; i < 8; i++) /* off */ {

        int idx = off + i * istride;

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

            setpx(idx, -1 - j, rnd() & mask);

            setpx(idx, j, rnd() & mask);

        }

    }

}


static av_cold int bmp_encode_close(AVCodecContext *avctx)

{

    av_frame_free(&avctx->coded_frame);

    return 0;

}


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

{

    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    k->init = pci_grackle_init_device;

    dc->no_user = 1;

}


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

                              int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    DNXHDContext *ctx = avctx->priv_data;

    ThreadFrame frame = { .f = data };

    AVFrame *picture = data;

    int first_field = 1;

    int ret;

    ff_dlog(avctx, "frame size %d\n", buf_size);

decode_coding_unit:

    if ((ret = dnxhd_decode_header(ctx, picture, buf, buf_size, first_field)) < 0)

        return ret;

    if ((avctx->width || avctx->height) &&

        (ctx->width != avctx->width || ctx->height != avctx->height)) {

        av_log(avctx, AV_LOG_WARNING, "frame size changed: %dx%d -> %dx%d\n",

               avctx->width, avctx->height, ctx->width, ctx->height);

        first_field = 1;

    }

    if (avctx->pix_fmt != AV_PIX_FMT_NONE && avctx->pix_fmt != ctx->pix_fmt) {

        av_log(avctx, AV_LOG_WARNING, "pix_fmt changed: %s -> %s\n",

               av_get_pix_fmt_name(avctx->pix_fmt), av_get_pix_fmt_name(ctx->pix_fmt));

        first_field = 1;

    }

    avctx->pix_fmt = ctx->pix_fmt;

    ret = ff_set_dimensions(avctx, ctx->width, ctx->height);

    if (ret < 0)

        return ret;

    if (first_field) {

        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)

            return ret;

        picture->pict_type = AV_PICTURE_TYPE_I;

        picture->key_frame = 1;

    }

    ctx->buf_size = buf_size - 0x280;

    ctx->buf = buf + 0x280;

    avctx->execute2(avctx, dnxhd_decode_row, picture, NULL, ctx->mb_height);

    if (first_field && picture->interlaced_frame) {

        buf      += ctx->cid_table->coding_unit_size;

        buf_size -= ctx->cid_table->coding_unit_size;

        first_field = 0;

        goto decode_coding_unit;

    }

    *got_frame = 1;

    return avpkt->size;

}


static void vtd_realize(DeviceState *dev, Error **errp)

{

    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());

    PCIBus *bus = pcms->bus;

    IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);

    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);

    VTD_DPRINTF(GENERAL, "");

    x86_iommu->type = TYPE_INTEL;

    if (!vtd_decide_config(s, errp)) {

        return;

    }

    QLIST_INIT(&s->notifiers_list);

    memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num));

    memory_region_init_io(&s->csrmem, OBJECT(s), &vtd_mem_ops, s,

                          "intel_iommu", DMAR_REG_SIZE);

    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->csrmem);

    /* No corresponding destroy */

    s->iotlb = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,

                                     g_free, g_free);

    s->vtd_as_by_busptr = g_hash_table_new_full(vtd_uint64_hash, vtd_uint64_equal,

                                              g_free, g_free);

    vtd_init(s);

    sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, Q35_HOST_BRIDGE_IOMMU_ADDR);

    pci_setup_iommu(bus, vtd_host_dma_iommu, dev);

    /* Pseudo address space under root PCI bus. */

    pcms->ioapic_as = vtd_host_dma_iommu(bus, s, Q35_PSEUDO_DEVFN_IOAPIC);

}


static inline void menelaus_rtc_start(struct menelaus_s *s)

{

    s->rtc.next =+ qemu_get_clock(rt_clock);

    qemu_mod_timer(s->rtc.hz, s->rtc.next);

}


static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...)

{

    int trig;

    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    switch (cmd) {

    case VOICE_ENABLE:

        {

            va_list ap;

            int poll_mode;

            va_start (ap, cmd);

            poll_mode = va_arg (ap, int);

            va_end (ap);

            ldebug ("enabling voice\n");

            if (poll_mode && oss_poll_out (hw)) {

                poll_mode = 0;

            }

            hw->poll_mode = poll_mode;

            if (!oss->mmapped) {

                return 0;

            }

            audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);

            trig = PCM_ENABLE_OUTPUT;

            if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {

                oss_logerr (

                    errno,

                    "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"

                    );

                return -1;

            }

        }

        break;

    case VOICE_DISABLE:

        if (hw->poll_mode) {

            qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);

            hw->poll_mode = 0;

        }

        if (!oss->mmapped) {

            return 0;

        }

        ldebug ("disabling voice\n");

        trig = 0;

        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {

            oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");

            return -1;

        }

        break;

    }

    return 0;

}


void op_ddiv (void)

{

    if (T1 != 0) {

        env->LO = (int64_t)T0 / (int64_t)T1;

        env->HI = (int64_t)T0 % (int64_t)T1;

    }

    RETURN();

}


static void decompress_data_with_multi_threads(QEMUFile *f,

                                               void *host, int len)

{

    int idx, thread_count;

    thread_count = migrate_decompress_threads();

    while (true) {

        for (idx = 0; idx < thread_count; idx++) {

            if (!decomp_param[idx].start) {

                qemu_get_buffer(f, decomp_param[idx].compbuf, len);

                decomp_param[idx].des = host;

                decomp_param[idx].len = len;

                start_decompression(&decomp_param[idx]);

                break;

            }

        }

        if (idx < thread_count) {

            break;

        }

    }

}


static int config_input(AVFilterLink *link)

{

    AVFilterContext *ctx = link->dst;

    CropContext *s = ctx->priv;

    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(link->format);

    int ret;

    const char *expr;

    double res;

    s->var_values[VAR_E]     = M_E;

    s->var_values[VAR_PHI]   = M_PHI;

    s->var_values[VAR_PI]    = M_PI;

    s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = ctx->inputs[0]->w;

    s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = ctx->inputs[0]->h;

    s->var_values[VAR_X]     = NAN;

    s->var_values[VAR_Y]     = NAN;

    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = NAN;

    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = NAN;

    s->var_values[VAR_N]     = 0;

    s->var_values[VAR_T]     = NAN;

    av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);

    s->hsub = pix_desc->log2_chroma_w;

    s->vsub = pix_desc->log2_chroma_h;

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr),

                                      var_names, s->var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto fail_expr;

    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->oh_expr),

                                      var_names, s->var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto fail_expr;

    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = res;

    /* evaluate again ow as it may depend on oh */

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr),

                                      var_names, s->var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto fail_expr;

    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;

    if (normalize_double(&s->w, s->var_values[VAR_OUT_W]) < 0 ||

        normalize_double(&s->h, s->var_values[VAR_OUT_H]) < 0) {

        av_log(ctx, AV_LOG_ERROR,

               "Too big value or invalid expression for out_w/ow or out_h/oh. "

               "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",

               s->ow_expr, s->oh_expr);

        return AVERROR(EINVAL);

    }

    s->w &= ~((1 << s->hsub) - 1);

    s->h &= ~((1 << s->vsub) - 1);

    if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,

                             NULL, NULL, NULL, NULL, 0, ctx)) < 0 ||

        (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,

                             NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        return AVERROR(EINVAL);

    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",

           link->w, link->h, s->w, s->h);

    if (s->w <= 0 || s->h <= 0 ||

        s->w > link->w || s->h > link->h) {

        av_log(ctx, AV_LOG_ERROR,

               "Invalid too big or non positive size for width '%d' or height '%d'\n",

               s->w, s->h);

        return AVERROR(EINVAL);

    }

    /* set default, required in the case the first computed value for x/y is NAN */

    s->x = (link->w - s->w) / 2;

    s->y = (link->h - s->h) / 2;

    s->x &= ~((1 << s->hsub) - 1);

    s->y &= ~((1 << s->vsub) - 1);

    return 0;

fail_expr:

    av_log(NULL, AV_LOG_ERROR, "Error when evaluating the expression '%s'\n", expr);

    return ret;

}


int av_opt_set_dict(void *obj, AVDictionary **options)
{
    AVDictionaryEntry *t = NULL;
    AVDictionary    *tmp = NULL;
    int ret = 0;
    while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
        ret = av_opt_set(obj, t->key, t->value, 0);
        if (ret == AVERROR_OPTION_NOT_FOUND)
            av_dict_set(&tmp, t->key, t->value, 0);
        else if (ret < 0) {
            av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
            break;
        }
        ret = 0;
    }
    av_dict_free(options);
    *options = tmp;
    return ret;
}


static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,

                             int nbits)

{

    int i, n, n4, ret;

    n  = 1 << nbits;

    n4 = n >> 2;

    mdct->nbits = nbits;

    ret = fft_init(avctx, mdct, nbits - 2);

    if (ret)

        return ret;

    mdct->window = ff_ac3_window;

    FF_ALLOC_OR_GOTO(avctx, mdct->xcos1,    n4 * sizeof(*mdct->xcos1),    mdct_alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, mdct->xsin1,    n4 * sizeof(*mdct->xsin1),    mdct_alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, mdct->rot_tmp,  n  * sizeof(*mdct->rot_tmp),  mdct_alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp), mdct_alloc_fail);

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

        float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;

        mdct->xcos1[i] = FIX15(-cos(alpha));

        mdct->xsin1[i] = FIX15(-sin(alpha));

    }

    return 0;

mdct_alloc_fail:

    mdct_end(mdct);

    return AVERROR(ENOMEM);

}


static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx)

{

    static const VAConfigAttrib default_config_attributes[] = {

        { .type  = VAConfigAttribRTFormat,

          .value = VA_RT_FORMAT_YUV420 },

        { .type  = VAConfigAttribEncPackedHeaders,

          .value = (VA_ENC_PACKED_HEADER_SEQUENCE |

                    VA_ENC_PACKED_HEADER_SLICE) },

    };

    VAAPIEncodeContext      *ctx = avctx->priv_data;

    VAAPIEncodeH264Context *priv = ctx->priv_data;

    VAAPIEncodeH264Options  *opt = ctx->codec_options;

    int i, err;

    switch (avctx->profile) {

    case FF_PROFILE_H264_CONSTRAINED_BASELINE:

        ctx->va_profile = VAProfileH264ConstrainedBaseline;

        break;

    case FF_PROFILE_H264_BASELINE:

        ctx->va_profile = VAProfileH264Baseline;

        break;

    case FF_PROFILE_H264_MAIN:

        ctx->va_profile = VAProfileH264Main;

        break;

    case FF_PROFILE_H264_EXTENDED:

        av_log(avctx, AV_LOG_ERROR, "H.264 extended profile "

               "is not supported.\n");

        return AVERROR_PATCHWELCOME;

    case FF_PROFILE_UNKNOWN:

    case FF_PROFILE_H264_HIGH:

        ctx->va_profile = VAProfileH264High;

        break;

    case FF_PROFILE_H264_HIGH_10:

    case FF_PROFILE_H264_HIGH_10_INTRA:

        av_log(avctx, AV_LOG_ERROR, "H.264 10-bit profiles "

               "are not supported.\n");

        return AVERROR_PATCHWELCOME;

    case FF_PROFILE_H264_HIGH_422:

    case FF_PROFILE_H264_HIGH_422_INTRA:

    case FF_PROFILE_H264_HIGH_444:

    case FF_PROFILE_H264_HIGH_444_PREDICTIVE:

    case FF_PROFILE_H264_HIGH_444_INTRA:

    case FF_PROFILE_H264_CAVLC_444:

        av_log(avctx, AV_LOG_ERROR, "H.264 non-4:2:0 profiles "

               "are not supported.\n");

        return AVERROR_PATCHWELCOME;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown H.264 profile %d.\n",

               avctx->profile);

        return AVERROR(EINVAL);

    }

    if (opt->low_power) {

#if VA_CHECK_VERSION(0, 39, 1)

        ctx->va_entrypoint = VAEntrypointEncSliceLP;

#else

        av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "

               "supported with this VAAPI version.\n");

        return AVERROR(EINVAL);

#endif

    } else {

        ctx->va_entrypoint = VAEntrypointEncSlice;

    }

    ctx->input_width    = avctx->width;

    ctx->input_height   = avctx->height;

    ctx->aligned_width  = FFALIGN(ctx->input_width,  16);

    ctx->aligned_height = FFALIGN(ctx->input_height, 16);

    priv->mb_width      = ctx->aligned_width  / 16;

    priv->mb_height     = ctx->aligned_height / 16;

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

        ctx->config_attributes[ctx->nb_config_attributes++] =

            default_config_attributes[i];

    }

    if (avctx->bit_rate > 0) {

        ctx->va_rc_mode = VA_RC_CBR;

        err = vaapi_encode_h264_init_constant_bitrate(avctx);

    } else {

        ctx->va_rc_mode = VA_RC_CQP;

        err = vaapi_encode_h264_init_fixed_qp(avctx);

    }

    if (err < 0)

        return err;

    ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) {

        .type  = VAConfigAttribRateControl,

        .value = ctx->va_rc_mode,

    };

    if (opt->quality > 0) {

#if VA_CHECK_VERSION(0, 36, 0)

        priv->quality_params.misc.type =

            VAEncMiscParameterTypeQualityLevel;

        priv->quality_params.quality.quality_level = opt->quality;

        ctx->global_params[ctx->nb_global_params] =

            &priv->quality_params.misc;

        ctx->global_params_size[ctx->nb_global_params++] =

            sizeof(priv->quality_params);

#else

        av_log(avctx, AV_LOG_WARNING, "The encode quality option is not "

               "supported with this VAAPI version.\n");

#endif

    }

    ctx->nb_recon_frames = 20;

    return 0;

}


static void do_video_out(AVFormatContext *s,
                         OutputStream *ost,
                         AVFrame *next_picture,
                         double sync_ipts)
{
    int ret, format_video_sync;
    AVPacket pkt;
    AVCodecContext *enc = ost->enc_ctx;
    AVCodecContext *mux_enc = ost->st->codec;
    int nb_frames, nb0_frames, i;
    double delta, delta0;
    double duration = 0;
    int frame_size = 0;
    InputStream *ist = NULL;
    AVFilterContext *filter = ost->filter->filter;
    if (ost->source_index >= 0)
        ist = input_streams[ost->source_index];
    if (filter->inputs[0]->frame_rate.num > 0 &&
        filter->inputs[0]->frame_rate.den > 0)
        duration = 1/(av_q2d(filter->inputs[0]->frame_rate) * av_q2d(enc->time_base));
    if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num)
        duration = FFMIN(duration, 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base)));
    if (!ost->filters_script &&
        !ost->filters &&
        next_picture &&
        ist &&
        lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) {
        duration = lrintf(av_frame_get_pkt_duration(next_picture) * av_q2d(ist->st->time_base) / av_q2d(enc->time_base));
    }
    if (!next_picture) {
        //end, flushing
        nb0_frames = nb_frames = mid_pred(ost->last_nb0_frames[0],
                                          ost->last_nb0_frames[1],
                                          ost->last_nb0_frames[2]);
    } else {
        delta0 = sync_ipts - ost->sync_opts;
        delta  = delta0 + duration;
        /* by default, we output a single frame */
        nb0_frames = 0;
        nb_frames = 1;
        format_video_sync = video_sync_method;
        if (format_video_sync == VSYNC_AUTO) {
            if(!strcmp(s->oformat->name, "avi")) {
                format_video_sync = VSYNC_VFR;
            } else
                format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR;
            if (   ist
                && format_video_sync == VSYNC_CFR
                && input_files[ist->file_index]->ctx->nb_streams == 1
                && input_files[ist->file_index]->input_ts_offset == 0) {
                format_video_sync = VSYNC_VSCFR;
            }
            if (format_video_sync == VSYNC_CFR && copy_ts) {
                format_video_sync = VSYNC_VSCFR;
            }
        }
        if (delta0 < 0 &&
            delta > 0 &&
            format_video_sync != VSYNC_PASSTHROUGH &&
            format_video_sync != VSYNC_DROP) {
            double cor = FFMIN(-delta0, duration);
            if (delta0 < -0.6) {
                av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
            } else
                av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
            sync_ipts += cor;
            duration -= cor;
            delta0 += cor;
        }
        switch (format_video_sync) {
        case VSYNC_VSCFR:
            if (ost->frame_number == 0 && delta - duration >= 0.5) {
                av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration));
                delta = duration;
                delta0 = 0;
                ost->sync_opts = lrint(sync_ipts);
            }
        case VSYNC_CFR:
            // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
            if (frame_drop_threshold && delta < frame_drop_threshold && ost->frame_number) {
                nb_frames = 0;
            } else if (delta < -1.1)
                nb_frames = 0;
            else if (delta > 1.1) {
                nb_frames = lrintf(delta);
                if (delta0 > 1.1)
                    nb0_frames = lrintf(delta0 - 0.6);
            }
            break;
        case VSYNC_VFR:
            if (delta <= -0.6)
                nb_frames = 0;
            else if (delta > 0.6)
                ost->sync_opts = lrint(sync_ipts);
            break;
        case VSYNC_DROP:
        case VSYNC_PASSTHROUGH:
            ost->sync_opts = lrint(sync_ipts);
            break;
        default:
            av_assert0(0);
        }
    }
    nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
    nb0_frames = FFMIN(nb0_frames, nb_frames);
    memmove(ost->last_nb0_frames + 1,
            ost->last_nb0_frames,
            sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1));
    ost->last_nb0_frames[0] = nb0_frames;
    if (nb0_frames == 0 && ost->last_droped) {
        nb_frames_drop++;
        av_log(NULL, AV_LOG_VERBOSE,
               "*** dropping frame %d from stream %d at ts %"PRId64"\n",
               ost->frame_number, ost->st->index, ost->last_frame->pts);
    }
    if (nb_frames > (nb0_frames && ost->last_droped) + (nb_frames > nb0_frames)) {
        if (nb_frames > dts_error_threshold * 30) {
            av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
            nb_frames_drop++;
        }
        nb_frames_dup += nb_frames - (nb0_frames && ost->last_droped) - (nb_frames > nb0_frames);
        av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
    }
    ost->last_droped = nb_frames == nb0_frames && next_picture;
  /* duplicates frame if needed */
  for (i = 0; i < nb_frames; i++) {
    AVFrame *in_picture;
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;
    if (i < nb0_frames && ost->last_frame) {
        in_picture = ost->last_frame;
    } else
        in_picture = next_picture;
    in_picture->pts = ost->sync_opts;
#if 1
    if (!check_recording_time(ost))
#else
    if (ost->frame_number >= ost->max_frames)
#endif
    if (s->oformat->flags & AVFMT_RAWPICTURE &&
        enc->codec->id == AV_CODEC_ID_RAWVIDEO) {
        /* raw pictures are written as AVPicture structure to
           avoid any copies. We support temporarily the older
           method. */
        if (in_picture->interlaced_frame)
            mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
        else
            mux_enc->field_order = AV_FIELD_PROGRESSIVE;
        pkt.data   = (uint8_t *)in_picture;
        pkt.size   =  sizeof(AVPicture);
        pkt.pts    = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
        pkt.flags |= AV_PKT_FLAG_KEY;
        write_frame(s, &pkt, ost);
    } else {
        int got_packet, forced_keyframe = 0;
        double pts_time;
        if (enc->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
            ost->top_field_first >= 0)
            in_picture->top_field_first = !!ost->top_field_first;
        if (in_picture->interlaced_frame) {
            if (enc->codec->id == AV_CODEC_ID_MJPEG)
                mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
            else
                mux_enc->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
        } else
            mux_enc->field_order = AV_FIELD_PROGRESSIVE;
        in_picture->quality = enc->global_quality;
        in_picture->pict_type = 0;
        pts_time = in_picture->pts != AV_NOPTS_VALUE ?
            in_picture->pts * av_q2d(enc->time_base) : NAN;
        if (ost->forced_kf_index < ost->forced_kf_count &&
            in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
            ost->forced_kf_index++;
            forced_keyframe = 1;
        } else if (ost->forced_keyframes_pexpr) {
            double res;
            ost->forced_keyframes_expr_const_values[FKF_T] = pts_time;
            res = av_expr_eval(ost->forced_keyframes_pexpr,
                               ost->forced_keyframes_expr_const_values, NULL);
            av_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n",
                    ost->forced_keyframes_expr_const_values[FKF_N],
                    ost->forced_keyframes_expr_const_values[FKF_N_FORCED],
                    ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N],
                    ost->forced_keyframes_expr_const_values[FKF_T],
                    ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T],
                    res);
            if (res) {
                forced_keyframe = 1;
                ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_N] =
                    ost->forced_keyframes_expr_const_values[FKF_N];
                ost->forced_keyframes_expr_const_values[FKF_PREV_FORCED_T] =
                    ost->forced_keyframes_expr_const_values[FKF_T];
                ost->forced_keyframes_expr_const_values[FKF_N_FORCED] += 1;
            }
            ost->forced_keyframes_expr_const_values[FKF_N] += 1;
        }
        if (forced_keyframe) {
            in_picture->pict_type = AV_PICTURE_TYPE_I;
            av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
        }
        update_benchmark(NULL);
        if (debug_ts) {
            av_log(NULL, AV_LOG_INFO, "encoder <- type:video "
                   "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n",
                   av_ts2str(in_picture->pts), av_ts2timestr(in_picture->pts, &enc->time_base),
                   enc->time_base.num, enc->time_base.den);
        }
        ost->frames_encoded++;
        ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet);
        update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
        if (ret < 0) {
            av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
            exit_program(1);
        }
        if (got_packet) {
            if (debug_ts) {
                av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
                       "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
                       av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &enc->time_base),
                       av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &enc->time_base));
            }
            if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))
                pkt.pts = ost->sync_opts;
            av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base);
            if (debug_ts) {
                av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
                    "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
                    av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
                    av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
            }
            frame_size = pkt.size;
            write_frame(s, &pkt, ost);
            /* if two pass, output log */
            if (ost->logfile && enc->stats_out) {
                fprintf(ost->logfile, "%s", enc->stats_out);
            }
        }
    }
    ost->sync_opts++;
    /*
     * For video, number of frames in == number of packets out.
     * But there may be reordering, so we can't throw away frames on encoder
     * flush, we need to limit them here, before they go into encoder.
     */
    ost->frame_number++;
    if (vstats_filename && frame_size)
        do_video_stats(ost, frame_size);
  }
    if (!ost->last_frame)
        ost->last_frame = av_frame_alloc();
    av_frame_unref(ost->last_frame);
    if (next_picture)
        av_frame_ref(ost->last_frame, next_picture);
}


static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds,

                               uint8_t *buffer, uint32_t count)

{

    uint32_t type, i;

    int ret;

    size_t new_size;

    uint32_t chunk_count;

    int64_t offset = 0;

    type = buff_read_uint32(buffer, offset);

    /* skip data that is not a valid MISH block (invalid magic or too small) */

    if (type != 0x6d697368 || count < 244) {

        /* assume success for now */

        return 0;

    }

    offset += 4;

    offset += 200;

    chunk_count = (count - 204) / 40;

    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);

    s->types = g_realloc(s->types, new_size / 2);

    s->offsets = g_realloc(s->offsets, new_size);

    s->lengths = g_realloc(s->lengths, new_size);

    s->sectors = g_realloc(s->sectors, new_size);

    s->sectorcounts = g_realloc(s->sectorcounts, new_size);

    for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) {

        s->types[i] = buff_read_uint32(buffer, offset);

        offset += 4;

        if (s->types[i] != 0x80000005 && s->types[i] != 1 &&

            s->types[i] != 2) {

            if (s->types[i] == 0xffffffff && i > 0) {

                ds->last_in_offset = s->offsets[i - 1] + s->lengths[i - 1];

                ds->last_out_offset = s->sectors[i - 1] +

                                      s->sectorcounts[i - 1];

            }

            chunk_count--;

            i--;

            offset += 36;

            continue;

        }

        offset += 4;

        s->sectors[i] = buff_read_uint64(buffer, offset);

        s->sectors[i] += ds->last_out_offset;

        offset += 8;

        s->sectorcounts[i] = buff_read_uint64(buffer, offset);

        offset += 8;

        if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {

            error_report("sector count %" PRIu64 " for chunk %" PRIu32

                         " is larger than max (%u)",

                         s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);

            ret = -EINVAL;

            goto fail;

        }

        s->offsets[i] = buff_read_uint64(buffer, offset);

        s->offsets[i] += ds->last_in_offset;

        offset += 8;

        s->lengths[i] = buff_read_uint64(buffer, offset);

        offset += 8;

        if (s->lengths[i] > DMG_LENGTHS_MAX) {

            error_report("length %" PRIu64 " for chunk %" PRIu32

                         " is larger than max (%u)",

                         s->lengths[i], i, DMG_LENGTHS_MAX);

            ret = -EINVAL;

            goto fail;

        }

        update_max_chunk_size(s, i, &ds->max_compressed_size,

                              &ds->max_sectors_per_chunk);

    }

    s->n_chunks += chunk_count;

    return 0;

fail:

    return ret;

}


static int png_decode_idat(PNGDecContext *s, int length)

{

    int ret;

    s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));

    s->zstream.next_in  = (unsigned char *)s->gb.buffer;

    bytestream2_skip(&s->gb, length);

    /* decode one line if possible */

    while (s->zstream.avail_in > 0) {

        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);

        if (ret != Z_OK && ret != Z_STREAM_END) {

            av_log(s->avctx, AV_LOG_ERROR, "inflate returned error %d\n", ret);

            return AVERROR_EXTERNAL;

        }

        if (s->zstream.avail_out == 0) {

            if (!(s->state & PNG_ALLIMAGE)) {

                png_handle_row(s);

            }

            s->zstream.avail_out = s->crow_size;

            s->zstream.next_out  = s->crow_buf;

        }

        if (ret == Z_STREAM_END && s->zstream.avail_in > 0) {

            av_log(NULL, AV_LOG_WARNING,

                   "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);

            return 0;

        }

    }

    return 0;

}


FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,

                                AddressSpace *dma_as)

{

    DeviceState *dev;

    SysBusDevice *sbd;

    FWCfgIoState *ios;

    FWCfgState *s;

    bool dma_requested = dma_iobase && dma_as;

    dev = qdev_create(NULL, TYPE_FW_CFG_IO);

    if (!dma_requested) {

        qdev_prop_set_bit(dev, "dma_enabled", false);

    }

    fw_cfg_init1(dev);

    sbd = SYS_BUS_DEVICE(dev);

    ios = FW_CFG_IO(dev);

    sysbus_add_io(sbd, iobase, &ios->comb_iomem);

    s = FW_CFG(dev);

    if (s->dma_enabled) {

        /* 64 bits for the address field */

        s->dma_as = dma_as;

        s->dma_addr = 0;

        sysbus_add_io(sbd, dma_iobase, &s->dma_iomem);

    }

    return s;

}


static int mpeg_decode_frame(AVCodecContext *avctx,

                             void *data, int *got_output,

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    Mpeg1Context *s = avctx->priv_data;

    AVFrame *picture = data;

    MpegEncContext *s2 = &s->mpeg_enc_ctx;

    av_dlog(avctx, "fill_buffer\n");

    if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {

        /* special case for last picture */

        if (s2->low_delay == 0 && s2->next_picture_ptr) {

            *picture = s2->next_picture_ptr->f;

            s2->next_picture_ptr = NULL;

            *got_output = 1;

        }

        return buf_size;

    }

    if (s2->flags & CODEC_FLAG_TRUNCATED) {

        int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);

        if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0)

            return buf_size;

    }

    if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2"))

        vcr2_init_sequence(avctx);

    s->slice_count = 0;

    if (avctx->extradata && !avctx->frame_number) {

        int ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size);

        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))

            return ret;

    }

    return decode_chunks(avctx, picture, got_output, buf, buf_size);

}


av_cold void ff_fft_fixed_init_arm(FFTContext *s)

{

    int cpu_flags = av_get_cpu_flags();

    if (have_neon(cpu_flags)) {

        s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;

        s->fft_calc        = ff_fft_fixed_calc_neon;

#if CONFIG_MDCT

        if (!s->inverse && s->mdct_bits >= 5) {

            s->mdct_permutation = FF_MDCT_PERM_INTERLEAVE;

            s->mdct_calc        = ff_mdct_fixed_calc_neon;

            s->mdct_calcw       = ff_mdct_fixed_calcw_neon;

        }

#endif

    }

}


static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)

{

    return timer_head && (timer_head->expire_time <= current_time);

}


void syscall_init(void)

{

    IOCTLEntry *ie;

    const argtype *arg_type;

    int size;

    int i;

#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);

#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);

#include "syscall_types.h"

#undef STRUCT

#undef STRUCT_SPECIAL

    /* we patch the ioctl size if necessary. We rely on the fact that

       no ioctl has all the bits at '1' in the size field */

    ie = ioctl_entries;

    while (ie->target_cmd != 0) {

        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==

            TARGET_IOC_SIZEMASK) {

            arg_type = ie->arg_type;

            if (arg_type[0] != TYPE_PTR) {

                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",

                        ie->target_cmd);

                exit(1);

            }

            arg_type++;

            size = thunk_type_size(arg_type, 0);

            ie->target_cmd = (ie->target_cmd &

                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |

                (size << TARGET_IOC_SIZESHIFT);

        }

        /* Build target_to_host_errno_table[] table from

         * host_to_target_errno_table[]. */

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

                target_to_host_errno_table[host_to_target_errno_table[i]] = i;

        /* automatic consistency check if same arch */

#if defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)

        if (ie->target_cmd != ie->host_cmd) {

            fprintf(stderr, "ERROR: ioctl: target=0x%x host=0x%x\n",

                    ie->target_cmd, ie->host_cmd);

        }

#endif

        ie++;

    }

}


static CharDriverState *qemu_chr_open_stdio(const char *id,

                                            ChardevBackend *backend,

                                            ChardevReturn *ret,

                                            Error **errp)

{

    ChardevStdio *opts = backend->u.stdio;

    CharDriverState *chr;

    struct sigaction act;

    if (is_daemonized()) {

        error_setg(errp, "cannot use stdio with -daemonize");

        return NULL;

    }

    if (stdio_in_use) {

        error_setg(errp, "cannot use stdio by multiple character devices");

        return NULL;

    }

    stdio_in_use = true;

    old_fd0_flags = fcntl(0, F_GETFL);

    tcgetattr(0, &oldtty);

    qemu_set_nonblock(0);

    atexit(term_exit);

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

    act.sa_handler = term_stdio_handler;

    sigaction(SIGCONT, &act, NULL);

    chr = qemu_chr_open_fd(0, 1);

    chr->chr_close = qemu_chr_close_stdio;

    chr->chr_set_echo = qemu_chr_set_echo_stdio;

    if (opts->has_signal) {

        stdio_allow_signal = opts->signal;

    }

    qemu_chr_fe_set_echo(chr, false);

    return chr;

}


static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)

{

    gen_mov_reg_N(cpu_tmp0, src);

    gen_mov_reg_V(dst, src);

    tcg_gen_xor_tl(dst, dst, cpu_tmp0);

    gen_mov_reg_Z(cpu_tmp0, src);

    tcg_gen_or_tl(dst, dst, cpu_tmp0);

    tcg_gen_xori_tl(dst, dst, 0x1);

}


START_TEST(qstring_destroy_test)

{

    QString *qstring = qstring_from_str("destroy test");

    QDECREF(qstring);

}


static av_cold int aac_decode_init(AVCodecContext *avctx)

{

    AACContext *ac = avctx->priv_data;

    float output_scale_factor;

    ac->avctx = avctx;

    ac->oc[1].m4ac.sample_rate = avctx->sample_rate;

    if (avctx->extradata_size > 0) {

        if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,

                                         avctx->extradata,

                                         avctx->extradata_size*8, 1) < 0)

            return -1;

    } else {

        int sr, i;

        uint8_t layout_map[MAX_ELEM_ID*4][3];

        int layout_map_tags;

        sr = sample_rate_idx(avctx->sample_rate);

        ac->oc[1].m4ac.sampling_index = sr;

        ac->oc[1].m4ac.channels = avctx->channels;

        ac->oc[1].m4ac.sbr = -1;

        ac->oc[1].m4ac.ps = -1;

        for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)

            if (ff_mpeg4audio_channels[i] == avctx->channels)

                break;

        if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {

            i = 0;

        }

        ac->oc[1].m4ac.chan_config = i;

        if (ac->oc[1].m4ac.chan_config) {

            int ret = set_default_channel_config(avctx, layout_map,

                &layout_map_tags, ac->oc[1].m4ac.chan_config);

            if (!ret)

                output_configure(ac, layout_map, layout_map_tags,

                                 ac->oc[1].m4ac.chan_config, OC_GLOBAL_HDR);

            else if (avctx->err_recognition & AV_EF_EXPLODE)

                return AVERROR_INVALIDDATA;

        }

    }

    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {

        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;

        output_scale_factor = 1.0 / 32768.0;

    } else {

        avctx->sample_fmt = AV_SAMPLE_FMT_S16;

        output_scale_factor = 1.0;

    }

    AAC_INIT_VLC_STATIC( 0, 304);

    AAC_INIT_VLC_STATIC( 1, 270);

    AAC_INIT_VLC_STATIC( 2, 550);

    AAC_INIT_VLC_STATIC( 3, 300);

    AAC_INIT_VLC_STATIC( 4, 328);

    AAC_INIT_VLC_STATIC( 5, 294);

    AAC_INIT_VLC_STATIC( 6, 306);

    AAC_INIT_VLC_STATIC( 7, 268);

    AAC_INIT_VLC_STATIC( 8, 510);

    AAC_INIT_VLC_STATIC( 9, 366);

    AAC_INIT_VLC_STATIC(10, 462);

    ff_aac_sbr_init();

    ff_dsputil_init(&ac->dsp, avctx);

    ff_fmt_convert_init(&ac->fmt_conv, avctx);

    avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);

    ac->random_state = 0x1f2e3d4c;

    ff_aac_tableinit();

    INIT_VLC_STATIC(&vlc_scalefactors,7,FF_ARRAY_ELEMS(ff_aac_scalefactor_code),

                    ff_aac_scalefactor_bits, sizeof(ff_aac_scalefactor_bits[0]), sizeof(ff_aac_scalefactor_bits[0]),

                    ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]),

                    352);

    ff_mdct_init(&ac->mdct,       11, 1, output_scale_factor/1024.0);

    ff_mdct_init(&ac->mdct_small,  8, 1, output_scale_factor/128.0);

    ff_mdct_init(&ac->mdct_ltp,   11, 0, -2.0/output_scale_factor);

    // window initialization

    ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);

    ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);

    ff_init_ff_sine_windows(10);

    ff_init_ff_sine_windows( 7);

    cbrt_tableinit();

    avcodec_get_frame_defaults(&ac->frame);

    avctx->coded_frame = &ac->frame;

    return 0;

}


static void test_validate_union_anon(TestInputVisitorData *data,

                                     const void *unused)

{

    UserDefAnonUnion *tmp = NULL;

    Visitor *v;

    Error *errp = NULL;

    v = validate_test_init(data, "42");

    visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);

    g_assert(!error_is_set(&errp));

    qapi_free_UserDefAnonUnion(tmp);

}


int qemu_input_key_value_to_qcode(const KeyValue *value)

{

    if (value->type == KEY_VALUE_KIND_QCODE) {

        return value->u.qcode;

    } else {

        assert(value->type == KEY_VALUE_KIND_NUMBER);

        return qemu_input_key_number_to_qcode(value->u.number);

    }

}


void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)

{

    /* We only support one address space per cpu at the moment.  */

    assert(cpu->as == as);

    if (cpu->cpu_ases) {

        /* We've already registered the listener for our only AS */

        return;

    }

    cpu->cpu_ases = g_new0(CPUAddressSpace, 1);

    cpu->cpu_ases[0].cpu = cpu;

    cpu->cpu_ases[0].as = as;

    cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit;

    memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as);

}


static struct iovec *lock_iovec(int type, abi_ulong target_addr,

                                int count, int copy)

{

    struct target_iovec *target_vec;

    struct iovec *vec;

    abi_ulong total_len, max_len;

    int i;

    int err = 0;

    if (count == 0) {

        errno = 0;

        return NULL;

    }

    if (count < 0 || count > IOV_MAX) {

        errno = EINVAL;

        return NULL;

    }

    vec = calloc(count, sizeof(struct iovec));

    if (vec == NULL) {

        errno = ENOMEM;

        return NULL;

    }

    target_vec = lock_user(VERIFY_READ, target_addr,

                           count * sizeof(struct target_iovec), 1);

    if (target_vec == NULL) {

        err = EFAULT;

        goto fail2;

    }

    /* ??? If host page size > target page size, this will result in a

       value larger than what we can actually support.  */

    max_len = 0x7fffffff & TARGET_PAGE_MASK;

    total_len = 0;

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

        abi_ulong base = tswapal(target_vec[i].iov_base);

        abi_long len = tswapal(target_vec[i].iov_len);

        if (len < 0) {

            err = EINVAL;

            goto fail;

        } else if (len == 0) {

            /* Zero length pointer is ignored.  */

            vec[i].iov_base = 0;

        } else {

            vec[i].iov_base = lock_user(type, base, len, copy);

            if (!vec[i].iov_base) {

                err = EFAULT;

                goto fail;

            }

            if (len > max_len - total_len) {

                len = max_len - total_len;

            }

        }

        vec[i].iov_len = len;

        total_len += len;

    }

    unlock_user(target_vec, target_addr, 0);

    return vec;

 fail:

    unlock_user(target_vec, target_addr, 0);

 fail2:

    free(vec);

    errno = err;

    return NULL;

}