PVideoFrame __stdcall MVDegrain1::GetFrame(int n, IScriptEnvironment* env) { int nWidth_B = nBlkX*(nBlkSizeX - nOverlapX) + nOverlapX; int nHeight_B = nBlkY*(nBlkSizeY - nOverlapY) + nOverlapY; PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst; BYTE *pDst[3], *pDstCur[3]; const BYTE *pSrcCur[3]; const BYTE *pSrc[3]; const BYTE *pRefB[3]; const BYTE *pRefF[3]; int nDstPitches[3], nSrcPitches[3]; int nRefBPitches[3], nRefFPitches[3]; unsigned char *pDstYUY2; const unsigned char *pSrcYUY2; int nDstPitchYUY2; int nSrcPitchYUY2; bool isUsableB, isUsableF; int tmpPitch = nBlkSizeX; int nLogPel = (nPel==4) ? 2 : (nPel==2) ? 1 : 0; // nLogPel=0 for nPel=1, 1 for nPel=2, 2 for nPel=4, i.e. (x*nPel) = (x<<nLogPel) PVideoFrame mvF = mvClipF.GetFrame(n, env); mvClipF.Update(mvF, env); isUsableF = mvClipF.IsUsable(); mvF = 0; // v2.0.9.2 - it seems, we do not need in vectors clip anymore when we finished copiing them to fakeblockdatas PVideoFrame mvB = mvClipB.GetFrame(n, env); mvClipB.Update(mvB, env); isUsableB = mvClipB.IsUsable(); mvB = 0; int lsb_offset_y = 0; int lsb_offset_u = 0; int lsb_offset_v = 0; // int sharp = mvClipB.GetSharp(); int ySubUV = (yRatioUV == 2) ? 1 : 0; // if ( mvClipB.IsUsable() && mvClipF.IsUsable() && mvClipB2.IsUsable() && mvClipF2.IsUsable() ) // { dst = env->NewVideoFrame(vi); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { if (!planar) { pDstYUY2 = dst->GetWritePtr(); nDstPitchYUY2 = dst->GetPitch(); pDst[0] = DstPlanes->GetPtr(); pDst[1] = DstPlanes->GetPtrU(); pDst[2] = DstPlanes->GetPtrV(); nDstPitches[0] = DstPlanes->GetPitch(); nDstPitches[1] = DstPlanes->GetPitchUV(); nDstPitches[2] = DstPlanes->GetPitchUV(); pSrcYUY2 = src->GetReadPtr(); nSrcPitchYUY2 = src->GetPitch(); pSrc[0] = SrcPlanes->GetPtr(); pSrc[1] = SrcPlanes->GetPtrU(); pSrc[2] = SrcPlanes->GetPtrV(); nSrcPitches[0] = SrcPlanes->GetPitch(); nSrcPitches[1] = SrcPlanes->GetPitchUV(); nSrcPitches[2] = SrcPlanes->GetPitchUV(); YUY2ToPlanes(pSrcYUY2, nSrcPitchYUY2, nWidth, nHeight, pSrc[0], nSrcPitches[0], pSrc[1], pSrc[2], nSrcPitches[1], isse); } else { pDst[0] = dst->GetWritePtr(); pDst[1] = pDst[0] + nWidth; pDst[2] = pDst[1] + nWidth/2; nDstPitches[0] = dst->GetPitch(); nDstPitches[1] = nDstPitches[0]; nDstPitches[2] = nDstPitches[0]; pSrc[0] = src->GetReadPtr(); pSrc[1] = pSrc[0] + nWidth; pSrc[2] = pSrc[1] + nWidth/2; nSrcPitches[0] = src->GetPitch(); nSrcPitches[1] = nSrcPitches[0]; nSrcPitches[2] = nSrcPitches[0]; } } else { pDst[0] = YWPLAN(dst); pDst[1] = UWPLAN(dst); pDst[2] = VWPLAN(dst); nDstPitches[0] = YPITCH(dst); nDstPitches[1] = UPITCH(dst); nDstPitches[2] = VPITCH(dst); pSrc[0] = YRPLAN(src); pSrc[1] = URPLAN(src); pSrc[2] = VRPLAN(src); nSrcPitches[0] = YPITCH(src); nSrcPitches[1] = UPITCH(src); nSrcPitches[2] = VPITCH(src); } lsb_offset_y = nDstPitches [0] * nHeight; lsb_offset_u = nDstPitches [1] * (nHeight / yRatioUV); lsb_offset_v = nDstPitches [2] * (nHeight / yRatioUV); if (lsb_flag) { memset (pDst [0] + lsb_offset_y, 0, lsb_offset_y); if (! planar) { memset (pDst [1] + lsb_offset_u, 0, lsb_offset_u); memset (pDst [2] + lsb_offset_v, 0, lsb_offset_v); } } // MVFrames *pFrames = mvCore->GetFrames(nIdx); PVideoFrame refB, refF; // PVideoFrame refB2x, refF2x; mvClipF.use_ref_frame (refF, isUsableF, super, n, env); mvClipB.use_ref_frame (refB, isUsableB, super, n, env); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { // planar data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 if (isUsableF) { pRefF[0] = refF->GetReadPtr(); pRefF[1] = pRefF[0] + refF->GetRowSize()/2; pRefF[2] = pRefF[1] + refF->GetRowSize()/4; nRefFPitches[0] = refF->GetPitch(); nRefFPitches[1] = nRefFPitches[0]; nRefFPitches[2] = nRefFPitches[0]; } if (isUsableB) { pRefB[0] = refB->GetReadPtr(); pRefB[1] = pRefB[0] + refB->GetRowSize()/2; pRefB[2] = pRefB[1] + refB->GetRowSize()/4; nRefBPitches[0] = refB->GetPitch(); nRefBPitches[1] = nRefBPitches[0]; nRefBPitches[2] = nRefBPitches[0]; } } else { if (isUsableF) { pRefF[0] = YRPLAN(refF); pRefF[1] = URPLAN(refF); pRefF[2] = VRPLAN(refF); nRefFPitches[0] = YPITCH(refF); nRefFPitches[1] = UPITCH(refF); nRefFPitches[2] = VPITCH(refF); } if (isUsableB) { pRefB[0] = YRPLAN(refB); pRefB[1] = URPLAN(refB); pRefB[2] = VRPLAN(refB); nRefBPitches[0] = YPITCH(refB); nRefBPitches[1] = UPITCH(refB); nRefBPitches[2] = VPITCH(refB); } } MVPlane *pPlanesB[3] = { 0 }; MVPlane *pPlanesF[3] = { 0 }; if (isUsableF) { pRefFGOF->Update(YUVplanes, (BYTE*)pRefF[0], nRefFPitches[0], (BYTE*)pRefF[1], nRefFPitches[1], (BYTE*)pRefF[2], nRefFPitches[2]); if (YUVplanes & YPLANE) pPlanesF[0] = pRefFGOF->GetFrame(0)->GetPlane(YPLANE); if (YUVplanes & UPLANE) pPlanesF[1] = pRefFGOF->GetFrame(0)->GetPlane(UPLANE); if (YUVplanes & VPLANE) pPlanesF[2] = pRefFGOF->GetFrame(0)->GetPlane(VPLANE); } if (isUsableB) { pRefBGOF->Update(YUVplanes, (BYTE*)pRefB[0], nRefBPitches[0], (BYTE*)pRefB[1], nRefBPitches[1], (BYTE*)pRefB[2], nRefBPitches[2]);// v2.0 if (YUVplanes & YPLANE) pPlanesB[0] = pRefBGOF->GetFrame(0)->GetPlane(YPLANE); if (YUVplanes & UPLANE) pPlanesB[1] = pRefBGOF->GetFrame(0)->GetPlane(UPLANE); if (YUVplanes & VPLANE) pPlanesB[2] = pRefBGOF->GetFrame(0)->GetPlane(VPLANE); } PROFILE_START(MOTION_PROFILE_COMPENSATION); pDstCur[0] = pDst[0]; pDstCur[1] = pDst[1]; pDstCur[2] = pDst[2]; pSrcCur[0] = pSrc[0]; pSrcCur[1] = pSrc[1]; pSrcCur[2] = pSrc[2]; // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // LUMA plane Y if (!(YUVplanes & YPLANE)) { BitBlt(pDstCur[0], nDstPitches[0], pSrcCur[0], nSrcPitches[0], nWidth, nHeight, isse); } else { if (nOverlapX==0 && nOverlapY==0) { for (int by=0; by<nBlkY; by++) { int xx = 0; for (int bx=0; bx<nBlkX; bx++) { int i = by*nBlkX + bx; const BYTE * pB, *pF; int npB, npF; int WSrc, WRefB, WRefF; use_block_y (pB , npB , WRefB , isUsableB , mvClipB , i, pPlanesB [0], pSrcCur [0], xx, nSrcPitches [0]); use_block_y (pF , npF , WRefF , isUsableF , mvClipF , i, pPlanesF [0], pSrcCur [0], xx, nSrcPitches [0]); norm_weights (WSrc, WRefB, WRefF); // luma DEGRAINLUMA(pDstCur[0] + xx, pDstCur[0] + lsb_offset_y + xx, lsb_flag, nDstPitches[0], pSrcCur[0]+ xx, nSrcPitches[0], pB, npB, pF, npF, WSrc, WRefB, WRefF); xx += (nBlkSizeX); if (bx == nBlkX-1 && nWidth_B < nWidth) // right non-covered region { // luma BitBlt(pDstCur[0] + nWidth_B, nDstPitches[0], pSrcCur[0] + nWidth_B, nSrcPitches[0], nWidth-nWidth_B, nBlkSizeY, isse); } } // for bx pDstCur[0] += ( nBlkSizeY ) * (nDstPitches[0]); pSrcCur[0] += ( nBlkSizeY ) * (nSrcPitches[0]); if (by == nBlkY-1 && nHeight_B < nHeight) // bottom uncovered region { // luma BitBlt(pDstCur[0], nDstPitches[0], pSrcCur[0], nSrcPitches[0], nWidth, nHeight-nHeight_B, isse); } } // for by } // nOverlapX==0 && nOverlapY==0 // ----------------------------------------------------------------- else // overlap { unsigned short *pDstShort = DstShort; int *pDstInt = DstInt; const int tmpPitch = nBlkSizeX; if (lsb_flag) { MemZoneSet(reinterpret_cast<unsigned char*>(pDstInt), 0, nWidth_B*4, nHeight_B, 0, 0, dstIntPitch*4); } else { MemZoneSet(reinterpret_cast<unsigned char*>(pDstShort), 0, nWidth_B*2, nHeight_B, 0, 0, dstShortPitch*2); } for (int by=0; by<nBlkY; by++) { int wby = ((by + nBlkY - 3)/(nBlkY - 2))*3; int xx = 0; for (int bx=0; bx<nBlkX; bx++) { // select window int wbx = (bx + nBlkX - 3)/(nBlkX - 2); short * winOver = OverWins->GetWindow(wby + wbx); int i = by*nBlkX + bx; const BYTE * pB, *pF; int npB, npF; int WSrc, WRefB, WRefF; use_block_y (pB , npB , WRefB , isUsableB , mvClipB , i, pPlanesB [0], pSrcCur [0], xx, nSrcPitches [0]); use_block_y (pF , npF , WRefF , isUsableF , mvClipF , i, pPlanesF [0], pSrcCur [0], xx, nSrcPitches [0]); norm_weights (WSrc, WRefB, WRefF); // luma DEGRAINLUMA(tmpBlock, tmpBlockLsb, lsb_flag, tmpPitch, pSrcCur[0]+ xx, nSrcPitches[0], pB, npB, pF, npF, WSrc, WRefB, WRefF); if (lsb_flag) { OVERSLUMALSB(pDstInt + xx, dstIntPitch, tmpBlock, tmpBlockLsb, tmpPitch, winOver, nBlkSizeX); } else { OVERSLUMA(pDstShort + xx, dstShortPitch, tmpBlock, tmpPitch, winOver, nBlkSizeX); } xx += (nBlkSizeX - nOverlapX); } // for bx pSrcCur[0] += (nBlkSizeY - nOverlapY) * (nSrcPitches[0]); pDstShort += (nBlkSizeY - nOverlapY) * dstShortPitch; pDstInt += (nBlkSizeY - nOverlapY) * dstIntPitch; } // for by if (lsb_flag) { Short2BytesLsb(pDst[0], pDst[0] + lsb_offset_y, nDstPitches[0], DstInt, dstIntPitch, nWidth_B, nHeight_B); } else { Short2Bytes(pDst[0], nDstPitches[0], DstShort, dstShortPitch, nWidth_B, nHeight_B); } if (nWidth_B < nWidth) { BitBlt(pDst[0] + nWidth_B, nDstPitches[0], pSrc[0] + nWidth_B, nSrcPitches[0], nWidth-nWidth_B, nHeight_B, isse); } if (nHeight_B < nHeight) // bottom noncovered region { BitBlt(pDst[0] + nHeight_B*nDstPitches[0], nDstPitches[0], pSrc[0] + nHeight_B*nSrcPitches[0], nSrcPitches[0], nWidth, nHeight-nHeight_B, isse); } } // overlap - end if (nLimit < 255) { if (isse) { LimitChanges_sse2(pDst[0], nDstPitches[0], pSrc[0], nSrcPitches[0], nWidth, nHeight, nLimit); } else { LimitChanges_c(pDst[0], nDstPitches[0], pSrc[0], nSrcPitches[0], nWidth, nHeight, nLimit); } } } //---------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // CHROMA plane U process_chroma ( UPLANE & nSuperModeYUV, pDst [1], pDstCur [1], nDstPitches [1], pSrc [1], pSrcCur [1], nSrcPitches [1], isUsableB, isUsableF, pPlanesB [1], pPlanesF [1], lsb_offset_u, nWidth_B, nHeight_B ); //---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // CHROMA plane V process_chroma ( VPLANE & nSuperModeYUV, pDst [2], pDstCur [2], nDstPitches [2], pSrc [2], pSrcCur [2], nSrcPitches [2], isUsableB, isUsableF, pPlanesB [2], pPlanesF [2], lsb_offset_v, nWidth_B, nHeight_B ); //-------------------------------------------------------------------------------- _mm_empty (); // (we may use double-float somewhere) Fizick PROFILE_STOP(MOTION_PROFILE_COMPENSATION); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 && !planar) { YUY2FromPlanes(pDstYUY2, nDstPitchYUY2, nWidth, nHeight * height_lsb_mul, pDst[0], nDstPitches[0], pDst[1], pDst[2], nDstPitches[1], isse); } return dst; }
//------------------------------------------------------------------------- PVideoFrame __stdcall MVFlowInter::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame dst; BYTE *pDst[3]; const BYTE *pRef[3], *pSrc[3]; int nDstPitches[3], nRefPitches[3], nSrcPitches[3]; unsigned char *pDstYUY2; int nDstPitchYUY2; int off = mvClipB.GetDeltaFrame(); // integer offset of reference frame PVideoFrame mvF = mvClipF.GetFrame(n+off, env); mvClipF.Update(mvF, env);// forward from current to next mvF = 0; PVideoFrame mvB = mvClipB.GetFrame(n, env); mvClipB.Update(mvB, env);// backward from next to current mvB = 0; // int sharp = mvClipB.GetSharp(); PVideoFrame src = finest->GetFrame(n, env); PVideoFrame ref = finest->GetFrame(n+off, env);// ref for compensation dst = env->NewVideoFrame(vi); if ( mvClipB.IsUsable() && mvClipF.IsUsable() ) { if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { // planar data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 pSrc[0] = src->GetReadPtr(); pSrc[1] = pSrc[0] + src->GetRowSize()/2; pSrc[2] = pSrc[1] + src->GetRowSize()/4; nSrcPitches[0] = src->GetPitch(); nSrcPitches[1] = nSrcPitches[0]; nSrcPitches[2] = nSrcPitches[0]; // planar data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 pRef[0] = ref->GetReadPtr(); pRef[1] = pRef[0] + ref->GetRowSize()/2; pRef[2] = pRef[1] + ref->GetRowSize()/4; nRefPitches[0] = ref->GetPitch(); nRefPitches[1] = nRefPitches[0]; nRefPitches[2] = nRefPitches[0]; if (!planar) { pDstYUY2 = dst->GetWritePtr(); nDstPitchYUY2 = dst->GetPitch(); pDst[0] = DstPlanes->GetPtr(); pDst[1] = DstPlanes->GetPtrU(); pDst[2] = DstPlanes->GetPtrV(); nDstPitches[0] = DstPlanes->GetPitch(); nDstPitches[1] = DstPlanes->GetPitchUV(); nDstPitches[2] = DstPlanes->GetPitchUV(); } else { pDst[0] = dst->GetWritePtr(); pDst[1] = pDst[0] + dst->GetRowSize()/2; pDst[2] = pDst[1] + dst->GetRowSize()/4;; nDstPitches[0] = dst->GetPitch(); nDstPitches[1] = nDstPitches[0]; nDstPitches[2] = nDstPitches[0]; } } else { pDst[0] = YWPLAN(dst); pDst[1] = UWPLAN(dst); pDst[2] = VWPLAN(dst); nDstPitches[0] = YPITCH(dst); nDstPitches[1] = UPITCH(dst); nDstPitches[2] = VPITCH(dst); pRef[0] = YRPLAN(ref); pRef[1] = URPLAN(ref); pRef[2] = VRPLAN(ref); nRefPitches[0] = YPITCH(ref); nRefPitches[1] = UPITCH(ref); nRefPitches[2] = VPITCH(ref); pSrc[0] = YRPLAN(src); pSrc[1] = URPLAN(src); pSrc[2] = VRPLAN(src); nSrcPitches[0] = YPITCH(src); nSrcPitches[1] = UPITCH(src); nSrcPitches[2] = VPITCH(src); } int nOffsetY = nRefPitches[0] * nVPadding*nPel + nHPadding*nPel; int nOffsetUV = nRefPitches[1] * nVPaddingUV*nPel + nHPaddingUV*nPel; // make vector vx and vy small masks // 1. ATTENTION: vectors are assumed SHORT (|vx|, |vy| < 127) ! // 2. they will be zeroed if not // 3. added 128 to all values MakeVectorSmallMasks(mvClipB, nBlkX, nBlkY, VXSmallYB, nBlkXP, VYSmallYB, nBlkXP); MakeVectorSmallMasks(mvClipF, nBlkX, nBlkY, VXSmallYF, nBlkXP, VYSmallYF, nBlkXP); if (nBlkXP > nBlkX) // fill right { for (int j=0; j<nBlkY; j++) { VXSmallYB[j*nBlkXP + nBlkX] = min(VXSmallYB[j*nBlkXP + nBlkX-1],128); VYSmallYB[j*nBlkXP + nBlkX] = VYSmallYB[j*nBlkXP + nBlkX-1]; VXSmallYF[j*nBlkXP + nBlkX] = min(VXSmallYF[j*nBlkXP + nBlkX-1],128); VYSmallYF[j*nBlkXP + nBlkX] = VYSmallYF[j*nBlkXP + nBlkX-1]; } } if (nBlkYP > nBlkY) // fill bottom { for (int i=0; i<nBlkXP; i++) { VXSmallYB[nBlkXP*nBlkY +i] = VXSmallYB[nBlkXP*(nBlkY-1) +i]; VYSmallYB[nBlkXP*nBlkY +i] = min(VYSmallYB[nBlkXP*(nBlkY-1) +i],128); VXSmallYF[nBlkXP*nBlkY +i] = VXSmallYF[nBlkXP*(nBlkY-1) +i]; VYSmallYF[nBlkXP*nBlkY +i] = min(VYSmallYF[nBlkXP*(nBlkY-1) +i],128); } } VectorSmallMaskYToHalfUV(VXSmallYB, nBlkXP, nBlkYP, VXSmallUVB, 2); VectorSmallMaskYToHalfUV(VYSmallYB, nBlkXP, nBlkYP, VYSmallUVB, yRatioUV); VectorSmallMaskYToHalfUV(VXSmallYF, nBlkXP, nBlkYP, VXSmallUVF, 2); VectorSmallMaskYToHalfUV(VYSmallYF, nBlkXP, nBlkYP, VYSmallUVF, yRatioUV); // analyse vectors field to detect occlusion // double occNormB = (256-time256)/(256*ml); MakeVectorOcclusionMaskTime(mvClipB, nBlkX, nBlkY, ml, 1.0, nPel, MaskSmallB, nBlkXP, (256-time256), nBlkSizeX - nOverlapX, nBlkSizeY - nOverlapY); // double occNormF = time256/(256*ml); MakeVectorOcclusionMaskTime(mvClipF, nBlkX, nBlkY, ml, 1.0, nPel, MaskSmallF, nBlkXP, time256, nBlkSizeX - nOverlapX, nBlkSizeY - nOverlapY); if (nBlkXP > nBlkX) // fill right { for (int j=0; j<nBlkY; j++) { MaskSmallB[j*nBlkXP + nBlkX] = MaskSmallB[j*nBlkXP + nBlkX-1]; MaskSmallF[j*nBlkXP + nBlkX] = MaskSmallF[j*nBlkXP + nBlkX-1]; } } if (nBlkYP > nBlkY) // fill bottom { for (int i=0; i<nBlkXP; i++) { MaskSmallB[nBlkXP*nBlkY +i] = MaskSmallB[nBlkXP*(nBlkY-1) +i]; MaskSmallF[nBlkXP*nBlkY +i] = MaskSmallF[nBlkXP*(nBlkY-1) +i]; } } // upsize (bilinear interpolate) vector masks to fullframe size int dummyplane = PLANAR_Y; // use luma plane resizer code for all planes if we resize from luma small mask upsizer->SimpleResizeDo(VXFullYB, nWidthP, nHeightP, VPitchY, VXSmallYB, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VYFullYB, nWidthP, nHeightP, VPitchY, VYSmallYB, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VXFullUVB, nWidthPUV, nHeightPUV, VPitchUV, VXSmallUVB, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VYFullUVB, nWidthPUV, nHeightPUV, VPitchUV, VYSmallUVB, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VXFullYF, nWidthP, nHeightP, VPitchY, VXSmallYF, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VYFullYF, nWidthP, nHeightP, VPitchY, VYSmallYF, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VXFullUVF, nWidthPUV, nHeightPUV, VPitchUV, VXSmallUVF, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VYFullUVF, nWidthPUV, nHeightPUV, VPitchUV, VYSmallUVF, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(MaskFullYB, nWidthP, nHeightP, VPitchY, MaskSmallB, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(MaskFullUVB, nWidthPUV, nHeightPUV, VPitchUV, MaskSmallB, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(MaskFullYF, nWidthP, nHeightP, VPitchY, MaskSmallF, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(MaskFullUVF, nWidthPUV, nHeightPUV, VPitchUV, MaskSmallF, nBlkXP, nBlkXP, dummyplane); // Get motion info from more frames for occlusion areas PVideoFrame mvFF = mvClipF.GetFrame(n, env); mvClipF.Update(mvFF, env);// forward from prev to cur mvFF = 0; PVideoFrame mvBB = mvClipB.GetFrame(n+off, env); mvClipB.Update(mvBB, env);// backward from next next to next mvBB = 0; if ( mvClipB.IsUsable() && mvClipF.IsUsable() ) { // get vector mask from extra frames MakeVectorSmallMasks(mvClipB, nBlkX, nBlkY, VXSmallYBB, nBlkXP, VYSmallYBB, nBlkXP); MakeVectorSmallMasks(mvClipF, nBlkX, nBlkY, VXSmallYFF, nBlkXP, VYSmallYFF, nBlkXP); if (nBlkXP > nBlkX) // fill right { for (int j=0; j<nBlkY; j++) { VXSmallYBB[j*nBlkXP + nBlkX] = min(VXSmallYBB[j*nBlkXP + nBlkX-1],128); VYSmallYBB[j*nBlkXP + nBlkX] = VYSmallYBB[j*nBlkXP + nBlkX-1]; VXSmallYFF[j*nBlkXP + nBlkX] = min(VXSmallYFF[j*nBlkXP + nBlkX-1],128); VYSmallYFF[j*nBlkXP + nBlkX] = VYSmallYFF[j*nBlkXP + nBlkX-1]; } } if (nBlkYP > nBlkY) // fill bottom { for (int i=0; i<nBlkXP; i++) { VXSmallYBB[nBlkXP*nBlkY +i] = VXSmallYBB[nBlkXP*(nBlkY-1) +i]; VYSmallYBB[nBlkXP*nBlkY +i] = min(VYSmallYBB[nBlkXP*(nBlkY-1) +i],128); VXSmallYFF[nBlkXP*nBlkY +i] = VXSmallYFF[nBlkXP*(nBlkY-1) +i]; VYSmallYFF[nBlkXP*nBlkY +i] = min(VYSmallYFF[nBlkXP*(nBlkY-1) +i],128); } } VectorSmallMaskYToHalfUV(VXSmallYBB, nBlkXP, nBlkYP, VXSmallUVBB, 2); VectorSmallMaskYToHalfUV(VYSmallYBB, nBlkXP, nBlkYP, VYSmallUVBB, yRatioUV); VectorSmallMaskYToHalfUV(VXSmallYFF, nBlkXP, nBlkYP, VXSmallUVFF, 2); VectorSmallMaskYToHalfUV(VYSmallYFF, nBlkXP, nBlkYP, VYSmallUVFF, yRatioUV); // upsize vectors to full frame upsizer->SimpleResizeDo(VXFullYBB, nWidthP, nHeightP, VPitchY, VXSmallYBB, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VYFullYBB, nWidthP, nHeightP, VPitchY, VYSmallYBB, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VXFullUVBB, nWidthPUV, nHeightPUV, VPitchUV, VXSmallUVBB, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VYFullUVBB, nWidthPUV, nHeightPUV, VPitchUV, VYSmallUVBB, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VXFullYFF, nWidthP, nHeightP, VPitchY, VXSmallYFF, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VYFullYFF, nWidthP, nHeightP, VPitchY, VYSmallYFF, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VXFullUVFF, nWidthPUV, nHeightPUV, VPitchUV, VXSmallUVFF, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VYFullUVFF, nWidthPUV, nHeightPUV, VPitchUV, VYSmallUVFF, nBlkXP, nBlkXP, dummyplane); FlowInterExtra(pDst[0], nDstPitches[0], pRef[0] + nOffsetY, pSrc[0] + nOffsetY, nRefPitches[0], VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF, VXFullYBB, VXFullYFF, VYFullYBB, VYFullYFF); FlowInterExtra(pDst[1], nDstPitches[1], pRef[1] + nOffsetUV, pSrc[1] + nOffsetUV, nRefPitches[1], VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF, VXFullUVBB, VXFullUVFF, VYFullUVBB, VYFullUVFF); FlowInterExtra(pDst[2], nDstPitches[2], pRef[2] + nOffsetUV, pSrc[2] + nOffsetUV, nRefPitches[2], VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF, VXFullUVBB, VXFullUVFF, VYFullUVBB, VYFullUVFF); } else // bad extra frames, use old method without extra frames { FlowInter(pDst[0], nDstPitches[0], pRef[0] + nOffsetY, pSrc[0] + nOffsetY, nRefPitches[0], VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[1], nDstPitches[1], pRef[1] + nOffsetUV, pSrc[1] + nOffsetUV, nRefPitches[1], VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[2], nDstPitches[2], pRef[2] + nOffsetUV, pSrc[2] + nOffsetUV, nRefPitches[2], VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); } if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 && !planar) { YUY2FromPlanes(pDstYUY2, nDstPitchYUY2, nWidth, nHeight, pDst[0], nDstPitches[0], pDst[1], pDst[2], nDstPitches[1], isse); } return dst; } else { // poor estimation // prepare pointers PVideoFrame src = child->GetFrame(n,env); // it is easy to use child here - v2.0 if (blend) //let's blend src with ref frames like ConvertFPS { PVideoFrame ref = child->GetFrame(n+off,env); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { pSrc[0] = src->GetReadPtr(); // we can blend YUY2 nSrcPitches[0] = src->GetPitch(); pRef[0] = ref->GetReadPtr(); nRefPitches[0] = ref->GetPitch(); pDstYUY2 = dst->GetWritePtr(); nDstPitchYUY2 = dst->GetPitch(); Blend(pDstYUY2, pSrc[0], pRef[0], nHeight, nWidth*2, nDstPitchYUY2, nSrcPitches[0], nRefPitches[0], time256, isse); } else { pDst[0] = YWPLAN(dst); pDst[1] = UWPLAN(dst); pDst[2] = VWPLAN(dst); nDstPitches[0] = YPITCH(dst); nDstPitches[1] = UPITCH(dst); nDstPitches[2] = VPITCH(dst); pRef[0] = YRPLAN(ref); pRef[1] = URPLAN(ref); pRef[2] = VRPLAN(ref); nRefPitches[0] = YPITCH(ref); nRefPitches[1] = UPITCH(ref); nRefPitches[2] = VPITCH(ref); pSrc[0] = YRPLAN(src); pSrc[1] = URPLAN(src); pSrc[2] = VRPLAN(src); nSrcPitches[0] = YPITCH(src); nSrcPitches[1] = UPITCH(src); nSrcPitches[2] = VPITCH(src); // blend with time weight Blend(pDst[0], pSrc[0], pRef[0], nHeight, nWidth, nDstPitches[0], nSrcPitches[0], nRefPitches[0], time256, isse); Blend(pDst[1], pSrc[1], pRef[1], nHeightUV, nWidthUV, nDstPitches[1], nSrcPitches[1], nRefPitches[1], time256, isse); Blend(pDst[2], pSrc[2], pRef[2], nHeightUV, nWidthUV, nDstPitches[2], nSrcPitches[2], nRefPitches[2], time256, isse); } return dst; } else { return src; // like ChangeFPS } } }