void copyPlanar(const uchar* srcp, PVideoFrame &dst, int bpp) { const int bytes_per_pixel = bpp / 8; const int cols = dst->GetRowSize(); const int rows = dst->GetHeight(); const int dst_pitch = dst->GetPitch(); const int src_pitch = cols / bytes_per_pixel; uchar* dstp = dst->GetWritePtr(); int y, x; const int dst_pitchUV = dst->GetPitch(PLANAR_U); const int dst_widthUV = dst->GetRowSize(PLANAR_U); const int dst_heightUV = dst->GetHeight(PLANAR_U); for (y = 0; y < rows; y++) { // copy mask to Y plane for (x = 0; x < cols; x++) { dstp[x] = srcp[x / bytes_per_pixel]; } srcp += src_pitch; dstp += dst_pitch; } dstp = dst->GetWritePtr(PLANAR_U); // set U plane to no color for (y = 0; y < dst_heightUV; y++) { for (x = 0; x < dst_widthUV; x++) { dstp[x] = 128; // set chroma to none } dstp += dst_pitchUV; } // set V plane to no color dstp = dst->GetWritePtr(PLANAR_V); for (y = 0; y < dst_heightUV; y++) { for (x = 0; x < dst_widthUV; x++) { dstp[x] = 128; // set chroma to none } dstp += dst_pitchUV; } }
//void MVClip::Update(int n, IScriptEnvironment *env) void MVClip::Update(PVideoFrame &fn, IScriptEnvironment *env) { // PVideoFrame fn = child->GetFrame(n, env); const int *pMv = reinterpret_cast<const int*>(fn->GetReadPtr()); int _headerSize = pMv[0]; int nMagicKey1 = pMv[1]; if (nMagicKey1 != MOTION_MAGIC_KEY) env->ThrowError("MVTools: invalid vectors stream"); int nVersion1 = pMv[2]; if (nVersion1 != MVANALYSIS_DATA_VERSION) env->ThrowError("MVTools: incompatible version of vectors stream"); pMv += _headerSize/sizeof(int); // go to data - v1.8.1 // FakeGroupOfPlanes::Update(reinterpret_cast<const int*>(fn->GetReadPtr()));// fixed a bug with lost frames FakeGroupOfPlanes::Update(pMv);// fixed a bug with lost frames }
PVideoFrame FTurn::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n,env); auto dst = env->NewVideoFrame(vi); auto pSrcY = src->GetReadPtr(PLANAR_Y); auto pDstY = dst->GetWritePtr(PLANAR_Y); int srcPitchY = src->GetPitch(PLANAR_Y); int dstPitchY = dst->GetPitch(PLANAR_Y); int srcWidthY = src->GetRowSize(PLANAR_Y); int srcHeightY = src->GetHeight(PLANAR_Y); if (!(chroma_ && hasChroma(vi.pixel_type))) { turnFunction_(pDstY, pSrcY, srcWidthY, srcHeightY, dstPitchY, srcPitchY); } else { auto pDstU = dst->GetWritePtr(PLANAR_U); auto pDstV = dst->GetWritePtr(PLANAR_V); auto pSrcU = src->GetReadPtr(PLANAR_U); auto pSrcV = src->GetReadPtr(PLANAR_V); int srcPitchUV = src->GetPitch(PLANAR_U); int dstPitchUV = dst->GetPitch(PLANAR_U); int srcWidthUV = src->GetRowSize(PLANAR_U); int srcHeightUV = src->GetHeight(PLANAR_V); if (mt_) { auto thread2 = std::async(launch::async, [=] { turnFunction_(pDstU, pSrcU, srcWidthUV, srcHeightUV, dstPitchUV, srcPitchUV); turnFunction_(pDstV, pSrcV, srcWidthUV, srcHeightUV, dstPitchUV, srcPitchUV); }); turnFunction_(pDstY, pSrcY, srcWidthY, srcHeightY, dstPitchY, srcPitchY); thread2.wait(); } else { turnFunction_(pDstU, pSrcU, srcWidthUV, srcHeightUV, dstPitchUV, srcPitchUV); turnFunction_(pDstV, pSrcV, srcWidthUV, srcHeightUV, dstPitchUV, srcPitchUV); turnFunction_(pDstY, pSrcY, srcWidthY, srcHeightY, dstPitchY, srcPitchY); } } return dst; }
void AvisynthVideoSource::OutputFrame(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env) { if (VI.pixel_type == VideoInfo::CS_I420) { BlitPlane(Frame, Dst, Env, 0); BlitPlane(Frame, Dst, Env, 1); BlitPlane(Frame, Dst, Env, 2); } else if (VI.IsYUY2()) { BlitPlane(Frame, Dst, Env, 0); } else { // RGB Env->BitBlt( Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1), -Dst->GetPitch(), Frame->Data[0], Frame->Linesize[0], Dst->GetRowSize(), Dst->GetHeight()); } }
PVideoFrame AreaResize::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); if (params[0].src_width == params[0].target_width && params[0].src_height == params[0].target_height) { return src; } PVideoFrame dst = env->NewVideoFrame(vi); int plane[] = {PLANAR_Y, PLANAR_U, PLANAR_V}; for (int i = 0, time = vi.IsInterleaved() ? 1 : 3; i < time; i++) { const BYTE* srcp = src->GetReadPtr(plane[i]); int src_pitch = src->GetPitch(plane[i]); const BYTE* resized_h; if (params[i].src_width == params[i].target_width) { resized_h = srcp; } else { if (!ResizeHorizontal(buff, srcp, src_pitch, ¶ms[i])) { return dst; } resized_h = buff; src_pitch = dst->GetRowSize(plane[i]); } BYTE* dstp = dst->GetWritePtr(plane[i]); int dst_pitch = dst->GetPitch(plane[i]); if (params[i].src_height == params[i].target_height) { env->BitBlt(dstp, dst_pitch, resized_h, src_pitch, dst->GetRowSize(plane[i]), dst->GetHeight(plane[i])); continue; } if (!ResizeVertical(dstp, dst_pitch, resized_h, src_pitch, ¶ms[i])) { return dst; } } return dst; }
void copyplane(PVideoFrame &result, const PVideoFrame &source, int plane, IScriptEnvironment *env) { // void __stdcall IScriptEnvironment::BitBlt //(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0 unsigned char *resultpointer = result->GetWritePtr(plane); const unsigned char *sourcepointer = source->GetReadPtr(plane); const int width = source->GetRowSize(plane); const int height = source->GetHeight(plane); const int sourcepitch = source->GetPitch(plane); const int resultpitch = result->GetPitch(plane); env->BitBlt(resultpointer, resultpitch, sourcepointer, sourcepitch, width, height); }
void AvisynthVideoSource::OutputField(const FFMS_Frame *Frame, PVideoFrame &Dst, int Field, IScriptEnvironment *Env) { const FFMS_Frame *SrcPicture = (Frame); if (VI.pixel_type == VideoInfo::CS_I420) { BlitField(Frame, Dst, Env, 0, Field); BlitField(Frame, Dst, Env, 1, Field); BlitField(Frame, Dst, Env, 2, Field); } else if (VI.IsYUY2()) { BlitField(Frame, Dst, Env, 0, Field); } else { // RGB Env->BitBlt( Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1 - Field), -Dst->GetPitch() * 2, SrcPicture->Data[0] + SrcPicture->Linesize[0] * Field, SrcPicture->Linesize[0] * 2, Dst->GetRowSize(), Dst->GetHeight() / 2); } }
PVideoFrame __stdcall MergeChroma::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); if (weight<0.0001f) return src; PVideoFrame chroma = clip->GetFrame(n, env); const int h = src->GetHeight(); const int w = src->GetRowSize()>>1; // width in pixels if (weight<0.9999f) { if (vi.IsYUY2()) { env->MakeWritable(&src); unsigned int* srcp = (unsigned int*)src->GetWritePtr(); unsigned int* chromap = (unsigned int*)chroma->GetReadPtr(); const int isrc_pitch = (src->GetPitch())>>2; // int pitch (one pitch=two pixels) const int ichroma_pitch = (chroma->GetPitch())>>2; // Ints ((TEST(4, 8) (env->GetCPUFlags() & CPUF_MMX)) ? mmx_weigh_chroma : weigh_chroma) (srcp,chromap,isrc_pitch,ichroma_pitch,w,h,(int)(weight*32768.0f),32768-(int)(weight*32768.0f)); } else { // Planar
static void make_black_background_planar_yuv_interleaved ( PVideoFrame &frame, int bitdepth_minus_8 ) { memset( frame->GetWritePtr( PLANAR_Y ), 0x00, frame->GetPitch( PLANAR_Y ) * frame->GetHeight( PLANAR_Y ) ); uint8_t msb = (uint8_t)((0x80U << bitdepth_minus_8) >> 8); int size = frame->GetPitch( PLANAR_U ) * frame->GetHeight( PLANAR_U ); for( int i = 0; i < size; i++ ) if( i & 1 ) { *(frame->GetWritePtr( PLANAR_U ) + i) = msb; *(frame->GetWritePtr( PLANAR_V ) + i) = msb; } else { *(frame->GetWritePtr( PLANAR_U ) + i) = 0x00; *(frame->GetWritePtr( PLANAR_V ) + i) = 0x00; } }
PVideoFrame __stdcall VNoise :: GetFrame(int n, IScriptEnvironment* env) { // Destination PVideoFrame dest = env->NewVideoFrame(this->clipInfo); unsigned char* destPtr = dest->GetWritePtr(); int destPitch = dest->GetPitch(); // Get main source PVideoFrame sourceMain = this->clip->GetFrame(n, env); const unsigned char* sourceMainPtr = sourceMain->GetReadPtr(); int sourceMainPitch = sourceMain->GetPitch(); int rgba[4]; // Loop values int x, y, j; int width = this->clipInfo.width; int height = this->clipInfo.height; int rowSize = width * this->components; // Copy from main source for (y = 0; y < height; ++y) { // Loop over line for (x = 0; x < rowSize; x += this->components) { // Get old for (j = 0; j < this->components; ++j) { rgba[j] = *(sourceMainPtr + x + j); } // Modify this->randomChange(rgba); // Set new for (j = 0; j < this->components; ++j) { *(destPtr + x + j) = rgba[j]; } } // Next line sourceMainPtr += sourceMainPitch; destPtr += destPitch; } // Done return dest; }
void f3kdb_avisynth::process_plane(int n, PVideoFrame src, PVideoFrame dst, unsigned char *dstp, int plane, IScriptEnvironment* env) { int f3kdb_plane; switch (plane & 7) { case PLANAR_Y: f3kdb_plane = PLANE_Y; break; case PLANAR_U: f3kdb_plane = PLANE_CB; break; case PLANAR_V: f3kdb_plane = PLANE_CR; break; default: assert(false); env->ThrowError("f3kdb: Invalid plane"); } int result = f3kdb_process_plane(_core, n, f3kdb_plane, dstp, dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane)); if (result != F3KDB_SUCCESS) { env->ThrowError("f3kdb: Unknown error, code = %d", result); } }
PVideoFrame __stdcall MVMultiExtract::GetFrame(int n, IScriptEnvironment* env) { // DebugPrintf("MVAnalyse: Get src frame %d",n); PVideoFrame src = child->GetFrame(n, env); const BYTE* srcPtr=src->GetReadPtr(); int SrcPitch=src->GetPitch(); PVideoFrame dst = env->NewVideoFrame(vi); unsigned char *pDst = dst->GetWritePtr(); int DstPitch = dst->GetPitch(); // extract the appropriate rows out of the frame RGB32 is 4 bytes per pixel for(int IndexNum=0; IndexNum<NumIndices; ++IndexNum) { memcpy(reinterpret_cast<void*>(pDst+DstPitch*IndexNum), reinterpret_cast<void const*>(srcPtr+SrcPitch*Index[IndexNum]), vi.width*4); } return dst; }
void AvisynthVideoSource::OutputFrame(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env) { if (VI.IsPlanar()) { BlitPlane(Frame, Dst, Env, 0, VI.IsRGB() ? PLANAR_G : PLANAR_Y); if (HighBitDepth ? !VI.IsY() : !VI.IsY8()) { BlitPlane(Frame, Dst, Env, 1, VI.IsRGB() ? PLANAR_B : PLANAR_U); BlitPlane(Frame, Dst, Env, 2, VI.IsRGB() ? PLANAR_R : PLANAR_V); } if (VI.IsYUVA() || VI.IsPlanarRGBA()) BlitPlane(Frame, Dst, Env, 3, PLANAR_A); } else if (VI.IsYUY2()) { BlitPlane(Frame, Dst, Env, 0, 0); } else if (VI.IsRGB24() || VI.IsRGB32()) { Env->BitBlt( Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1), -Dst->GetPitch(), Frame->Data[0], Frame->Linesize[0], Dst->GetRowSize(), Dst->GetHeight()); } else { assert(false); } }
PVideoFrame __stdcall CSRIAviSynth::GetFrame(int n, IScriptEnvironment *env) { PVideoFrame avsframe = child->GetFrame(n, env); struct csri_frame frame; env->MakeWritable(&avsframe); frame.pixfmt = GetPixfmt(); frame.planes[0] = avsframe->GetWritePtr(); frame.strides[0] = avsframe->GetPitch(); if (csri_is_yuv_planar(frame.pixfmt)) { frame.planes[1] = avsframe->GetWritePtr(PLANAR_U); frame.strides[1] = avsframe->GetPitch(PLANAR_U); frame.planes[2] = avsframe->GetWritePtr(PLANAR_V); frame.strides[2] = avsframe->GetPitch(PLANAR_V); } if (csri_is_rgb(frame.pixfmt)) { frame.planes[0] += (vi.height - 1) * frame.strides[0]; frame.strides[0] = -frame.strides[0]; } csri_render(inst, &frame, n * spf); return avsframe; }
void AvisynthVideoSource::OutputField(const FFMS_Frame *Frame, PVideoFrame &Dst, int Field, IScriptEnvironment *Env) { const FFMS_Frame *SrcPicture = Frame; if (VI.IsPlanar()) { BlitField(Frame, Dst, Env, 0, VI.IsRGB() ? PLANAR_G : PLANAR_Y, Field); if (HighBitDepth ? !VI.IsY() : !VI.IsY8()) { BlitField(Frame, Dst, Env, 1, VI.IsRGB() ? PLANAR_B : PLANAR_U, Field); BlitField(Frame, Dst, Env, 2, VI.IsRGB() ? PLANAR_R : PLANAR_V, Field); } if (VI.IsYUVA() || VI.IsPlanarRGBA()) BlitField(Frame, Dst, Env, 3, PLANAR_A, Field); } else if (VI.IsYUY2()) { BlitField(Frame, Dst, Env, 0, 0, Field); } else if (VI.IsRGB24() || VI.IsRGB32()) { Env->BitBlt( Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1 - Field), -Dst->GetPitch() * 2, SrcPicture->Data[0] + SrcPicture->Linesize[0] * Field, SrcPicture->Linesize[0] * 2, Dst->GetRowSize(), Dst->GetHeight() / 2); } else { assert(false); } }
PVideoFrame __stdcall MVDepan::GetFrame(int ndest, IScriptEnvironment* env) { // isBackward = false; // bool ifZoom = true; // bool ifRot = true; // float pixaspect = 1; // float error = 15; // bool info = true; int nFields = (vi.IsFieldBased()) ? 2 : 1; PVideoFrame src = child->GetFrame(ndest, env); PVideoFrame dst = env->NewVideoFrame(vi); const BYTE * srcp; BYTE * dstp; int src_width; int src_height; int src_pitch; int dst_pitch; if (vi.IsYV12()) { // copy U srcp= src->GetReadPtr(PLANAR_U); src_width= src->GetRowSize(PLANAR_U); src_height= src->GetHeight(PLANAR_U); src_pitch= src->GetPitch(PLANAR_U); dstp= dst->GetWritePtr(PLANAR_U); dst_pitch= dst->GetPitch(PLANAR_U); env->BitBlt(dstp, dst_pitch, srcp, src_pitch, src_width, src_height); // copy V srcp = src->GetReadPtr(PLANAR_V); src_width = src->GetRowSize(PLANAR_V); src_height = src->GetHeight(PLANAR_V); src_pitch = src->GetPitch(PLANAR_V); dstp = dst->GetWritePtr(PLANAR_V); dst_pitch = dst->GetPitch(PLANAR_V); env->BitBlt(dstp, dst_pitch, srcp, src_pitch, src_width, src_height); // copy Y and prepare for output data srcp = src->GetReadPtr(PLANAR_Y); src_width = src->GetRowSize(PLANAR_Y); src_height = src->GetHeight(PLANAR_Y); src_pitch = src->GetPitch(PLANAR_Y); dstp = dst->GetWritePtr(PLANAR_Y); dst_pitch = dst->GetPitch(PLANAR_Y); env->BitBlt(dstp, dst_pitch, srcp, src_pitch, src_width, src_height); } else { srcp = src->GetReadPtr(); src_width = src->GetRowSize(); src_height = src->GetHeight(); src_pitch = src->GetPitch(); dstp = dst->GetWritePtr(); dst_pitch = dst->GetPitch(); env->BitBlt(dstp, dst_pitch, srcp, src_pitch, src_width, src_height); } float dPel = 1.0f/nPel; // subpixel precision value // declare motion transform structure transform tr; int backward; if (mvclip.IsBackward()) backward = 1; // for backward transform else backward = 0; int framefirst = max(ndest - range, 0); int framelast = min(ndest + range, vi.num_frames-1); float safety; float errorcur; int iter; float errordif = 0.01f; // error difference to terminate iterations int itermax = 150; // maximum iteration number float zeroWeight = 0.05f; // zero vector weight for (int nframe=framefirst; nframe<=framelast; nframe++) { // init motion transform as null tr.dxc=0; tr.dxx=1; tr.dxy=0; tr.dyc=0; tr.dyx=0; tr.dyy=1; if (motionx[nframe] != MOTIONUNKNOWN) continue; errorcur = error*2; // v1.2.3 iter = 0; // start iteration int nframemv = (backward) ? nframe-1: nframe; // set prev frame number as data frame if backward PVideoFrame mvn = mvclip.GetFrame(nframemv, env); mvclip.Update(mvn, env); if ( nframemv >= 0 && mvclip.IsUsable() ) { // float testDx = 0; // float testDy = 0; for (int j=0; j< nBlkY; j++) { for (int i=0; i<nBlkX; i++) { int nb = j*nBlkX+i; blockDx[nb] = mvclip.GetBlock(0,nb).GetMV().x * dPel; blockDy[nb] = mvclip.GetBlock(0,nb).GetMV().y * dPel; blockSAD[nb] = mvclip.GetBlock(0,nb).GetSAD(); blockX[nb] = mvclip.GetBlock(0,nb).GetX()+ nBlkSizeX/2;//i*nBlkSize + nBlkSize/2;// rewritten in v1.2.5 blockY[nb] = mvclip.GetBlock(0,nb).GetY()+ nBlkSizeY/2;//j*nBlkSize + nBlkSize/2;// blockWeight[nb] = 1; // testDx += blockDx[nb]; // testDy += blockDy[nb]; } } // testDx /= nBlkX*nBlkY; // testDy /= nBlkX*nBlkY; // char debugbuf[200]; // sprintf(debugbuf,"MVDEPAN: %d %f %f %d %d", n, testDx, testDy, blockX[nBlkX*nBlkY-1], blockY[nBlkX*nBlkY-1]); // OutputDebugString(debugbuf); // begin with translation only safety = 0.3f; // begin with small safety factor bool ifRot0 = false; bool ifZoom0 = false; float globalDif0 = 1000.0f; for (; iter<5; iter++) { TrasformUpdate(&tr, blockDx, blockDy, blockSAD, blockX, blockY, blockWeight, nBlkX, nBlkY, safety, ifZoom0, ifRot0, &errorcur, pixaspect/nFields); RejectBadBlocks(tr, blockDx, blockDy, blockSAD, blockX, blockY, blockWeight, nBlkX, nBlkY, wrongDif, globalDif0, mvclip.GetThSCD1(), zeroWeight); } for (; iter<100; iter++) { if (iter < 8) safety = 0.3f; // use for safety else if (iter < 10) safety = 0.6f; else safety = 1.0f; float errorprev = errorcur; TrasformUpdate(&tr, blockDx, blockDy, blockSAD, blockX, blockY, blockWeight, nBlkX, nBlkY, safety, ifZoom, ifRot, &errorcur, pixaspect/nFields); if (((errorprev - errorcur) < errordif*0.5 && iter > 9) || errorcur<errordif) break; // check convergence, accuracy increased in v1.2.5 float globalDif = errorcur*2; RejectBadBlocks(tr, blockDx, blockDy, blockSAD, blockX, blockY, blockWeight, nBlkX, nBlkY, wrongDif, globalDif, mvclip.GetThSCD1(), zeroWeight); } } // we get transform (null if scenechange) float xcenter = (float)vi.width/2; float ycenter = (float)vi.height/2; motionx[nframe] = 0; motiony[nframe] = 0; motionrot[nframe] = 0; motionzoom[nframe] = 1; if (errorcur < error) // if not bad result { // convert transform data to ordinary motion format if (mvclip.IsBackward()) { transform trinv; inversetransform(tr, &trinv); transform2motion (trinv, 0, xcenter, ycenter, pixaspect/nFields, &motionx[nframe], &motiony[nframe], &motionrot[nframe], &motionzoom[nframe]); } else transform2motion (tr, 1, xcenter, ycenter, pixaspect/nFields, &motionx[nframe], &motiony[nframe], &motionrot[nframe], &motionzoom[nframe]); // fieldbased correction - added in v1.2.3 int isnframeodd = nframe%2; // =0 for even, =1 for odd float yadd = 0; if (vi.IsFieldBased()) { // correct line shift for fields, if not scenechange // correct unneeded fields matching { if ( vi.IsTFF()) yadd += 0.5f - isnframeodd; // TFF else yadd += - 0.5f + isnframeodd; // BFF (or undefined?) } // scale dy for fieldbased frame by factor 2 (for compatibility) yadd = yadd *2; motiony[nframe] += yadd; } if (fabs(motionx[nframe]) < 0.01f) // if it is accidentally very small, reset it to small, but non-zero value , motionx[nframe] = (2*rand()-RAND_MAX) > 0 ? 0.011f : -0.011f; // to differ from pure 0, which be interpreted as bad value mark (scene change) } // char debugbuf[200]; // sprintf(debugbuf,"MVDEPAN: %d %d %d", ndest, nframe, nframemv); // OutputDebugString(debugbuf); if (info && nframe == ndest) // type text info to output frame { int xmsg = 0; int ymsg = 1; sprintf(messagebuf,"MVDepan data"); if (vi.IsYUY2()) DrawStringYUY2(dst,xmsg,ymsg,messagebuf); else DrawString(dst,xmsg,ymsg,messagebuf); sprintf(messagebuf,"fn=%5d iter=%3d error=%7.3f", nframe, iter, errorcur); ymsg++; if (vi.IsYUY2()) DrawStringYUY2(dst,xmsg,ymsg,messagebuf); else DrawString(dst,xmsg,ymsg,messagebuf); sprintf(messagebuf," dx dy rot zoom"); ymsg++; if (vi.IsYUY2()) DrawStringYUY2(dst,xmsg,ymsg,messagebuf); else DrawString(dst,xmsg,ymsg,messagebuf); sprintf(messagebuf,"%7.2f %7.2f %7.3f %7.5f", motionx[nframe], motiony[nframe], motionrot[nframe], motionzoom[nframe]); ymsg++; if (vi.IsYUY2()) DrawStringYUY2(dst,xmsg,ymsg,messagebuf); else DrawString(dst,xmsg,ymsg,messagebuf); } } // write global motion data in Depan plugin format to start of dest frame buffer write_depan_data(dst->GetWritePtr(), framefirst, framelast, motionx, motiony, motionzoom, motionrot); int nf = (backward) ? ndest: ndest; // set next frame number as data frame if backward // nframe = ndest; // set next frame number as data frame if backward if ( logfile != NULL ) // write frame number, dx, dy, rotation and zoom in Deshaker log format - aaded in v.1.2.3 write_deshakerlog1(logfile, vi.IsFieldBased(), vi.IsTFF(), nf, motionx[nf], motiony[nf], motionzoom[nf], motionrot[nf]); return dst; }
PVideoFrame __stdcall TCPClient::GetFrame(int n, IScriptEnvironment* env) { int al_b = sizeof(ClientRequestFrame); ClientRequestFrame f; memset(&f, 0 , sizeof(ClientRequestFrame)); f.n = n; bool ready = false; if (client->IsDataPending()) { client->GetReply(); if (client->reply->last_reply_type == SERVER_SENDING_FRAME) { ServerFrameInfo* fi = (ServerFrameInfo *)client->reply->last_reply; if ((int)fi->framenumber == n) { ready = true; _RPT1(0, "TCPClient: Frame was PreRequested (hit!). Found frame %d.\n", n); } } } if (!ready) { _RPT1(0, "TCPClient: Frame was not PreRequested (miss). Requesting frame %d.\n", n); client->SendRequest(CLIENT_REQUEST_FRAME, &f, sizeof(ClientRequestFrame)); client->GetReply(); } PVideoFrame frame; int incoming_pitch; unsigned int incoming_bytes; if (client->reply->last_reply_type == SERVER_SENDING_FRAME) { ServerFrameInfo* fi = (ServerFrameInfo *)client->reply->last_reply; frame = env->NewVideoFrame(vi); if ((unsigned int)frame->GetRowSize() != fi->row_size) env->ThrowError("TCPClient: Internal Error - rowsize alignment was not correct."); if ((unsigned int)frame->GetHeight() != fi->height) env->ThrowError("TCPClient: Internal Error - height was not correct."); if (fi->framenumber != (unsigned int)n) env->ThrowError("TCPClient: Internal Error - framenumber was not correct."); incoming_pitch = fi->pitch; incoming_bytes = fi->data_size; BYTE* dstp = frame->GetWritePtr(); BYTE* srcp = (unsigned char*)client->reply->last_reply + sizeof(ServerFrameInfo); TCPCompression* t = 0; switch (fi->compression) { case ServerFrameInfo::COMPRESSION_NONE: t = (TCPCompression*)new TCPCompression(); break; case ServerFrameInfo::COMPRESSION_DELTADOWN_LZO: { t = (TCPCompression*)new PredictDownLZO(); break; } case ServerFrameInfo::COMPRESSION_DELTADOWN_HUFFMAN: { t = (TCPCompression*)new PredictDownHuffman(); break; } case ServerFrameInfo::COMPRESSION_DELTADOWN_GZIP: { t = (TCPCompression*)new PredictDownGZip(); break; } default: env->ThrowError("TCPClient: Unknown compression."); } if (!vi.IsPlanar()) { t->DeCompressImage(srcp, fi->row_size, fi->height, fi->pitch, fi->compressed_bytes); env->BitBlt(dstp, frame->GetPitch(), t->dst, incoming_pitch, frame->GetRowSize(), frame->GetHeight()); if (!t->inplace) { _aligned_free(t->dst); } delete t; } else { // Y t->DeCompressImage(srcp, fi->row_size, fi->height, fi->pitch, fi->comp_Y_bytes); env->BitBlt(dstp, frame->GetPitch(), t->dst, incoming_pitch, frame->GetRowSize(), frame->GetHeight()); if (!t->inplace) _aligned_free(t->dst); int uv_pitch = fi->pitchUV; int uv_rowsize = fi->row_sizeUV; int uv_height = fi->heightUV; // U srcp += fi->comp_Y_bytes; t->DeCompressImage(srcp, uv_rowsize, uv_height, uv_pitch, fi->comp_U_bytes); env->BitBlt(frame->GetWritePtr(PLANAR_U), frame->GetPitch(PLANAR_U), t->dst, uv_pitch, frame->GetRowSize(PLANAR_U), frame->GetHeight(PLANAR_U)); if (!t->inplace) _aligned_free(t->dst); // V srcp += fi->comp_U_bytes; t->DeCompressImage(srcp, uv_rowsize, uv_height, uv_pitch, fi->comp_V_bytes); env->BitBlt(frame->GetWritePtr(PLANAR_V), frame->GetPitch(PLANAR_V), t->dst, uv_pitch, frame->GetRowSize(PLANAR_V), frame->GetHeight(PLANAR_V)); if (!t->inplace) _aligned_free(t->dst); delete t; } } else { if (client->reply->last_reply_type == INTERNAL_DISCONNECTED) env->ThrowError("TCPClient: Disconnected from server"); env->ThrowError("TCPClient: Did not recieve expected packet (SERVER_SENDING_FRAME)"); } if (true) { // Request next frame f.n = n + 1; client->SendRequest(CLIENT_REQUEST_FRAME, &f, sizeof(ClientRequestFrame)); _RPT1(0, "TCPClient: PreRequesting frame frame %d.\n", f.n); } return frame; }
PVideoFrame Waifu2xVideoFilter::GetFrame(int n, IScriptEnvironment* env) { int percent = (int)((n / (double)vi.num_frames) * 100); outputDebug([&](std::ostringstream& s) { s << "Waifu2x GetFrame Starting: " << n << "/" << vi.num_frames << "(" << percent << "%)"; }); PVideoFrame src = child->GetFrame(n, env); // Assume YV12, YV16 or YV24 (with chroma, planar) // Process Y at first. cv::Mat yImg(src->GetHeight(PLANAR_Y), src->GetRowSize(PLANAR_Y), CV_8U, (void *)src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y)); yImg.convertTo(yImg, CV_32F, 1.0 / 255.0); if (this->nrLevel > 0) { OutputDebugStringA("Waifu2x NR Start."); if (!filterWithModels(this->modelsNR, yImg, yImg)) { env->ThrowError("Waifu2x NR Failed."); return src; } OutputDebugStringA("Waifu2x NR Finished."); } if (this->enableScaling) { OutputDebugStringA("Waifu2x Scaling Start."); int curRowSize = src->GetRowSize(PLANAR_Y); int curHeight = src->GetHeight(PLANAR_Y); for (int i = 0; i < iterTimesTwiceScaling; i++) { curRowSize *= 2; curHeight *= 2; cv::resize(yImg, yImg, cv::Size(curRowSize, curHeight), 0, 0, cv::INTER_NEAREST); if (!filterWithModels(this->modelsScale, yImg, yImg)) { env->ThrowError("Waifu2x filtering failed."); return src; } } OutputDebugStringA("Waifu2x Scaling Finished."); } yImg.convertTo(yImg, CV_8U, 255.0); // Finally process U, V cv::Mat uImg(src->GetHeight(PLANAR_U), src->GetRowSize(PLANAR_U), CV_8U, (void *)src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U)); cv::Mat vImg(src->GetHeight(PLANAR_V), src->GetRowSize(PLANAR_V), CV_8U, (void *)src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V)); if (this->enableScaling) { // process U and V at first (just INTER_CUBIC resize). cv::resize(uImg, uImg, cv::Size(uImg.cols * this->scaleRatioAdjusted, uImg.rows * this->scaleRatioAdjusted), 0, 0, cv::INTER_CUBIC); cv::resize(vImg, vImg, cv::Size(vImg.cols * this->scaleRatioAdjusted, vImg.rows * this->scaleRatioAdjusted), 0, 0, cv::INTER_CUBIC); } auto dst = env->NewVideoFrame(vi); env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), yImg.data, yImg.step, yImg.cols, yImg.rows); env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), uImg.data, uImg.step, uImg.cols, uImg.rows); env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), vImg.data, vImg.step, vImg.cols, vImg.rows); OutputDebugStringA("Waifu2x GetFrame Finished."); return dst; }
PVideoFrame __stdcall Null::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); BYTE * foo = new BYTE[256]; BYTE * bar = new BYTE[256]; MemDebug md; md.randomFill(foo, 8, 8, 8); BitBlt(bar, 8, foo, 8, 8, 8); md.reset(); int i = md.randomCheck(bar, 9, 8, 8); if (i) env->ThrowError("bug found"); delete [] foo; delete [] bar; if (!lstrcmpi(copy, "makewritable")) { env->MakeWritable(&src); return src; } // TODO: no support for planar formats! if (!lstrcmpi(copy, "memcopy")) { PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16); if (dst->IsWritable() == false) env->ThrowError("new frame not writable"); // honestly don't know whether to expect this condition memcpy( dst->GetWritePtr(), src->GetReadPtr(), src->GetPitch() * src->GetHeight() ); return dst; } if (!lstrcmpi(copy, "bitblt")) { PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16); if (dst->IsWritable() == false) env->ThrowError("new frame not writable"); // honestly don't know whether to expect this condition BitBlt( dst->GetWritePtr(), src->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight() ); return dst; } //if (!lstrcmpi(copy, "none")) // do nothing return src; }
// Requests should optimally be handled by a separate thread to avoid blocking other clients while requesting the frame. void TCPServerListener::SendFrameInfo(ServerReply* s, const char* request) { _RPT0(0, "TCPServer: Sending Frame Info!\n"); ClientRequestFrame* f = (ClientRequestFrame *) request; PVideoFrame src = child->GetFrame(f->n, env); prefetch_frame = f->n + 1; env->MakeWritable(&src); ServerFrameInfo sfi; memset(&sfi, 0, sizeof(ServerFrameInfo)); sfi.framenumber = f->n; sfi.compression = ServerFrameInfo::COMPRESSION_NONE; // Prepare data sfi.height = src->GetHeight(); sfi.row_size = src->GetRowSize(); sfi.pitch = src->GetPitch(); int data_size = sfi.height * sfi.pitch; if (child->GetVideoInfo().IsYV12()) { data_size = data_size + data_size / 2; } BYTE* dstp; sfi.data_size = data_size; // Compress the data. if (!child->GetVideoInfo().IsPlanar()) { sfi.compression = s->client->compression->compression_type; sfi.compressed_bytes = s->client->compression->CompressImage(src->GetWritePtr(), sfi.row_size, sfi.height, sfi.pitch); s->allocateBuffer(sizeof(ServerFrameInfo) + sfi.compressed_bytes); dstp = s->data + sizeof(ServerFrameInfo); env->BitBlt(dstp, 0, s->client->compression->dst, 0, sfi.compressed_bytes, 1); if (!s->client->compression->inplace) { _aligned_free(s->client->compression->dst); } } else { BYTE *dst1, *dst2, *dst3; sfi.row_sizeUV = src->GetRowSize(PLANAR_U_ALIGNED); sfi.pitchUV = src->GetPitch(PLANAR_U); sfi.heightUV = src->GetHeight(PLANAR_U); sfi.comp_Y_bytes = s->client->compression->CompressImage(src->GetWritePtr(PLANAR_Y), sfi.row_size, sfi.height, sfi.pitch); dst1 = s->client->compression->dst; sfi.comp_U_bytes = s->client->compression->CompressImage(src->GetWritePtr(PLANAR_U), sfi.row_sizeUV, src->GetHeight(PLANAR_U), sfi.pitchUV); dst2 = s->client->compression->dst; sfi.comp_V_bytes = s->client->compression->CompressImage(src->GetWritePtr(PLANAR_V), sfi.row_sizeUV, src->GetHeight(PLANAR_U), sfi.pitchUV); dst3 = s->client->compression->dst; sfi.compressed_bytes = sfi.comp_Y_bytes + sfi.comp_U_bytes + sfi.comp_V_bytes; s->allocateBuffer(sizeof(ServerFrameInfo) + sfi.compressed_bytes); dstp = s->data + sizeof(ServerFrameInfo); sfi.compression = s->client->compression->compression_type; env->BitBlt(dstp, 0, dst1, 0, sfi.comp_Y_bytes, 1); env->BitBlt(&dstp[sfi.comp_Y_bytes], 0, dst2, 0, sfi.comp_U_bytes, 1); env->BitBlt(&dstp[sfi.comp_Y_bytes+sfi.comp_U_bytes], 0, dst3, 0, sfi.comp_V_bytes, 1); if (!s->client->compression->inplace) { _aligned_free(dst1); _aligned_free(dst2); _aligned_free(dst3); } } s->setType(SERVER_SENDING_FRAME); // Send Reply memcpy(s->data, &sfi, sizeof(ServerFrameInfo)); }
//------------------------------------------------------------------------- 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 } } }
PVideoFrame WeaveRows::GetFrame(int n, IScriptEnvironment* env) { const int b = n * period; const int e = b + period; PVideoFrame dst = env->NewVideoFrame(vi); BYTE *dstp = dst->GetWritePtr(); const int dstpitch = dst->GetPitch(); if (vi.IsRGB()) { // RGB upsidedown dstp += dstpitch * period; for (int i=b; i<e; i++) { dstp -= dstpitch; const int j = i < inframes ? i : inframes-1; PVideoFrame src = child->GetFrame(j, env); BitBlt( dstp, dstpitch * period, src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight() ); } } else { BYTE *dstpU = dst->GetWritePtr(PLANAR_U); BYTE *dstpV = dst->GetWritePtr(PLANAR_V); const int dstpitchUV = dst->GetPitch(PLANAR_U); for (int i=b; i<e; i++) { const int j = i < inframes ? i : inframes-1; PVideoFrame src = child->GetFrame(j, env); BitBlt( dstp, dstpitch * period, src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight() ); dstp += dstpitch; if (dstpitchUV) { BitBlt( dstpU, dstpitchUV * period, src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U) ); BitBlt( dstpV, dstpitchUV * period, src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V) ); dstpU += dstpitchUV; dstpV += dstpitchUV; } } } return dst; }
// // **************************************************************************** // PVideoFrame __stdcall DePanScenes::GetFrame(int ndest, IScriptEnvironment* env) { // This is the implementation of the GetFrame function. int h,w; const BYTE * srcp; BYTE * dstp; int src_width, src_height, src_pitch; int dst_pitch; // get source depan data frame (with motion data) PVideoFrame src = child->GetFrame(ndest, env); // get pointer to data frame srcp = src->GetReadPtr(); bool isSceneChange = false; // get motion info about frames in interval from prev source to dest if (motionx[ndest] == MOTIONUNKNOWN) { // motion data is unknown for needed frame // note: if inputlogfile has been read, all motion data are always known // get motiondata from DePanData clip framebuffer int error = read_depan_data(srcp, motionx, motiony, motionzoom, motionrot, ndest); // check if correct if (error != 0) env->ThrowError("DePanScenes: input clip is NOT good DePanEstimate clip !"); } if (motionx[ndest] == MOTIONBAD ) isSceneChange = true; // if any strictly =0, than no good int mark = isSceneChange ? 255 : 0; // mark scenechange as max value // Construct a new frame based on the information of the current frame // contained in the "vi" struct. PVideoFrame dst = env->NewVideoFrame(vi); // Request a Write pointer from the newly created destination image. if (vi.IsYV12()) { // luma srcp = src->GetReadPtr(); src_width = src->GetRowSize(); src_height = src->GetHeight(); src_pitch = src->GetPitch(); dstp = dst->GetWritePtr(); dst_pitch = dst->GetPitch(); for (h=0; h<src_height; h++) { if (plane & 1) { // mark for (w=0; w<src_width; w++) { dstp[w] = mark; } } else { // copy for (w=0; w<src_width; w++) { dstp[w] = srcp[w]; } } srcp += src_pitch; dstp += dst_pitch; } // plane U dstp = dst->GetWritePtr(PLANAR_U); dst_pitch = dst->GetPitch(PLANAR_U); srcp = src->GetReadPtr(PLANAR_U); src_width = src->GetRowSize(PLANAR_U); src_height = src->GetHeight(PLANAR_U); src_pitch = src->GetPitch(PLANAR_U); for (h=0; h<src_height; h++) { if (plane & 2) { // mark for (w=0; w<src_width; w++) { dstp[w] = mark; // set all pixels to mark value } } else { // copy for (w=0; w<src_width; w++) { dstp[w] = srcp[w]; } } srcp += src_pitch; dstp += dst_pitch; } // plane V dstp = dst->GetWritePtr(PLANAR_V); dst_pitch = dst->GetPitch(PLANAR_V); srcp = src->GetReadPtr(PLANAR_V); src_width = src->GetRowSize(PLANAR_V); src_height = src->GetHeight(PLANAR_V); src_pitch = src->GetPitch(PLANAR_V); for (h=0; h<src_height; h++) { if (plane & 4) { // mark for (w=0; w<src_width; w++) { dstp[w] = mark; // set all pixels to mark value } } else { // copy for (w=0; w<src_width; w++) { dstp[w] = srcp[w]; } } srcp += src_pitch; dstp += dst_pitch; } } else { // YUY2 srcp = src->GetReadPtr(); src_width = src->GetRowSize(); src_height = src->GetHeight(); src_pitch = src->GetPitch(); dstp = dst->GetWritePtr(); dst_pitch = dst->GetPitch(); // fill dest frame for ( h=0; h<src_height; h++) { if (plane == 1) // Y { // mark for ( w=0; w<src_width; w+=4) { dstp[w] = mark; dstp[w+1] = srcp[w+1]; dstp[w+2] = mark; dstp[w+3] = srcp[w+3]; } } else if (plane == 2) // U { // copy for (w=0; w<src_width; w+=4) { dstp[w] = srcp[w]; dstp[w+1] = mark; dstp[w+2] = srcp[w+2]; dstp[w+3] = srcp[w+3]; } } else if (plane == 3) // Y,U { // copy for (w=0; w<src_width; w+=4) { dstp[w] = mark; dstp[w+1] = mark; dstp[w+2] = mark; dstp[w+3] = srcp[w+3]; } } else if (plane == 4) // V { // copy for (w=0; w<src_width; w+=4) { dstp[w] = srcp[w]; dstp[w+1] = srcp[w+1]; dstp[w+2] = srcp[w+2]; dstp[w+3] = mark; } } else if (plane == 5) // Y,V { // copy for (w=0; w<src_width; w+=4) { dstp[w] = mark; dstp[w+1] = srcp[w+1]; dstp[w+2] = mark; dstp[w+3] = mark; } } else if (plane == 6) // U,V { // copy for (w=0; w<src_width; w+=4) { dstp[w] = srcp[w]; dstp[w+1] = mark; dstp[w+2] = srcp[w+2]; dstp[w+3] = mark; } } else if (plane == 7) // Y,U,V { // copy for (w=0; w<src_width; w+=4) { dstp[w] = mark; dstp[w+1] = mark; dstp[w+2] = mark; dstp[w+3] = mark; } } srcp += src_pitch; dstp += dst_pitch; } } return dst; }
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 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 SeparateColumns::GetFrame(int n, IScriptEnvironment* env) { const int m = n%interval; const int f = n/interval; PVideoFrame src = child->GetFrame(f, env); PVideoFrame dst = env->NewVideoFrame(vi); if (vi.IsPlanar()) { const int srcpitchY = src->GetPitch(PLANAR_Y); const int dstpitchY = dst->GetPitch(PLANAR_Y); const int heightY = dst->GetHeight(PLANAR_Y); const int rowsizeY = dst->GetRowSize(PLANAR_Y); const BYTE* srcpY = src->GetReadPtr(PLANAR_Y); BYTE* dstpY = dst->GetWritePtr(PLANAR_Y); for (int yY=0; yY<heightY; yY+=1) { for (int i=m, j=0; j<rowsizeY; i+=interval, j+=1) { dstpY[j] = srcpY[i]; } srcpY += srcpitchY; dstpY += dstpitchY; } const int srcpitchUV = src->GetPitch(PLANAR_U); const int dstpitchUV = dst->GetPitch(PLANAR_U); const int heightUV = dst->GetHeight(PLANAR_U); const int rowsizeUV = dst->GetRowSize(PLANAR_U); if (dstpitchUV) { const BYTE* srcpV = src->GetReadPtr(PLANAR_V); BYTE* dstpV = dst->GetWritePtr(PLANAR_V); for (int yV=0; yV<heightUV; yV+=1) { for (int i=m, j=0; j<rowsizeUV; i+=interval, j+=1) { dstpV[j] = srcpV[i]; } srcpV += srcpitchUV; dstpV += dstpitchUV; } const BYTE* srcpU = src->GetReadPtr(PLANAR_U); BYTE* dstpU = dst->GetWritePtr(PLANAR_U); for (int yU=0; yU<heightUV; yU+=1) { for (int i=m, j=0; j<rowsizeUV; i+=interval, j+=1) { dstpU[j] = srcpU[i]; } srcpU += srcpitchUV; dstpU += dstpitchUV; } } } else if (vi.IsYUY2()) { const int srcpitch = src->GetPitch(); const int dstpitch = dst->GetPitch(); const int height = dst->GetHeight(); const int rowsize = dst->GetRowSize(); const BYTE* srcp = src->GetReadPtr(); BYTE* dstp = dst->GetWritePtr(); const int m2 = m*2; const int interval2 = interval*2; const int interval4 = interval*4; for (int y=0; y<height; y+=1) { for (int i=m2, j=0; j<rowsize; i+=interval4, j+=4) { // Luma dstp[j+0] = srcp[i+0]; dstp[j+2] = srcp[i+interval2]; // Chroma dstp[j+1] = srcp[i+m2+1]; dstp[j+3] = srcp[i+m2+3]; } srcp += srcpitch; dstp += dstpitch; } } else if (vi.IsRGB24()) { const int srcpitch = src->GetPitch(); const int dstpitch = dst->GetPitch(); const int height = dst->GetHeight(); const int rowsize = dst->GetRowSize(); const BYTE* srcp = src->GetReadPtr(); BYTE* dstp = dst->GetWritePtr(); const int m3 = m*3; const int interval3 = interval*3; for (int y=0; y<height; y+=1) { for (int i=m3, j=0; j<rowsize; i+=interval3, j+=3) { dstp[j+0] = srcp[i+0]; dstp[j+1] = srcp[i+1]; dstp[j+2] = srcp[i+2]; } srcp += srcpitch; dstp += dstpitch; } } else if (vi.IsRGB32()) { const int srcpitch4 = src->GetPitch()>>2; const int dstpitch4 = dst->GetPitch()>>2; const int height = dst->GetHeight(); const int rowsize4 = dst->GetRowSize()>>2; const int* srcp4 = (const int*)src->GetReadPtr(); int* dstp4 = (int*)dst->GetWritePtr(); for (int y=0; y<height; y+=1) { for (int i=m, j=0; j<rowsize4; i+=interval, j+=1) { dstp4[j] = srcp4[i]; } srcp4 += srcpitch4; dstp4 += dstpitch4; } } return dst; }
PVideoFrame WeaveColumns::GetFrame(int n, IScriptEnvironment* env) { const int b = n * period; PVideoFrame dst = env->NewVideoFrame(vi); BYTE *_dstp = dst->GetWritePtr(); const int dstpitch = dst->GetPitch(); BYTE *_dstpU = dst->GetWritePtr(PLANAR_U); BYTE *_dstpV = dst->GetWritePtr(PLANAR_V); const int dstpitchUV = dst->GetPitch(PLANAR_U); for (int m=0; m<period; m++) { const int f = b+m < inframes ? b+m : inframes-1; PVideoFrame src = child->GetFrame(f, env); if (vi.IsPlanar()) { const int srcpitchY = src->GetPitch(PLANAR_Y); const int heightY = src->GetHeight(PLANAR_Y); const int rowsizeY = src->GetRowSize(PLANAR_Y); const BYTE* srcpY = src->GetReadPtr(PLANAR_Y); BYTE* dstpY = _dstp; for (int yY=0; yY<heightY; yY+=1) { for (int i=m, j=0; j<rowsizeY; i+=period, j+=1) { dstpY[i] = srcpY[j]; } srcpY += srcpitchY; dstpY += dstpitch; } if (dstpitchUV) { const int srcpitchUV = src->GetPitch(PLANAR_U); const int heightUV = src->GetHeight(PLANAR_U); const int rowsizeUV = src->GetRowSize(PLANAR_U); const BYTE* srcpU = src->GetReadPtr(PLANAR_U); BYTE* dstpU = _dstpU; for (int yU=0; yU<heightUV; yU+=1) { for (int i=m, j=0; j<rowsizeUV; i+=period, j+=1) { dstpU[i] = srcpU[j]; } srcpU += srcpitchUV; dstpU += dstpitchUV; } const BYTE* srcpV = src->GetReadPtr(PLANAR_V); BYTE* dstpV = _dstpV; for (int yV=0; yV<heightUV; yV+=1) { for (int i=m, j=0; j<rowsizeUV; i+=period, j+=1) { dstpV[i] = srcpV[j]; } srcpV += srcpitchUV; dstpV += dstpitchUV; } } } else if (vi.IsYUY2()) { const int srcpitch = src->GetPitch(); const int height = src->GetHeight(); const int rowsize = src->GetRowSize(); const BYTE* srcp = src->GetReadPtr(); BYTE* dstp = _dstp; const int m2 = m*2; const int period2 = period*2; const int period4 = period*4; for (int y=0; y<height; y+=1) { for (int i=m2, j=0; j<rowsize; i+=period4, j+=4) { // Luma dstp[i+0] = srcp[j+0]; dstp[i+period2] = srcp[j+2]; // Chroma dstp[i+m2+1] = srcp[j+1]; dstp[i+m2+3] = srcp[j+3]; } srcp += srcpitch; dstp += dstpitch; } } else if (vi.IsRGB24()) { const int srcpitch = src->GetPitch(); const int height = src->GetHeight(); const int rowsize = src->GetRowSize(); const BYTE* srcp = src->GetReadPtr(); BYTE* dstp = _dstp; const int m3 = m*3; const int period3 = period*3; for (int y=0; y<height; y+=1) { for (int i=m3, j=0; j<rowsize; i+=period3, j+=3) { dstp[i+0] = srcp[j+0]; dstp[i+1] = srcp[j+1]; dstp[i+2] = srcp[j+2]; } srcp += srcpitch; dstp += dstpitch; } } else if (vi.IsRGB32()) { const int srcpitch4 = src->GetPitch()>>2; const int dstpitch4 = dstpitch>>2; const int height = src->GetHeight(); const int rowsize4 = src->GetRowSize()>>2; const int* srcp4 = (const int*)src->GetReadPtr(); int* dstp4 = (int*)_dstp; for (int y=0; y<height; y+=1) { for (int i=m, j=0; j<rowsize4; i+=period, j+=1) { dstp4[i] = srcp4[j]; } srcp4 += srcpitch4; dstp4 += dstpitch4; } } } return dst; }
PVideoFrame __stdcall MVRecalculate::GetFrame(int n, IScriptEnvironment* env) { const unsigned char *pSrcY, *pSrcU, *pSrcV; const unsigned char *pRefY, *pRefU, *pRefV; // const unsigned char *pSrc2xY, *pSrc2xU, *pSrc2xV; // const unsigned char *pRef2xY, *pRef2xU, *pRef2xV; unsigned char *pDst; int nSrcPitchY, nSrcPitchUV; int nRefPitchY, nRefPitchUV; // int nSrc2xPitchY, nSrc2xPitchUV; // int nRef2xPitchY, nRef2xPitchUV; int minframe = ( analysisData.isBackward ) ? 0 : analysisData.nDeltaFrame; int maxframe = ( analysisData.isBackward ) ? vi.num_frames - analysisData.nDeltaFrame : vi.num_frames; int offset = ( analysisData.isBackward ) ? analysisData.nDeltaFrame : -analysisData.nDeltaFrame; // DebugPrintf("MVRecalculate: Get src frame %d",n); PVideoFrame src = child->GetFrame(n, env); bool paritysrc = child->GetParity(n); // PVideoFrame src2x; // if (analysisData.usePelClip) // src2x = pelclip->GetFrame(n, env); PROFILE_START(MOTION_PROFILE_YUY2CONVERT); if ( (analysisData.pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { // planer data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 pSrcY = src->GetReadPtr(); pSrcU = pSrcY + src->GetRowSize()/2; pSrcV = pSrcU + src->GetRowSize()/4; nSrcPitchY = src->GetPitch(); nSrcPitchUV = nSrcPitchY; } else { pSrcY = src->GetReadPtr(PLANAR_Y); pSrcU = src->GetReadPtr(PLANAR_U); pSrcV = src->GetReadPtr(PLANAR_V); nSrcPitchY = src->GetPitch(PLANAR_Y); nSrcPitchUV = src->GetPitch(PLANAR_U); } PROFILE_STOP(MOTION_PROFILE_YUY2CONVERT); PVideoFrame dst; dst = env->NewVideoFrame(vi); pDst = dst->GetWritePtr(); // write analysis parameters as a header to frame memcpy(pDst, &headerSize, sizeof(int)); if (divideExtra) memcpy(pDst+sizeof(int), &analysisDataDivided, sizeof(analysisData)); else memcpy(pDst+sizeof(int), &analysisData, sizeof(analysisData)); pDst += headerSize; // DebugPrintf("MVRecalculate: Get ref frame %d",n + offset); PVideoFrame mvn = mvClip.GetFrame(n, env); // get pointer to vectors mvClip.Update(mvn, env); // force calulation of vectors if (mvClip.IsUsable() && ( n < maxframe ) && ( n >= minframe )) { PVideoFrame ref = child->GetFrame(n + offset, env); bool parityref = child->GetParity(n + offset); // PVideoFrame ref2x; // if (analysisData.usePelClip) // ref2x = pelclip->GetFrame(n + offset, env); int fieldShift = 0; if (vi.IsFieldBased() && analysisData.nPel > 1 && (analysisData.nDeltaFrame %2 != 0)) { fieldShift = (paritysrc && !parityref) ? analysisData.nPel/2 : ( (parityref && !paritysrc) ? -(analysisData.nPel/2) : 0); // vertical shift of fields for fieldbased video at finest level pel2 } PROFILE_START(MOTION_PROFILE_YUY2CONVERT); if ( (analysisData.pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { // planer data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 pRefY = ref->GetReadPtr(); pRefU = pRefY + ref->GetRowSize()/2; pRefV = pRefU + ref->GetRowSize()/4; nRefPitchY = ref->GetPitch(); nRefPitchUV = nRefPitchY; } else { pRefY = ref->GetReadPtr(PLANAR_Y); pRefU = ref->GetReadPtr(PLANAR_U); pRefV = ref->GetReadPtr(PLANAR_V); nRefPitchY = ref->GetPitch(PLANAR_Y); nRefPitchUV = ref->GetPitch(PLANAR_U); } PROFILE_STOP(MOTION_PROFILE_YUY2CONVERT); /* MVFrames *pFrames = mvCore->GetFrames(analysisData.nIdx); PROFILE_START(MOTION_PROFILE_INTERPOLATION); PMVGroupOfFrames pSrcGOF = pFrames->GetFrame(n); pSrcGOF->SetPlane(pSrcY, nSrcPitchY, YPLANE); pSrcGOF->SetPlane(pSrcU, nSrcPitchUV, UPLANE); pSrcGOF->SetPlane(pSrcV, nSrcPitchUV, VPLANE); // pSrcGOF->Reduce(); // disabled in v1.11.02 - we use top level only here pSrcGOF->Pad(YUVPLANES); if (analysisData.usePelClip) { MVFrame *srcFrames = pSrcGOF->GetFrame(0); MVPlane *srcPlaneY = srcFrames->GetPlane(YPLANE); srcPlaneY->RefineExt(pSrc2xY, nSrc2xPitchY); MVPlane *srcPlaneU = srcFrames->GetPlane(UPLANE); srcPlaneU->RefineExt(pSrc2xU, nSrc2xPitchUV); MVPlane *srcPlaneV = srcFrames->GetPlane(VPLANE); srcPlaneV->RefineExt(pSrc2xV, nSrc2xPitchUV); } else pSrcGOF->Refine(YUVPLANES, analysisData.sharp); PMVGroupOfFrames pRefGOF = pFrames->GetFrame(n + offset); pRefGOF->SetPlane(pRefY, nRefPitchY, YPLANE); pRefGOF->SetPlane(pRefU, nRefPitchUV, UPLANE); pRefGOF->SetPlane(pRefV, nRefPitchUV, VPLANE); // pRefGOF->Reduce(); pRefGOF->Pad(YUVPLANES); if (analysisData.usePelClip) { MVFrame *refFrames = pRefGOF->GetFrame(0); MVPlane *refPlaneY = refFrames->GetPlane(YPLANE); refPlaneY->RefineExt(pRef2xY, nRef2xPitchY); MVPlane *refPlaneU = refFrames->GetPlane(UPLANE); refPlaneU->RefineExt(pRef2xU, nRef2xPitchUV); MVPlane *refPlaneV = refFrames->GetPlane(VPLANE); refPlaneV->RefineExt(pRef2xV, nRef2xPitchUV); } else pRefGOF->Refine(YUVPLANES, analysisData.sharp); PROFILE_STOP(MOTION_PROFILE_INTERPOLATION); */ if (outfile != NULL) { fwrite( &n, sizeof( int ), 1, outfile );// write frame number } pSrcGOF->Update(nModeYUV, (BYTE*)pSrcY, nSrcPitchY, (BYTE*)pSrcU, nSrcPitchUV, (BYTE*)pSrcV, nSrcPitchUV); // v2.0 pRefGOF->Update(nModeYUV, (BYTE*)pRefY, nRefPitchY, (BYTE*)pRefU, nRefPitchUV, (BYTE*)pRefV, nRefPitchUV); // v2.0 vectorFields->RecalculateMVs(mvClip, pSrcGOF, pRefGOF, searchType, nSearchParam, nLambda, lsad, pnew, analysisData.nFlags, reinterpret_cast<int*>(pDst), outfilebuf, fieldShift, thSAD, DCTc, smooth); if (divideExtra) { // make extra level with divided sublocks with median (not estimated) motion vectorFields->ExtraDivide(reinterpret_cast<int*>(pDst), analysisData.nFlags); } // PROFILE_CUMULATE(); if (outfile != NULL) fwrite( outfilebuf, sizeof(short)* analysisData.nBlkX*analysisData.nBlkY*4, 1, outfile ); } else { vectorFields->WriteDefaultToArray(reinterpret_cast<int*>(pDst)); } return dst; }
PVideoFrame VerticalReduceBy2::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); int src_pitch = src->GetPitch(); int dst_pitch = dst->GetPitch(); int row_size = src->GetRowSize(); BYTE* dstp = dst->GetWritePtr(); const BYTE* srcp = src->GetReadPtr(); if (vi.IsPlanar()) { mmx_process(srcp,src_pitch, row_size, dstp,dst_pitch,dst->GetHeight(PLANAR_Y)); if (src->GetRowSize(PLANAR_V)) { src_pitch = src->GetPitch(PLANAR_V); dst_pitch = dst->GetPitch(PLANAR_V); row_size = src->GetRowSize(PLANAR_V_ALIGNED); dstp = dst->GetWritePtr(PLANAR_V); srcp = src->GetReadPtr(PLANAR_V); mmx_process(srcp,src_pitch, row_size, dstp,dst_pitch,dst->GetHeight(PLANAR_V)); src_pitch = src->GetPitch(PLANAR_U); dst_pitch = dst->GetPitch(PLANAR_U); row_size = src->GetRowSize(PLANAR_U_ALIGNED); dstp = dst->GetWritePtr(PLANAR_U); srcp = src->GetReadPtr(PLANAR_U); mmx_process(srcp,src_pitch, row_size, dstp,dst_pitch,dst->GetHeight(PLANAR_U)); } return dst; } //if ((env->GetCPUFlags() & CPUF_MMX)) { if ((row_size&3)==0) { // row width divideable with 4 (one dword per loop) mmx_process(srcp,src_pitch, row_size, dstp,dst_pitch,vi.height); return dst; } //} for (int y=0; y<vi.height; ++y) { const BYTE* line0 = src->GetReadPtr() + (y*2)*src_pitch; const BYTE* line1 = line0 + src_pitch; const BYTE* line2 = (y*2 < original_height-2) ? (line1 + src_pitch) : line0; for (int x=0; x<row_size; ++x) dstp[x] = (line0[x] + 2*line1[x] + line2[x] + 2) >> 2; dstp += dst_pitch; } return dst; }
PVideoFrame __stdcall MVSuper::GetFrame(int n, IScriptEnvironment* env) { const unsigned char *pSrcY, *pSrcU, *pSrcV; unsigned char *pDstY, *pDstU, *pDstV; const unsigned char *pSrcPelY, *pSrcPelU, *pSrcPelV; // unsigned char *pDstYUY2; int nSrcPitchY, nSrcPitchUV; int nDstPitchY, nDstPitchUV; int nSrcPelPitchY, nSrcPelPitchUV; // int nDstPitchYUY2; DebugPrintf("MSuper: Get src frame %d clip %d",n,child); PVideoFrame src = child->GetFrame(n, env); PVideoFrame srcPel; if (usePelClip) srcPel = pelclip->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); PROFILE_START(MOTION_PROFILE_YUY2CONVERT); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { if (!planar) { pSrcY = SrcPlanes->GetPtr(); pSrcU = SrcPlanes->GetPtrU(); pSrcV = SrcPlanes->GetPtrV(); nSrcPitchY = SrcPlanes->GetPitch(); nSrcPitchUV = SrcPlanes->GetPitchUV(); YUY2ToPlanes(src->GetReadPtr(), src->GetPitch(), nWidth, nHeight, pSrcY, nSrcPitchY, pSrcU, pSrcV, nSrcPitchUV, isse); if (usePelClip) { pSrcPelY = SrcPelPlanes->GetPtr(); pSrcPelU = SrcPelPlanes->GetPtrU(); pSrcPelV = SrcPelPlanes->GetPtrV(); nSrcPelPitchY = SrcPelPlanes->GetPitch(); nSrcPelPitchUV = SrcPelPlanes->GetPitchUV(); YUY2ToPlanes(srcPel->GetReadPtr(), srcPel->GetPitch(), srcPel->GetRowSize()/2, srcPel->GetHeight(), pSrcPelY, nSrcPelPitchY, pSrcPelU, pSrcPelV, nSrcPelPitchUV, isse); } } else { pSrcY = src->GetReadPtr(); pSrcU = pSrcY + src->GetRowSize()/2; pSrcV = pSrcU + src->GetRowSize()/4; nSrcPitchY = src->GetPitch(); nSrcPitchUV = nSrcPitchY; if (usePelClip) { pSrcPelY = srcPel->GetReadPtr(); pSrcPelU = pSrcPelY + srcPel->GetRowSize()/2; pSrcPelV = pSrcPelU + srcPel->GetRowSize()/4; nSrcPelPitchY = srcPel->GetPitch(); nSrcPelPitchUV = nSrcPelPitchY; } } // pDstY = DstPlanes->GetPtr(); // pDstU = DstPlanes->GetPtrU(); // pDstV = DstPlanes->GetPtrV(); // nDstPitchY = DstPlanes->GetPitch(); // nDstPitchUV = DstPlanes->GetPitchUV(); // planer data packed to interleaved format (same as interleved2planar by kassandro) - v2.0.0.5 pDstY = dst->GetWritePtr(); pDstU = pDstY + nSuperWidth; pDstV = pDstU + nSuperWidth/2; nDstPitchY = dst->GetPitch(); nDstPitchUV = nDstPitchY; } else { pSrcY = src->GetReadPtr(PLANAR_Y); pSrcU = src->GetReadPtr(PLANAR_U); pSrcV = src->GetReadPtr(PLANAR_V); nSrcPitchY = src->GetPitch(PLANAR_Y); nSrcPitchUV = src->GetPitch(PLANAR_U); if (usePelClip) { pSrcPelY = srcPel->GetReadPtr(PLANAR_Y); pSrcPelU = srcPel->GetReadPtr(PLANAR_U); pSrcPelV = srcPel->GetReadPtr(PLANAR_V); nSrcPelPitchY = srcPel->GetPitch(PLANAR_Y); nSrcPelPitchUV = srcPel->GetPitch(PLANAR_U); } pDstY = dst->GetWritePtr(PLANAR_Y); pDstU = dst->GetWritePtr(PLANAR_U); pDstV = dst->GetWritePtr(PLANAR_V); nDstPitchY = dst->GetPitch(PLANAR_Y); nDstPitchUV = dst->GetPitch(PLANAR_U); } PROFILE_STOP(MOTION_PROFILE_YUY2CONVERT); PROFILE_START(MOTION_PROFILE_INTERPOLATION); pSrcGOF->Update(YUVPLANES, pDstY, nDstPitchY, pDstU, nDstPitchUV, pDstV, nDstPitchUV); pSrcGOF->SetPlane(pSrcY, nSrcPitchY, YPLANE); pSrcGOF->SetPlane(pSrcU, nSrcPitchUV, UPLANE); pSrcGOF->SetPlane(pSrcV, nSrcPitchUV, VPLANE); pSrcGOF->Reduce(nModeYUV); pSrcGOF->Pad(nModeYUV); if (usePelClip) { MVFrame *srcFrames = pSrcGOF->GetFrame(0); MVPlane *srcPlaneY = srcFrames->GetPlane(YPLANE); if (nModeYUV & YPLANE) srcPlaneY->RefineExt(pSrcPelY, nSrcPelPitchY, isPelClipPadded); MVPlane *srcPlaneU = srcFrames->GetPlane(UPLANE); if (nModeYUV & UPLANE) srcPlaneU->RefineExt(pSrcPelU, nSrcPelPitchUV, isPelClipPadded); MVPlane *srcPlaneV = srcFrames->GetPlane(VPLANE); if (nModeYUV & VPLANE) srcPlaneV->RefineExt(pSrcPelV, nSrcPelPitchUV, isPelClipPadded); } else { pSrcGOF->Refine(nModeYUV); } PROFILE_STOP(MOTION_PROFILE_INTERPOLATION); /* PROFILE_START(MOTION_PROFILE_YUY2CONVERT); if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 ) { pDstYUY2 = dst->GetWritePtr(); nDstPitchYUY2 = dst->GetPitch(); YUY2FromPlanes(pDstYUY2, nDstPitchYUY2, nSuperWidth, nSuperHeight, pDstY, nDstPitchY, pDstU, pDstV, nDstPitchUV, isse); } PROFILE_STOP(MOTION_PROFILE_YUY2CONVERT); */ PROFILE_CUMULATE(); return dst; }