From ebbf0ed4367748254a42cda891674817ee78cb33 Mon Sep 17 00:00:00 2001 From: homuler Date: Mon, 28 Dec 2020 20:08:31 +0900 Subject: [PATCH] feat(example): render external textures directly --- .../Scripts/OfficialDemo/OfficialDemoCPU.cs | 10 +-- .../Scripts/OfficialDemo/OfficialDemoGPU.cs | 79 ++++++++----------- .../Scripts/WebCamScreenController.cs | 5 ++ 3 files changed, 41 insertions(+), 53 deletions(-) diff --git a/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoCPU.cs b/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoCPU.cs index 4cc89802b..b16bc5e97 100644 --- a/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoCPU.cs +++ b/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoCPU.cs @@ -31,11 +31,11 @@ protected override void OnDestroy() { public override void RenderOutput(WebCamScreenController screenController, TextureFrame textureFrame) { lock (outputImageLock) { - if (outputImage != null) { - screenController.DrawScreen(outputImage); - outputImage.Dispose(); - outputImage = null; - } + if (outputImage == null) { return; } + + screenController.DrawScreen(outputImage); + outputImage.Dispose(); + outputImage = null; } } diff --git a/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoGPU.cs b/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoGPU.cs index 54278057f..69fe6000c 100644 --- a/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoGPU.cs +++ b/Assets/MediaPipe/Examples/Scripts/OfficialDemo/OfficialDemoGPU.cs @@ -5,16 +5,16 @@ public class OfficialDemoGPU : DemoGraph { private const string outputStream = "output_video"; - private readonly object outputImageLock = new object(); - private GpuBuffer outputImage; - private GCHandle outputVideoCallbackHandle; + private OutputStreamPoller outputStreamPoller; + private GpuBufferPacket outputPacket; private SidePacket sidePacket; public override Status StartRun() { Debug.LogWarning("This graph is for testing official examples. You can customize the graph by editing `official_demo_gpu.txt` (default is `hand_tracking_mobile.pbtxt`)"); - graph.ObserveOutputStream(outputStream, OutputVideoCallback, out outputVideoCallbackHandle).AssertOk(); + outputStreamPoller = graph.AddOutputStreamPoller(outputStream).ConsumeValueOrDie(); + outputPacket = new GpuBufferPacket(); sidePacket = new SidePacket(); sidePacket.Emplace("num_hands", new IntPacket(2)); @@ -23,58 +23,41 @@ public override Status StartRun() { } public override void RenderOutput(WebCamScreenController screenController, TextureFrame textureFrame) { - ImageFrame imageFrame = null; - - lock (outputImageLock) { - if (outputImage == null) { return; } - - var status = gpuHelper.RunInGlContext(() => { - var gpuBufferFormat = outputImage.Format(); - var sourceTexture = gpuHelper.CreateSourceTexture(outputImage); + if (!outputStreamPoller.Next(outputPacket)) { + Debug.LogWarning("Failed to fetch an output packet, rendering the input image"); + screenController.DrawScreen(textureFrame); + return; + } - imageFrame = new ImageFrame( - gpuBufferFormat.ImageFormatFor(), outputImage.Width(), outputImage.Height(), ImageFrame.kGlDefaultAlignmentBoundary); + using (var gpuBuffer = outputPacket.Get()) { + #if UNITY_ANDROID + // OpenGL ES + screenController.DrawScreen(gpuBuffer); + #else + ImageFrame imageFrame = null; - gpuHelper.BindFramebuffer(sourceTexture); - var info = gpuBufferFormat.GlTextureInfoFor(0); + gpuHelper.RunInGlContext(() => { + var gpuBufferFormat = gpuBuffer.Format(); + var sourceTexture = gpuHelper.CreateSourceTexture(gpuBuffer); - Gl.ReadPixels(0, 0, sourceTexture.width, sourceTexture.height, info.glFormat, info.glType, imageFrame.MutablePixelData()); - Gl.Flush(); + imageFrame = new ImageFrame( + gpuBufferFormat.ImageFormatFor(), gpuBuffer.Width(), gpuBuffer.Height(), ImageFrame.kGlDefaultAlignmentBoundary); - sourceTexture.Release(); + gpuHelper.BindFramebuffer(sourceTexture); + var info = gpuBufferFormat.GlTextureInfoFor(0); - return Status.Ok(false); - }); + Gl.ReadPixels(0, 0, sourceTexture.width, sourceTexture.height, info.glFormat, info.glType, imageFrame.MutablePixelData()); + Gl.Flush(); - outputImage.Dispose(); - outputImage = null; + sourceTexture.Release(); - if (!status.ok) { - Debug.LogError(status.ToString()); - return; - } - } + return Status.Ok(false); + }).AssertOk(); - if (imageFrame != null) { /// always true - screenController.DrawScreen(imageFrame); - } - } - - private Status OutputVideoCallback(GpuBufferPacket packet) { - return gpuHelper.RunInGlContext(() => { - var statusOrGpuBuffer = packet.Consume(); - - if (statusOrGpuBuffer.ok) { - lock (outputImageLock) { - if (outputImage != null) { - outputImage.Dispose(); - } - - outputImage = statusOrGpuBuffer.ConsumeValueOrDie(); + if (imageFrame != null) { // always true + screenController.DrawScreen(imageFrame); } - } - - return Status.Ok(); - }); + #endif + } } } diff --git a/Assets/MediaPipe/Examples/Scripts/WebCamScreenController.cs b/Assets/MediaPipe/Examples/Scripts/WebCamScreenController.cs index 622c5d99f..478081960 100644 --- a/Assets/MediaPipe/Examples/Scripts/WebCamScreenController.cs +++ b/Assets/MediaPipe/Examples/Scripts/WebCamScreenController.cs @@ -91,6 +91,11 @@ public void DrawScreen(ImageFrame imageFrame) { outputTexture.Apply(); } + public void DrawScreen(GpuBuffer gpuBuffer) { + // TODO: create an external texture + outputTexture.UpdateExternalTexture((IntPtr)gpuBuffer.GetGlTextureBuffer().Name()); + } + public TextureFramePool.TextureFrameRequest RequestNextFrame() { return WebCamTextureFramePool.Instance.RequestNextTextureFrame((TextureFrame textureFrame) => { textureFrame.CopyTextureFrom(webCamTexture);