HRESULT TaudioFilterResampleLavc::process(TfilterQueue::iterator it, TsampleFormat &fmt, void *samples, size_t numsamples, const TfilterSettingsAudio *cfg0) { const TresampleSettings *cfg = (const TresampleSettings*)cfg0; if (is(fmt, cfg)) { if (!cfg->equal(old) || oldfreq != fmt.freq || oldnchannels != fmt.nchannels || oldsf != fmt.sf) { old = *cfg; oldfreq = fmt.freq; oldnchannels = fmt.nchannels; oldsf = fmt.sf; done(); buffIn.clear(); buffOut.clear(); bool libsamplerateok = false; int mode = limit(cfg->mode, (int)TresampleSettings::RESAMPLE_LAVC_NORMAL, (int)TresampleSettings::RESAMPLE_LAVC_HIGHEST); TsampleFormat fmtOut = fmt; getOutputFmt(fmtOut, cfg); if (fmtOut.sf == TsampleFormat::SF_PCM16) for (unsigned int i = 0; i < fmt.nchannels; i++) switch (mode) { case TresampleSettings::RESAMPLE_LAVC_NORMAL : ctxsInt[i] = new TreSampleContext<int16_t>(1, cfg->freq, fmt.freq, 16 , 10, 0, 1.0, 15); break; case TresampleSettings::RESAMPLE_LAVC_HIGH : ctxsInt[i] = new TreSampleContext<int16_t>(1, cfg->freq, fmt.freq, 16 , 10, 1, 1.0, 22); break; case TresampleSettings::RESAMPLE_LAVC_HIGHEST: ctxsInt[i] = new TreSampleContext<int16_t>(1, cfg->freq, fmt.freq, int(16 * 2.2), 10, 1, 1.0, 22); break; } else for (unsigned int i = 0; i < fmt.nchannels; i++) switch (mode) { case TresampleSettings::RESAMPLE_LAVC_NORMAL : ctxsFloat[i] = new TreSampleContext<float>(1, cfg->freq, fmt.freq, 16 , 10, 0, 1.0, 0); break; case TresampleSettings::RESAMPLE_LAVC_HIGH : ctxsFloat[i] = new TreSampleContext<float>(1, cfg->freq, fmt.freq, 16 , 10, 1, 1.0, 0); break; case TresampleSettings::RESAMPLE_LAVC_HIGHEST: ctxsFloat[i] = new TreSampleContext<float>(1, cfg->freq, fmt.freq, int(16 * 2.2), 10, 1, 1.0, 0); break; } } if (ctxsInt[0]) { resample(fmt, (int16_t*&)samples, numsamples, cfg, ctxsInt); } else { resample(fmt, (float*&)samples, numsamples, cfg, ctxsFloat); } } return parent->deliverSamples(++it, fmt, samples, numsamples); }
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; } }