示例#1
0
        public Models(int numPipelines = 1)
        {
            NumPipelines = numPipelines;
            CheckDeviceCapabilities();

            SharedModel        = new SharedModel();
            Images             = new ImagesModel(SharedModel.ScaleShader);
            TextureCache       = new TextureCache(Images);
            pixelValueShader   = new PixelValueShader(SharedModel);
            polarConvertShader = new ConvertPolarShader(SharedModel.QuadShader);

            Export = new ExportModel(SharedModel);
            Filter = new FiltersModel(Images);
            //Gif = new GifModel(sharedModel.QuadShader);
            Progress = new ProgressModel();

            for (int i = 0; i < numPipelines; ++i)
            {
                pipelines.Add(new ImagePipeline(i));
                pipelines.Last().PropertyChanged += PipeOnPropertyChanged;
            }
            Pipelines = pipelines;

            stats     = new StatisticsModel(SharedModel);
            thumbnail = new ThumbnailModel(SharedModel.QuadShader);

            // pipeline controller
            pipelineController = new PipelineController(this);
        }
示例#2
0
 public virtual void Dispose()
 {
     //Gif?.Dispose();
     Images?.Dispose();
     Filter?.Dispose();
     polarConvertShader?.Dispose();
     foreach (var imagePipeline in pipelines)
     {
         imagePipeline.Dispose();
     }
     pixelValueShader?.Dispose();
     SharedModel?.Dispose();
 }
示例#3
0
        public void CreateGif(Config cfg, SharedModel shared)
        {
            Debug.Assert(cfg.Left != null);
            Debug.Assert(cfg.Right != null);
            Debug.Assert(cfg.Left.Size == cfg.Right.Size);
            Debug.Assert(!progressModel.IsProcessing);
            if (cfg.Overlay != null)
            {
                Debug.Assert(cfg.Left.Size == cfg.Overlay.Size);
            }

            var cts = new CancellationTokenSource();

            progressModel.AddTask(CreateGifAsync(cfg, progressModel.GetProgressInterface(cts.Token), shared), cts);
        }
示例#4
0
        public virtual void Dispose()
        {
            Progress?.Dispose();
            thumbnail?.Dispose();
            stats?.Dispose();
            gif?.Dispose();

            Images?.Dispose();
            Filter?.Dispose();
            polarConvertShader?.Dispose();
            foreach (var imagePipeline in pipelines)
            {
                imagePipeline.Dispose();
            }
            pixelValueShader?.Dispose();
            SharedModel?.Dispose();
        }
示例#5
0
        public Models(int numPipelines = 1)
        {
            NumPipelines = numPipelines;
            CheckDeviceCapabilities();

            SharedModel  = new SharedModel();
            Images       = new ImagesModel(SharedModel.ScaleShader);
            TextureCache = new ImageModelTextureCache(Images);

            Filter   = new FiltersModel(Images);
            Progress = new ProgressModel();

            for (int i = 0; i < numPipelines; ++i)
            {
                pipelines.Add(new ImagePipeline(i));
                pipelines.Last().PropertyChanged += PipeOnPropertyChanged;
            }
            Pipelines = pipelines;

            // pipeline controller
            pipelineController = new PipelineController(this);
        }
示例#6
0
        public virtual void Dispose()
        {
            Progress?.Dispose();
            thumbnail?.Dispose();
            stats?.Dispose();
            gif?.Dispose();
            scaling?.Dispose();
            overlay?.Dispose();
            ssim?.Dispose();

            Images?.Dispose();
            Filter?.Dispose();
            polarConvertShader?.Dispose();
            convertTo3DShader?.Dispose();
            foreach (var imagePipeline in pipelines)
            {
                imagePipeline.Dispose();
            }
            pixelValueShader?.Dispose();
            SharedModel?.Dispose();

            // finally, destroy directx resources
            Device.Get().Dispose();
        }
示例#7
0
        private async Task CreateGifAsync(Config cfg, IProgress progress, SharedModel shared)
        {
            // delay in milliseconds
            var numFrames = cfg.FramesPerSecond * cfg.NumSeconds;
            var left      = cfg.Left;
            var right     = cfg.Right;
            var overlay   = cfg.Overlay;

            // size compatible?
            bool disposeImages = false;

            if ((left.Size.Width % 2) != 0 || (left.Size.Height % 2) != 0)
            {
                disposeImages = true;
                var pad = Size3.Zero;
                pad.X = left.Size.Width % 2;
                pad.Y = left.Size.Height % 2;
                left  = (TextureArray2D)shared.Padding.Run(left, Size3.Zero, pad, PaddingShader.FillMode.Clamp, null, shared, false);
                right = (TextureArray2D)shared.Padding.Run(right, Size3.Zero, pad, PaddingShader.FillMode.Clamp, null, shared, false);
                if (overlay != null)
                {
                    overlay = (TextureArray2D)shared.Padding.Run(overlay, Size3.Zero, pad,
                                                                 PaddingShader.FillMode.Transparent, null, shared, false);
                }

                Debug.Assert(left.Size.Width % 2 == 0 && left.Size.Height % 2 == 0);
            }

            try
            {
                progressModel.EnableDllProgress = false;
                var leftView    = left.GetSrView(LayerMipmapSlice.Mip0);
                var rightView   = right.GetSrView(LayerMipmapSlice.Mip0);
                var overlayView = overlay?.GetSrView(LayerMipmapSlice.Mip0);

                var curProg = progress.CreateSubProgress(0.9f);

                // prepare parallel processing
                var numTasks = Environment.ProcessorCount;
                var tasks    = new Task[numTasks];
                var images   = new DllImageData[numTasks];
                for (int i = 0; i < numTasks; ++i)
                {
                    images[i] = IO.CreateImage(new ImageFormat(Format.R8G8B8A8_UNorm_SRgb), left.Size,
                                               LayerMipmapCount.One);
                }
                int   textSize = left.Size.Y / 18;
                float padding  = textSize / 4.0f;

                // render frames into texture
                using (var frame = new TextureArray2D(LayerMipmapCount.One, left.Size,
                                                      Format.R8G8B8A8_UNorm_SRgb, false))
                {
                    var frameView = frame.GetRtView(LayerMipmapSlice.Mip0);
                    using (var d2d = new Direct2D(frame))
                    {
                        for (int i = 0; i < numFrames; ++i)
                        {
                            float t         = (float)i / (numFrames - 1);
                            int   borderPos = (int)(t * (frame.Size.Width - 1));
                            int   idx       = i % numTasks;

                            // render frame
                            shader.Run(leftView, rightView, overlayView, frameView, cfg.SliderWidth, borderPos,
                                       frame.Size.Width, frame.Size.Height, shared.QuadShader, shared.Upload);

                            // add text
                            using (var c = d2d.Begin())
                            {
                                c.Text(new Float2(padding), new Float2(left.Size.X - padding, left.Size.Y - padding),
                                       textSize, Colors.White, cfg.Label1, TextAlignment.Leading);

                                c.Text(new Float2(padding), new Float2(left.Size.X - padding, left.Size.Y - padding), textSize,
                                       Colors.White, cfg.Label2, TextAlignment.Trailing);
                            }

                            // copy frame from gpu to cpu
                            var dstMip  = images[idx].GetMipmap(LayerMipmapSlice.Mip0);
                            var dstPtr  = dstMip.Bytes;
                            var dstSize = dstMip.ByteSize;

                            // wait for previous task to finish before writing it to the file
                            if (tasks[idx] != null)
                            {
                                await tasks[idx];
                            }

                            frame.CopyPixels(LayerMipmapSlice.Mip0, dstPtr, dstSize);
                            var filename = $"{cfg.TmpFilename}{i:D4}";

                            // write to file
                            tasks[idx] = Task.Run(() =>
                            {
                                try
                                {
                                    IO.SaveImage(images[idx], filename, "png", GliFormat.RGBA8_SRGB);
                                }
                                catch (Exception)
                                {
                                    // ignored (probably cancelled by user)
                                }
                            }, progress.Token);

                            curProg.Progress = i / (float)numFrames;
                            curProg.What     = "creating frames";

                            progress.Token.ThrowIfCancellationRequested();
                        }
                    }
                }

                // wait for tasks to finish
                for (var i = 0; i < tasks.Length; i++)
                {
                    if (tasks[i] != null)
                    {
                        await tasks[i];
                    }
                    tasks[i] = null;
                }

                // convert video
                await FFMpeg.ConvertAsync(cfg, progress.CreateSubProgress(1.0f));
            }
            finally
            {
                progressModel.EnableDllProgress = true;

                if (disposeImages)
                {
                    left.Dispose();
                    right.Dispose();
                    overlay?.Dispose();
                }
            }
        }