Ejemplo n.º 1
0
PVideoFrame __stdcall MVSCDetection::GetFrame(int n, IScriptEnvironment* env)
{
   PVideoFrame dst = env->NewVideoFrame(vi);

	PVideoFrame mvn = mvClip.GetFrame(n, env);
   mvClip.Update(mvn, env);

   if ( mvClip.IsUsable() )
	{
	   if(vi.IsYV12())
	   {
//      MemZoneSet(YWPLAN(dst), 0, nWidth, nHeight, 0, 0, YPITCH(dst));
//      MemZoneSet(UWPLAN(dst), 0, nWidth/2, nHeight/2, 0, 0, UPITCH(dst));
//      MemZoneSet(VWPLAN(dst), 0, nWidth/2, nHeight/2, 0, 0, VPITCH(dst));
		  MemZoneSet(dst->GetWritePtr(PLANAR_Y), 0, dst->GetRowSize(PLANAR_Y), dst->GetHeight(PLANAR_Y), 0, 0, dst->GetPitch(PLANAR_Y));
		  MemZoneSet(dst->GetWritePtr(PLANAR_U), 0, dst->GetRowSize(PLANAR_U), dst->GetHeight(PLANAR_U), 0, 0, dst->GetPitch(PLANAR_U));
		  MemZoneSet(dst->GetWritePtr(PLANAR_V), 0, dst->GetRowSize(PLANAR_V), dst->GetHeight(PLANAR_V), 0, 0, dst->GetPitch(PLANAR_V));
	   }
	   else
	   {
		  MemZoneSet(dst->GetWritePtr(), 0, dst->GetRowSize(), dst->GetHeight(), 0, 0, dst->GetPitch());
	   }
	}
   else {
	   if(vi.IsYV12())
	   {
//      MemZoneSet(YWPLAN(dst), sceneChangeValue, nWidth, nHeight, 0, 0, YPITCH(dst));
//      MemZoneSet(UWPLAN(dst), sceneChangeValue, nWidth/2, nHeight/2, 0, 0, UPITCH(dst));
//      MemZoneSet(VWPLAN(dst), sceneChangeValue, nWidth/2, nHeight/2, 0, 0, VPITCH(dst));
		  MemZoneSet(dst->GetWritePtr(PLANAR_Y), sceneChangeValue, dst->GetRowSize(PLANAR_Y), dst->GetHeight(PLANAR_Y), 0, 0, dst->GetPitch(PLANAR_Y));
		  MemZoneSet(dst->GetWritePtr(PLANAR_U), sceneChangeValue, dst->GetRowSize(PLANAR_U), dst->GetHeight(PLANAR_U), 0, 0, dst->GetPitch(PLANAR_U));
		  MemZoneSet(dst->GetWritePtr(PLANAR_V), sceneChangeValue, dst->GetRowSize(PLANAR_V), dst->GetHeight(PLANAR_V), 0, 0, dst->GetPitch(PLANAR_V));
	   }
	   else
	   {
		  MemZoneSet(dst->GetWritePtr(), sceneChangeValue, dst->GetRowSize(), dst->GetHeight(), 0, 0, dst->GetPitch());
	   }
   }

	return dst;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
//-------------------------------------------------------------------------
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;
    }
}