SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat,

                           int dstW, int dstH, enum PixelFormat dstFormat, int flags,

                           SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)

{

    SwsContext *c;

    int i;

    int usesVFilter, usesHFilter;

    int unscaled;

    int srcRange, dstRange;

    SwsFilter dummyFilter= {NULL, NULL, NULL, NULL};

#if ARCH_X86

    if (flags & SWS_CPU_CAPS_MMX)

        __asm__ volatile("emms\n\t"::: "memory");

#endif

#if !CONFIG_RUNTIME_CPUDETECT //ensure that the flags match the compiled variant if cpudetect is off

    flags &= ~(SWS_CPU_CAPS_MMX|SWS_CPU_CAPS_MMX2|SWS_CPU_CAPS_3DNOW|SWS_CPU_CAPS_ALTIVEC|SWS_CPU_CAPS_BFIN);

    flags |= ff_hardcodedcpuflags();

#endif /* CONFIG_RUNTIME_CPUDETECT */

    if (!rgb15to16) sws_rgb2rgb_init(flags);

    unscaled = (srcW == dstW && srcH == dstH);

    srcRange = handle_jpeg(&srcFormat);

    dstRange = handle_jpeg(&dstFormat);

    if (!isSupportedIn(srcFormat)) {

        av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as input pixel format\n", sws_format_name(srcFormat));

        return NULL;

    }

    if (!isSupportedOut(dstFormat)) {

        av_log(NULL, AV_LOG_ERROR, "swScaler: %s is not supported as output pixel format\n", sws_format_name(dstFormat));

        return NULL;

    }

    i= flags & ( SWS_POINT

                |SWS_AREA

                |SWS_BILINEAR

                |SWS_FAST_BILINEAR

                |SWS_BICUBIC

                |SWS_X

                |SWS_GAUSS

                |SWS_LANCZOS

                |SWS_SINC

                |SWS_SPLINE

                |SWS_BICUBLIN);

    if(!i || (i & (i-1))) {

        av_log(NULL, AV_LOG_ERROR, "swScaler: Exactly one scaler algorithm must be chosen\n");

        return NULL;

    }

    /* sanity check */

    if (srcW<4 || srcH<1 || dstW<8 || dstH<1) { //FIXME check if these are enough and try to lowwer them after fixing the relevant parts of the code

        av_log(NULL, AV_LOG_ERROR, "swScaler: %dx%d -> %dx%d is invalid scaling dimension\n",

               srcW, srcH, dstW, dstH);

        return NULL;

    }

    if(srcW > VOFW || dstW > VOFW) {

        av_log(NULL, AV_LOG_ERROR, "swScaler: Compile-time maximum width is "AV_STRINGIFY(VOFW)" change VOF/VOFW and recompile\n");

        return NULL;

    }

    if (!dstFilter) dstFilter= &dummyFilter;

    if (!srcFilter) srcFilter= &dummyFilter;

    FF_ALLOCZ_OR_GOTO(NULL, c, sizeof(SwsContext), fail);

    c->av_class = &sws_context_class;

    c->srcW= srcW;

    c->srcH= srcH;

    c->dstW= dstW;

    c->dstH= dstH;

    c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;

    c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;

    c->flags= flags;

    c->dstFormat= dstFormat;

    c->srcFormat= srcFormat;

    c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]);

    c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]);

    c->vRounder= 4* 0x0001000100010001ULL;

    usesVFilter = (srcFilter->lumV && srcFilter->lumV->length>1) ||

                  (srcFilter->chrV && srcFilter->chrV->length>1) ||

                  (dstFilter->lumV && dstFilter->lumV->length>1) ||

                  (dstFilter->chrV && dstFilter->chrV->length>1);

    usesHFilter = (srcFilter->lumH && srcFilter->lumH->length>1) ||

                  (srcFilter->chrH && srcFilter->chrH->length>1) ||

                  (dstFilter->lumH && dstFilter->lumH->length>1) ||

                  (dstFilter->chrH && dstFilter->chrH->length>1);

    getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);

    getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);

    // reuse chroma for 2 pixels RGB/BGR unless user wants full chroma interpolation

    if (isAnyRGB(dstFormat) && !(flags&SWS_FULL_CHR_H_INT)) c->chrDstHSubSample=1;

    // drop some chroma lines if the user wants it

    c->vChrDrop= (flags&SWS_SRC_V_CHR_DROP_MASK)>>SWS_SRC_V_CHR_DROP_SHIFT;

    c->chrSrcVSubSample+= c->vChrDrop;

    // drop every other pixel for chroma calculation unless user wants full chroma

    if (isAnyRGB(srcFormat) && !(flags&SWS_FULL_CHR_H_INP)

      && srcFormat!=PIX_FMT_RGB8      && srcFormat!=PIX_FMT_BGR8

      && srcFormat!=PIX_FMT_RGB4      && srcFormat!=PIX_FMT_BGR4

      && srcFormat!=PIX_FMT_RGB4_BYTE && srcFormat!=PIX_FMT_BGR4_BYTE

      && ((dstW>>c->chrDstHSubSample) <= (srcW>>1) || (flags&(SWS_FAST_BILINEAR|SWS_POINT))))

        c->chrSrcHSubSample=1;

    if (param) {

        c->param[0] = param[0];

        c->param[1] = param[1];

    } else {

        c->param[0] =

        c->param[1] = SWS_PARAM_DEFAULT;

    }

    // Note the -((-x)>>y) is so that we always round toward +inf.

    c->chrSrcW= -((-srcW) >> c->chrSrcHSubSample);

    c->chrSrcH= -((-srcH) >> c->chrSrcVSubSample);

    c->chrDstW= -((-dstW) >> c->chrDstHSubSample);

    c->chrDstH= -((-dstH) >> c->chrDstVSubSample);

    sws_setColorspaceDetails(c, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT], srcRange, ff_yuv2rgb_coeffs[SWS_CS_DEFAULT] /* FIXME*/, dstRange, 0, 1<<16, 1<<16);

    /* unscaled special cases */

    if (unscaled && !usesHFilter && !usesVFilter && (srcRange == dstRange || isAnyRGB(dstFormat))) {

        ff_get_unscaled_swscale(c);

        if (c->swScale) {

            if (flags&SWS_PRINT_INFO)

                av_log(c, AV_LOG_INFO, "using unscaled %s -> %s special converter\n",

                       sws_format_name(srcFormat), sws_format_name(dstFormat));

            return c;

        }

    }

    if (flags & SWS_CPU_CAPS_MMX2) {

        c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;

        if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) {

            if (flags&SWS_PRINT_INFO)

                av_log(c, AV_LOG_INFO, "output width is not a multiple of 32 -> no MMX2 scaler\n");

        }

        if (usesHFilter) c->canMMX2BeUsed=0;

    }

    else

        c->canMMX2BeUsed=0;

    c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;

    c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;

    // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst

    // but only for the FAST_BILINEAR mode otherwise do correct scaling

    // n-2 is the last chrominance sample available

    // this is not perfect, but no one should notice the difference, the more correct variant

    // would be like the vertical one, but that would require some special code for the

    // first and last pixel

    if (flags&SWS_FAST_BILINEAR) {

        if (c->canMMX2BeUsed) {

            c->lumXInc+= 20;

            c->chrXInc+= 20;

        }

        //we don't use the x86 asm scaler if MMX is available

        else if (flags & SWS_CPU_CAPS_MMX) {

            c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;

            c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;

        }

    }

    /* precalculate horizontal scaler filter coefficients */

    {

#if ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) && CONFIG_GPL

// can't downscale !!!

        if (c->canMMX2BeUsed && (flags & SWS_FAST_BILINEAR)) {

            c->lumMmx2FilterCodeSize = initMMX2HScaler(      dstW, c->lumXInc, NULL, NULL, NULL, 8);

            c->chrMmx2FilterCodeSize = initMMX2HScaler(c->chrDstW, c->chrXInc, NULL, NULL, NULL, 4);

#ifdef MAP_ANONYMOUS

            c->lumMmx2FilterCode = mmap(NULL, c->lumMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

            c->chrMmx2FilterCode = mmap(NULL, c->chrMmx2FilterCodeSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

#elif HAVE_VIRTUALALLOC

            c->lumMmx2FilterCode = VirtualAlloc(NULL, c->lumMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

            c->chrMmx2FilterCode = VirtualAlloc(NULL, c->chrMmx2FilterCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

#else

            c->lumMmx2FilterCode = av_malloc(c->lumMmx2FilterCodeSize);

            c->chrMmx2FilterCode = av_malloc(c->chrMmx2FilterCodeSize);

#endif

            FF_ALLOCZ_OR_GOTO(c, c->hLumFilter   , (dstW        /8+8)*sizeof(int16_t), fail);

            FF_ALLOCZ_OR_GOTO(c, c->hChrFilter   , (c->chrDstW  /4+8)*sizeof(int16_t), fail);

            FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW      /2/8+8)*sizeof(int32_t), fail);

            FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW/2/4+8)*sizeof(int32_t), fail);

            initMMX2HScaler(      dstW, c->lumXInc, c->lumMmx2FilterCode, c->hLumFilter, c->hLumFilterPos, 8);

            initMMX2HScaler(c->chrDstW, c->chrXInc, c->chrMmx2FilterCode, c->hChrFilter, c->hChrFilterPos, 4);

#ifdef MAP_ANONYMOUS

            mprotect(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, PROT_EXEC | PROT_READ);

            mprotect(c->chrMmx2FilterCode, c->chrMmx2FilterCodeSize, PROT_EXEC | PROT_READ);

#endif

        } else

#endif /* ARCH_X86 && (HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT) && CONFIG_GPL */

        {

            const int filterAlign=

                (flags & SWS_CPU_CAPS_MMX) ? 4 :

                (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :

                1;

            if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc,

                           srcW      ,       dstW, filterAlign, 1<<14,

                           (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC)  : flags,

                           srcFilter->lumH, dstFilter->lumH, c->param) < 0)

            if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc,

                           c->chrSrcW, c->chrDstW, filterAlign, 1<<14,

                           (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,

                           srcFilter->chrH, dstFilter->chrH, c->param) < 0)

        }

    } // initialize horizontal stuff

    /* precalculate vertical scaler filter coefficients */

    {

        const int filterAlign=

            (flags & SWS_CPU_CAPS_MMX) && (flags & SWS_ACCURATE_RND) ? 2 :

            (flags & SWS_CPU_CAPS_ALTIVEC) ? 8 :

            1;

        if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc,

                       srcH      ,        dstH, filterAlign, (1<<12),

                       (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC)  : flags,

                       srcFilter->lumV, dstFilter->lumV, c->param) < 0)

        if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc,

                       c->chrSrcH, c->chrDstH, filterAlign, (1<<12),

                       (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags,

                       srcFilter->chrV, dstFilter->chrV, c->param) < 0)

#if ARCH_PPC && (HAVE_ALTIVEC || CONFIG_RUNTIME_CPUDETECT)

        FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof (vector signed short)*c->vLumFilterSize*c->dstH, fail);

        FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof (vector signed short)*c->vChrFilterSize*c->chrDstH, fail);

        for (i=0;i<c->vLumFilterSize*c->dstH;i++) {

            int j;

            short *p = (short *)&c->vYCoeffsBank[i];

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

                p[j] = c->vLumFilter[i];

        }

        for (i=0;i<c->vChrFilterSize*c->chrDstH;i++) {

            int j;

            short *p = (short *)&c->vCCoeffsBank[i];

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

                p[j] = c->vChrFilter[i];

        }

#endif

    }

    // calculate buffer sizes so that they won't run out while handling these damn slices

    c->vLumBufSize= c->vLumFilterSize;

    c->vChrBufSize= c->vChrFilterSize;

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

        int chrI= i*c->chrDstH / dstH;

        int nextSlice= FFMAX(c->vLumFilterPos[i   ] + c->vLumFilterSize - 1,

                           ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<c->chrSrcVSubSample));

        nextSlice>>= c->chrSrcVSubSample;

        nextSlice<<= c->chrSrcVSubSample;

        if (c->vLumFilterPos[i   ] + c->vLumBufSize < nextSlice)

            c->vLumBufSize= nextSlice - c->vLumFilterPos[i];

        if (c->vChrFilterPos[chrI] + c->vChrBufSize < (nextSlice>>c->chrSrcVSubSample))

            c->vChrBufSize= (nextSlice>>c->chrSrcVSubSample) - c->vChrFilterPos[chrI];

    }

    // allocate pixbufs (we use dynamic allocation because otherwise we would need to

    // allocate several megabytes to handle all possible cases)

    FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);

    FF_ALLOC_OR_GOTO(c, c->chrPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail);

    if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat))

        FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail);

    //Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000)

    /* align at 16 bytes for AltiVec */

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

        FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], VOF+1, fail);

        c->lumPixBuf[i] = c->lumPixBuf[i+c->vLumBufSize];

    }

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

        FF_ALLOC_OR_GOTO(c, c->chrPixBuf[i+c->vChrBufSize], (VOF+1)*2, fail);

        c->chrPixBuf[i] = c->chrPixBuf[i+c->vChrBufSize];

    }

    if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf)

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

            FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf[i+c->vLumBufSize], VOF+1, fail);

            c->alpPixBuf[i] = c->alpPixBuf[i+c->vLumBufSize];

        }

    //try to avoid drawing green stuff between the right end and the stride end

    for (i=0; i<c->vChrBufSize; i++) memset(c->chrPixBuf[i], 64, (VOF+1)*2);

    assert(2*VOFW == VOF);

    assert(c->chrDstH <= dstH);

    if (flags&SWS_PRINT_INFO) {

        if (flags&SWS_FAST_BILINEAR)

            av_log(c, AV_LOG_INFO, "FAST_BILINEAR scaler, ");

        else if (flags&SWS_BILINEAR)

            av_log(c, AV_LOG_INFO, "BILINEAR scaler, ");

        else if (flags&SWS_BICUBIC)

            av_log(c, AV_LOG_INFO, "BICUBIC scaler, ");

        else if (flags&SWS_X)

            av_log(c, AV_LOG_INFO, "Experimental scaler, ");

        else if (flags&SWS_POINT)

            av_log(c, AV_LOG_INFO, "Nearest Neighbor / POINT scaler, ");

        else if (flags&SWS_AREA)

            av_log(c, AV_LOG_INFO, "Area Averaging scaler, ");

        else if (flags&SWS_BICUBLIN)

            av_log(c, AV_LOG_INFO, "luma BICUBIC / chroma BILINEAR scaler, ");

        else if (flags&SWS_GAUSS)

            av_log(c, AV_LOG_INFO, "Gaussian scaler, ");

        else if (flags&SWS_SINC)

            av_log(c, AV_LOG_INFO, "Sinc scaler, ");

        else if (flags&SWS_LANCZOS)

            av_log(c, AV_LOG_INFO, "Lanczos scaler, ");

        else if (flags&SWS_SPLINE)

            av_log(c, AV_LOG_INFO, "Bicubic spline scaler, ");

        else

            av_log(c, AV_LOG_INFO, "ehh flags invalid?! ");

        av_log(c, AV_LOG_INFO, "from %s to %s%s ",

               sws_format_name(srcFormat),

#ifdef DITHER1XBPP

               dstFormat == PIX_FMT_BGR555 || dstFormat == PIX_FMT_BGR565 ? "dithered " : "",

#else

               "",

#endif

               sws_format_name(dstFormat));

        if (flags & SWS_CPU_CAPS_MMX2)

            av_log(c, AV_LOG_INFO, "using MMX2\n");

        else if (flags & SWS_CPU_CAPS_3DNOW)

            av_log(c, AV_LOG_INFO, "using 3DNOW\n");

        else if (flags & SWS_CPU_CAPS_MMX)

            av_log(c, AV_LOG_INFO, "using MMX\n");

        else if (flags & SWS_CPU_CAPS_ALTIVEC)

            av_log(c, AV_LOG_INFO, "using AltiVec\n");

        else

            av_log(c, AV_LOG_INFO, "using C\n");

        if (flags & SWS_CPU_CAPS_MMX) {

            if (c->canMMX2BeUsed && (flags&SWS_FAST_BILINEAR))

                av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR MMX2 scaler for horizontal scaling\n");

            else {

                if (c->hLumFilterSize==4)

                    av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal luminance scaling\n");

                else if (c->hLumFilterSize==8)

                    av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal luminance scaling\n");

                else

                    av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal luminance scaling\n");

                if (c->hChrFilterSize==4)

                    av_log(c, AV_LOG_VERBOSE, "using 4-tap MMX scaler for horizontal chrominance scaling\n");

                else if (c->hChrFilterSize==8)

                    av_log(c, AV_LOG_VERBOSE, "using 8-tap MMX scaler for horizontal chrominance scaling\n");

                else

                    av_log(c, AV_LOG_VERBOSE, "using n-tap MMX scaler for horizontal chrominance scaling\n");

            }

        } else {

#if ARCH_X86

            av_log(c, AV_LOG_VERBOSE, "using x86 asm scaler for horizontal scaling\n");

#else

            if (flags & SWS_FAST_BILINEAR)

                av_log(c, AV_LOG_VERBOSE, "using FAST_BILINEAR C scaler for horizontal scaling\n");

            else

                av_log(c, AV_LOG_VERBOSE, "using C scaler for horizontal scaling\n");

#endif

        }

        if (isPlanarYUV(dstFormat)) {

            if (c->vLumFilterSize==1)

                av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

            else

                av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (YV12 like)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

        } else {

            if (c->vLumFilterSize==1 && c->vChrFilterSize==2)

                av_log(c, AV_LOG_VERBOSE, "using 1-tap %s \"scaler\" for vertical luminance scaling (BGR)\n"

                       "      2-tap scaler for vertical chrominance scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

            else if (c->vLumFilterSize==2 && c->vChrFilterSize==2)

                av_log(c, AV_LOG_VERBOSE, "using 2-tap linear %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

            else

                av_log(c, AV_LOG_VERBOSE, "using n-tap %s scaler for vertical scaling (BGR)\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

        }

        if (dstFormat==PIX_FMT_BGR24)

            av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR24 converter\n",

                   (flags & SWS_CPU_CAPS_MMX2) ? "MMX2" : ((flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C"));

        else if (dstFormat==PIX_FMT_RGB32)

            av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR32 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

        else if (dstFormat==PIX_FMT_BGR565)

            av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR16 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

        else if (dstFormat==PIX_FMT_BGR555)

            av_log(c, AV_LOG_VERBOSE, "using %s YV12->BGR15 converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");

        av_log(c, AV_LOG_VERBOSE, "%dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);

        av_log(c, AV_LOG_DEBUG, "lum srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",

               c->srcW, c->srcH, c->dstW, c->dstH, c->lumXInc, c->lumYInc);

        av_log(c, AV_LOG_DEBUG, "chr srcW=%d srcH=%d dstW=%d dstH=%d xInc=%d yInc=%d\n",

               c->chrSrcW, c->chrSrcH, c->chrDstW, c->chrDstH, c->chrXInc, c->chrYInc);

    }

    c->swScale= ff_getSwsFunc(c);

    return c;

fail:

    sws_freeContext(c);

    return NULL;

}


static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){

    const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);

    void *dst;

    if(!o || o->offset<=0)

        return NULL;

    if(o->max*den < num*intnum || o->min*den > num*intnum) {

        av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name);

        return NULL;

    }

    dst= ((uint8_t*)obj) + o->offset;

    switch(o->type){

    case FF_OPT_TYPE_FLAGS:

    case FF_OPT_TYPE_INT:   *(int       *)dst= llrint(num/den)*intnum; break;

    case FF_OPT_TYPE_INT64: *(int64_t   *)dst= llrint(num/den)*intnum; break;

    case FF_OPT_TYPE_FLOAT: *(float     *)dst= num*intnum/den;         break;

    case FF_OPT_TYPE_DOUBLE:*(double    *)dst= num*intnum/den;         break;

    case FF_OPT_TYPE_RATIONAL:

        if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den};

        else                *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);

        break;

    default:

        return NULL;

    }

    return o;

}


static void jpeg2000_flush(Jpeg2000DecoderContext *s)

{

    if (*s->buf == 0xff)

        s->buf++;

    s->bit_index = 8;

    s->buf++;

}


static void setup_frame(int sig, struct target_sigaction *ka,

                        target_sigset_t *set, CPUMBState *env)

{

    struct target_signal_frame *frame;

    abi_ulong frame_addr;

    int err = 0;

    int i;

    frame_addr = get_sigframe(ka, env, sizeof *frame);

    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))

        goto badframe;

    /* Save the mask.  */

    __put_user(set->sig[0], &frame->uc.tuc_mcontext.oldmask);

    if (err)

        goto badframe;

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

        if (__put_user(set->sig[i], &frame->extramask[i - 1]))

            goto badframe;

    }

    setup_sigcontext(&frame->uc.tuc_mcontext, env);

    /* Set up to return from userspace. If provided, use a stub

       already in userspace. */

    /* minus 8 is offset to cater for "rtsd r15,8" offset */

    if (ka->sa_flags & TARGET_SA_RESTORER) {

        env->regs[15] = ((unsigned long)ka->sa_restorer)-8;

    } else {

        uint32_t t;

        /* Note, these encodings are _big endian_! */

        /* addi r12, r0, __NR_sigreturn */

        t = 0x31800000UL | TARGET_NR_sigreturn;

        __put_user(t, frame->tramp + 0);

        /* brki r14, 0x8 */

        t = 0xb9cc0008UL;

        __put_user(t, frame->tramp + 1);

        /* Return from sighandler will jump to the tramp.

           Negative 8 offset because return is rtsd r15, 8 */

        env->regs[15] = ((unsigned long)frame->tramp) - 8;

    }

    if (err)

        goto badframe;

    /* Set up registers for signal handler */

    env->regs[1] = frame_addr;

    /* Signal handler args: */

    env->regs[5] = sig; /* Arg 0: signum */

    env->regs[6] = 0;

    /* arg 1: sigcontext */

    env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);

    /* Offset of 4 to handle microblaze rtid r14, 0 */

    env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;

    unlock_user_struct(frame, frame_addr, 1);

    return;

  badframe:

    unlock_user_struct(frame, frame_addr, 1);

    force_sig(TARGET_SIGSEGV);

}


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

{

    ISADevice *isa = ISA_DEVICE(dev);

    I8257State *d = I8257(dev);

    int i;

    memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d,

                          "dma-chan", 8 << d->dshift);

    memory_region_add_subregion(isa_address_space_io(isa),

                                d->base, &d->channel_io);

    isa_register_portio_list(isa, d->page_base, page_portio_list, d,

                             "dma-page");

    if (d->pageh_base >= 0) {

        isa_register_portio_list(isa, d->pageh_base, pageh_portio_list, d,

                                 "dma-pageh");

    }

    memory_region_init_io(&d->cont_io, OBJECT(isa), &cont_io_ops, d,

                          "dma-cont", 8 << d->dshift);

    memory_region_add_subregion(isa_address_space_io(isa),

                                d->base + (8 << d->dshift), &d->cont_io);

    for (i = 0; i < ARRAY_SIZE(d->regs); ++i) {

        d->regs[i].transfer_handler = i8257_phony_handler;

    }

    d->dma_bh = qemu_bh_new(i8257_dma_run, d);

}


static void flush_dpb(AVCodecContext *avctx){

    H264Context *h= avctx->priv_data;

    int i;

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

        h->delayed_pic[i]= NULL;

    h->delayed_output_pic= NULL;

    idr(h);

}


void pcie_aer_root_init(PCIDevice *dev)

{

    uint16_t pos = dev->exp.aer_cap;

    pci_set_long(dev->wmask + pos + PCI_ERR_ROOT_COMMAND,

                 PCI_ERR_ROOT_CMD_EN_MASK);

    pci_set_long(dev->w1cmask + pos + PCI_ERR_ROOT_STATUS,

                 PCI_ERR_ROOT_STATUS_REPORT_MASK);

}


static void mpegvideo_extract_headers(AVCodecParserContext *s,
                                      AVCodecContext *avctx,
                                      const uint8_t *buf, int buf_size)
{
    ParseContext1 *pc = s->priv_data;
    const uint8_t *buf_end;
    const uint8_t *buf_start= buf;
    uint32_t start_code;
    int frame_rate_index, ext_type, bytes_left;
    int frame_rate_ext_n, frame_rate_ext_d;
    int picture_structure, top_field_first, repeat_first_field, progressive_frame;
    int horiz_size_ext, vert_size_ext, bit_rate_ext;
//FIXME replace the crap with get_bits()
    s->repeat_pict = 0;
    buf_end = buf + buf_size;
    while (buf < buf_end) {
        start_code= -1;
        buf= ff_find_start_code(buf, buf_end, &start_code);
        bytes_left = buf_end - buf;
        switch(start_code) {
        case PICTURE_START_CODE:
            if (bytes_left >= 2) {
                s->pict_type = (buf[1] >> 3) & 7;
            }
            break;
        case SEQ_START_CODE:
            if (bytes_left >= 7) {
                pc->width  = (buf[0] << 4) | (buf[1] >> 4);
                pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
                avcodec_set_dimensions(avctx, pc->width, pc->height);
                frame_rate_index = buf[3] & 0xf;
                pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num;
                pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den;
                avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
                avctx->codec_id = CODEC_ID_MPEG1VIDEO;
                avctx->sub_id = 1;
            }
            break;
        case EXT_START_CODE:
            if (bytes_left >= 1) {
                ext_type = (buf[0] >> 4);
                switch(ext_type) {
                case 0x1: /* sequence extension */
                    if (bytes_left >= 6) {
                        horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
                        vert_size_ext = (buf[2] >> 5) & 3;
                        bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
                        frame_rate_ext_n = (buf[5] >> 5) & 3;
                        frame_rate_ext_d = (buf[5] & 0x1f);
                        pc->progressive_sequence = buf[1] & (1 << 3);
                        avctx->has_b_frames= !(buf[5] >> 7);
                        pc->width  |=(horiz_size_ext << 12);
                        pc->height |=( vert_size_ext << 12);
                        avctx->bit_rate += (bit_rate_ext << 18) * 400;
                        avcodec_set_dimensions(avctx, pc->width, pc->height);
                        avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1);
                        avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
                        avctx->codec_id = CODEC_ID_MPEG2VIDEO;
                        avctx->sub_id = 2; /* forces MPEG2 */
                    }
                    break;
                case 0x8: /* picture coding extension */
                    if (bytes_left >= 5) {
                        picture_structure = buf[2]&3;
                        top_field_first = buf[3] & (1 << 7);
                        repeat_first_field = buf[3] & (1 << 1);
                        progressive_frame = buf[4] & (1 << 7);
                        /* check if we must repeat the frame */
                        if (repeat_first_field) {
                            if (pc->progressive_sequence) {
                                if (top_field_first)
                                    s->repeat_pict = 4;
                                else
                                    s->repeat_pict = 2;
                            } else if (progressive_frame) {
                                s->repeat_pict = 1;
                            }
                        }
                    }
                    break;
                }
            }
            break;
        case -1:
            goto the_end;
        default:
            /* we stop parsing when we encounter a slice. It ensures
               that this function takes a negligible amount of time */
            if (start_code >= SLICE_MIN_START_CODE &&
                start_code <= SLICE_MAX_START_CODE)
                goto the_end;
            break;
        }
    }
 the_end: ;
}


static inline void RENAME(yuv2yuyv422_2)(SwsContext *c, const uint16_t *buf0,

                                         const uint16_t *buf1, const uint16_t *ubuf0,

                                         const uint16_t *ubuf1, const uint16_t *vbuf0,

                                         const uint16_t *vbuf1, const uint16_t *abuf0,

                                         const uint16_t *abuf1, uint8_t *dest,

                                         int dstW, int yalpha, int uvalpha, int y)

{

    x86_reg uv_off = c->uv_off << 1;

    //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(

    __asm__ volatile(

        "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

        "mov %4, %%"REG_b"                        \n\t"

        "push %%"REG_BP"                        \n\t"

        YSCALEYUV2PACKED(%%REGBP, %5, %6)

        WRITEYUY2(%%REGb, 8280(%5), %%REGBP)

        "pop %%"REG_BP"                         \n\t"

        "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

        :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

           "a" (&c->redDither), "m"(uv_off)

    );

}


static int dc1394_read_header(AVFormatContext *c)
{
    dc1394_data* dc1394 = c->priv_data;
    dc1394camera_list_t *list;
    int res, i;
    const struct dc1394_frame_format *fmt = NULL;
    const struct dc1394_frame_rate *fps = NULL;
    if (dc1394_read_common(c, &fmt, &fps) != 0)
       return -1;
    /* Now let us prep the hardware. */
    dc1394->d = dc1394_new();
    if (dc1394_camera_enumerate(dc1394->d, &list) != DC1394_SUCCESS || !list) {
        av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera.\n");
    if (list->num == 0) {
        av_log(c, AV_LOG_ERROR, "No cameras found.\n");
    /* FIXME: To select a specific camera I need to search in list its guid */
    dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid);
    if (list->num > 1) {
        av_log(c, AV_LOG_INFO, "Working with the first camera found\n");
    /* Freeing list of cameras */
    dc1394_camera_free_list (list);
    /* Select MAX Speed possible from the cam */
    if (dc1394->camera->bmode_capable>0) {
       dc1394_video_set_operation_mode(dc1394->camera, DC1394_OPERATION_MODE_1394B);
       i = DC1394_ISO_SPEED_800;
    } else {
       i = DC1394_ISO_SPEED_400;
    for (res = DC1394_FAILURE; i >= DC1394_ISO_SPEED_MIN && res != DC1394_SUCCESS; i--) {
            res=dc1394_video_set_iso_speed(dc1394->camera, i);
    if (res != DC1394_SUCCESS) {
        av_log(c, AV_LOG_ERROR, "Couldn't set ISO Speed\n");
        goto out_camera;
    if (dc1394_video_set_mode(dc1394->camera, fmt->frame_size_id) != DC1394_SUCCESS) {
        av_log(c, AV_LOG_ERROR, "Couldn't set video format\n");
        goto out_camera;
    if (dc1394_video_set_framerate(dc1394->camera,fps->frame_rate_id) != DC1394_SUCCESS) {
        av_log(c, AV_LOG_ERROR, "Couldn't set framerate %d \n",fps->frame_rate);
        goto out_camera;
    if (dc1394_capture_setup(dc1394->camera, 10, DC1394_CAPTURE_FLAGS_DEFAULT)!=DC1394_SUCCESS) {
        av_log(c, AV_LOG_ERROR, "Cannot setup camera \n");
        goto out_camera;
    if (dc1394_video_set_transmission(dc1394->camera, DC1394_ON) !=DC1394_SUCCESS) {
        av_log(c, AV_LOG_ERROR, "Cannot start capture\n");
        goto out_camera;
    return 0;
out_camera:
    dc1394_capture_stop(dc1394->camera);
    dc1394_video_set_transmission(dc1394->camera, DC1394_OFF);
    dc1394_camera_free (dc1394->camera);
out:
    dc1394_free(dc1394->d);
    return -1;


static void error_mem_write(void *opaque, hwaddr addr,

                            uint64_t value, unsigned size)

{

    abort();

}


static void spitz_common_init(MachineState *machine,

                              enum spitz_model_e model, int arm_id)

{

    PXA2xxState *mpu;

    DeviceState *scp0, *scp1 = NULL;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *rom = g_new(MemoryRegion, 1);

    const char *cpu_model = machine->cpu_model;

    if (!cpu_model)

        cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";

    /* Setup CPU & memory */

    mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size, cpu_model);

    sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);

    memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_abort);

    vmstate_register_ram_global(rom);

    memory_region_set_readonly(rom, true);

    memory_region_add_subregion(address_space_mem, 0, rom);

    /* Setup peripherals */

    spitz_keyboard_register(mpu);

    spitz_ssp_attach(mpu);

    scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);

    if (model != akita) {

        scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);

    }

    spitz_scoop_gpio_setup(mpu, scp0, scp1);

    spitz_gpio_setup(mpu, (model == akita) ? 1 : 2);

    spitz_i2c_setup(mpu);

    if (model == akita)

        spitz_akita_i2c_setup(mpu);

    if (model == terrier)

        /* A 6.0 GB microdrive is permanently sitting in CF slot 1.  */

        spitz_microdrive_attach(mpu, 1);

    else if (model != akita)

        /* A 4.0 GB microdrive is permanently sitting in CF slot 0.  */

        spitz_microdrive_attach(mpu, 0);

    spitz_binfo.kernel_filename = machine->kernel_filename;

    spitz_binfo.kernel_cmdline = machine->kernel_cmdline;

    spitz_binfo.initrd_filename = machine->initrd_filename;

    spitz_binfo.board_id = arm_id;

    arm_load_kernel(mpu->cpu, &spitz_binfo);

    sl_bootparam_write(SL_PXA_PARAM_BASE);

}


static void blk_mig_read_cb(void *opaque, int ret)

{

    BlkMigBlock *blk = opaque;

    blk_mig_lock();

    blk->ret = ret;

    QSIMPLEQ_INSERT_TAIL(&block_mig_state.blk_list, blk, entry);

    bmds_set_aio_inflight(blk->bmds, blk->sector, blk->nr_sectors, 0);

    block_mig_state.submitted--;

    block_mig_state.read_done++;

    assert(block_mig_state.submitted >= 0);

    blk_mig_unlock();

}


static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)

{

    int compno;

    int x;

    int y;

    int *image_line;

    int frame_index;

    const int numcomps = image->numcomps;

    uint16_t *frame_ptr = (uint16_t*)frame->data[0];

    for (compno = 0; compno < numcomps; ++compno) {

        if (image->comps[compno].w > frame->linesize[0] / numcomps) {

            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");

            return 0;

        }

    }

    for (compno = 0; compno < numcomps; ++compno) {

        for (y = 0; y < avctx->height; ++y) {

            image_line = image->comps[compno].data + y * image->comps[compno].w;

            frame_index = y * (frame->linesize[0] / 2) + compno;

            for (x = 0; x < avctx->width; ++x) {

                image_line[x] = frame_ptr[frame_index];

                frame_index += numcomps;

            }

            for (; x < image->comps[compno].w; ++x) {

                image_line[x] = image_line[x - 1];

            }

        }

        for (; y < image->comps[compno].h; ++y) {

            image_line = image->comps[compno].data + y * image->comps[compno].w;

            for (x = 0; x < image->comps[compno].w; ++x) {

                image_line[x] = image_line[x - image->comps[compno].w];

            }

        }

    }

    return 1;

}


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

{

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    k->is_bridge = 1;

    k->vendor_id = PCI_VENDOR_ID_INTEL;

    k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;

    k->revision = ICH9_D2P_A2_REVISION;

    k->init = i82801b11_bridge_initfn;

    k->config_write = pci_bridge_write_config;

    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);

}


static void tcg_handle_interrupt(CPUArchState *env, int mask)

{

    CPUState *cpu = ENV_GET_CPU(env);

    int old_mask;

    old_mask = env->interrupt_request;

    env->interrupt_request |= mask;

    /*

     * If called from iothread context, wake the target cpu in

     * case its halted.

     */

    if (!qemu_cpu_is_self(cpu)) {

        qemu_cpu_kick(cpu);

        return;

    }

    if (use_icount) {

        env->icount_decr.u16.high = 0xffff;

        if (!can_do_io(env)

            && (mask & ~old_mask) != 0) {

            cpu_abort(env, "Raised interrupt while not in I/O function");

        }

    } else {

        cpu_unlink_tb(cpu);

    }

}


static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert)

{

    int data_off = bytestream2_get_le16(&s->gb), y;

    GetByteContext data_ptr;

    if (bytestream2_get_bytes_left(&s->gb) < data_off)

        return AVERROR_INVALIDDATA;

    bytestream2_init(&data_ptr, s->gb.buffer + data_off, bytestream2_get_bytes_left(&s->gb) - data_off);

    while (s->gb.buffer < data_ptr.buffer_start) {

        int i, j;

        int length = bytestream2_get_byte(&s->gb);

        int x = bytestream2_get_byte(&s->gb) + ((length & 0x80) << 1);

        length &= 0x7F;

        if (length==0) {

            y += x;

            continue;

        }

        if (y + half_vert >= s->avctx->height)

            return 0;

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

            int replace_array = bytestream2_get_byte(&s->gb);

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

                int replace = (replace_array >> (7-j)) & 1;

                if (replace) {

                    int color = bytestream2_get_byte(&data_ptr);

                    s->frame.data[0][y*s->frame.linesize[0] + x] = color;

                    if (half_horiz)

                        s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color;

                    if (half_vert) {

                        s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color;

                        if (half_horiz)

                            s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color;

                    }

                }

                x += 1 + half_horiz;

            }

        }

        y += 1 + half_vert;

    }

    return 0;

}


int parse_host_src_port(struct sockaddr_in *haddr,

                        struct sockaddr_in *saddr,

                        const char *input_str)

{

    char *str = strdup(input_str);

    char *host_str = str;

    char *src_str;

    const char *src_str2;

    char *ptr;

    /*

     * Chop off any extra arguments at the end of the string which

     * would start with a comma, then fill in the src port information

     * if it was provided else use the "any address" and "any port".

     */

    if ((ptr = strchr(str,',')))

        *ptr = '\0';

    if ((src_str = strchr(input_str,'@'))) {

        *src_str = '\0';

        src_str++;

    }

    if (parse_host_port(haddr, host_str) < 0)

        goto fail;

    src_str2 = src_str;

    if (!src_str || *src_str == '\0')

        src_str2 = ":0";

    if (parse_host_port(saddr, src_str2) < 0)

        goto fail;

    free(str);

    return(0);

fail:

    free(str);

    return -1;

}


static av_cold int decode_end(AVCodecContext *avctx)

{

    ALSDecContext *ctx = avctx->priv_data;

    av_freep(&ctx->sconf.chan_pos);

    ff_bgmc_end(&ctx->bgmc_lut, &ctx->bgmc_lut_status);

    av_freep(&ctx->const_block);

    av_freep(&ctx->shift_lsbs);

    av_freep(&ctx->opt_order);

    av_freep(&ctx->store_prev_samples);

    av_freep(&ctx->use_ltp);

    av_freep(&ctx->ltp_lag);

    av_freep(&ctx->ltp_gain);

    av_freep(&ctx->ltp_gain_buffer);

    av_freep(&ctx->quant_cof);

    av_freep(&ctx->lpc_cof);

    av_freep(&ctx->quant_cof_buffer);

    av_freep(&ctx->lpc_cof_buffer);

    av_freep(&ctx->lpc_cof_reversed_buffer);

    av_freep(&ctx->prev_raw_samples);

    av_freep(&ctx->raw_samples);

    av_freep(&ctx->raw_buffer);

    av_freep(&ctx->chan_data);

    av_freep(&ctx->chan_data_buffer);

    av_freep(&ctx->reverted_channels);

    return 0;

}


static int xan_decode_init(AVCodecContext *avctx)
{
    XanContext *s = avctx->priv_data;
    int i;
    s->avctx = avctx;
    if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
        (s->avctx->palctrl == NULL)) {
        av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
    }
    avctx->pix_fmt = PIX_FMT_PAL8;
    avctx->has_b_frames = 0;
    dsputil_init(&s->dsp, avctx);
    /* initialize the RGB -> YUV tables */
    for (i = 0; i < 256; i++) {
        y_r_table[i] = Y_R * i;
        y_g_table[i] = Y_G * i;
        y_b_table[i] = Y_B * i;
        u_r_table[i] = U_R * i;
        u_g_table[i] = U_G * i;
        u_b_table[i] = U_B * i;
        v_r_table[i] = V_R * i;
        v_g_table[i] = V_G * i;
        v_b_table[i] = V_B * i;
    }
    s->buffer1 = av_malloc(avctx->width * avctx->height);
    s->buffer2 = av_malloc(avctx->width * avctx->height);
    if (!s->buffer1 || !s->buffer2)
    return 0;
}


void HELPER(cksm)(uint32_t r1, uint32_t r2)

{

    uint64_t src = get_address_31fix(r2);

    uint64_t src_len = env->regs[(r2 + 1) & 15];

    uint64_t cksm = 0;

    while (src_len >= 4) {

        cksm += ldl(src);

        cksm = cksm_overflow(cksm);

        /* move to next word */

        src_len -= 4;

        src += 4;

    }

    switch (src_len) {

    case 0:

        break;

    case 1:

        cksm += ldub(src);

        cksm = cksm_overflow(cksm);

        break;

    case 2:

        cksm += lduw(src);

        cksm = cksm_overflow(cksm);

        break;

    case 3:

        /* XXX check if this really is correct */

        cksm += lduw(src) << 8;

        cksm += ldub(src + 2);

        cksm = cksm_overflow(cksm);

        break;

    }

    /* indicate we've processed everything */

    env->regs[(r2 + 1) & 15] = 0;

    /* store result */

    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (uint32_t)cksm;

}


static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)

{

    Error *local_err = NULL;

    USBDevice *dev;

    QemuOpts *opts;

    int idx;

    opts = qemu_opts_parse(qemu_find_opts("net"), cmdline, 0);

    if (!opts) {

        return NULL;

    }

    qemu_opt_set(opts, "type", "nic");

    qemu_opt_set(opts, "model", "usb");

    idx = net_client_init(opts, 0, &local_err);

    if (local_err) {

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

        error_free(local_err);

        return NULL;

    }

    dev = usb_create(bus, "usb-net");

    qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);

    qdev_init_nofail(&dev->qdev);

    return dev;

}


static void gen_spr_book3s_pmu_sup(CPUPPCState *env)

{

    spr_register(env, SPR_POWER_MMCR0, "MMCR0",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_MMCR1, "MMCR1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_MMCRA, "MMCRA",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC1, "PMC1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC2, "PMC2",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC3, "PMC3",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC4, "PMC4",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC5, "PMC5",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_PMC6, "PMC6",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_SIAR, "SIAR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_POWER_SDAR, "SDAR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

}


size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t new_len)

{

    if (new_len <= qsb->size) {

        qsb->used = new_len;

    } else {

        qsb->used = qsb->size;

    }

    return qsb->used;

}


static void process_tns_coeffs(TemporalNoiseShaping *tns, double *coef_raw,

                               int *order_p, int w, int filt)

{

    int i, j, order = *order_p;

    int *idx = tns->coef_idx[w][filt];

    float *lpc = tns->coef[w][filt];

    float temp[TNS_MAX_ORDER] = {0.0f}, out[TNS_MAX_ORDER] = {0.0f};

    if (!order)

        return;

    /* Not what the specs say, but it's better */

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

        idx[i] = quant_array_idx(coef_raw[i], tns_tmp2_map_0_4, 16);

        lpc[i] = tns_tmp2_map_0_4[idx[i]];

    }

    /* Trim any coeff less than 0.1f from the end */

    for (i = order-1; i > -1; i--) {

        lpc[i] = (fabs(lpc[i]) > 0.1f) ? lpc[i] : 0.0f;

        if (lpc[i] != 0.0 ) {

            order = i;

            break;

        }

    }

    /* Step up procedure, convert to LPC coeffs */

    out[0] = 1.0f;

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

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

            temp[j] = out[j] + lpc[i]*out[i-j];

        }

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

            out[j] = temp[j];

        }

        out[i] = lpc[i-1];

    }

    *order_p = order;

    memcpy(lpc, out, TNS_MAX_ORDER*sizeof(float));

}


int ff_mpv_lowest_referenced_row(MpegEncContext *s, int dir)

{

    int my_max = INT_MIN, my_min = INT_MAX, qpel_shift = !s->quarter_sample;

    int my, off, i, mvs;

    if (s->picture_structure != PICT_FRAME || s->mcsel)

        goto unhandled;

    switch (s->mv_type) {

        case MV_TYPE_16X16:

            mvs = 1;

            break;

        case MV_TYPE_16X8:

            mvs = 2;

            break;

        case MV_TYPE_8X8:

            mvs = 4;

            break;

        default:

            goto unhandled;

    }

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

        my = s->mv[dir][i][1]<<qpel_shift;

        my_max = FFMAX(my_max, my);

        my_min = FFMIN(my_min, my);

    }

    off = (FFMAX(-my_min, my_max) + 63) >> 6;

    return FFMIN(FFMAX(s->mb_y + off, 0), s->mb_height-1);

unhandled:

    return s->mb_height-1;

}


static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)

{

    SSISlave *ss = SSI_SLAVE(opaque);

    ssd0323_state *s = (ssd0323_state *)opaque;

    int i;

    if (version_id != 1)

    s->cmd_len = qemu_get_be32(f);

    s->cmd = qemu_get_be32(f);

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

        s->cmd_data[i] = qemu_get_be32(f);

    s->row = qemu_get_be32(f);

    s->row_start = qemu_get_be32(f);

    s->row_end = qemu_get_be32(f);

    s->col = qemu_get_be32(f);

    s->col_start = qemu_get_be32(f);

    s->col_end = qemu_get_be32(f);

    s->redraw = qemu_get_be32(f);

    s->remap = qemu_get_be32(f);

    s->mode = qemu_get_be32(f);

    qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));

    ss->cs = qemu_get_be32(f);

    return 0;


static int s390_ipl_init(SysBusDevice *dev)

{

    S390IPLState *ipl = S390_IPL(dev);

    int kernel_size;

    if (!ipl->kernel) {

        int bios_size;

        char *bios_filename;

        /* Load zipl bootloader */

        if (bios_name == NULL) {

            bios_name = ipl->firmware;

        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

        if (bios_filename == NULL) {

            hw_error("could not find stage1 bootloader\n");

        }

        bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,

                             NULL, 1, ELF_MACHINE, 0);

        if (bios_size == -1) {

            bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,

                                            4096);

            ipl->start_addr = ZIPL_IMAGE_START;

            if (bios_size > 4096) {

                hw_error("stage1 bootloader is > 4k\n");

            }

        }

        g_free(bios_filename);

        if (bios_size == -1) {

            hw_error("could not load bootloader '%s'\n", bios_name);

        }

        return 0;

    } else {

        uint64_t pentry = KERN_IMAGE_START;

        kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,

                               NULL, 1, ELF_MACHINE, 0);

        if (kernel_size == -1) {

            kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);

        }

        if (kernel_size == -1) {

            fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);

            return -1;

        }

        /*

         * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the

         * kernel parameters here as well. Note: For old kernels (up to 3.2)

         * we can not rely on the ELF entry point - it was 0x800 (the SALIPL

         * loader) and it won't work. For this case we force it to 0x10000, too.

         */

        if (pentry == KERN_IMAGE_START || pentry == 0x800) {

            ipl->start_addr = KERN_IMAGE_START;

            /* Overwrite parameters in the kernel image, which are "rom" */

            strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);

        } else {

            ipl->start_addr = pentry;

        }

    }

    if (ipl->initrd) {

        ram_addr_t initrd_offset;

        int initrd_size;

        initrd_offset = INITRD_START;

        while (kernel_size + 0x100000 > initrd_offset) {

            initrd_offset += 0x100000;

        }

        initrd_size = load_image_targphys(ipl->initrd, initrd_offset,

                                          ram_size - initrd_offset);

        if (initrd_size == -1) {

            fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd);

            exit(1);

        }

        /* we have to overwrite values in the kernel image, which are "rom" */

        stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);

        stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);

    }

    return 0;

}


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

{

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    k->init      = grackle_pci_host_init;

    k->vendor_id = PCI_VENDOR_ID_MOTOROLA;

    k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;

    k->revision  = 0x00;

    k->class_id  = PCI_CLASS_BRIDGE_HOST;

    dc->no_user = 1;

}


int main(int argc, char *argv[])

{

    g_test_init(&argc, &argv, NULL);

    qtest_add_func("qmp/protocol", test_qmp_protocol);

    return g_test_run();

}


void virtio_irq(VirtQueue *vq)

{

    trace_virtio_irq(vq);

    virtio_set_isr(vq->vdev, 0x1);

    virtio_notify_vector(vq->vdev, vq->vector);

}


target_ulong helper_rdhwr_xnp(CPUMIPSState *env)

{

    check_hwrena(env, 5);

    return (env->CP0_Config5 >> CP0C5_XNP) & 1;

}


unsigned long get_checksum(ByteIOContext *s){

    s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);

    s->checksum_ptr= NULL;

    return s->checksum;

}


static int decode_rle_bpp2(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)

{

    int offset = avctx->width;

    uint8_t *outdata = p->data[0];

    int i, j;

    for (i = 0; i < avctx->height; i++) {

        int size, left, code, pix;

        uint8_t *out = outdata;

        int pos = 0;

        /* size of packed line */

        size = left = bytestream2_get_be16(gbc);

        if (bytestream2_get_bytes_left(gbc) < size)

            return AVERROR_INVALIDDATA;

        /* decode line */

        while (left > 0) {

            code = bytestream2_get_byte(gbc);

            if (code & 0x80 ) { /* run */

                pix = bytestream2_get_byte(gbc);

                for (j = 0; j < 257 - code; j++) {

                    if (pos < offset)

                        out[pos++] = (pix & 0xC0) >> 6;

                    if (pos < offset)

                        out[pos++] = (pix & 0x30) >> 4;

                    if (pos < offset)

                        out[pos++] = (pix & 0x0C) >> 2;

                    if (pos < offset)

                        out[pos++] = (pix & 0x03);

                }

                left  -= 2;

            } else { /* copy */

                for (j = 0; j < code + 1; j++) {

                    pix = bytestream2_get_byte(gbc);

                    if (pos < offset)

                        out[pos++] = (pix & 0xC0) >> 6;

                    if (pos < offset)

                        out[pos++] = (pix & 0x30) >> 4;

                    if (pos < offset)

                        out[pos++] = (pix & 0x0C) >> 2;

                    if (pos < offset)

                        out[pos++] = (pix & 0x03);

                }

                left  -= 1 + (code + 1);

            }

        }

        outdata += p->linesize[0];

    }

    return 0;

}


void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)

{

    int mm_flags = av_get_cpu_flags();

    if (mm_flags & AV_CPU_FLAG_MMX) {

#if HAVE_YASM

        c->float_interleave = float_interleave_mmx;

        if(mm_flags & AV_CPU_FLAG_3DNOW){

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->float_to_int16 = ff_float_to_int16_3dnow;

                c->float_to_int16_interleave = float_to_int16_interleave_3dnow;

            }

        }

        if(mm_flags & AV_CPU_FLAG_3DNOWEXT){

            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){

                c->float_to_int16_interleave = float_to_int16_interleave_3dn2;

            }

        }

#endif

        if(mm_flags & AV_CPU_FLAG_SSE){

            c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse;

#if HAVE_YASM

            c->float_to_int16 = ff_float_to_int16_sse;

            c->float_to_int16_interleave = float_to_int16_interleave_sse;

            c->float_interleave = float_interleave_sse;

#endif

        }

        if(mm_flags & AV_CPU_FLAG_SSE2){

            c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2;

#if HAVE_YASM

            c->float_to_int16 = ff_float_to_int16_sse2;

            c->float_to_int16_interleave = float_to_int16_interleave_sse2;

#endif

        }

    }

}


static KVMSlot *kvm_lookup_slot(KVMState *s, target_phys_addr_t start_addr)

{

    int i;

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

        KVMSlot *mem = &s->slots[i];

        if (start_addr >= mem->start_addr &&

            start_addr < (mem->start_addr + mem->memory_size))

            return mem;

    }

    return NULL;

}


static inline void tcg_out_qemu_st(TCGContext *s, int cond,

                const TCGArg *args, int opc)

{

    int addr_reg, data_reg, data_reg2;

#ifdef CONFIG_SOFTMMU

    int mem_index, s_bits;

# if TARGET_LONG_BITS == 64

    int addr_reg2;

# endif

    uint32_t *label_ptr;

#endif

    data_reg = *args++;

    if (opc == 3)

        data_reg2 = *args++;

    else

        data_reg2 = 0; /* surpress warning */

    addr_reg = *args++;

#if TARGET_LONG_BITS == 64

    addr_reg2 = *args++;

#endif

#ifdef CONFIG_SOFTMMU

    mem_index = *args;

    s_bits = opc & 3;

    /* Should generate something like the following:

     *  shr r8, addr_reg, #TARGET_PAGE_BITS

     *  and r0, r8, #(CPU_TLB_SIZE - 1)   @ Assumption: CPU_TLB_BITS <= 8

     *  add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS

     */

    tcg_out_dat_reg(s, COND_AL, ARITH_MOV,

                    8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));

    tcg_out_dat_imm(s, COND_AL, ARITH_AND,

                    0, 8, CPU_TLB_SIZE - 1);

    tcg_out_dat_reg(s, COND_AL, ARITH_ADD,

                    0, TCG_AREG0, 0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));

    /* In the

     *  ldr r1 [r0, #(offsetof(CPUState, tlb_table[mem_index][0].addr_write))]

     * below, the offset is likely to exceed 12 bits if mem_index != 0 and

     * not exceed otherwise, so use an

     *  add r0, r0, #(mem_index * sizeof *CPUState.tlb_table)

     * before.

     */

    if (mem_index)

        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, 0, 0,

                        (mem_index << (TLB_SHIFT & 1)) |

                        ((16 - (TLB_SHIFT >> 1)) << 8));

    tcg_out_ld32_12(s, COND_AL, 1, 0,

                    offsetof(CPUState, tlb_table[0][0].addr_write));

    tcg_out_dat_reg(s, COND_AL, ARITH_CMP,

                    0, 1, 8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));

    /* Check alignment.  */

    if (s_bits)

        tcg_out_dat_imm(s, COND_EQ, ARITH_TST,

                        0, addr_reg, (1 << s_bits) - 1);

#  if TARGET_LONG_BITS == 64

    /* XXX: possibly we could use a block data load or writeback in

     * the first access.  */

    tcg_out_ld32_12(s, COND_EQ, 1, 0,

                    offsetof(CPUState, tlb_table[0][0].addr_write)

                    + 4);

    tcg_out_dat_reg(s, COND_EQ, ARITH_CMP,

                    0, 1, addr_reg2, SHIFT_IMM_LSL(0));

#  endif

    tcg_out_ld32_12(s, COND_EQ, 1, 0,

                    offsetof(CPUState, tlb_table[0][0].addend));

    switch (opc) {

    case 0:

        tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, 1);

        break;

    case 0 | 4:

        tcg_out_st8s_r(s, COND_EQ, data_reg, addr_reg, 1);

        break;

    case 1:

        tcg_out_st16u_r(s, COND_EQ, data_reg, addr_reg, 1);

        break;

    case 1 | 4:

        tcg_out_st16s_r(s, COND_EQ, data_reg, addr_reg, 1);

        break;

    case 2:

    default:

        tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, 1);

        break;

    case 3:

        tcg_out_st32_rwb(s, COND_EQ, data_reg, 1, addr_reg);

        tcg_out_st32_12(s, COND_EQ, data_reg2, 1, 4);

        break;

    }

    label_ptr = (void *) s->code_ptr;

    tcg_out_b(s, COND_EQ, 8);

    /* TODO: move this code to where the constants pool will be */

    if (addr_reg)

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        0, 0, addr_reg, SHIFT_IMM_LSL(0));

# if TARGET_LONG_BITS == 32

    switch (opc) {

    case 0:

        tcg_out_dat_imm(s, cond, ARITH_AND, 1, data_reg, 0xff);

        tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);

        break;

    case 1:

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        1, 0, data_reg, SHIFT_IMM_LSL(16));

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        1, 0, 1, SHIFT_IMM_LSR(16));

        tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);

        break;

    case 2:

        if (data_reg != 1)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            1, 0, data_reg, SHIFT_IMM_LSL(0));

        tcg_out_dat_imm(s, cond, ARITH_MOV, 2, 0, mem_index);

        break;

    case 3:

        if (data_reg != 1)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            1, 0, data_reg, SHIFT_IMM_LSL(0));

        if (data_reg2 != 2)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            2, 0, data_reg2, SHIFT_IMM_LSL(0));

        tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);

        break;

    }

# else

    if (addr_reg2 != 1)

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        1, 0, addr_reg2, SHIFT_IMM_LSL(0));

    switch (opc) {

    case 0:

        tcg_out_dat_imm(s, cond, ARITH_AND, 2, data_reg, 0xff);

        tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);

        break;

    case 1:

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        2, 0, data_reg, SHIFT_IMM_LSL(16));

        tcg_out_dat_reg(s, cond, ARITH_MOV,

                        2, 0, 2, SHIFT_IMM_LSR(16));

        tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);

        break;

    case 2:

        if (data_reg != 2)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            2, 0, data_reg, SHIFT_IMM_LSL(0));

        tcg_out_dat_imm(s, cond, ARITH_MOV, 3, 0, mem_index);

        break;

    case 3:

        tcg_out_dat_imm(s, cond, ARITH_MOV, 8, 0, mem_index);

        tcg_out32(s, (cond << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */

        if (data_reg != 2)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            2, 0, data_reg, SHIFT_IMM_LSL(0));

        if (data_reg2 != 3)

            tcg_out_dat_reg(s, cond, ARITH_MOV,

                            3, 0, data_reg2, SHIFT_IMM_LSL(0));

        break;

    }

# endif

# ifdef SAVE_LR

    tcg_out_dat_reg(s, cond, ARITH_MOV, 8, 0, 14, SHIFT_IMM_LSL(0));

# endif

    tcg_out_bl(s, cond, (tcg_target_long) qemu_st_helpers[s_bits] -

                    (tcg_target_long) s->code_ptr);

# if TARGET_LONG_BITS == 64

    if (opc == 3)

        tcg_out_dat_imm(s, cond, ARITH_ADD, 13, 13, 0x10);

# endif

# ifdef SAVE_LR

    tcg_out_dat_reg(s, cond, ARITH_MOV, 14, 0, 8, SHIFT_IMM_LSL(0));

# endif

    *label_ptr += ((void *) s->code_ptr - (void *) label_ptr - 8) >> 2;

#else

    switch (opc) {

    case 0:

        tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);

        break;

    case 0 | 4:

        tcg_out_st8s_8(s, COND_AL, data_reg, addr_reg, 0);

        break;

    case 1:

        tcg_out_st16u_8(s, COND_AL, data_reg, addr_reg, 0);

        break;

    case 1 | 4:

        tcg_out_st16s_8(s, COND_AL, data_reg, addr_reg, 0);

        break;

    case 2:

    default:

        tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);

        break;

    case 3:

        /* TODO: use block store -

         * check that data_reg2 > data_reg or the other way */

        tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);

        tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);

        break;

    }

#endif

}


static int update_offset(RTMPContext *rt, int size)

{

    int old_flv_size;

    // generate packet header and put data into buffer for FLV demuxer

    if (rt->flv_off < rt->flv_size) {

        // There is old unread data in the buffer, thus append at the end

        old_flv_size  = rt->flv_size;

        rt->flv_size += size + 15;

    } else {

        // All data has been read, write the new data at the start of the buffer

        old_flv_size = 0;

        rt->flv_size = size + 15;

        rt->flv_off  = 0;

    }

    return old_flv_size;

}


void qpci_io_writew(QPCIDevice *dev, void *data, uint16_t value)

{

    uintptr_t addr = (uintptr_t)data;

    if (addr < QPCI_PIO_LIMIT) {

        dev->bus->pio_writew(dev->bus, addr, value);

    } else {

        value = cpu_to_le16(value);

        dev->bus->memwrite(dev->bus, addr, &value, sizeof(value));

    }

}


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

                                 int *got_frame_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    const uint8_t *buf_end;

    int buf_size = avpkt->size;

    VmdAudioContext *s = avctx->priv_data;

    int block_type, silent_chunks, audio_chunks;

    int ret;

    uint8_t *output_samples_u8;

    int16_t *output_samples_s16;

    if (buf_size < 16) {

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

        *got_frame_ptr = 0;

        return buf_size;

    }

    block_type = buf[6];

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

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

        return AVERROR(EINVAL);

    }

    buf      += 16;

    buf_size -= 16;

    /* get number of silent chunks */

    silent_chunks = 0;

    if (block_type == BLOCK_TYPE_INITIAL) {

        uint32_t flags;

        if (buf_size < 4) {

            av_log(avctx, AV_LOG_ERROR, "packet is too small\n");

            return AVERROR(EINVAL);

        }

        flags         = AV_RB32(buf);

        silent_chunks = av_popcount(flags);

        buf      += 4;

        buf_size -= 4;

    } else if (block_type == BLOCK_TYPE_SILENCE) {

        silent_chunks = 1;

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

    }

    /* ensure output buffer is large enough */

    audio_chunks = buf_size / s->chunk_size;

    /* get output buffer */

    s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;

    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {

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

        return ret;

    }

    output_samples_u8  = s->frame.data[0];

    output_samples_s16 = (int16_t *)s->frame.data[0];

    /* decode silent chunks */

    if (silent_chunks > 0) {

        int silent_size = avctx->block_align * silent_chunks;

        if (s->out_bps == 2) {

            memset(output_samples_s16, 0x00, silent_size * 2);

            output_samples_s16 += silent_size;

        } else {

            memset(output_samples_u8,  0x80, silent_size);

            output_samples_u8 += silent_size;

        }

    }

    /* decode audio chunks */

    if (audio_chunks > 0) {

        buf_end = buf + buf_size;

        while (buf < buf_end) {

            if (s->out_bps == 2) {

                decode_audio_s16(output_samples_s16, buf, s->chunk_size,

                                 avctx->channels);

                output_samples_s16 += avctx->block_align;

            } else {

                memcpy(output_samples_u8, buf, s->chunk_size);

                output_samples_u8  += avctx->block_align;

            }

            buf += s->chunk_size;

        }

    }

    *got_frame_ptr   = 1;

    *(AVFrame *)data = s->frame;

    return avpkt->size;

}


static void search_for_quantizers_twoloop(AVCodecContext *avctx,

                                          AACEncContext *s,

                                          SingleChannelElement *sce,

                                          const float lambda)

{

    int start = 0, i, w, w2, g;

    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;

    float dists[128], uplims[128];

    int fflag, minscaler;

    int its  = 0;

    int allz = 0;

    float minthr = INFINITY;

    //XXX: some heuristic to determine initial quantizers will reduce search time

    memset(dists, 0, sizeof(dists));

    //determine zero bands and upper limits

    for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {

        for (g = 0;  g < sce->ics.num_swb; g++) {

            int nz = 0;

            float uplim = 0.0f;

            for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {

                FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];

                uplim += band->threshold;

                if (band->energy <= band->threshold || band->threshold == 0.0f) {

                    sce->zeroes[(w+w2)*16+g] = 1;

                    continue;

                }

                nz = 1;

            }

            uplims[w*16+g] = uplim *512;

            sce->zeroes[w*16+g] = !nz;

            if (nz)

                minthr = FFMIN(minthr, uplim);

            allz = FFMAX(allz, nz);

        }

    }

    for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {

        for (g = 0;  g < sce->ics.num_swb; g++) {

            if (sce->zeroes[w*16+g]) {

                sce->sf_idx[w*16+g] = SCALE_ONE_POS;

                continue;

            }

            sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2(uplims[w*16+g]/minthr)*4,59);

        }

    }

    if (!allz)

        return;

    abs_pow34_v(s->scoefs, sce->coeffs, 1024);

    //perform two-loop search

    //outer loop - improve quality

    do {

        int tbits, qstep;

        minscaler = sce->sf_idx[0];

        //inner loop - quantize spectrum to fit into given number of bits

        qstep = its ? 1 : 32;

        do {

            int prev = -1;

            tbits = 0;

            fflag = 0;

            for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {

                start = w*128;

                for (g = 0;  g < sce->ics.num_swb; g++) {

                    const float *coefs = sce->coeffs + start;

                    const float *scaled = s->scoefs + start;

                    int bits = 0;

                    int cb;

                    float mindist = INFINITY;

                    int minbits = 0;

                    if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {

                        start += sce->ics.swb_sizes[g];

                        continue;

                    }

                    minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);

                    for (cb = 0; cb <= ESC_BT; cb++) {

                        float dist = 0.0f;

                        int bb = 0;

                        for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {

                            int b;

                            dist += quantize_band_cost(s, coefs + w2*128,

                                                       scaled + w2*128,

                                                       sce->ics.swb_sizes[g],

                                                       sce->sf_idx[w*16+g],

                                                       cb,

                                                       lambda,

                                                       INFINITY,

                                                       &b);

                            bb += b;

                        }

                        if (dist < mindist) {

                            mindist = dist;

                            minbits = bb;

                        }

                    }

                    dists[w*16+g] = (mindist - minbits) / lambda;

                    bits = minbits;

                    if (prev != -1) {

                        bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];

                    }

                    tbits += bits;

                    start += sce->ics.swb_sizes[g];

                    prev = sce->sf_idx[w*16+g];

                }

            }

            if (tbits > destbits) {

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

                    if (sce->sf_idx[i] < 218 - qstep)

                        sce->sf_idx[i] += qstep;

            } else {

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

                    if (sce->sf_idx[i] > 60 - qstep)

                        sce->sf_idx[i] -= qstep;

            }

            qstep >>= 1;

            if (!qstep && tbits > destbits*1.02)

                qstep = 1;

            if (sce->sf_idx[0] >= 217)

                break;

        } while (qstep);

        fflag = 0;

        minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);

        for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {

            start = w*128;

            for (g = 0; g < sce->ics.num_swb; g++) {

                int prevsc = sce->sf_idx[w*16+g];

                if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)

                    sce->sf_idx[w*16+g]--;

                sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);

                sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);

                if (sce->sf_idx[w*16+g] != prevsc)

                    fflag = 1;

            }

        }

        its++;

    } while (fflag && its < 10);

}


static struct pathelem *new_entry(const char *root,

                                  struct pathelem *parent,

                                  const char *name)

{

    struct pathelem *new = malloc(sizeof(*new));

    new->name = strdup(name);

    new->pathname = g_strdup_printf("%s/%s", root, name);

    new->num_entries = 0;

    return new;

}


static void address_space_update_ioeventfds(AddressSpace *as)

{

    FlatRange *fr;

    unsigned ioeventfd_nb = 0;

    MemoryRegionIoeventfd *ioeventfds = NULL;

    AddrRange tmp;

    unsigned i;

    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {

        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {

            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,

                                  int128_sub(fr->addr.start,

                                             int128_make64(fr->offset_in_region)));

            if (addrrange_intersects(fr->addr, tmp)) {

                ++ioeventfd_nb;

                ioeventfds = g_realloc(ioeventfds,

                                          ioeventfd_nb * sizeof(*ioeventfds));

                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];

                ioeventfds[ioeventfd_nb-1].addr = tmp;

            }

        }

    }

    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,

                                     as->ioeventfds, as->ioeventfd_nb);

    g_free(as->ioeventfds);

    as->ioeventfds = ioeventfds;

    as->ioeventfd_nb = ioeventfd_nb;

}


static void adb_kbd_class_init(ObjectClass *oc, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);

    ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);

    akc->parent_realize = dc->realize;

    dc->realize = adb_kbd_realizefn;

    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);

    adc->devreq = adb_kbd_request;

    dc->reset = adb_kbd_reset;

    dc->vmsd = &vmstate_adb_kbd;

}


is_vlan_packet(E1000State *s, const uint8_t *buf)

{

    return (be16_to_cpup((uint16_t *)(buf + 12)) ==

                le16_to_cpup((uint16_t *)(s->mac_reg + VET)));

}


static int ohci_eof_timer_pre_load(void *opaque)

{

    OHCIState *ohci = opaque;

    ohci_bus_start(ohci);

    return 0;

}


envlist_free(envlist_t *envlist)

{

	struct envlist_entry *entry;

	assert(envlist != NULL);

	while (envlist->el_entries.lh_first != NULL) {

		entry = envlist->el_entries.lh_first;

		QLIST_REMOVE(entry, ev_link);

		free((char *)entry->ev_var);

		free(entry);

	}

	free(envlist);

}


static void test_visitor_in_intList(TestInputVisitorData *data,
                                    const void *unused)
{
    /* Note: the visitor *sorts* ranges *unsigned* */
    int64_t expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 };
    int64_t expect2[] = { 32767, -32768, -32767 };
    int64_t expect3[] = { INT64_MAX, INT64_MIN };
    uint64_t expect4[] = { UINT64_MAX };
    Error *err = NULL;
    int64List *res = NULL;
    int64List *tail;
    Visitor *v;
    int64_t val;
    /* Valid lists */
    v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
    check_ilist(v, expect1, ARRAY_SIZE(expect1));
    v = visitor_input_test_init(data, "32767,-32768--32767");
    check_ilist(v, expect2, ARRAY_SIZE(expect2));
    v = visitor_input_test_init(data,
                                "-9223372036854775808,9223372036854775807");
    check_ilist(v, expect3, ARRAY_SIZE(expect3));
    v = visitor_input_test_init(data, "18446744073709551615");
    check_ulist(v, expect4, ARRAY_SIZE(expect4));
    /* Empty list is invalid (weird) */
    v = visitor_input_test_init(data, "");
    visit_type_int64List(v, NULL, &res, &err);
    error_free_or_abort(&err);
    /* Not a list */
    v = visitor_input_test_init(data, "not an int list");
    visit_type_int64List(v, NULL, &res, &err);
    error_free_or_abort(&err);
    g_assert(!res);
    /* Unvisited list tail */
    v = visitor_input_test_init(data, "0,2-3");
    /* Would be simpler if the visitor genuinely supported virtual walks */
    visit_type_int64(v, NULL, &tail->value, &error_abort);
    tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res));
    g_assert(tail);
    visit_type_int64(v, NULL, &tail->value, &error_abort);
    g_assert_cmpint(tail->value, ==, 2);
    tail = (int64List *)visit_next_list(v, (GenericList *)tail, sizeof(*res));
    g_assert(tail);
    visit_check_list(v, &err);
    error_free_or_abort(&err);
}


static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)

{

    static const uint8_t buf[1024];

    int block_len;

    while (size > 0) {

        block_len = MIN(sizeof(buf), size);

        size -= block_len;

        qemu_put_buffer(f, buf, block_len);

    }

}


static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str)

{

    BDRVQcowState *s = bs->opaque;

    int i;

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

        if (!strcmp(s->snapshots[i].id_str, id_str))

            return i;

    }

    return -1;

}


static inline void vmsvga_update_rect(struct vmsvga_state_s *s,

                                      int x, int y, int w, int h)

{

    DisplaySurface *surface = qemu_console_surface(s->vga.con);

    int line;

    int bypl;

    int width;

    int start;

    uint8_t *src;

    uint8_t *dst;

    if (x < 0) {

        fprintf(stderr, "%s: update x was < 0 (%d)\n", __func__, x);

        w += x;

        x = 0;

    }

    if (w < 0) {

        fprintf(stderr, "%s: update w was < 0 (%d)\n", __func__, w);

        w = 0;

    }

    if (x + w > surface_width(surface)) {

        fprintf(stderr, "%s: update width too large x: %d, w: %d\n",

                __func__, x, w);

        x = MIN(x, surface_width(surface));

        w = surface_width(surface) - x;

    }

    if (y < 0) {

        fprintf(stderr, "%s: update y was < 0 (%d)\n",  __func__, y);

        h += y;

        y = 0;

    }

    if (h < 0) {

        fprintf(stderr, "%s: update h was < 0 (%d)\n",  __func__, h);

        h = 0;

    }

    if (y + h > surface_height(surface)) {

        fprintf(stderr, "%s: update height too large y: %d, h: %d\n",

                __func__, y, h);

        y = MIN(y, surface_height(surface));

        h = surface_height(surface) - y;

    }

    bypl = surface_stride(surface);

    width = surface_bytes_per_pixel(surface) * w;

    start = surface_bytes_per_pixel(surface) * x + bypl * y;

    src = s->vga.vram_ptr + start;

    dst = surface_data(surface) + start;

    for (line = h; line > 0; line--, src += bypl, dst += bypl) {

        memcpy(dst, src, width);

    }

    dpy_gfx_update(s->vga.con, x, y, w, h);

}


static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range)

{

    MatroskaDemuxContext *matroska = s->priv_data;

    EbmlList *seekhead_list = &matroska->seekhead;

    MatroskaSeekhead *seekhead = seekhead_list->elem;

    char *buf;

    int64_t cues_start = -1, cues_end = -1, before_pos, bandwidth;

    int i;

    int end = 0;

    // determine cues start and end positions

    for (i = 0; i < seekhead_list->nb_elem; i++)

        if (seekhead[i].id == MATROSKA_ID_CUES)

            break;

    if (i >= seekhead_list->nb_elem) return -1;

    before_pos = avio_tell(matroska->ctx->pb);

    cues_start = seekhead[i].pos + matroska->segment_start;

    if (avio_seek(matroska->ctx->pb, cues_start, SEEK_SET) == cues_start) {

        // cues_end is computed as cues_start + cues_length + length of the

        // Cues element ID + EBML length of the Cues element. cues_end is

        // inclusive and the above sum is reduced by 1.

        uint64_t cues_length = 0, cues_id = 0, bytes_read = 0;

        bytes_read += ebml_read_num(matroska, matroska->ctx->pb, 4, &cues_id);

        bytes_read += ebml_read_length(matroska, matroska->ctx->pb, &cues_length);

        cues_end = cues_start + cues_length + bytes_read - 1;

    }

    avio_seek(matroska->ctx->pb, before_pos, SEEK_SET);

    if (cues_start == -1 || cues_end == -1) return -1;

    // parse the cues

    matroska_parse_cues(matroska);

    // cues start

    av_dict_set_int(&s->streams[0]->metadata, CUES_START, cues_start, 0);

    // cues end

    av_dict_set_int(&s->streams[0]->metadata, CUES_END, cues_end, 0);

    // if the file has cues at the start, fix up the init range so tht

    // it does not include it

    if (cues_start <= init_range)

        av_dict_set_int(&s->streams[0]->metadata, INITIALIZATION_RANGE, cues_start - 1, 0);

    // bandwidth

    bandwidth = webm_dash_manifest_compute_bandwidth(s, cues_start);

    if (bandwidth < 0) return -1;

    av_dict_set_int(&s->streams[0]->metadata, BANDWIDTH, bandwidth, 0);

    // check if all clusters start with key frames

    av_dict_set_int(&s->streams[0]->metadata, CLUSTER_KEYFRAME, webm_clusters_start_with_keyframe(s), 0);

    // store cue point timestamps as a comma separated list for checking subsegment alignment in

    // the muxer. assumes that each timestamp cannot be more than 20 characters long.

    buf = av_malloc_array(s->streams[0]->nb_index_entries, 20 * sizeof(char));

    if (!buf) return -1;

    strcpy(buf, "");

    for (i = 0; i < s->streams[0]->nb_index_entries; i++) {

        int ret = snprintf(buf + end, 20 * sizeof(char),

                           "%" PRId64, s->streams[0]->index_entries[i].timestamp);

        if (ret <= 0 || (ret == 20 && i ==  s->streams[0]->nb_index_entries - 1)) {

            av_log(s, AV_LOG_ERROR, "timestamp too long.\n");

            return AVERROR_INVALIDDATA;

        }

        end += ret;

        if (i != s->streams[0]->nb_index_entries - 1) {

            strncat(buf, ",", sizeof(char));

            end++;

        }

    }

    av_dict_set(&s->streams[0]->metadata, CUE_TIMESTAMPS, buf, 0);

    return 0;

}


int avresample_convert(AVAudioResampleContext *avr, void **output,

                       int out_plane_size, int out_samples, void **input,

                       int in_plane_size, int in_samples)

{

    AudioData input_buffer;

    AudioData output_buffer;

    AudioData *current_buffer;

    int ret;

    /* reset internal buffers */

    if (avr->in_buffer) {

        avr->in_buffer->nb_samples = 0;

        ff_audio_data_set_channels(avr->in_buffer,

                                   avr->in_buffer->allocated_channels);

    }

    if (avr->resample_out_buffer) {

        avr->resample_out_buffer->nb_samples = 0;

        ff_audio_data_set_channels(avr->resample_out_buffer,

                                   avr->resample_out_buffer->allocated_channels);

    }

    if (avr->out_buffer) {

        avr->out_buffer->nb_samples = 0;

        ff_audio_data_set_channels(avr->out_buffer,

                                   avr->out_buffer->allocated_channels);

    }

    av_dlog(avr, "[start conversion]\n");

    /* initialize output_buffer with output data */

    if (output) {

        ret = ff_audio_data_init(&output_buffer, output, out_plane_size,

                                 avr->out_channels, out_samples,

                                 avr->out_sample_fmt, 0, "output");

        if (ret < 0)

            return ret;

        output_buffer.nb_samples = 0;

    }

    if (input) {

        /* initialize input_buffer with input data */

        ret = ff_audio_data_init(&input_buffer, input, in_plane_size,

                                 avr->in_channels, in_samples,

                                 avr->in_sample_fmt, 1, "input");

        if (ret < 0)

            return ret;

        current_buffer = &input_buffer;

        if (avr->upmix_needed && !avr->in_convert_needed && !avr->resample_needed &&

            !avr->out_convert_needed && output && out_samples >= in_samples) {

            /* in some rare cases we can copy input to output and upmix

               directly in the output buffer */

            av_dlog(avr, "[copy] %s to output\n", current_buffer->name);

            ret = ff_audio_data_copy(&output_buffer, current_buffer);

            if (ret < 0)

                return ret;

            current_buffer = &output_buffer;

        } else if (avr->mixing_needed || avr->in_convert_needed) {

            /* if needed, copy or convert input to in_buffer, and downmix if

               applicable */

            if (avr->in_convert_needed) {

                ret = ff_audio_data_realloc(avr->in_buffer,

                                            current_buffer->nb_samples);

                if (ret < 0)

                    return ret;

                av_dlog(avr, "[convert] %s to in_buffer\n", current_buffer->name);

                ret = ff_audio_convert(avr->ac_in, avr->in_buffer, current_buffer,

                                       current_buffer->nb_samples);

                if (ret < 0)

                    return ret;

            } else {

                av_dlog(avr, "[copy] %s to in_buffer\n", current_buffer->name);

                ret = ff_audio_data_copy(avr->in_buffer, current_buffer);

                if (ret < 0)

                    return ret;

            }

            ff_audio_data_set_channels(avr->in_buffer, avr->in_channels);

            if (avr->downmix_needed) {

                av_dlog(avr, "[downmix] in_buffer\n");

                ret = ff_audio_mix(avr->am, avr->in_buffer);

                if (ret < 0)

                    return ret;

            }

            current_buffer = avr->in_buffer;

        }

    } else {

        /* flush resampling buffer and/or output FIFO if input is NULL */

        if (!avr->resample_needed)

            return handle_buffered_output(avr, output ? &output_buffer : NULL,

                                          NULL);

        current_buffer = NULL;

    }

    if (avr->resample_needed) {

        AudioData *resample_out;

        int consumed = 0;

        if (!avr->out_convert_needed && output && out_samples > 0)

            resample_out = &output_buffer;

        else

            resample_out = avr->resample_out_buffer;

        av_dlog(avr, "[resample] %s to %s\n", current_buffer->name,

                resample_out->name);

        ret = ff_audio_resample(avr->resample, resample_out,

                                current_buffer, &consumed);

        if (ret < 0)

            return ret;

        /* if resampling did not produce any samples, just return 0 */

        if (resample_out->nb_samples == 0) {

            av_dlog(avr, "[end conversion]\n");

            return 0;

        }

        current_buffer = resample_out;

    }

    if (avr->upmix_needed) {

        av_dlog(avr, "[upmix] %s\n", current_buffer->name);

        ret = ff_audio_mix(avr->am, current_buffer);

        if (ret < 0)

            return ret;

    }

    /* if we resampled or upmixed directly to output, return here */

    if (current_buffer == &output_buffer) {

        av_dlog(avr, "[end conversion]\n");

        return current_buffer->nb_samples;

    }

    if (avr->out_convert_needed) {

        if (output && out_samples >= current_buffer->nb_samples) {

            /* convert directly to output */

            av_dlog(avr, "[convert] %s to output\n", current_buffer->name);

            ret = ff_audio_convert(avr->ac_out, &output_buffer, current_buffer,

                                   current_buffer->nb_samples);

            if (ret < 0)

                return ret;

            av_dlog(avr, "[end conversion]\n");

            return output_buffer.nb_samples;

        } else {

            ret = ff_audio_data_realloc(avr->out_buffer,

                                        current_buffer->nb_samples);

            if (ret < 0)

                return ret;

            av_dlog(avr, "[convert] %s to out_buffer\n", current_buffer->name);

            ret = ff_audio_convert(avr->ac_out, avr->out_buffer,

                                   current_buffer, current_buffer->nb_samples);

            if (ret < 0)

                return ret;

            current_buffer = avr->out_buffer;

        }

    }

    return handle_buffered_output(avr, &output_buffer, current_buffer);

}