Esempio n. 1
0
bool Tswscale::init(unsigned int Idx,unsigned int Idy,uint64_t incsp,uint64_t outcsp)
{
    done();
    PixelFormat sw_incsp=csp_ffdshow2lavc(incsp),sw_outcsp=csp_ffdshow2lavc(outcsp);
    dx=Idx;
    dy=Idy;
    sws_flags = SWS_BILINEAR | SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP; //Resize method
    SwsParams params;
    Tlibavcodec::swsInitParams(&params,SWS_BILINEAR,sws_flags);
    swsc=libavcodec->sws_getCachedContext(NULL,dx,dy,sw_incsp,dx,dy,sw_outcsp,sws_flags,NULL,NULL,NULL,&params);
    return !!swsc;
}
Esempio n. 2
0
HRESULT TimgFilterAvcodecBlur::process(TfilterQueue::iterator it, TffPict &pict, const TfilterSettingsVideo *cfg0)
{
    if (is(pict, cfg0)) {
        const TblurSettings *cfg = (const TblurSettings*)cfg0;
        init(pict, cfg->full, cfg->half);
        bool cspChanged = false;
        const unsigned char *src[4];
        cspChanged |= getCur(SWS_IN_CSPS, pict, cfg->full, &src[0], &src[1], &src[2], &src[3]);
        unsigned char *dst[4];
        cspChanged |= getNext(SWS_OUT_CSPS, pict, cfg->full, &dst[0], &dst[1], &dst[2], &dst[3]);
        if (cspChanged || !swsc || oldradius != cfg->avcodecBlurRadius || oldluma != cfg->avcodecBlurLuma || oldchroma != cfg->avcodecBlurChroma) {
            done();
            if (!libavcodec) {
                deci->getLibavcodec(&libavcodec);
            }
            oldradius = cfg->avcodecBlurRadius;
            oldluma = cfg->avcodecBlurLuma;
            oldchroma = cfg->avcodecBlurChroma;
            SwsFilter swsf;
            if (oldluma) {
                swsf.lumH = libavcodec->sws_getGaussianVec(oldluma / 100.0, oldradius);
                libavcodec->sws_normalizeVec(swsf.lumH, 1.0);
                swsf.lumV = libavcodec->sws_getGaussianVec(oldluma / 100.0, oldradius);
                libavcodec->sws_normalizeVec(swsf.lumV, 1.0);
            } else {
                swsf.lumH = swsf.lumV = NULL;
            }
            if (oldchroma) {
                swsf.chrH = libavcodec->sws_getGaussianVec(oldchroma / 100.0, oldradius);
                libavcodec->sws_normalizeVec(swsf.chrH, 1.0);
                swsf.chrV = libavcodec->sws_getGaussianVec(oldchroma / 100.0, oldradius);
                libavcodec->sws_normalizeVec(swsf.chrV, 1.0);
            } else {
                swsf.chrH = swsf.chrV = NULL;
            }
            int swsflags = 0;
            SwsParams params;
            Tlibavcodec::swsInitParams(&params, 0, swsflags);
            swsc = libavcodec->sws_getCachedContext(NULL, dx1[0], dy1[0], csp_ffdshow2lavc(csp1), dx1[0], dy1[0], csp_ffdshow2lavc(csp2), swsflags, &swsf, NULL, NULL, &params);
            if (oldluma) {
                libavcodec->sws_freeVec(swsf.lumH);
                libavcodec->sws_freeVec(swsf.lumV);
            }
            if (oldchroma) {
                libavcodec->sws_freeVec(swsf.chrH);
                libavcodec->sws_freeVec(swsf.chrV);
            }
        }

        if (swsc) {
            libavcodec->sws_scale(swsc, src, stride1, 0, dy1[0], dst, stride2);
        }
    }
    return parent->processSample(++it, pict);
}
HRESULT TimgFilterResize::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
    const TresizeAspectSettings *cfg=(const TresizeAspectSettings*)cfg0;
    init(pict,cfg->full,0);
    int swsflags = 0;
    if (sizeChanged || !cfg->equal(oldSettings) || oldSettings.is!=cfg->is || oldSettings.full!=cfg->full || oldcsp != pict.csp) {
        sizeChanged=false;
        oldSettings=*cfg;
        oldcsp=pict.csp;
        done();
        inited=false;
        newpict.rectFull=pict.rectFull;
        newpict.rectClip=pict.rectClip;
        newpict.csp=pict.csp;
        getOutputFmt(newpict,cfg);
        enum TffdshowDecVideo::DOWNSTREAM_FILTER_TYPE downstream=(TffdshowDecVideo::DOWNSTREAM_FILTER_TYPE)deciV->get_downstreamID();
        char_t outputfourcc[20];
        deciV->getOutputFourcc(outputfourcc,20);

        if ((pict.rectClip!=newpict.rectClip || pict.rectFull!=newpict.rectFull)
                &&!(   pict.cspInfo.id==FF_CSP_420P       // I want to avoid resizing here. YV12 odd number lines.
                       && pict.rectFull==newpict.rectFull
                       && newpict.rectClip.dy==(pict.rectClip.dy&~1)
                       && newpict.rectClip.dx==pict.rectClip.dx
                       && newpict.rectClip.x==pict.rectClip.x
                       && newpict.rectClip.y==pict.rectClip.y
                   )) {
            switch (TresizeAspectSettings::methodsProps[oldSettings.methodLuma].library) {
                case TresizeAspectSettings::LIB_SWSCALER:
                    Tlibavcodec::swsInitParams(swsparams,TresizeAspectSettings::methodsProps[oldSettings.methodLuma].flags);
                    switch (oldSettings.methodLuma) {
                        case TresizeAspectSettings::METHOD_SWS_BICUBIC:
                            swsparams->methodLuma.param[0]=(double)oldSettings.bicubicLumaParam/100;
                            break;
                        case TresizeAspectSettings::METHOD_SWS_GAUSS:
                            swsparams->methodLuma.param[0]=(double)oldSettings.gaussLumaParam/10;
                            break;
                        case TresizeAspectSettings::METHOD_SWS_LANCZOS:
                            swsparams->methodLuma.param[0]=(double)oldSettings.lanczosLumaParam;
                            break;
                    }
                    if (oldSettings.methodsLocked) {
                        swsparams->methodChroma=swsparams->methodLuma;
                    } else {
                        swsparams->methodChroma.method=TresizeAspectSettings::methodsProps[oldSettings.methodChroma].flags;
                        switch (oldSettings.methodChroma) {
                            case TresizeAspectSettings::METHOD_SWS_BICUBIC:
                                swsparams->methodChroma.param[0]=(double)oldSettings.bicubicChromaParam/100;
                                break;
                            case TresizeAspectSettings::METHOD_SWS_GAUSS:
                                swsparams->methodChroma.param[0]=(double)oldSettings.gaussChromaParam/10;
                                break;
                            case TresizeAspectSettings::METHOD_SWS_LANCZOS:
                                swsparams->methodChroma.param[0]=(double)oldSettings.lanczosChromaParam;
                                break;
                        }
                    }
                    break;
                case TresizeAspectSettings::LIB_NONE:
                    if (pictRect.dy<newpict.rectClip.dy) {
                        dynone=pictRect.dy;
                        ydif1none=(newpict.rectClip.dy-pictRect.dy)/2;
                        ydif2none=0;
                    } else {
                        dynone=newpict.rectClip.dy;
                        ydif1none=0;
                        ydif2none=(pictRect.dy-newpict.rectClip.dy)/2;
                    }
                    if (pictRect.dx<newpict.rectClip.dx) {
                        dxnone=pictRect.dx;
                        xdif1none=(newpict.rectClip.dx-pictRect.dx)/2;
                        xdif2none=0;
                    } else {
                        dxnone=newpict.rectClip.dx;
                        xdif1none=0;
                        xdif2none=(pictRect.dx-newpict.rectClip.dx)/2;
                    }
                    break;
            }
            parent->dirtyBorder=1;
            inited=true;
        }
    }

    if (inited) {
        parent->adhocDVDsub(it, pict); // draw DVD subtitles and menu before resize, if it is not done.

        bool interlace;
        switch (cfg->interlaced) {
            case 0 :
                interlace=false;
                break;
            case 1 :
                interlace=true;
                break;
            case 2 :
                interlace=pict.fieldtype&FIELD_TYPE::MASK_INT?true:false;
                break;
            default:
                interlace=false;
                break;
        }
        switch (TresizeAspectSettings::methodsProps[oldSettings.methodLuma].library) {
            case TresizeAspectSettings::LIB_SWSCALER: {
                if (pict.rectFull.dx!=pict.rectClip.dx) {
                    parent->dirtyBorder=1;
                }
                bool cspChanged=false;
                const unsigned char *src[4];
                cspChanged|=getCur(SWS_IN_CSPS,pict,cfg->full,src);
                unsigned char *dst[4];
                cspChanged|=getNext(SWS_OUT_CSPS,pict,newpict.rectClip,dst,&newpict.rectFull);
                if (cspChanged || !swsc || oldinterlace!=interlace) {
                    if (!libavcodec) {
                        deci->getLibavcodec(&libavcodec);
                    }
                    if (swsc) {
                        libavcodec->sws_freeContext(swsc);
                    }
                    swsc=NULL;
                    if (swsf) {
                        libavcodec->sws_freeFilter(swsf);
                    }
                    swsf=NULL;
                    oldinterlace=interlace;
                    if(cfg->accurateRounding) {
                        swsflags|=SWS_ACCURATE_RND;
                    }

                    // Add the CPU flags and others (SWS_ACCURATE_RND if set) to the chroma & luma flags
                    SwsParams mixedparams;
                    memcpy(&mixedparams, swsparams, sizeof(SwsParams));
                    mixedparams.methodChroma.method|=swsflags;
                    mixedparams.methodLuma.method|=swsflags;

                    swsf=libavcodec->sws_getDefaultFilter(oldSettings.GblurLum/100.0f,oldSettings.GblurChrom/100.0f,oldSettings.sharpenLum/100.0f,oldSettings.sharpenChrom/100.0f,0,0,0);
                    if (!oldinterlace) {
                        swsc=libavcodec->sws_getCachedContext(NULL,pictRect.dx,pictRect.dy,csp_ffdshow2lavc(csp1),newpict.rectClip.dx,newpict.rectClip.dy,csp_ffdshow2lavc(csp2),swsflags,swsf,NULL,NULL,&mixedparams);
                    } else {
                        swsc=libavcodec->sws_getCachedContext(NULL,pictRect.dx,pictRect.dy/2,csp_ffdshow2lavc(csp1),newpict.rectClip.dx,newpict.rectClip.dy/2,csp_ffdshow2lavc(csp2),swsflags,swsf,NULL,NULL,&mixedparams);
                    }
                }
                if (!oldinterlace) {
                    libavcodec->sws_scale(swsc,src,stride1,0,pictRect.dy,dst,stride2);
                } else {
                    stride_t stride1I[]= {stride1[0]*2,stride1[1]*2,stride1[2]*2,stride1[3]*2};
                    stride_t stride2I[]= {stride2[0]*2,stride2[1]*2,stride2[2]*2,stride2[3]*2};
                    libavcodec->sws_scale(swsc,src,stride1I,0,pictRect.dy/2,dst,stride2I);
                    for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                        src[i]+=stride1[i];
                        dst[i]+=stride2[i];
                    }
                    libavcodec->sws_scale(swsc,src,stride1I,0,pictRect.dy/2,dst,stride2I);
                }
                break;
            }
            case TresizeAspectSettings::LIB_NONE: {
                const unsigned char *src[4];
                getCur(pict.csp,pict,cfg->full,src);
                unsigned char *dst[4];
                getNext(pict.csp,pict,newpict.rectClip,dst,&newpict.rectFull);
                for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                    const unsigned char *src0=src[i]+(ydif2none>>pict.cspInfo.shiftY[i])*stride1[i]+pict.cspInfo.Bpp*(xdif2none>>pict.cspInfo.shiftX[i]);
                    unsigned char       *dst0=dst[i]+(ydif1none>>pict.cspInfo.shiftY[i])*stride2[i]+pict.cspInfo.Bpp*(xdif1none>>pict.cspInfo.shiftX[i]);
                    TffPict::copy(dst0,stride2[i],src0,stride1[i],pict.cspInfo.Bpp*(dxnone>>pict.cspInfo.shiftX[i]),dynone>>pict.cspInfo.shiftY[i]);
                }
                break;
            }
            case TresizeAspectSettings::LIB_SIMPLE: {
                bool warped=oldSettings.methodLuma==TresizeAspectSettings::METHOD_WARPED;
                if (!simple || oldinterlace!=interlace || oldWarped!=warped) {
                    oldinterlace=interlace;
                    oldWarped=warped;
                    SimpleResize::VideoInfo vi;
                    vi.width=pictRect.dx;
                    vi.height=pictRect.dy/(oldinterlace?2:1);
                    vi.IsYV12=!warped;
                    vi.IsYUY2=!vi.IsYV12;
                    simple=new SimpleResize(vi,newpict.rectClip.dx,newpict.rectClip.dy/(oldinterlace?2:1),warped?cfg->simpleWarpXparam/1000.0:1.0,warped?cfg->simpleWarpYparam/1000.0:1.0,false);
                }
                if (simple->ok) {
                    SimpleResize::PVideoFrame srcFrame;
                    getCur(warped?FF_CSP_YUY2:FF_CSP_420P,pict,cfg->full,(const unsigned char**)srcFrame.ptr);
                    for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                        srcFrame.pitch[i]=stride1[i];
                        srcFrame.rowSize[i]=dx1[i]*pict.cspInfo.Bpp;
                        srcFrame.height[i]=dy1[i];
                    }
                    SimpleResize::PVideoFrame dstFrame;
                    getNext(warped?FF_CSP_YUY2:FF_CSP_420P,pict,newpict.rectClip,dstFrame.ptr,&newpict.rectFull);
                    for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                        dstFrame.pitch[i]=stride2[i];
                        dstFrame.rowSize[i]=(newpict.rectClip.dx*pict.cspInfo.Bpp)>>pict.cspInfo.shiftX[i];
                        dstFrame.height[i]=newpict.rectClip.dy>>pict.cspInfo.shiftY[i];
                    }
                    if (!oldinterlace) {
                        simple->GetFrame(&srcFrame,&dstFrame);
                    } else {
                        for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                            srcFrame.height[i]/=2;
                            srcFrame.pitch[i]*=2;
                            dstFrame.height[i]/=2;
                            dstFrame.pitch[i]*=2;
                        }
                        simple->GetFrame(&srcFrame,&dstFrame);
                        for (unsigned int i=0; i<pict.cspInfo.numPlanes; i++) {
                            srcFrame.ptr[i]+=stride1[i];
                            dstFrame.ptr[i]+=stride2[i];
                        }
                        simple->GetFrame(&srcFrame,&dstFrame);
                    }
                }
                break;
            }
            case TresizeAspectSettings::LIB_SAI:
                switch (TresizeAspectSettings::methodsProps[oldSettings.methodLuma].flags) {
                    case 0: {
                        const unsigned char *src;
                        getCur(FF_CSP_RGB32,pict,cfg->full,&src,NULL,NULL,NULL);
                        unsigned char *dst;
                        getNext(FF_CSP_RGB32,pict,newpict.rectClip,&dst,NULL,NULL,NULL,&newpict.rectFull);
                        T2xSaI::super(src,stride1[0],dst,stride2[0],dx1[0],dy1[0]);
                        break;
                    }
                    case 1: {
                        const unsigned char *src;
                        getCur(FF_CSP_RGB16,pict,cfg->full,&src,NULL,NULL,NULL);
                        unsigned char *dst;
                        getNext(FF_CSP_RGB16,pict,newpict.rectClip,&dst,NULL,NULL,NULL,&newpict.rectFull);
                        T2xSaI::_2xSaI(src,stride1[0],dst,dx1[0],dy1[0],stride2[0]);
                        break;
                    }
                    case 2: {
                        const unsigned char *src;
                        getCur(FF_CSP_RGB16,pict,cfg->full,&src,NULL,NULL,NULL);
                        unsigned char *dst;
                        getNext(FF_CSP_RGB32,pict,newpict.rectClip,&dst,NULL,NULL,NULL,&newpict.rectFull);
                        Thq2x::hq2x_32(src,dst,dx1[0],dy1[0],stride1[0],stride2[0]);
                        break;
                    }
                }
                break;
        }
        if (!parent->dirtyBorder) {
            parent->dirtyBorder=1;
        }
    }