protected override ITextureFilter CreateFilter(ITextureFilter input) { if (!Renderer.IsDx11Avail) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // DX11 is not available; fallback } Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Height, s.Width); var shaderPass1 = LoadShader11(GetShaderFileName(Neurons1)); var shaderPass2 = LoadShader11(GetShaderFileName(Neurons2)); var interleave = CompileShader("Interleave.hlsl").Configure(transform: transform); var sourceSize = input.Size(); if ((Renderer.TargetSize <= sourceSize).Any) { return(input); } var yuv = input.ConvertToYuv(); m_Filter1 = NNedi3Helpers.CreateFilter(shaderPass1, yuv, Neurons1, Structured); var resultY = interleave.ApplyTo(yuv, m_Filter1); m_Filter2 = NNedi3Helpers.CreateFilter(shaderPass2, resultY, Neurons2, Structured); var luma = interleave.ApplyTo(resultY, m_Filter2); var result = ChromaScaler.ScaleChroma( new CompositionFilter(luma, yuv, targetSize: luma.Size(), chromaOffset: new Vector2(-0.25f, -0.25f))); return(result.Convolve(null, offset: new Vector2(0.5f, 0.5f))); }
protected override ITextureFilter CreateFilter(ITextureFilter sourceFilter) { if (sourceFilter.Output.Size == Renderer.TargetSize) { return(sourceFilter); } try { m_DxvaHd = Renderer.CreateDxvaHd((Size)sourceFilter.Output.Size, TextureFormat.Unorm8, Renderer.TargetSize, TextureFormat.Unorm8, Quality); } catch (DxvaHdException) { // DXVA HD not available; fallback Renderer.FallbackOccurred = true; return(sourceFilter); } var input = YuvMode ? sourceFilter.ConvertToYuv() : sourceFilter; if (sourceFilter.Output.Format != TextureFormat.Unorm8) { // Convert input to Unorm8 (and unforunately murdering quality at the same time) var copy = CompileShader("Copy.hlsl").Configure(linearSampling: false, format: TextureFormat.Unorm8); input = new ShaderFilter(copy, input); } var result = new DxvaHdResizeFilter(m_DxvaHd, input); return(YuvMode ? result.ConvertToRgb() : result); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (!Renderer.IsDx11Avail) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // DX11 is not available; fallback } Func <TextureSize, TextureSize> transform = s => new TextureSize(2 * s.Height, s.Width); var shaderPass1 = GetShader(Neurons1); var shaderPass2 = GetShader(Neurons2); var interleave = new Shader(FromFile("Interleave.hlsl")) { Transform = transform }; if ((Renderer.TargetSize <= input.Size()).Any) { return(input); } var yuv = input.ConvertToYuv(); var composition = input.Decompose(); var resultY = interleave.ApplyTo(composition.Luma, shaderPass1.ApplyTo(yuv)); var luma = interleave.ApplyTo(resultY, shaderPass2.ApplyTo(resultY)); composition = luma.ComposeWith(composition.Chroma, chromaOffset: new Vector2(-0.25f, -0.25f)); var result = ChromaScaler.ScaleChroma(composition); return(result.Convolve(null, offset: new Vector2(0.5f, 0.5f))); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } int bits = Renderer.InputFormat.GetBitDepth(); if (bits > MaxBitDepth) { return(input); } float[] consts = { (1 << bits) - 1, Power }; var Deband = new Shader(FromFile("Deband.hlsl", compilerOptions: PreserveDetail ? "PRESERVE_DETAIL=1" : "")) { Arguments = consts, PerTextureLinearSampling = new[] { true, false } }; ITextureFilter yuv = input.ConvertToYuv(); var inputsize = yuv.Size(); var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int maxWidth = Math.Min(Math.Min(inputsize.Width, inputsize.Height) / 3, 256); int max = (int)Math.Floor(Math.Log(maxWidth, factor)); for (int i = max; i >= 0; i--) { double scale = Math.Pow(factor, i); var size = new TextureSize((int)Math.Round(inputsize.Width / scale), (int)Math.Round(inputsize.Height / scale)); if (size.Width == 0 || size.Height == 0) { continue; } if (i == 0) { size = inputsize; } Deband.Transform = s => size; deband = Deband.ApplyTo(yuv, deband); } return(deband.ConvertToRgb()); }
public static ICompositionFilter Decompose(this ITextureFilter filter) { var result = filter as ICompositionFilter; if (result != null) { return(result); } var yuv = filter.ConvertToYuv(); return(new CompositionFilter(yuv, yuv, fallback: filter)); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (!Renderer.IsOpenClAvail || Renderer.RenderQuality.PerformanceMode()) { Renderer.FallbackOccurred = true; // Warn user via player stats OSD return(input); // OpenCL is not available, or UNORM8 textures used (not supported); fallback } Func <TextureSize, TextureSize> transformWidth = s => new TextureSize(2 * s.Width, s.Height); Func <TextureSize, TextureSize> transformHeight = s => new TextureSize(s.Width, 2 * s.Height); var kernel = CompileKernel(); var shaderH = kernel.Configure(transform: transformWidth); var shaderV = kernel.Configure(transform: transformHeight); var neuronCount1 = s_NeuronCount[(int)Neurons1]; var neuronCount2 = s_NeuronCount[(int)Neurons2]; var weights1 = s_Weights[(int)Neurons1]; var buffer1 = Renderer.CreateClBuffer(weights1); var buffer2 = buffer1; var differentWeights = neuronCount1 != neuronCount2; if (differentWeights) { var weights2 = s_Weights[(int)Neurons2]; buffer2 = Renderer.CreateClBuffer(weights2); } var sourceSize = input.Output.Size; if (!IsUpscalingFrom(sourceSize)) { return(input); } var yuv = input.ConvertToYuv(); var localWorkSizes = new[] { 8, 8 }; var nnedi3H = new NNedi3HKernelFilter(shaderH, buffer1, neuronCount1, new TextureSize(yuv.Output.Size.Width, yuv.Output.Size.Height), localWorkSizes, yuv); var nnedi3V = new NNedi3VKernelFilter(shaderV, buffer2, neuronCount2, differentWeights, new TextureSize(nnedi3H.Output.Size.Width, nnedi3H.Output.Size.Height), localWorkSizes, nnedi3H); var result = ChromaScaler.MakeChromaFilter(nnedi3V, yuv, chromaOffset: new Vector2(-0.25f, -0.25f)); return(new ResizeFilter(result, result.Output.Size, new Vector2(0.5f, 0.5f), Renderer.LumaUpscaler, Renderer.LumaDownscaler)); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (ProcessInYUV) { input = input.ConvertToYuv(); } var output = ShaderFileNames.Aggregate(input, (current, filename) => current.Apply(GetShader(filename))); return(ProcessInYUV ? output.ConvertToRgb() : output); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } int bits = Renderer.InputFormat.GetBitDepth(); if (bits > maxbitdepth) { return(input); } float[] consts = { (1 << bits) - 1, power }; var Deband = CompileShader("Deband.hlsl", macroDefinitions: !grain ? "SkipDithering=1" : "") .Configure(arguments: consts, perTextureLinearSampling: new[] { true, false }); ITextureFilter yuv = input.ConvertToYuv(); var inputsize = yuv.Output.Size; var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int max = (int)Math.Floor(Math.Log(Math.Min(inputsize.Width, inputsize.Height) / 3.0, factor)); for (int i = max; i >= 0; i--) { double scale = Math.Pow(factor, i); var size = new TextureSize((int)Math.Round(inputsize.Width / scale), (int)Math.Round(inputsize.Height / scale)); if (size.Width == 0 || size.Height == 0) { continue; } if (i == 0) { size = inputsize; } deband = Deband.Configure(transform: s => size).ApplyTo(yuv, deband); } return(deband.ConvertToRgb()); }
protected override IFilter <ITextureOutput <ITexture2D> > Optimize() { ITextureFilter result = m_TrueSource.Resize(Output.Size); if (m_TrueSource.IsYuv() && !m_WantYuv) { result = result.ConvertToRgb(); } if (!m_TrueSource.IsYuv() && m_WantYuv) { result = result.ConvertToYuv(); } return(result.Compile()); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (ProcessInYUV) { input = input.ConvertToYuv(); } var output = ShaderFileNames.Aggregate(input, (current, filename) => CompileShader(filename) .Configure(format: GetTextureFormat()) .ApplyTo(current)); return(ProcessInYUV ? output.ConvertToRgb() : output); }
private VideoSourceFilter(TrueSourceFilter trueSource, TextureSize outputSize, bool wantYuv) : base(Compile(new TextureDescription(outputSize), () => { ITextureFilter source = trueSource; if (trueSource.IsYuv() && !wantYuv) source = source.ConvertToYuv(); if (!trueSource.IsYuv() && wantYuv) source = source.ConvertToRgb(); return(source.SetSize(outputSize)); })) { m_TrueSource = trueSource; m_WantYuv = wantYuv; if (m_WantYuv) { m_TrueSource.WantYuv = true; // Prefer enabling (generates less overhead) } m_TrueSource.PrescaleSize = Output.Size; // Try change source size, always use latest value }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (Renderer.InputFormat.IsRgb()) return input; int bits = Renderer.InputFormat.GetBitDepth(); if (bits > MaxBitDepth) return input; float[] consts = { (1 << bits) - 1, Power }; var Deband = CompileShader("Deband.hlsl", macroDefinitions: PreserveDetail ? "PRESERVE_DETAIL=1" : "") .Configure(arguments: consts, perTextureLinearSampling: new[] { true, false }); ITextureFilter yuv = input.ConvertToYuv(); var inputsize = yuv.Size(); var deband = yuv; double factor = 2.0;// 0.5 * Math.Sqrt(5) + 0.5; int maxWidth = Math.Min(Math.Min(inputsize.Width, inputsize.Height) / 3, 256); int max = (int)Math.Floor(Math.Log(maxWidth, factor)); for (int i = max; i >= 0; i--) { double scale = Math.Pow(factor, i); var size = new TextureSize((int)Math.Round(inputsize.Width / scale), (int)Math.Round(inputsize.Height / scale)); if (size.Width == 0 || size.Height == 0) continue; if (i == 0) size = inputsize; deband = Deband.Configure(transform: s => size).ApplyTo(yuv, deband); } return deband.ConvertToRgb(); }
ITextureFilter ICanUndo <RgbProcess> .Undo() { return(m_Fallback.ConvertToYuv()); }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } int bits = Renderer.InputFormat.GetBitDepth(); if (bits > MaxBitDepth) { return(input); } float[] consts = { (1 << bits) - 1, Power }; var Downscale = new Shader(FromFile("Downscale.hlsl")) { Transform = s => new TextureSize(s.Width / 2, s.Height / 2), Arguments = consts }; var DownscaleLuma = new Shader(FromFile("DownscaleLuma.hlsl")) { SizeIndex = 1, Arguments = consts }; DownscaleLuma["iteration"] = 0; var Deband = new Shader(FromFile("Deband.hlsl", compilerOptions: PreserveDetail ? "PRESERVE_DETAIL=1" : "")) { Arguments = consts, LinearSampling = false, SizeIndex = 1 }; var pyramid = new Stack <ITextureFilter>(); var composition = input as ICompositionFilter; if (composition != null) { pyramid.Push(composition.Luma); pyramid.Push(DownscaleLuma.ApplyTo(composition.Luma, composition.Chroma)); } else { pyramid.Push(input.ConvertToYuv()); } // Build gaussian pyramid while (pyramid.Peek().Size().Width >= 2 && pyramid.Peek().Size().Height >= 2) { Downscale["iteration"] = pyramid.Count - 1; pyramid.Push(Downscale.ApplyTo(pyramid.Peek())); } // Process pyramid ITextureFilter chroma = null; ITextureFilter result = pyramid.Peek(); while (pyramid.Count > 1) { if (composition != null && pyramid.Count == 2) { chroma = result; Deband.Format = TextureFormat.Unorm16_R; } result = Deband.ApplyTo(pyramid.Pop(), pyramid.Peek(), result); } if (composition != null) { return(result.ComposeWith(chroma, copyParametersFrom: composition)); } else { return(result.ConvertToRgb()); } }
protected override ITextureFilter CreateFilter(ITextureFilter input) { if (Renderer.InputFormat.IsRgb()) { return(input); } int bits = Renderer.InputFormat.GetBitDepth(); if (bits > MaxBitDepth) { return(input); } var composition = input as ICompositionFilter; var offset = new SharpDX.Vector2(0.0f, 0.0f); // TODO: process chroma offset properly float[] consts = { (1 << bits) - 1, Power }; var Downscale = new Shader(FromFile("Downscale.hlsl")) { Transform = s => new TextureSize(s.Width / 2, s.Height / 2), Arguments = consts }; var DownscaleLuma = new Shader(FromFile("DownscaleLuma.hlsl")) { SizeIndex = 1, Arguments = consts }; DownscaleLuma["iteration"] = 0; var Deband = new Shader(FromFile("Deband.hlsl", macroDefinitions: PreserveDetail ? "PRESERVE_DETAIL=1" : "")) { Arguments = consts, LinearSampling = false, SizeIndex = 1 }; ITextureFilter deband, chroma = null, luma = null; var pyramid = new Stack <ITextureFilter>(); if (composition != null) { deband = composition.Luma; pyramid.Push(deband); pyramid.Push(DownscaleLuma.ApplyTo(composition.Luma, composition.Chroma)); } else { deband = input.ConvertToYuv(); pyramid.Push(deband); } // Build gaussian pyramid while (pyramid.Peek().Size().Width >= 2 && pyramid.Peek().Size().Height >= 2) { Downscale["iteration"] = pyramid.Count - 1; pyramid.Push(Downscale.ApplyTo(pyramid.Peek())); } // Process pyramid var result = pyramid.Peek(); while (pyramid.Count > 1) { result = Deband.ApplyTo(pyramid.Pop(), pyramid.Peek(), result); if (composition != null && pyramid.Count == 2) { chroma = result; Deband.Format = TextureFormat.Unorm16_R; } } if (composition != null) { luma = result; return(new CompositionFilter(luma, chroma, composition.TargetSize, composition.ChromaOffset)); } else { return(result.ConvertToRgb()); } }