void deathray::MultiFrameCopy(const int &n) { result status = FILTER_OK; int frame_number; if (temporal_radius_Y_ > 0 && h_Y_ > 0.f) { MultiFrameRequest frames_Y; g_MultiFrame_Y.SupplyFrameNumbers(n, &frames_Y); while (frames_Y.GetFrameNumber(&frame_number)) { PVideoFrame Y = child->GetFrame(frame_number, env_); const unsigned char* ptr_Y = Y->GetReadPtr(PLANAR_Y); frames_Y.Supply(frame_number, ptr_Y); } status = g_MultiFrame_Y.CopyTo(&frames_Y); if (status != FILTER_OK ) env_->ThrowError("Deathray: Copy Y to device, status=%d and OpenCL status=%d", status, g_last_cl_error); } if (temporal_radius_UV_ > 0 && h_UV_ > 0.f) { MultiFrameRequest frames_U; MultiFrameRequest frames_V; g_MultiFrame_U.SupplyFrameNumbers(n, &frames_U); g_MultiFrame_V.SupplyFrameNumbers(n, &frames_V); while (frames_U.GetFrameNumber(&frame_number)) { PVideoFrame UV = child->GetFrame(frame_number, env_); const unsigned char* ptr_U = UV->GetReadPtr(PLANAR_U); const unsigned char* ptr_V = UV->GetReadPtr(PLANAR_V); frames_U.Supply(frame_number, ptr_U); frames_V.Supply(frame_number, ptr_V); } status = g_MultiFrame_U.CopyTo(&frames_U); if (status != FILTER_OK ) env_->ThrowError("Deathray: Copy U to device, status=%d and OpenCL status=%d", status, g_last_cl_error); status = g_MultiFrame_V.CopyTo(&frames_V); if (status != FILTER_OK ) env_->ThrowError("Deathray: Copy V to device, status=%d and OpenCL status=%d", status, g_last_cl_error); } }
PVideoFrame __stdcall TurnsTile::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env), sht = 0, dst = env->NewVideoFrame(vi); const unsigned char * srcY = src->GetReadPtr(PLANAR_Y), * srcU = src->GetReadPtr(PLANAR_U), * srcV = src->GetReadPtr(PLANAR_V), * shtY = 0, * shtU = 0, * shtV = 0; unsigned char * dstY = dst->GetWritePtr(PLANAR_Y), * dstU = dst->GetWritePtr(PLANAR_U), * dstV = dst->GetWritePtr(PLANAR_V); int SRC_PITCH_SAMPLES_Y = src->GetPitch(PLANAR_Y), SRC_PITCH_SAMPLES_U = src->GetPitch(PLANAR_U), SHT_PITCH_SAMPLES_Y = 0, SHT_PITCH_SAMPLES_U = 0, DST_PITCH_SAMPLES_Y = dst->GetPitch(PLANAR_Y), DST_PITCH_SAMPLES_U = dst->GetPitch(PLANAR_U); if (tilesheet) { sht = tilesheet->GetFrame(n, env); shtY = sht->GetReadPtr(PLANAR_Y); shtU = sht->GetReadPtr(PLANAR_U); shtV = sht->GetReadPtr(PLANAR_V); SHT_PITCH_SAMPLES_Y = sht->GetPitch(PLANAR_Y); SHT_PITCH_SAMPLES_U = sht->GetPitch(PLANAR_U); } if (PLANAR) processFramePlanar( srcY, srcU, srcV, shtY, shtU, shtV, dstY, dstU, dstV, SRC_PITCH_SAMPLES_Y, SRC_PITCH_SAMPLES_U, SHT_PITCH_SAMPLES_Y, SHT_PITCH_SAMPLES_U, DST_PITCH_SAMPLES_Y, DST_PITCH_SAMPLES_U, env); else processFramePacked( srcY, shtY, dstY, SRC_PITCH_SAMPLES_Y, SHT_PITCH_SAMPLES_Y, DST_PITCH_SAMPLES_Y, env); 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; }
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 ShapeMask::GetFrame(int n, IScriptEnvironment* env) { int colorspace; if (vi.IsRGB24()) colorspace = RGB24; else if (vi.IsRGB32()) colorspace = RGB32; else if (vi.IsYUY2()) colorspace = YUV2; else if (vi.IsYV12()) colorspace = YV12; else raiseError(env, "Unsupported color space, must be one of RGB24, RGB32, YUV2 or YV12"); PClip srcClip = toGrayScale(env, child); PVideoFrame src = srcClip->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); const uchar* srcp = src->GetReadPtr(); const int src_pitch = src->GetPitch(); const int bpp = vi.BitsPerPixel(); uchar* retp; // No change to the source pixels in the process steps, so ok to cast to non-const // returns a 1 channel gray scale image which needs to be converted to whatever format the source clip is in. retp = process_frame((uchar*)srcp, vi.width, vi.height, src_pitch, colorspace, threshold, minarea, rectonly); if (vi.IsPlanar()) copyPlanar(retp, dst, bpp); else if (vi.IsYUY2()) copyYUY2(retp, dst); else copyRGB(retp, dst, bpp); delete retp; return dst; }
PVideoFrame SkewRows::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); const int srowsize = src->GetRowSize(); const int spitch = src->GetPitch(); const BYTE *sptr = src->GetReadPtr(); const int drowsize = dst->GetRowSize(); const int dpitch = dst->GetPitch(); BYTE *dptr = dst->GetWritePtr(); const int ssize = src->GetHeight()*srowsize; int s=0, d=0; for (int i=0; i < ssize; i++) { if (s >= srowsize) { s = 0; sptr += spitch; } if (d >= drowsize) { d = 0; dptr += dpitch; } dptr[d++] = sptr[s++]; } while (d < drowsize) dptr[d++] = 128; return dst; }
PVideoFrame PeculiarBlend::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame a = child->GetFrame(n, env); PVideoFrame b = child->GetFrame(n+1, env); env->MakeWritable(&a); BYTE* main = a->GetWritePtr(); const BYTE* other = b->GetReadPtr(); const int main_pitch = a->GetPitch(); const int other_pitch = b->GetPitch(); const int row_size = a->GetRowSize(); if (cutoff-31 > 0) { int copy_top = min(cutoff-31, vi.height); BitBlt(main, main_pitch, other, other_pitch, row_size, copy_top); main += main_pitch * copy_top; other += other_pitch * copy_top; } for (int y = max(0, cutoff-31); y < min(cutoff, vi.height-1); ++y) { int scale = cutoff - y; for (int x = 0; x < row_size; ++x) main[x] += ((other[x] - main[x]) * scale + 16) >> 5; main += main_pitch; other += other_pitch; } return a; }
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 TMaskCleaner::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n,env); PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo()); memset(dst->GetWritePtr(PLANAR_Y), 0, dst->GetPitch(PLANAR_Y) * dst->GetHeight(PLANAR_Y)); memset(lookup, 0, child->GetVideoInfo().height * child->GetVideoInfo().width / 8); ClearMask(dst->GetWritePtr(PLANAR_Y), src->GetReadPtr(PLANAR_Y), dst->GetRowSize(PLANAR_Y), dst->GetHeight(PLANAR_Y),src->GetPitch(PLANAR_Y), dst->GetPitch(PLANAR_Y)); return dst; }
PVideoFrame __stdcall AlignPlanar::GetFrame(int n, IScriptEnvironment* env) { int plane = (env->PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentTest)) ? PLANAR_U_ALIGNED : PLANAR_Y_ALIGNED; PVideoFrame src = child->GetFrame(n, env); if (!(src->GetRowSize(plane)&(FRAME_ALIGN-1))) return src; PVideoFrame dst = env->NewVideoFrame(vi); if ((dst->GetRowSize(PLANAR_Y_ALIGNED)&(FRAME_ALIGN-1))) env->ThrowError("AlignPlanar: [internal error] Returned frame was not aligned!"); env->BitBlt(dst->GetWritePtr(), dst->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight()); env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V)); env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U)); return dst; }
extern "C" HRESULT __stdcall read_data(VF_FileHandle in, DWORD stream, void *out) { if (stream == VF_STREAM_VIDEO) { LPVF_ReadData_Video data = (LPVF_ReadData_Video)out; unsigned char *dst = (unsigned char *)data->lpData; if (data == NULL) return VF_ERROR; if (data->dwSize != sizeof(VF_ReadData_Video)) return VF_ERROR; vfMI *i = (vfMI*)in; if (i->type == D2V_TYPE) { unsigned char *src = i->getRGBFrameMI(data->dwFrameNumberL, i->ident); int y, height = i->vi->height; for (y = 0; y < height; y++) memcpy(dst+y*data->lPitch, src+y*i->vi->width*3, i->vi->width*3); } else { PVideoFrame src = (*i->clip)->GetFrame(data->dwFrameNumberL, i->avsEnv); i->avsEnv->BitBlt(dst, data->lPitch, src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight()); } } else if (stream == VF_STREAM_AUDIO) { LPVF_ReadData_Audio data = (LPVF_ReadData_Audio)out; if (data == NULL) return VF_ERROR; if (data->dwSize != sizeof(VF_ReadData_Audio)) return VF_ERROR; vfMI *i = (vfMI*)in; if (i->type == D2V_TYPE) return VF_ERROR; else { if (!(*i->clip)->GetVideoInfo().HasAudio()) return VF_ERROR; (*i->clip)->GetAudio(data->lpBuf, data->dwSamplePosL, data->dwSampleCount, i->avsEnv); data->dwReadedSampleCount = (unsigned long) min(data->dwSampleCount, max((*i->clip)->GetVideoInfo().num_audio_samples-data->dwSamplePosL,0)); } } else return VF_ERROR; return VF_OK; }
PVideoFrame __stdcall Turn::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); if (vi.IsPlanar()) TurnPlanFunc(src->GetReadPtr(PLANAR_Y), dst->GetWritePtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), dst->GetWritePtr(PLANAR_U), src->GetReadPtr(PLANAR_V), dst->GetWritePtr(PLANAR_V), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U), src->GetPitch(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetPitch(PLANAR_V), direction); else TurnFunc(src->GetReadPtr(),dst->GetWritePtr(),src->GetRowSize(), src->GetHeight(),src->GetPitch(),dst->GetPitch(),direction); return dst; }
PVideoFrame __stdcall AutoTraceFilter::GetFrame(int n, IScriptEnvironment* env) { // Grab the child frame PVideoFrame childFrame = child->GetFrame(n, env); // Create the bitmap - AutoTrace always wants a 24-bpp bitmap for some dumb reason at_bitmap_type *bitmap; bitmap = at_bitmap_new(srcWidth, srcHeight, 3); size_t bitmap_size = srcWidth * srcHeight * 3; // Pull the bitmap data // We can just blt lines const BYTE* srcBitmap = childFrame->GetReadPtr(); int pitch = childFrame->GetPitch(); int rowSize = childFrame->GetRowSize(); for (int y = 0; y < srcHeight; y++) { // Note that R and B are swapped in this. It doesn't really matter. memcpy_s(bitmap->bitmap + ((srcHeight - y - 1) * rowSize), bitmap_size, srcBitmap + (y * pitch), rowSize); } // This does the actual tracing: at_splines_type* splines = at_splines_new(bitmap, fitting_opts, exception_handler, NULL); // Now create the new frame. First, blank out the old frame graphics->Clear(*backgroundColor); at_real tx = ((at_real)destWidth) / ((at_real)srcWidth); at_real ty = ((at_real)destHeight) / ((at_real)srcHeight); for (unsigned int i = 0; i < splines->length; i++) { at_spline_list_type spline_list = splines->data[i]; Gdiplus::GraphicsPath path; for (unsigned int j = 0; j < spline_list.length; j++) { at_spline_type* spline = &(spline_list.data[j]); if (spline->degree == AT_LINEARTYPE) { path.AddLine((Gdiplus::REAL)(spline->v[0].x * tx), (Gdiplus::REAL)(spline->v[0].y * ty), (Gdiplus::REAL)(spline->v[3].x * tx), (Gdiplus::REAL)(spline->v[3].y * ty)); } else { path.AddBezier( (Gdiplus::REAL)(spline->v[0].x * tx), (Gdiplus::REAL)(spline->v[0].y * ty), (Gdiplus::REAL)(spline->v[1].x * tx), (Gdiplus::REAL)(spline->v[1].y * ty), (Gdiplus::REAL)(spline->v[2].x * tx), (Gdiplus::REAL)(spline->v[2].y * ty), (Gdiplus::REAL)(spline->v[3].x * tx), (Gdiplus::REAL)(spline->v[3].y * ty)); } } path.CloseFigure(); // Red and blue are swapped here, so swap them back. Gdiplus::Color color(spline_list.color.b, spline_list.color.g, spline_list.color.r); Gdiplus::SolidBrush brush(color); graphics->FillPath(&brush, &path); } at_splines_free(splines); at_bitmap_free(bitmap); // Now we need to create our result frame PVideoFrame outputFrame = env->NewVideoFrame(vi); BYTE* outputData = outputFrame->GetWritePtr(); env->BitBlt(outputData, outputFrame->GetPitch(), renderedFrameData, renderedFramePitch, destWidth*4, destHeight); return outputFrame; }
PVideoFrame __stdcall TEMmod::GetFrame(int n, IScriptEnvironment* env) { const int planes[3] = {PLANAR_Y, PLANAR_U, PLANAR_V}; PVideoFrame src = child->GetFrame(n, env); PVideoFrame dst = env->NewVideoFrame(vi); for (int i = 0; i < 3; i++) { if (process[i] == 0) { break; } int p = planes[i]; int dst_pitch = dst->GetPitch(p); uint8_t* dstp = dst->GetWritePtr(p); int height = src->GetHeight(p); if (process[i] == 2) { memset(dstp, 0, dst_pitch * height); continue; } int src_pitch = src->GetPitch(p); int width = src->GetRowSize(p); const uint8_t* srcp = src->GetReadPtr(p); if (((intptr_t)srcp & 15) && type > 2) { env->ThrowError("TEMmod: invalid memory alignment found!"); } calc_map(srcp, dstp, buff, src_pitch, dst_pitch, buff_pitch, width, height, threshold[i], scale); } if (link > 0) { link_planes(dst); } if (!invert) { return dst; } for (int i = 0; i < 3; i++) { if (process[i] == 0) { break; } invert_plane(dst->GetWritePtr(planes[i]), dst->GetPitch(planes[i]), dst->GetHeight(planes[i])); } return dst; }
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 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 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 }
const AegiVideoFrame AvisynthVideoProvider::GetFrame(int n) { if (n == last_fnum) return iframe; wxMutexLocker lock(avs.GetMutex()); PVideoFrame frame = RGB32Video->GetFrame(n, avs.GetEnv()); iframe.pitch = frame->GetPitch(); iframe.w = frame->GetRowSize() / (vi.BitsPerPixel() / 8); iframe.h = frame->GetHeight(); iframe.Allocate(); memcpy(iframe.data, frame->GetReadPtr(), iframe.pitch * iframe.h); last_fnum = n; return iframe; }
int __stdcall dimzon_avs_getvframe(SafeStruct* pstr, void *buf, int stride, int frm) { try { PVideoFrame f = pstr->clp->GetFrame(frm, pstr->env); if(buf && stride) { pstr->env->BitBlt((BYTE*)buf, stride, f->GetReadPtr(), f->GetPitch(), f->GetRowSize(), f->GetHeight()); } pstr->err[0] = 0; return 0; } catch(AvisynthError err) { strncpy_s(pstr->err, ERRMSG_LEN, err.msg, _TRUNCATE); return AVS_GERROR; } }
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; }
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; }
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; }
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
PVideoFrame __stdcall ConvertToY8::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); if (blit_luma_only) { // Abuse Subframe to snatch the Y plane return env->Subframe(src, 0, src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y)); } PVideoFrame dst = env->NewVideoFrame(vi); if (yuy2_input) { const BYTE* srcP = src->GetReadPtr(); const int srcPitch = src->GetPitch(); const int awidth = min(srcPitch>>1, (vi.width+7) & -8); BYTE* dstY = dst->GetWritePtr(PLANAR_Y); const int dstPitch = dst->GetPitch(PLANAR_Y); if (!(awidth & 7)) { this->convYUV422toY8(srcP, dstY, srcPitch, dstPitch, awidth, vi.height); return dst; } const int w = dst->GetRowSize(PLANAR_Y); const int h = dst->GetHeight(PLANAR_Y); for (int y=0; y<h; y++) { for (int x=0; x<w; x++) { dstY[x] = srcP[x*2]; } srcP+=srcPitch; dstY+=dstPitch; } } else if (rgb_input) {
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 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 __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 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 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 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; }