public override VideoFrame GetFrame(int n, ScriptEnvironment env) { if (noRotate) { return(base.GetFrame(n, env)); } var res = NewVideoFrame(env); using (var frame = Child.GetFrame(n, env)) { var vi = Child.GetVideoInfo(); Parallel.ForEach(planes, plane => { var zero = plane == YUVPlanes.PLANAR_U || plane == YUVPlanes.PLANAR_V ? 128 : 0; OverlayUtils.MemSet(res.GetWritePtr(plane), zero, res.GetPitch(plane) * res.GetHeight(plane)); // get source image size var height = frame.GetHeight(plane); var width = vi.width / (vi.height / height); var pixelSize = frame.GetRowSize(plane) / width; NativeUtils.BilinearRotate( frame.GetReadPtr(plane), frame.GetRowSize(plane) / pixelSize, frame.GetHeight(plane), frame.GetPitch(plane), res.GetWritePtr(plane), res.GetRowSize(plane) / pixelSize, res.GetHeight(plane), res.GetPitch(plane), angle, pixelSize); }); } return(res); }
public override VideoFrame GetFrame(int n, ScriptEnvironment env) { var frame = NewVideoFrame(env); if (realPlanar) { OverlayUtils.ResetChroma(frame); } OverlayUtils.MemSet(frame.GetWritePtr(), byte.MaxValue, frame.GetHeight() * frame.GetPitch()); var stride = frame.GetPitch(); var pixelSize = frame.GetRowSize() / GetVideoInfo().width; var random = new Random(seed == int.MaxValue ? n : seed); unsafe { void LeftRight(int length, Func <int, int> offset) { if (length > 0) { for (var x = 0; x < length; x++) { var data = (byte *)frame.GetWritePtr() + offset(x) * pixelSize; var gradientVal = GradientVal(x, length); for (var y = 0; y < height; y++, data += stride) { var val = gradientVal; if (noise && random.Next(length + 1) > x && random.Next(length + 1) > x) { val = 0; } if (val != byte.MaxValue) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } } void TopBottom(int length, Func <int, int> offset) { if (length > 0) { for (var y = 0; y < length; y++) { var data = (byte *)frame.GetWritePtr() + offset(rgb ? (height - y - 1) : y) * stride; var gradientVal = GradientVal(y, length); for (var x = 0; x < width; x++, data += pixelSize) { var val = gradientVal; if (noise && random.Next(length + 1) > y && random.Next(length + 1) > y) { val = 0; } if (val != byte.MaxValue && data[0] > val) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } } LeftRight(left, x => x); LeftRight(right, x => width - x - 1); TopBottom(top, y => y); TopBottom(bottom, y => height - y - 1); } return(frame); }
public override VideoFrame GetFrame(int n, ScriptEnvironment env) { if (noRotate) { return(base.GetFrame(n, env)); } var res = NewVideoFrame(env); var frame = Child.GetFrame(n, env); var vi = Child.GetVideoInfo(); Parallel.ForEach(planes, plane => { var zero = plane == YUVPlanes.PLANAR_U || plane == YUVPlanes.PLANAR_V ? 128 : 0; OverlayUtils.MemSet(res.GetWritePtr(plane), zero, res.GetPitch(plane) * res.GetHeight(plane)); // get source image size var height = frame.GetHeight(plane); var width = vi.width / (vi.height / height); var oldXradius = (width - 1) / 2.0; var oldYradius = (height - 1) / 2.0; var pixelSize = frame.GetRowSize(plane) / width; // get destination image size var newWidth = GetVideoInfo().width; var newHeight = GetVideoInfo().height; var newXradius = (newWidth - 1) / 2.0; var newYradius = (newHeight - 1) / 2.0; // angle's sine and cosine var angleRad = -angle * Math.PI / 180; var angleCos = Cos(angleRad); var angleSin = Sin(angleRad); var ymax = height - 1; var xmax = width - 1; var srcStride = frame.GetPitch(plane); var dstOffset = res.GetPitch(plane) - res.GetRowSize(plane); unsafe { var src = (byte *)frame.GetReadPtr(plane); var dst = (byte *)res.GetWritePtr(plane); var cy = -newYradius; for (int y = 0; y < newHeight; y++, cy++) { // do some pre-calculations of source points' coordinates // (calculate the part which depends on y-loop, but does not // depend on x-loop) var tx = angleSin * cy + oldXradius; var ty = angleCos * cy + oldYradius; var cx = -newXradius; for (int x = 0; x < newWidth; x++, dst += pixelSize, cx++) { // coordinates of source point var ox = tx + angleCos * cx; var oy = ty - angleSin * cx; // top-left coordinate var ox1 = (int)ox; var oy1 = (int)oy; // validate source pixel's coordinates if (ox1 >= 0 && oy1 >= 0 && ox1 < width && oy1 < height) { // bottom-right coordinate var ox2 = ox1 == xmax ? ox1 : ox1 + 1; var oy2 = oy1 == ymax ? oy1 : oy1 + 1; var dx1 = ox - ox1; if (dx1 < 0) { dx1 = 0; } var dx2 = 1.0f - dx1; var dy1 = oy - oy1; if (dy1 < 0) { dy1 = 0; } var dy2 = 1.0f - dy1; // get four points byte *p1, p2; p1 = p2 = src + oy1 * srcStride; p1 += ox1 * pixelSize; p2 += ox2 * pixelSize; byte *p3, p4; p3 = p4 = src + oy2 * srcStride; p3 += ox1 * pixelSize; p4 += ox2 * pixelSize; // interpolate using 4 points for (var z = 0; z < pixelSize; z++) { dst[z] = (byte)( dy2 * (dx2 * p1[z] + dx1 * p2[z]) + dy1 * (dx2 * p3[z] + dx1 * p4[z])); } } } dst += dstOffset; } } }); return(res); }
protected override VideoFrame GetFrame(int n) { var frame = NewVideoFrame(StaticEnv); if (realPlanar) { OverlayUtils.ResetChroma(frame); } OverlayUtils.MemSet(frame.GetWritePtr(), byte.MaxValue, frame.GetHeight() * frame.GetPitch()); var stride = frame.GetPitch() / byteDepth; var pixelSize = frame.GetRowSize() / (GetVideoInfo().width *byteDepth); var random = new FastRandom(Seed == 0 ? n : Seed); unsafe { void LeftRightByte(int length, Func <int, int> offset) { if (length == 0) { return; } for (var x = 0; x < length; x++) { var data = (byte *)frame.GetWritePtr() + offset(x) * pixelSize; var gradientVal = GradientValByte(x, length); for (var y = 0; y < Height; y++, data += stride) { var val = gradientVal; if (Noise && random.Next(length) > x && random.Next(length) > x) { val = 0; } if (val != byte.MaxValue) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } void TopBottomByte(int length, Func <int, int> offset) { if (length == 0) { return; } for (var y = 0; y < length; y++) { var data = (byte *)frame.GetWritePtr() + offset(rgb ? (Height - y - 1) : y) * stride; var gradientVal = GradientValByte(y, length); for (var x = 0; x < Width; x++, data += pixelSize) { var val = gradientVal; if (Noise && random.Next(length) > y && random.Next(length) > y) { val = 0; } if (val != byte.MaxValue && data[0] > val) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } void LeftRightShort(int length, Func <int, int> offset) { if (length == 0) { return; } for (var x = 0; x < length; x++) { var data = (ushort *)frame.GetWritePtr() + offset(x) * pixelSize; var gradientVal = GradientValShort(x, length); for (var y = 0; y < Height; y++, data += stride) { var val = gradientVal; if (Noise && random.Next(length) > x && random.Next(length) > x) { val = 0; } if (val != shortMaxValue) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } void TopBottomShort(int length, Func <int, int> offset) { if (length == 0) { return; } for (var y = 0; y < length; y++) { var data = (ushort *)frame.GetWritePtr() + offset(rgb ? (Height - y - 1) : y) * stride; var gradientVal = GradientValShort(y, length); for (var x = 0; x < Width; x++, data += pixelSize) { var val = gradientVal; if (Noise && random.Next(length) > y && random.Next(length) > y) { val = 0; } if (val != shortMaxValue && data[0] > val) { for (var i = 0; i < pixelSize; i++) { data[i] = val; } } } } } if (GetVideoInfo().pixel_type.GetBitDepth() == 8) { Parallel.Invoke(() => LeftRightByte(Left, x => x), () => LeftRightByte(Right, x => Width - x - 1)); Parallel.Invoke(() => TopBottomByte(Top, y => y), () => TopBottomByte(Bottom, y => Height - y - 1)); } else { Parallel.Invoke(() => LeftRightShort(Left, x => x), () => LeftRightShort(Right, x => Width - x - 1)); Parallel.Invoke(() => TopBottomShort(Top, y => y), () => TopBottomShort(Bottom, y => Height - y - 1)); } } return(frame); }