static void VS_CC mvsuperCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) { MVSuperData d; MVSuperData *data; int err; d.nHPad = int64ToIntS(vsapi->propGetInt(in, "hpad", 0, &err)); if (err) d.nHPad = 8; d.nVPad = int64ToIntS(vsapi->propGetInt(in, "vpad", 0, &err)); if (err) d.nVPad = 8; d.nPel = int64ToIntS(vsapi->propGetInt(in, "pel", 0, &err)); if (err) d.nPel = 2; d.nLevels = int64ToIntS(vsapi->propGetInt(in, "levels", 0, &err)); d.chroma = !!vsapi->propGetInt(in, "chroma", 0, &err); if (err) d.chroma = 1; d.sharp = int64ToIntS(vsapi->propGetInt(in, "sharp", 0, &err)); if (err) d.sharp = 2; d.rfilter = int64ToIntS(vsapi->propGetInt(in, "rfilter", 0, &err)); if (err) d.rfilter = 2; if ((d.nPel != 1) && (d.nPel != 2) && (d.nPel != 4)) { vsapi->setError(out, "Super: pel must be 1, 2, or 4."); return; } if (d.sharp < 0 || d.sharp > 2) { vsapi->setError(out, "Super: sharp must be between 0 and 2 (inclusive)."); return; } if (d.rfilter < 0 || d.rfilter > 4) { vsapi->setError(out, "Super: rfilter must be between 0 and 4 (inclusive)."); return; } d.node = vsapi->propGetNode(in, "clip", 0, 0); d.vi = *vsapi->getVideoInfo(d.node); d.nWidth = d.vi.width; d.nHeight = d.vi.height; if (!isConstantFormat(&d.vi) || d.vi.format->bitsPerSample < 32 || d.vi.format->sampleType != stFloat) { vsapi->setError(out, "Super: input clip must be single precision fp, with constant dimensions."); vsapi->freeNode(d.node); return; } if (d.vi.format->colorFamily == cmGray) d.chroma = 0; if (d.vi.format->colorFamily == cmRGB) d.chroma = 1; d.nModeYUV = d.chroma ? YUVPLANES : YPLANE; d.xRatioUV = 1 << d.vi.format->subSamplingW; d.yRatioUV = 1 << d.vi.format->subSamplingH; int32_t nLevelsMax = 0; while (PlaneHeightLuma(d.vi.height, nLevelsMax, d.yRatioUV, d.nVPad) >= d.yRatioUV * 2 && PlaneWidthLuma(d.vi.width, nLevelsMax, d.xRatioUV, d.nHPad) >= d.xRatioUV * 2) { ++nLevelsMax; } if (d.nLevels <= 0 || d.nLevels > nLevelsMax) d.nLevels = nLevelsMax; d.pelclip = vsapi->propGetNode(in, "pelclip", 0, &err); const VSVideoInfo *pelvi = d.pelclip ? vsapi->getVideoInfo(d.pelclip) : nullptr; if (d.pelclip && (!isConstantFormat(pelvi) || pelvi->format != d.vi.format)) { vsapi->setError(out, "Super: pelclip must have the same format as the input clip, and it must have constant dimensions."); vsapi->freeNode(d.node); vsapi->freeNode(d.pelclip); return; } d.usePelClip = false; if (d.pelclip && (d.nPel >= 2)) { if ((pelvi->width == d.vi.width * d.nPel) && (pelvi->height == d.vi.height * d.nPel)) { d.usePelClip = true; d.isPelClipPadded = false; } else if ((pelvi->width == (d.vi.width + d.nHPad * 2) * d.nPel) && (pelvi->height == (d.vi.height + d.nVPad * 2) * d.nPel)) { d.usePelClip = true; d.isPelClipPadded = true; } else { vsapi->setError(out, "Super: pelclip's dimensions must be multiples of the input clip's dimensions."); vsapi->freeNode(d.pelclip); vsapi->freeNode(d.node); return; } } d.nSuperWidth = d.nWidth + 2 * d.nHPad; d.nSuperHeight = PlaneSuperOffset(false, d.nHeight, d.nLevels, d.nPel, d.nVPad, d.nSuperWidth, d.yRatioUV) / d.nSuperWidth; if (d.yRatioUV == 2 && d.nSuperHeight & 1) ++d.nSuperHeight; if (d.xRatioUV == 2 && d.nSuperWidth & 1) ++d.nSuperWidth; d.vi.width = d.nSuperWidth; d.vi.height = d.nSuperHeight; data = new MVSuperData; *data = d; vsapi->createFilter(in, out, "Super", mvsuperInit, mvsuperGetFrame, mvsuperFree, fmParallel, 0, data, core); }
MVSuper::MVSuper ( PClip _child, int _hPad, int _vPad, int _pel, int _levels, bool _chroma, int _sharp, int _rfilter, PClip _pelclip, bool _isse, bool _planar, bool mt_flag, IScriptEnvironment* env ) : GenericVideoFilter (_child) , pelclip (_pelclip) , _mt_flag (mt_flag) { planar = _planar; nWidth = vi.width; nHeight = vi.height; if (!vi.IsYV12() && !vi.IsYUY2()) { env->ThrowError("MSuper: Clip must be YV12 or YUY2"); } nPel = _pel; if (( nPel != 1 ) && ( nPel != 2 ) && ( nPel != 4 )) { env->ThrowError("MSuper: pel has to be 1 or 2 or 4"); } nHPad = _hPad; nVPad = _vPad; rfilter = _rfilter; sharp = _sharp; // pel2 interpolation type isse = _isse; chroma = _chroma; nModeYUV = chroma ? YUVPLANES : YPLANE; pixelType = vi.pixel_type; yRatioUV = (vi.IsYV12()) ? 2 : 1; xRatioUV = 2; // for YV12 and YUY2, really do not used and assumed to 2 nLevels = _levels; int nLevelsMax = 0; while (PlaneHeightLuma(vi.height, nLevelsMax, yRatioUV, nVPad) >= yRatioUV*2 && PlaneWidthLuma(vi.width, nLevelsMax, xRatioUV, nHPad) >= xRatioUV*2) // at last two pixels width and height of chroma { nLevelsMax++; } if (nLevels<=0 || nLevels> nLevelsMax) nLevels = nLevelsMax; usePelClip = false; if (pelclip && (nPel >= 2)) { if (pelclip->GetVideoInfo().width == vi.width*nPel && pelclip->GetVideoInfo().height == vi.height*nPel) { usePelClip = true; isPelClipPadded = false; } else if (pelclip->GetVideoInfo().width == (vi.width + nHPad*2)*nPel && pelclip->GetVideoInfo().height == (vi.height+ nVPad*2)*nPel) { usePelClip = true; isPelClipPadded = true; } else { env->ThrowError("MSuper: pelclip frame size must be Pel of source!"); } } nSuperWidth = nWidth + 2*nHPad; nSuperHeight = PlaneSuperOffset(false, nHeight, nLevels, nPel, nVPad, nSuperWidth, yRatioUV)/nSuperWidth; if (yRatioUV==2 && nSuperHeight&1) nSuperHeight++; // even vi.width = nSuperWidth; vi.height = nSuperHeight; if ( (pixelType & VideoInfo::CS_YUY2) == VideoInfo::CS_YUY2 && !planar) { SrcPlanes = new YUY2Planes(nWidth, nHeight); // DstPlanes = new YUY2Planes(nSuperWidth, nSuperHeight); // other size! if (usePelClip) { SrcPelPlanes = new YUY2Planes(pelclip->GetVideoInfo().width, pelclip->GetVideoInfo().height); } } SuperParams64Bits params; params.nHeight = nHeight; params.nHPad = nHPad; params.nVPad = nVPad; params.nPel = nPel; params.nModeYUV = nModeYUV; params.nLevels = nLevels; // pack parameters to fake audio properties memcpy(&vi.num_audio_samples, ¶ms, 8); //nHeight + (nHPad<<16) + (nVPad<<24) + ((_int64)(nPel)<<32) + ((_int64)nModeYUV<<40) + ((_int64)nLevels<<48); vi.audio_samples_per_second = 0; // kill audio // LDS: why not nModeYUV? // pSrcGOF = new MVGroupOfFrames(nLevels, nWidth, nHeight, nPel, nHPad, nVPad, nModeYUV, isse, yRatioUV, mt_flag); pSrcGOF = new MVGroupOfFrames(nLevels, nWidth, nHeight, nPel, nHPad, nVPad, YUVPLANES, isse, yRatioUV, mt_flag); pSrcGOF->set_interp (nModeYUV, rfilter, sharp); PROFILE_INIT(); }
static void VS_CC mvsuperCreate(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi) { (void)userData; MVSuperData d; MVSuperData *data; int err; d.nHPad = int64ToIntS(vsapi->propGetInt(in, "hpad", 0, &err)); if (err) d.nHPad = 8; d.nVPad = int64ToIntS(vsapi->propGetInt(in, "vpad", 0, &err)); if (err) d.nVPad = 8; d.nPel = int64ToIntS(vsapi->propGetInt(in, "pel", 0, &err)); if (err) d.nPel = 2; d.nLevels = int64ToIntS(vsapi->propGetInt(in, "levels", 0, &err)); d.chroma = !!vsapi->propGetInt(in, "chroma", 0, &err); if (err) d.chroma = 1; d.sharp = int64ToIntS(vsapi->propGetInt(in, "sharp", 0, &err)); // pel2 interpolation type if (err) d.sharp = SharpWiener; d.rfilter = int64ToIntS(vsapi->propGetInt(in, "rfilter", 0, &err)); if (err) d.rfilter = RfilterBilinear; d.opt = !!vsapi->propGetInt(in, "opt", 0, &err); if (err) d.opt = 1; if ((d.nPel != 1) && (d.nPel != 2) && (d.nPel != 4)) { vsapi->setError(out, "Super: pel must be 1, 2, or 4."); return; } if (d.sharp < SharpBilinear || d.sharp > SharpWiener) { vsapi->setError(out, "Super: sharp must be between 0 and 2 (inclusive)."); return; } if (d.rfilter < RfilterSimple || d.rfilter > RfilterCubic) { vsapi->setError(out, "Super: rfilter must be between 0 and 4 (inclusive)."); return; } d.node = vsapi->propGetNode(in, "clip", 0, 0); d.vi = *vsapi->getVideoInfo(d.node); d.nWidth = d.vi.width; d.nHeight = d.vi.height; if (!isConstantFormat(&d.vi) || d.vi.format->bitsPerSample > 16 || d.vi.format->sampleType != stInteger || d.vi.format->subSamplingW > 1 || d.vi.format->subSamplingH > 1 || (d.vi.format->colorFamily != cmYUV && d.vi.format->colorFamily != cmGray)) { vsapi->setError(out, "Super: input clip must be GRAY, 420, 422, 440, or 444, up to 16 bits, with constant dimensions."); vsapi->freeNode(d.node); return; } if (d.vi.format->colorFamily == cmGray) d.chroma = 0; d.nModeYUV = d.chroma ? YUVPLANES : YPLANE; d.xRatioUV = 1 << d.vi.format->subSamplingW; d.yRatioUV = 1 << d.vi.format->subSamplingH; int nLevelsMax = 0; while (PlaneHeightLuma(d.vi.height, nLevelsMax, d.yRatioUV, d.nVPad) >= d.yRatioUV * 2 && PlaneWidthLuma(d.vi.width, nLevelsMax, d.xRatioUV, d.nHPad) >= d.xRatioUV * 2) // at last two pixels width and height of chroma { nLevelsMax++; } if (d.nLevels <= 0 || d.nLevels > nLevelsMax) d.nLevels = nLevelsMax; d.pelclip = vsapi->propGetNode(in, "pelclip", 0, &err); const VSVideoInfo *pelvi = d.pelclip ? vsapi->getVideoInfo(d.pelclip) : NULL; if (d.pelclip && (!isConstantFormat(pelvi) || pelvi->format != d.vi.format)) { vsapi->setError(out, "Super: pelclip must have the same format as the input clip, and it must have constant dimensions."); vsapi->freeNode(d.node); vsapi->freeNode(d.pelclip); return; } d.usePelClip = 0; if (d.pelclip && (d.nPel >= 2)) { if ((pelvi->width == d.vi.width * d.nPel) && (pelvi->height == d.vi.height * d.nPel)) { d.usePelClip = 1; d.isPelClipPadded = 0; } else if ((pelvi->width == (d.vi.width + d.nHPad * 2) * d.nPel) && (pelvi->height == (d.vi.height + d.nVPad * 2) * d.nPel)) { d.usePelClip = 1; d.isPelClipPadded = 1; } else { vsapi->setError(out, "Super: pelclip's dimensions must be multiples of the input clip's dimensions."); vsapi->freeNode(d.pelclip); vsapi->freeNode(d.node); return; } } d.nSuperWidth = d.nWidth + 2 * d.nHPad; d.nSuperHeight = PlaneSuperOffset(0, d.nHeight, d.nLevels, d.nPel, d.nVPad, d.nSuperWidth, d.yRatioUV) / d.nSuperWidth; if (d.yRatioUV == 2 && d.nSuperHeight & 1) d.nSuperHeight++; // even if (d.xRatioUV == 2 && d.nSuperWidth & 1) d.nSuperWidth++; d.vi.width = d.nSuperWidth; d.vi.height = d.nSuperHeight; data = (MVSuperData *)malloc(sizeof(d)); *data = d; vsapi->createFilter(in, out, "Super", mvsuperInit, mvsuperGetFrame, mvsuperFree, fmParallel, 0, data, core); }