//------------------------------------------------------------------------- PVideoFrame __stdcall MVFlowInter::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); // convert to frames unsigned char *pDst[3]; int nDstPitches[3]; DstPlanes->ConvertVideoFrameToPlanes(&dst, pDst, nDstPitches); int off = mvClipB.GetDeltaFrame(); // integer offset of reference frame // get reference frame PVideoFrame ref = child->GetFrame(n+off, env);// ref for compensation PVideoFrame mvB = mvClipB.GetFrame(n, env); mvClipB.Update(mvB, env);// backward from next to current PVideoFrame mvF = mvClipF.GetFrame(n+off, env); mvClipF.Update(mvF, env);// forward from current to next if ( mvClipB.IsUsable() && mvClipF.IsUsable()) { PMVGroupOfFrames pRefGOFF = mvCore->GetFrame(nIdx, n); // forward ref PMVGroupOfFrames pRefGOFB = mvCore->GetFrame(nIdx, n + off); // backward ref if (!pRefGOFF->IsProcessed()) { PVideoFrame src2x; pRefGOFF->SetParity(child->GetParity(n)); if (usePelClipHere) { src2x = pelclip->GetFrame(n, env); } ProcessFrameIntoGroupOfFrames(&pRefGOFF, &src, &src2x, mvClipF.GetSharp(), pixelType, nHeight, nWidth, nPel, isse); } if (!pRefGOFB->IsProcessed()) { PVideoFrame ref2x; pRefGOFB->SetParity(child->GetParity(n + off)); if (usePelClipHere) { ref2x = pelclip->GetFrame(n+off, env); } ProcessFrameIntoGroupOfFrames(&pRefGOFB, &ref, &ref2x, mvClipB.GetSharp(), pixelType, nHeight, nWidth, nPel, isse); } MVPlane *pPlanesB[3]; MVPlane *pPlanesF[3]; pPlanesB[0] = pRefGOFB->GetFrame(0)->GetPlane(YPLANE); pPlanesB[1] = pRefGOFB->GetFrame(0)->GetPlane(UPLANE); pPlanesB[2] = pRefGOFB->GetFrame(0)->GetPlane(VPLANE); pPlanesF[0] = pRefGOFF->GetFrame(0)->GetPlane(YPLANE); pPlanesF[1] = pRefGOFF->GetFrame(0)->GetPlane(UPLANE); pPlanesF[2] = pRefGOFF->GetFrame(0)->GetPlane(VPLANE); if (nPel>=2) { if (usePelClipHere) { // simply padding 2x planes PlaneCopy(pel2PlaneYB + nHPadding*nPel + nVPadding*nPel * pel2PitchY, pel2PitchY, pRefGOFB->GetVF2xYPtr(), pRefGOFB->GetVF2xYPitch(), nWidth*nPel, nHeight*nPel, isse); Padding::PadReferenceFrame(pel2PlaneYB, pel2PitchY, nHPadding*nPel, nVPadding*nPel, nWidth*nPel, nHeight*nPel); PlaneCopy(pel2PlaneUB + nHPaddingUV*nPel + nVPaddingUV*nPel * pel2PitchUV, pel2PitchUV, pRefGOFB->GetVF2xUPtr(), pRefGOFB->GetVF2xUPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneUB, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); PlaneCopy(pel2PlaneVB + nHPaddingUV*nPel + nVPaddingUV*nPel * pel2PitchUV, pel2PitchUV, pRefGOFB->GetVF2xVPtr(), pRefGOFB->GetVF2xVPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneVB, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); PlaneCopy(pel2PlaneYF + nHPadding*nPel + nVPadding*nPel * pel2PitchY, pel2PitchY, pRefGOFF->GetVF2xYPtr(), pRefGOFF->GetVF2xYPitch(), nWidth*nPel, nHeight*nPel, isse); Padding::PadReferenceFrame(pel2PlaneYB, pel2PitchY, nHPadding*nPel, nVPadding*nPel, nWidth*nPel, nHeight*nPel); PlaneCopy(pel2PlaneUF + nHPaddingUV*nPel + nVPaddingUV*nPel * pel2PitchUV, pel2PitchUV, pRefGOFF->GetVF2xUPtr(), pRefGOFF->GetVF2xUPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneUB, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); PlaneCopy(pel2PlaneVF + nHPaddingUV*nPel + nVPaddingUV*nPel * pel2PitchUV, pel2PitchUV, pRefGOFF->GetVF2xVPtr(), pRefGOFF->GetVF2xVPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneVF, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); } else if (nPel==2) { // merge refined planes to big single plane Merge4PlanesToBig(pel2PlaneYB, pel2PitchY, pPlanesB[0]->GetAbsolutePointer(0,0), pPlanesB[0]->GetAbsolutePointer(1,0), pPlanesB[0]->GetAbsolutePointer(0,1), pPlanesB[0]->GetAbsolutePointer(1,1), pPlanesB[0]->GetExtendedWidth(), pPlanesB[0]->GetExtendedHeight(), pPlanesB[0]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneUB, pel2PitchUV, pPlanesB[1]->GetAbsolutePointer(0,0), pPlanesB[1]->GetAbsolutePointer(1,0), pPlanesB[1]->GetAbsolutePointer(0,1), pPlanesB[1]->GetAbsolutePointer(1,1), pPlanesB[1]->GetExtendedWidth(), pPlanesB[1]->GetExtendedHeight(), pPlanesB[1]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneVB, pel2PitchUV, pPlanesB[2]->GetAbsolutePointer(0,0), pPlanesB[2]->GetAbsolutePointer(1,0), pPlanesB[2]->GetAbsolutePointer(0,1), pPlanesB[2]->GetAbsolutePointer(1,1), pPlanesB[2]->GetExtendedWidth(), pPlanesB[2]->GetExtendedHeight(), pPlanesB[2]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneYF, pel2PitchY, pPlanesF[0]->GetAbsolutePointer(0,0), pPlanesF[0]->GetAbsolutePointer(1,0), pPlanesF[0]->GetAbsolutePointer(0,1), pPlanesF[0]->GetAbsolutePointer(1,1), pPlanesF[0]->GetExtendedWidth(), pPlanesF[0]->GetExtendedHeight(), pPlanesF[0]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneUF, pel2PitchUV, pPlanesF[1]->GetAbsolutePointer(0,0), pPlanesF[1]->GetAbsolutePointer(1,0), pPlanesF[1]->GetAbsolutePointer(0,1), pPlanesF[1]->GetAbsolutePointer(1,1), pPlanesF[1]->GetExtendedWidth(), pPlanesF[1]->GetExtendedHeight(), pPlanesF[1]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneVF, pel2PitchUV, pPlanesF[2]->GetAbsolutePointer(0,0), pPlanesF[2]->GetAbsolutePointer(1,0), pPlanesF[2]->GetAbsolutePointer(0,1), pPlanesF[2]->GetAbsolutePointer(1,1), pPlanesF[2]->GetExtendedWidth(), pPlanesF[2]->GetExtendedHeight(), pPlanesF[2]->GetPitch(), isse); } else if (nPel==4) { // merge refined planes to big single plane Merge16PlanesToBig(pel2PlaneYB, pel2PitchY, pPlanesB[0]->GetAbsolutePointer(0,0), pPlanesB[0]->GetAbsolutePointer(1,0), pPlanesB[0]->GetAbsolutePointer(2,0), pPlanesB[0]->GetAbsolutePointer(3,0), pPlanesB[0]->GetAbsolutePointer(1,0), pPlanesB[0]->GetAbsolutePointer(1,1), pPlanesB[0]->GetAbsolutePointer(1,2), pPlanesB[0]->GetAbsolutePointer(1,3), pPlanesB[0]->GetAbsolutePointer(2,0), pPlanesB[0]->GetAbsolutePointer(2,1), pPlanesB[0]->GetAbsolutePointer(2,2), pPlanesB[0]->GetAbsolutePointer(2,3), pPlanesB[0]->GetAbsolutePointer(3,0), pPlanesB[0]->GetAbsolutePointer(3,1), pPlanesB[0]->GetAbsolutePointer(3,2), pPlanesB[0]->GetAbsolutePointer(3,3), pPlanesB[0]->GetExtendedWidth(), pPlanesB[0]->GetExtendedHeight(), pPlanesB[0]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneUB, pel2PitchUV, pPlanesB[1]->GetAbsolutePointer(0,0), pPlanesB[1]->GetAbsolutePointer(1,0), pPlanesB[1]->GetAbsolutePointer(2,0), pPlanesB[1]->GetAbsolutePointer(3,0), pPlanesB[1]->GetAbsolutePointer(1,0), pPlanesB[1]->GetAbsolutePointer(1,1), pPlanesB[1]->GetAbsolutePointer(1,2), pPlanesB[1]->GetAbsolutePointer(1,3), pPlanesB[1]->GetAbsolutePointer(2,0), pPlanesB[1]->GetAbsolutePointer(2,1), pPlanesB[1]->GetAbsolutePointer(2,2), pPlanesB[1]->GetAbsolutePointer(2,3), pPlanesB[1]->GetAbsolutePointer(3,0), pPlanesB[1]->GetAbsolutePointer(3,1), pPlanesB[1]->GetAbsolutePointer(3,2), pPlanesB[1]->GetAbsolutePointer(3,3), pPlanesB[1]->GetExtendedWidth(), pPlanesB[1]->GetExtendedHeight(), pPlanesB[1]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneVB, pel2PitchUV, pPlanesB[2]->GetAbsolutePointer(0,0), pPlanesB[2]->GetAbsolutePointer(1,0), pPlanesB[2]->GetAbsolutePointer(2,0), pPlanesB[2]->GetAbsolutePointer(3,0), pPlanesB[2]->GetAbsolutePointer(1,0), pPlanesB[2]->GetAbsolutePointer(1,1), pPlanesB[2]->GetAbsolutePointer(1,2), pPlanesB[2]->GetAbsolutePointer(1,3), pPlanesB[2]->GetAbsolutePointer(2,0), pPlanesB[2]->GetAbsolutePointer(2,1), pPlanesB[2]->GetAbsolutePointer(2,2), pPlanesB[2]->GetAbsolutePointer(2,3), pPlanesB[2]->GetAbsolutePointer(3,0), pPlanesB[2]->GetAbsolutePointer(3,1), pPlanesB[2]->GetAbsolutePointer(3,2), pPlanesB[2]->GetAbsolutePointer(3,3), pPlanesB[2]->GetExtendedWidth(), pPlanesB[2]->GetExtendedHeight(), pPlanesB[2]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneYF, pel2PitchY, pPlanesF[0]->GetAbsolutePointer(0,0), pPlanesF[0]->GetAbsolutePointer(1,0), pPlanesF[0]->GetAbsolutePointer(2,0), pPlanesF[0]->GetAbsolutePointer(3,0), pPlanesF[0]->GetAbsolutePointer(1,0), pPlanesF[0]->GetAbsolutePointer(1,1), pPlanesF[0]->GetAbsolutePointer(1,2), pPlanesF[0]->GetAbsolutePointer(1,3), pPlanesF[0]->GetAbsolutePointer(2,0), pPlanesF[0]->GetAbsolutePointer(2,1), pPlanesF[0]->GetAbsolutePointer(2,2), pPlanesF[0]->GetAbsolutePointer(2,3), pPlanesF[0]->GetAbsolutePointer(3,0), pPlanesF[0]->GetAbsolutePointer(3,1), pPlanesF[0]->GetAbsolutePointer(3,2), pPlanesF[0]->GetAbsolutePointer(3,3), pPlanesF[0]->GetExtendedWidth(), pPlanesF[0]->GetExtendedHeight(), pPlanesF[0]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneUF, pel2PitchUV, pPlanesF[1]->GetAbsolutePointer(0,0), pPlanesF[1]->GetAbsolutePointer(1,0), pPlanesF[1]->GetAbsolutePointer(2,0), pPlanesF[1]->GetAbsolutePointer(3,0), pPlanesF[1]->GetAbsolutePointer(1,0), pPlanesF[1]->GetAbsolutePointer(1,1), pPlanesF[1]->GetAbsolutePointer(1,2), pPlanesF[1]->GetAbsolutePointer(1,3), pPlanesF[1]->GetAbsolutePointer(2,0), pPlanesF[1]->GetAbsolutePointer(2,1), pPlanesF[1]->GetAbsolutePointer(2,2), pPlanesF[1]->GetAbsolutePointer(2,3), pPlanesF[1]->GetAbsolutePointer(3,0), pPlanesF[1]->GetAbsolutePointer(3,1), pPlanesF[1]->GetAbsolutePointer(3,2), pPlanesF[1]->GetAbsolutePointer(3,3), pPlanesF[1]->GetExtendedWidth(), pPlanesF[1]->GetExtendedHeight(), pPlanesF[1]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneVF, pel2PitchUV, pPlanesF[2]->GetAbsolutePointer(0,0), pPlanesF[2]->GetAbsolutePointer(1,0), pPlanesF[2]->GetAbsolutePointer(2,0), pPlanesF[2]->GetAbsolutePointer(3,0), pPlanesF[2]->GetAbsolutePointer(1,0), pPlanesF[2]->GetAbsolutePointer(1,1), pPlanesF[2]->GetAbsolutePointer(1,2), pPlanesF[2]->GetAbsolutePointer(1,3), pPlanesF[2]->GetAbsolutePointer(2,0), pPlanesF[2]->GetAbsolutePointer(2,1), pPlanesF[2]->GetAbsolutePointer(2,2), pPlanesF[2]->GetAbsolutePointer(2,3), pPlanesF[2]->GetAbsolutePointer(3,0), pPlanesF[2]->GetAbsolutePointer(3,1), pPlanesF[2]->GetAbsolutePointer(3,2), pPlanesF[2]->GetAbsolutePointer(3,3), pPlanesF[2]->GetExtendedWidth(), pPlanesF[2]->GetExtendedHeight(), pPlanesF[2]->GetPitch(), isse); } } // 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] = std::min<BYTE>(VXSmallYB[j*nBlkXP + nBlkX-1],128); VYSmallYB[j*nBlkXP + nBlkX] = VYSmallYB[j*nBlkXP + nBlkX-1]; VXSmallYF[j*nBlkXP + nBlkX] = std::min<BYTE>(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] = std::min<BYTE>(VYSmallYB[nBlkXP*(nBlkY-1) +i],128); VXSmallYF[nBlkXP*nBlkY +i] = VXSmallYF[nBlkXP*(nBlkY-1) +i]; VYSmallYF[nBlkXP*nBlkY +i] = std::min<BYTE>(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, 1/ml, 1.0, nPel, MaskSmallB, nBlkXP, (256-time256), nBlkSizeX - nOverlapX, nBlkSizeY - nOverlapY); // double occNormF = time256/(256*ml); MakeVectorOcclusionMaskTime(mvClipF, nBlkX, nBlkY, 1/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]; } } 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, and reverse backward and forward PVideoFrame mvBB = mvClipB.GetFrame(n+off, env); mvClipB.Update(mvBB, env);// backward from next next to next PVideoFrame mvFF = mvClipF.GetFrame(n, env); mvClipF.Update(mvFF, env);// forward from prev to cur 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] = std::min<BYTE>(VXSmallYBB[j*nBlkXP + nBlkX-1],128); VYSmallYBB[j*nBlkXP + nBlkX] = VYSmallYBB[j*nBlkXP + nBlkX-1]; VXSmallYFF[j*nBlkXP + nBlkX] = std::min<BYTE>(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] = std::min<BYTE>(VYSmallYBB[nBlkXP*(nBlkY-1) +i],128); VXSmallYFF[nBlkXP*nBlkY +i] = VXSmallYFF[nBlkXP*(nBlkY-1) +i]; VYSmallYFF[nBlkXP*nBlkY +i] = std::min<BYTE>(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); if (nPel>=2) { FlowInterExtra(pDst[0], nDstPitches[0], pel2PlaneYB + pel2OffsetY, pel2PlaneYF + pel2OffsetY, pel2PitchY, VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF, VXFullYBB, VXFullYFF, VYFullYBB, VYFullYFF); FlowInterExtra(pDst[1], nDstPitches[1], pel2PlaneUB + pel2OffsetUV, pel2PlaneUF + pel2OffsetUV, pel2PitchUV, VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF, VXFullUVBB, VXFullUVFF, VYFullUVBB, VYFullUVFF); FlowInterExtra(pDst[2], nDstPitches[2], pel2PlaneVB + pel2OffsetUV, pel2PlaneVF + pel2OffsetUV, pel2PitchUV, VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF, VXFullUVBB, VXFullUVFF, VYFullUVBB, VYFullUVFF); } else if (nPel==1) { FlowInterExtra(pDst[0], nDstPitches[0], pPlanesB[0]->GetPointer(0,0), pPlanesF[0]->GetPointer(0,0), pPlanesB[0]->GetPitch(), VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF, VXFullYBB, VXFullYFF, VYFullYBB, VYFullYFF); FlowInterExtra(pDst[1], nDstPitches[1], pPlanesB[1]->GetPointer(0,0), pPlanesF[1]->GetPointer(0,0), pPlanesB[1]->GetPitch(), VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF, VXFullUVBB, VXFullUVFF, VYFullUVBB, VYFullUVFF); FlowInterExtra(pDst[2], nDstPitches[2], pPlanesB[2]->GetPointer(0,0), pPlanesF[2]->GetPointer(0,0), pPlanesB[2]->GetPitch(), 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 { if (nPel>=2) { FlowInter(pDst[0], nDstPitches[0], pel2PlaneYB + pel2OffsetY, pel2PlaneYF + pel2OffsetY, pel2PitchY, VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[1], nDstPitches[1], pel2PlaneUB + pel2OffsetUV, pel2PlaneUF + pel2OffsetUV, pel2PitchUV, VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[2], nDstPitches[2], pel2PlaneVB + pel2OffsetUV, pel2PlaneVF + pel2OffsetUV, pel2PitchUV, VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); } else if (nPel==1) { FlowInter(pDst[0], nDstPitches[0], pPlanesB[0]->GetPointer(0,0), pPlanesF[0]->GetPointer(0,0), pPlanesB[0]->GetPitch(), VXFullYB, VXFullYF, VYFullYB, VYFullYF, MaskFullYB, MaskFullYF, VPitchY, nWidth, nHeight, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[1], nDstPitches[1], pPlanesB[1]->GetPointer(0,0), pPlanesF[1]->GetPointer(0,0), pPlanesB[1]->GetPitch(), VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); FlowInter(pDst[2], nDstPitches[2], pPlanesB[2]->GetPointer(0,0), pPlanesF[2]->GetPointer(0,0), pPlanesB[2]->GetPitch(), VXFullUVB, VXFullUVF, VYFullUVB, VYFullUVF, MaskFullUVB, MaskFullUVF, VPitchUV, nWidthUV, nHeightUV, time256, nPel, LUTVB, LUTVF); } } } else { // return src; // poor estimation, let's blend src with ref frames unsigned char const *pRef[3], *pSrc[3]; int nRefPitches[3], nSrcPitches[3]; SrcPlanes->ConvertVideoFrameToPlanes(&src, pSrc, nSrcPitches); RefPlanes->ConvertVideoFrameToPlanes(&ref, pRef, nRefPitches); // 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); } // convert back from planes unsigned char *pDstYUY2 = dst->GetWritePtr(); int nDstPitchYUY2 = dst->GetPitch(); DstPlanes->YUY2FromPlanes(pDstYUY2, nDstPitchYUY2); return dst; }
//------------------------------------------------------------------------- PVideoFrame __stdcall MVFlow::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); bool paritySrc = child->GetParity(n); int nref; int off = mvClip.GetDeltaFrame(); // integer offset of reference frame if ( mvClip.IsBackward() ) { nref = n + off; } else { nref = n - off; } PVideoFrame mvn = mvClip.GetFrame(n, env); mvClip.Update(mvn, env);// backward from next to current int sharp = mvClip.GetSharp(); if ( mvClip.IsUsable()) { // get reference frames PMVGroupOfFrames pRefGOF = mvCore->GetFrame(nIdx, nref); if (!pRefGOF->IsProcessed()) { PVideoFrame ref, ref2x; ref = child->GetFrame(nref, env); pRefGOF->SetParity(child->GetParity(nref)); if (usePelClipHere) ref2x= pelclip->GetFrame(nref, env); ProcessFrameIntoGroupOfFrames(&pRefGOF, &ref, &ref2x, sharp, pixelType, nHeight, nWidth, nPel, isse); } PVideoFrame dst = env->NewVideoFrame(vi); // convert to frames unsigned char *pDst[3]; int nDstPitches[3]; DstPlanes->ConvertVideoFrameToPlanes(&dst, pDst, nDstPitches); MVPlane *pPlanes[3]; pPlanes[0] = pRefGOF->GetFrame(0)->GetPlane(YPLANE); pPlanes[1] = pRefGOF->GetFrame(0)->GetPlane(UPLANE); pPlanes[2] = pRefGOF->GetFrame(0)->GetPlane(VPLANE); if (nPel>=2 ){ if (usePelClipHere) { // simply padding 2x or 4x planes PlaneCopy(pel2PlaneY + pel2OffsetY, pel2PitchY, pRefGOF->GetVFYPtr(), pRefGOF->GetVFYPitch(), nWidth*nPel, nHeight*nPel, isse); Padding::PadReferenceFrame(pel2PlaneY, pel2PitchY, nHPadding*nPel, nVPadding*nPel, nWidth*nPel, nHeight*nPel); PlaneCopy(pel2PlaneU + pel2OffsetUV, pel2PitchUV, pRefGOF->GetVFUPtr(), pRefGOF->GetVFUPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneU, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); PlaneCopy(pel2PlaneV + pel2OffsetUV, pel2PitchUV, pRefGOF->GetVFVPtr(), pRefGOF->GetVFVPitch(), nWidthUV*nPel, nHeightUV*nPel, isse); Padding::PadReferenceFrame(pel2PlaneV, pel2PitchUV, nHPaddingUV*nPel, nVPaddingUV*nPel, nWidthUV*nPel, nHeightUV*nPel); } else if (nPel==2) { // merge refined planes to big single plane Merge4PlanesToBig(pel2PlaneY, pel2PitchY, pPlanes[0]->GetAbsolutePointer(0,0), pPlanes[0]->GetAbsolutePointer(1,0), pPlanes[0]->GetAbsolutePointer(0,1), pPlanes[0]->GetAbsolutePointer(1,1), pPlanes[0]->GetExtendedWidth(), pPlanes[0]->GetExtendedHeight(), pPlanes[0]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneU, pel2PitchUV, pPlanes[1]->GetAbsolutePointer(0,0), pPlanes[1]->GetAbsolutePointer(1,0), pPlanes[1]->GetAbsolutePointer(0,1), pPlanes[1]->GetAbsolutePointer(1,1), pPlanes[1]->GetExtendedWidth(), pPlanes[1]->GetExtendedHeight(), pPlanes[1]->GetPitch(), isse); Merge4PlanesToBig(pel2PlaneV, pel2PitchUV, pPlanes[2]->GetAbsolutePointer(0,0), pPlanes[2]->GetAbsolutePointer(1,0), pPlanes[2]->GetAbsolutePointer(0,1), pPlanes[2]->GetAbsolutePointer(1,1), pPlanes[2]->GetExtendedWidth(), pPlanes[2]->GetExtendedHeight(), pPlanes[2]->GetPitch(), isse); } else if (nPel==4) { // merge refined planes to big single plane Merge16PlanesToBig(pel2PlaneY, pel2PitchY, pPlanes[0]->GetAbsolutePointer(0,0), pPlanes[0]->GetAbsolutePointer(1,0), pPlanes[0]->GetAbsolutePointer(2,0), pPlanes[0]->GetAbsolutePointer(3,0), pPlanes[0]->GetAbsolutePointer(1,0), pPlanes[0]->GetAbsolutePointer(1,1), pPlanes[0]->GetAbsolutePointer(1,2), pPlanes[0]->GetAbsolutePointer(1,3), pPlanes[0]->GetAbsolutePointer(2,0), pPlanes[0]->GetAbsolutePointer(2,1), pPlanes[0]->GetAbsolutePointer(2,2), pPlanes[0]->GetAbsolutePointer(2,3), pPlanes[0]->GetAbsolutePointer(3,0), pPlanes[0]->GetAbsolutePointer(3,1), pPlanes[0]->GetAbsolutePointer(3,2), pPlanes[0]->GetAbsolutePointer(3,3), pPlanes[0]->GetExtendedWidth(), pPlanes[0]->GetExtendedHeight(), pPlanes[0]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneU, pel2PitchUV, pPlanes[1]->GetAbsolutePointer(0,0), pPlanes[1]->GetAbsolutePointer(1,0), pPlanes[1]->GetAbsolutePointer(2,0), pPlanes[1]->GetAbsolutePointer(3,0), pPlanes[1]->GetAbsolutePointer(1,0), pPlanes[1]->GetAbsolutePointer(1,1), pPlanes[1]->GetAbsolutePointer(1,2), pPlanes[1]->GetAbsolutePointer(1,3), pPlanes[1]->GetAbsolutePointer(2,0), pPlanes[1]->GetAbsolutePointer(2,1), pPlanes[1]->GetAbsolutePointer(2,2), pPlanes[1]->GetAbsolutePointer(2,3), pPlanes[1]->GetAbsolutePointer(3,0), pPlanes[1]->GetAbsolutePointer(3,1), pPlanes[1]->GetAbsolutePointer(3,2), pPlanes[1]->GetAbsolutePointer(3,3), pPlanes[1]->GetExtendedWidth(), pPlanes[1]->GetExtendedHeight(), pPlanes[1]->GetPitch(), isse); Merge16PlanesToBig(pel2PlaneV, pel2PitchUV, pPlanes[2]->GetAbsolutePointer(0,0), pPlanes[2]->GetAbsolutePointer(1,0), pPlanes[2]->GetAbsolutePointer(2,0), pPlanes[2]->GetAbsolutePointer(3,0), pPlanes[2]->GetAbsolutePointer(1,0), pPlanes[2]->GetAbsolutePointer(1,1), pPlanes[2]->GetAbsolutePointer(1,2), pPlanes[2]->GetAbsolutePointer(1,3), pPlanes[2]->GetAbsolutePointer(2,0), pPlanes[2]->GetAbsolutePointer(2,1), pPlanes[2]->GetAbsolutePointer(2,2), pPlanes[2]->GetAbsolutePointer(2,3), pPlanes[2]->GetAbsolutePointer(3,0), pPlanes[2]->GetAbsolutePointer(3,1), pPlanes[2]->GetAbsolutePointer(3,2), pPlanes[2]->GetAbsolutePointer(3,3), pPlanes[2]->GetExtendedWidth(), pPlanes[2]->GetExtendedHeight(), pPlanes[2]->GetPitch(), isse); } } // char debugbuf[100]; // for (int V=100; V<145; V++) // { // int vx1 = ((V-128)*time256)>>8; // int vx2 = ((V*time256+127)>>8) - (time256>>1); // int vx3 = ((V*time256)/256) - (time256/2); // int vx4 = ((V-128)*time256)/256; // int vx5 = V-128; // if (vx5 < 0) vx5++; // vx5 = (vx5*time256)>>8; // // sprintf(debugbuf,"MVFlow: V=%d %d %d %d %d %d", V,vx1,vx2,vx3,vx4,vx5); // OutputDebugString(debugbuf); // } // // 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(mvClip, nBlkX, nBlkY, VXSmallY, nBlkXP, VYSmallY, nBlkXP); if (nBlkXP > nBlkX) // fill right { for (int j=0; j<nBlkY; j++) { VXSmallY[j*nBlkXP + nBlkX] = std::min<BYTE>(VXSmallY[j*nBlkXP + nBlkX-1],128); VYSmallY[j*nBlkXP + nBlkX] = VYSmallY[j*nBlkXP + nBlkX-1]; } } if (nBlkYP > nBlkY) // fill bottom { for (int i=0; i<nBlkXP; i++) { VXSmallY[nBlkXP*nBlkY +i] = VXSmallY[nBlkXP*(nBlkY-1) +i]; VYSmallY[nBlkXP*nBlkY +i] = std::min<BYTE>(VYSmallY[nBlkXP*(nBlkY-1) +i],128); } } int fieldShift = 0; if (fields && (nPel >= 2) && (off %2 != 0)) { fieldShift = (paritySrc && !pRefGOF->Parity()) ? (nPel/2) : ((pRefGOF->Parity() && !paritySrc) ? -(nPel/2) : 0); // vertical shift of fields for fieldbased video at finest level pel2 } for (int j=0; j<nBlkYP; j++) { for (int i=0; i<nBlkXP; i++) { VYSmallY[j*nBlkXP + i] += fieldShift; } } VectorSmallMaskYToHalfUV(VXSmallY, nBlkXP, nBlkYP, VXSmallUV, 2); VectorSmallMaskYToHalfUV(VYSmallY, nBlkXP, nBlkYP, VYSmallUV, yRatioUV); // 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(VXFullY, nWidthP, nHeightP, VPitchY, VXSmallY, nBlkXP, nBlkXP, dummyplane); upsizer->SimpleResizeDo(VYFullY, nWidthP, nHeightP, VPitchY, VYSmallY, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VXFullUV, nWidthPUV, nHeightPUV, VPitchUV, VXSmallUV, nBlkXP, nBlkXP, dummyplane); upsizerUV->SimpleResizeDo(VYFullUV, nWidthPUV, nHeightPUV, VPitchUV, VYSmallUV, nBlkXP, nBlkXP, dummyplane); if (mode==0) // fetch mode { if (nPel>=2) { Fetch(pDst[0], nDstPitches[0], pel2PlaneY + pel2OffsetY, pel2PitchY, VXFullY, VPitchY, VYFullY, VPitchY, nWidth, nHeight, time256); //padded Fetch(pDst[1], nDstPitches[1], pel2PlaneU + pel2OffsetUV, pel2PitchUV, VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); Fetch(pDst[2], nDstPitches[2], pel2PlaneV + pel2OffsetUV, pel2PitchUV, VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); } else //(nPel==1) { Fetch(pDst[0], nDstPitches[0], pPlanes[0]->GetPointer(0,0), pPlanes[0]->GetPitch(), VXFullY, VPitchY, VYFullY, VPitchY, nWidth, nHeight, time256); //padded Fetch(pDst[1], nDstPitches[1], pPlanes[1]->GetPointer(0,0), pPlanes[1]->GetPitch(), VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); Fetch(pDst[2], nDstPitches[2], pPlanes[2]->GetPointer(0,0), pPlanes[2]->GetPitch(), VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); } } else if (mode==1) // shift mode { MemZoneSet(pDst[0], 0, nWidth, nHeight, 0, 0, nDstPitches[0]); MemZoneSet(pDst[1], 0, nWidthUV, nHeightUV, 0, 0, nDstPitches[1]); MemZoneSet(pDst[2], 0, nWidthUV, nHeightUV, 0, 0, nDstPitches[2]); Shift(pDst[0], nDstPitches[0], pPlanes[0]->GetPointer(0,0), pPlanes[0]->GetPitch(), VXFullY, VPitchY, VYFullY, VPitchY, nWidth, nHeight, time256); Shift(pDst[1], nDstPitches[1], pPlanes[1]->GetPointer(0,0), pPlanes[1]->GetPitch(), VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); Shift(pDst[2], nDstPitches[2], pPlanes[2]->GetPointer(0,0), pPlanes[2]->GetPitch(), VXFullUV, VPitchUV, VYFullUV, VPitchUV, nWidthUV, nHeightUV, time256); } // convert back from planes unsigned char *pDstYUY2 = dst->GetWritePtr(); int nDstPitchYUY2 = dst->GetPitch(); DstPlanes->YUY2FromPlanes(pDstYUY2, nDstPitchYUY2); return dst; } else { return src; } }