/// <summary> /// Draws the given frame to the video. /// </summary> /// <param name="device">The device on which the given framebuffer is created.</param> /// <param name="uploadedTexture">The texture which should be added to the video.</param> public void DrawFrame(EngineDevice device, MemoryMappedTexture32bpp uploadedTexture) { try { device.EnsureNotNull(nameof(device)); uploadedTexture.EnsureNotNull(nameof(uploadedTexture)); if (!m_hasStarted) { throw new SeeingSharpGraphicsException($"{nameof(SeeingSharpVideoWriter)} is not started!"); } if (m_hasFinished) { throw new SeeingSharpGraphicsException($"{nameof(SeeingSharpVideoWriter)} has already finished before!"); } // Check for correct image size if (m_videoSize != uploadedTexture.PixelSize) { throw new SeeingSharpGraphicsException("Size has changed during recording!"); } this.DrawFrameInternal(device, uploadedTexture); } catch (Exception ex) { m_drawException = ex; } }
public async Task ReadSimple_WmvVideo_Seek() { await UnitTestHelper.InitializeWithGrahicsAsync(); ResourceLink videoLink = new AssemblyResourceLink( this.GetType().Assembly, "SeeingSharp.Tests.Rendering.Ressources.Videos", "DummyVideo.wmv"); GDI.Bitmap bitmapFrame = null; using (FrameByFrameVideoReader videoReader = new FrameByFrameVideoReader(videoLink)) using (MemoryMappedTexture32bpp actFrameBuffer = new MemoryMappedTexture32bpp(videoReader.FrameSize)) { videoReader.SetCurrentPosition(TimeSpan.FromSeconds(2.0)); videoReader.ReadFrame(actFrameBuffer); actFrameBuffer.SetAllAlphaValuesToOne_ARGB(); using (bitmapFrame = GraphicsHelper.LoadBitmapFromMappedTexture(actFrameBuffer)) { Assert.NotNull(bitmapFrame); Assert.True(videoReader.CurrentPosition > TimeSpan.FromSeconds(1.9)); Assert.True(videoReader.CurrentPosition < TimeSpan.FromSeconds(2.1)); Assert.True(videoReader.Duration > TimeSpan.FromSeconds(3.9)); Assert.True(videoReader.Duration < TimeSpan.FromSeconds(4.1)); Assert.True(videoReader.IsSeekable); Assert.True( BitmapComparison.IsNearEqual(bitmapFrame, Properties.Resources.ReferenceImage_VideoFrameWmv_Seek)); } } }
public static MemoryMappedTexture32bpp ToMemoryMappedTexture(this byte[] pixels) { var tex = new MemoryMappedTexture32bpp(new SharpDX.Size2(KinectManager.ColorWidth, KinectManager.ColorHeight)); tex.FillWith(pixels); return(tex); }
public static MemoryMappedTexture32bpp BGRAToMemoryMappedTextureARGB(this byte[] bgra) { var tex = new MemoryMappedTexture32bpp(new SharpDX.Size2(KinectManager.ColorWidth, KinectManager.ColorHeight)); tex.FillWith(bgra.Reverse()); return(tex); }
/// <summary> /// Loads all resources. /// </summary> /// <param name="device">The device on which to load all resources.</param> /// <param name="resources">The current ResourceDictionary.</param> protected override void LoadResourceInternal(EngineDevice device, ResourceDictionary resources) { // Prepare texture m_texture = GraphicsHelper.CreateCpuWritableTexture( device, m_videoWidth, m_videoHeight); m_textureView = new D3D11.ShaderResourceView(device.DeviceD3D11_1, m_texture); // Read the thumbnail m_videoReader.SetCurrentPosition(m_thumbnailTimestamp); m_thumbnailFrame = m_videoReader.ReadFrame(); m_thumbnailFrame.SetAllAlphaValuesToOne_ARGB(); }
/// <summary> /// Sets the bitmap to be displayed. /// </summary> protected void SetBitmap(Bitmap bitmap) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } m_bitmap = bitmap; m_mappedTexture = null; base.ReloadResource(); }
/// <summary> /// Reads the next frame and puts it into the provided buffer. /// </summary> /// <param name="targetBuffer">The target buffer to write to.</param> public bool ReadFrame(MemoryMappedTexture32bpp targetBuffer) { this.EnsureNotNullOrDisposed("this"); targetBuffer.EnsureNotNull(nameof(targetBuffer)); if ((targetBuffer.Width != base.FrameSize.Width) || (targetBuffer.Height != base.FrameSize.Height)) { throw new SeeingSharpGraphicsException("Size of the given buffer does not match the video size!"); } // Read the frame SeeingSharpMediaBuffer mediaSharpManaged = base.ReadFrameInternal(); if (mediaSharpManaged == null) { return(false); } // Process the frame try { MF.MediaBuffer mediaBuffer = mediaSharpManaged.GetBuffer(); int cbMaxLength; int cbCurrentLenght; IntPtr mediaBufferPointer = mediaBuffer.Lock(out cbMaxLength, out cbCurrentLenght); // Performance optimization using CopyMemory method // see http://www.rolandk.de/wp/2015/05/wie-schnell-man-speicher-falsch-kopieren-kann/ CommonTools.CopyMemory( mediaBufferPointer, targetBuffer.Pointer, (ulong)(base.FrameSize.Width * base.FrameSize.Height * 4)); return(true); } finally { mediaSharpManaged.Dispose(); } }
public async Task ReadSimple_WmvVideo() { await UnitTestHelper.InitializeWithGrahicsAsync(); ResourceLink videoLink = new AssemblyResourceLink( this.GetType().Assembly, "SeeingSharp.Tests.Rendering.Ressources.Videos", "DummyVideo.wmv"); GDI.Bitmap bitmapFrame10 = null; using (FrameByFrameVideoReader videoReader = new FrameByFrameVideoReader(videoLink)) using (MemoryMappedTexture32bpp actFrameBuffer = new MemoryMappedTexture32bpp(videoReader.FrameSize)) { int frameIndex = 0; while (!videoReader.EndReached) { if (videoReader.ReadFrame(actFrameBuffer)) { actFrameBuffer.SetAllAlphaValuesToOne_ARGB(); frameIndex++; if (frameIndex != 10) { continue; } bitmapFrame10 = GraphicsHelper.LoadBitmapFromMappedTexture(actFrameBuffer); break; } } Assert.NotNull(bitmapFrame10); Assert.True(videoReader.Duration > TimeSpan.FromSeconds(3.9)); Assert.True(videoReader.Duration < TimeSpan.FromSeconds(4.1)); Assert.True(videoReader.IsSeekable); Assert.True( BitmapComparison.IsNearEqual(bitmapFrame10, Properties.Resources.ReferenceImage_VideoFrameWmv)); } }
///// <summary> ///// Reads frames from the source until we reach a valid one. ///// </summary> ///// <param name="maxTries">Maximum count of tries.</param> //public MemoryMappedTexture32bpp ReadFramesUntilValid(int maxTries = 50) //{ //} /// <summary> /// Reads the next frame and puts it into a newly generated buffer. /// </summary> public MemoryMappedTexture32bpp ReadFrame() { this.EnsureNotNullOrDisposed("this"); MemoryMappedTexture32bpp result = new MemoryMappedTexture32bpp(base.FrameSize); try { if (this.ReadFrame(result)) { return(result); } else { result.Dispose(); return(null); } } catch (Exception) { result.Dispose(); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="StandardTextureResource" /> class. /// </summary> internal StandardTextureResource(MemoryMappedTexture32bpp inMemoryTexture) { inMemoryTexture.EnsureNotNull(nameof(inMemoryTexture)); m_inMemoryTexture = inMemoryTexture; }
/// <summary> /// Resizes the sync buffer when the given size is different to the current one. /// </summary> /// <param name="newSize">The new size to be set.</param> public void ResizeSyncBufferIfNeeded(Size2 newSize) { if (IsDisposed) { throw new ObjectDisposedException("ImageDataFlowHelper"); } if ((newSize != this.SyncBufferSize) || (this.SyncBuffer == null)) { lock (this.SyncBufferLock) { CommonTools.SafeDispose(ref this.SyncBuffer); this.SyncBuffer = new MemoryMappedTexture32bpp( new Size2(newSize.Width, newSize.Height)); this.SyncBufferSize = newSize; } } }
/// <summary> /// Initializes a new instance of the <see cref="ImageDataFlowHelper"/> class. /// </summary> /// <param name="width">The width of the image.</param> /// <param name="height">The height of the image.</param> public ImageDataFlowHelper(string streamName) { this.StreamName = streamName; this.TextFormat = new TextFormatResource("Arial", 18f, FontWeight.Bold); this.TextFormat.TextAlignment = TextAlignment.Center; this.TextFormat.ParagraphAlignment = ParagraphAlignment.Center; this.TextBackground = new SolidBrushResource(Color4.LightGray.ChangeAlphaTo(0.7f)); this.TextForeground = new SolidBrushResource(Color4.DarkBlue); // Initialize scene(s) this.Scene = new Scene(); this.Scene.ManipulateSceneAsync((manipulator) => { manipulator.AddDrawingLayer(OnDraw); }).FireAndForget(); // Initialize members for Direct2D rendering this.Bitmap = null; this.BitmapSize = new Size2(0, 0); // Initialize members for synchronization this.SyncBufferSize = new Size2(0, 0); this.SyncBuffer = null; this.SyncBufferLock = new object(); this.SyncBufferChanged = false; }
/// <summary> /// Imports the texture node where the xml reader is currently located. /// </summary> /// <param name="inStreamXml">The xml reader object.</param> /// <param name="container">The container where to import to.</param> private void ImportTexture(XmlReader inStreamXml, ImportedModelContainer container) { string id = inStreamXml.GetAttribute("ID"); int width = 0; int height = 0; MemoryMappedTexture32bpp inMemoryTexture = null; while (inStreamXml.Read()) { // Ending condition if ((inStreamXml.NodeType == XmlNodeType.EndElement) && (inStreamXml.Name == NODE_NAME_TEXTURE)) { break; } // Continue condition if (inStreamXml.NodeType != XmlNodeType.Element) { continue; } // Read all texture data switch (inStreamXml.Name) { case NODE_NAME_TEXTURE_RGBA: width = Int32.Parse(inStreamXml.GetAttribute("WIDTH")); height = Int32.Parse(inStreamXml.GetAttribute("HEIGHT")); unsafe { inMemoryTexture = new MemoryMappedTexture32bpp(new Size2(width, height)); byte *inMemoryTextureP = (byte *)inMemoryTexture.Pointer.ToPointer(); int fullSize = width * height * 4; byte[] sourceBuffer = new byte[fullSize]; inStreamXml.Read(); inStreamXml.ReadContentAsBinHex(sourceBuffer, 0, fullSize); for (int loop = 0; loop < fullSize; loop += 4) { // Target format is BGRA (default one in Seeing#) inMemoryTextureP[loop + 2] = sourceBuffer[loop]; inMemoryTextureP[loop + 1] = sourceBuffer[loop + 1]; inMemoryTextureP[loop + 0] = sourceBuffer[loop + 2]; inMemoryTextureP[loop + 3] = sourceBuffer[loop + 3]; } } break; case NODE_NAME_TEXTURE_RGB: width = Int32.Parse(inStreamXml.GetAttribute("WIDTH")); height = Int32.Parse(inStreamXml.GetAttribute("HEIGHT")); unsafe { inMemoryTexture = new MemoryMappedTexture32bpp(new Size2(width, height)); byte *inMemoryTextureP = (byte *)inMemoryTexture.Pointer.ToPointer(); int fullSize = width * height * 3; int loopTarget = 0; byte[] sourceBuffer = new byte[fullSize]; inStreamXml.Read(); inStreamXml.ReadContentAsBinHex(sourceBuffer, 0, fullSize); for (int loop = 0; loop < fullSize; loop += 3) { // Target format is BGRA (default one in Seeing#) inMemoryTextureP[loopTarget + 2] = sourceBuffer[loop]; inMemoryTextureP[loopTarget + 1] = sourceBuffer[loop + 1]; inMemoryTextureP[loopTarget + 0] = sourceBuffer[loop + 2]; inMemoryTextureP[loopTarget + 3] = 255; loopTarget += 4; } } break; case NODE_NAME_TEXTURE_MODULATE: break; case NODE_NAME_TEXTURE_REPEAT: break; default: //throw new SeeingSharpGraphicsException(string.Format( // "Unknown element {0} in xgl file!", // inStreamXml.Name)); break; } } // Check values if (width < 0) { throw new SeeingSharpGraphicsException("Unable to read with of a texture!"); } if (height < 0) { throw new SeeingSharpGraphicsException("Unable to read height of a texture!"); } if (inMemoryTexture == null) { throw new SeeingSharpGraphicsException("Unable to read the contents of a texture!"); } // Add the imported texture var resKeyTexture = container.GetResourceKey(RES_CLASS_TEXTURE, id); container.ImportedResources.Add(new ImportedResourceInfo( resKeyTexture, () => new StandardTextureResource(inMemoryTexture))); container.ImportedResources.Add(new ImportedResourceInfo( container.GetResourceKey(RES_CLASS_MATERIAL, id), () => new SimpleColoredMaterialResource(resKeyTexture))); }
/// <summary> /// Draws the given frame to the video. /// </summary> /// <param name="device">The device on which the given framebuffer is created.</param> /// <param name="uploadedTexture">The texture which should be added to the video.</param> protected override void DrawFrameInternal(EngineDevice device, MemoryMappedTexture32bpp uploadedTexture) { // Cancel here if the given texture has an invalid size if (m_videoPixelSize != new Size2(uploadedTexture.Width, uploadedTexture.Height)) { return; } m_frameIndex++; MF.MediaBuffer mediaBuffer = MF.MediaFactory.CreateMemoryBuffer((int)uploadedTexture.SizeInBytes); try { // Write all contents to the MediaBuffer for media foundation int cbMaxLength = 0; int cbCurrentLength = 0; IntPtr mediaBufferPointer = mediaBuffer.Lock(out cbMaxLength, out cbCurrentLength); try { if (this.FlipY) { unsafe { int stride = m_videoPixelSize.Width; int *mediaBufferPointerNative = (int *)mediaBufferPointer.ToPointer(); int *targetBufferPointerNative = (int *)uploadedTexture.Pointer.ToPointer(); for (int loopY = 0; loopY < m_videoPixelSize.Height; loopY++) { for (int loopX = 0; loopX < m_videoPixelSize.Width; loopX++) { int actIndexTarget = loopX + (loopY * m_videoPixelSize.Width); int actIndexSource = loopX + ((m_videoPixelSize.Height - (1 + loopY)) * m_videoPixelSize.Width); mediaBufferPointerNative[actIndexTarget] = targetBufferPointerNative[actIndexSource]; } } } } else { unsafe { int stride = m_videoPixelSize.Width; int *mediaBufferPointerNative = (int *)mediaBufferPointer.ToPointer(); int *targetBufferPointerNative = (int *)uploadedTexture.Pointer.ToPointer(); for (int loopY = 0; loopY < m_videoPixelSize.Height; loopY++) { for (int loopX = 0; loopX < m_videoPixelSize.Width; loopX++) { int actIndex = loopX + (loopY * m_videoPixelSize.Width); mediaBufferPointerNative[actIndex] = targetBufferPointerNative[actIndex]; } } } } } finally { mediaBuffer.Unlock(); } mediaBuffer.CurrentLength = (int)uploadedTexture.SizeInBytes; // Create the sample (includes image and timing information) MF.Sample sample = MF.MediaFactory.CreateSample(); try { sample.AddBuffer(mediaBuffer); long frameDuration = 10 * 1000 * 1000 / m_framerate; sample.SampleTime = frameDuration * m_frameIndex; sample.SampleDuration = frameDuration; m_sinkWriter.WriteSample(m_streamIndex, sample); } finally { GraphicsHelper.SafeDispose(ref sample); } } finally { GraphicsHelper.SafeDispose(ref mediaBuffer); } }
/// <summary> /// Draws the given frame to the video. /// </summary> /// <param name="device">The device on which the given framebuffer is created.</param> /// <param name="uploadedTexture">The texture which should be added to the video.</param> protected abstract void DrawFrameInternal(EngineDevice device, MemoryMappedTexture32bpp uploadedTexture);
/// <summary> /// Initializes a new instance of the <see cref="BitmapTextureResource"/> class. /// </summary> /// <param name="mappedTexture">The mapped texture.</param> public BitmapTextureResource(MemoryMappedTexture32bpp mappedTexture) { mappedTexture.EnsureNotNull(nameof(mappedTexture)); m_mappedTexture = mappedTexture; }