public virtual CVOpenGLESTexture LumaTextureForPixelBuffer(CVPixelBuffer pixelBuffer) { CVOpenGLESTexture lumaTexture = null; if (_videoTextureCache == null) { Console.Error.WriteLine("No video texture cache"); goto bail; } // Periodic texture cache flush every frame _videoTextureCache.Flush(0); // CVOpenGLTextureCacheCreateTextureFromImage will create GL texture optimally from CVPixelBufferRef. // Y lumaTexture = _videoTextureCache.TextureFromImage(pixelBuffer, true, All.RedExt, (int)pixelBuffer.Width, (int)pixelBuffer.Height, All.RedExt, DataType.UnsignedByte, 0, out CVReturn error); if (lumaTexture == null || error != CVReturn.Success) { Console.Error.WriteLine($"Error at creating luma texture using CVOpenGLESTextureCacheCreateTextureFromImage: {error}"); } bail: return(lumaTexture); }
public virtual CVOpenGLESTexture ChromaTextureForPixelBuffer(CVPixelBuffer pixelBuffer) { CVOpenGLESTexture chromaTexture = null; CVReturn err; if (VideoTextureCache == null) { Console.Error.WriteLine("No video texture cache"); return(chromaTexture); } // Periodic texture cache flush every frame VideoTextureCache.Flush(0); // CVOpenGLTextureCacheCreateTextureFromImage will create GL texture optimally from CVPixelBufferRef. // UV var height = pixelBuffer.GetHeightOfPlane(1); var width = pixelBuffer.GetWidthOfPlane(1); chromaTexture = VideoTextureCache.TextureFromImage(pixelBuffer, true, All.RgExt, width, height, All.RgExt, DataType.UnsignedByte, 1, out err); if (chromaTexture == null || err != CVReturn.Success) { Console.Error.WriteLine("Error at creating chroma texture using CVOpenGLESTextureCacheCreateTextureFromImage: " + err.ToString()); } return(chromaTexture); }
virtual void Dispose(bool disposing) { if (handle != IntPtr.Zero) { CVOpenGLESTexture.CFRelease(handle); handle = IntPtr.Zero; } }
public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection) { try { using (var pixelBuffer = sampleBuffer.GetImageBuffer() as CVPixelBuffer) { int width = (int)pixelBuffer.Width; int height = (int)pixelBuffer.Height; if (this.viewControllerReference.TryGetTarget(out var container)) { if (container.Ripple == null || width != this.textureWidth || height != this.textureHeight) { this.textureWidth = width; this.textureHeight = height; container.SetupRipple(this.textureWidth, this.textureHeight); } this.CleanupTextures(); // Y-plane GL.ActiveTexture(TextureUnit.Texture0); All re = (All)0x1903; // GL_RED_EXT, RED component from ARB OpenGL extension this.lumaTexture = container.VideoTextureCache.TextureFromImage(pixelBuffer, true, re, this.textureWidth, this.textureHeight, re, DataType.UnsignedByte, 0, out CVReturn status); if (this.lumaTexture == null) { Console.WriteLine("Error creating luma texture: {0}", status); return; } GL.BindTexture(this.lumaTexture.Target, this.lumaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); // UV Plane GL.ActiveTexture(TextureUnit.Texture1); re = (All)0x8227; // GL_RG_EXT, RED GREEN component from ARB OpenGL extension this.chromaTexture = container.VideoTextureCache.TextureFromImage(pixelBuffer, true, re, this.textureWidth / 2, this.textureHeight / 2, re, DataType.UnsignedByte, 1, out status); if (this.chromaTexture == null) { Console.WriteLine("Error creating chroma texture: {0}", status); return; } GL.BindTexture(this.chromaTexture.Target, this.chromaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); } } } finally { sampleBuffer.Dispose(); } }
void CleanUpTextures() { if (lumaTexture != null) { lumaTexture.Dispose(); lumaTexture = null; } if (chromaTexture != null) { chromaTexture.Dispose(); chromaTexture = null; } }
public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, MonoTouch.CoreMedia.CMSampleBuffer sampleBuffer, AVCaptureConnection connection) { try { using (var pixelBuffer = sampleBuffer.GetImageBuffer() as CVPixelBuffer){ int width = pixelBuffer.Width; int height = pixelBuffer.Height; if (container.ripple == null || width != textureWidth || height != textureHeight) { textureWidth = width; textureHeight = height; container.SetupRipple(textureWidth, textureHeight); } CleanupTextures(); // Y-plane GL.ActiveTexture(All.Texture0); All re = (All)0x1903; // GL_RED_EXT, RED component from ARB OpenGL extension CVReturn status; lumaTexture = container.videoTextureCache.TextureFromImage(pixelBuffer, true, re, textureWidth, textureHeight, re, DataType.UnsignedByte, 0, out status); if (lumaTexture == null) { Console.WriteLine("Error creating luma texture: {0}", status); return; } GL.BindTexture((All)lumaTexture.Target, lumaTexture.Name); GL.TexParameter(All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge); // UV Plane GL.ActiveTexture(All.Texture1); re = (All)0x8227; // GL_RG_EXT, RED GREEN component from ARB OpenGL extension chromaTexture = container.videoTextureCache.TextureFromImage(pixelBuffer, true, re, textureWidth / 2, textureHeight / 2, re, DataType.UnsignedByte, 1, out status); if (chromaTexture == null) { Console.WriteLine("Error creating chroma texture: {0}", status); return; } GL.BindTexture((All)chromaTexture.Target, chromaTexture.Name); GL.TexParameter(All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge); } } finally { sampleBuffer.Dispose(); } }
private void CleanupTextures() { if (this.lumaTexture != null) { this.lumaTexture.Dispose(); this.lumaTexture = null; } if (this.chromaTexture != null) { this.chromaTexture.Dispose(); this.chromaTexture = null; } if (this.viewControllerReference.TryGetTarget(out var container)) { container.VideoTextureCache.Flush(CVOptionFlags.None); } }
void CleanUpTextures () { if (lumaTexture != null) { lumaTexture.Dispose (); lumaTexture = null; } if (chromaTexture != null) { chromaTexture.Dispose (); chromaTexture = null; } }
public void DisplayPixelBuffer (CVPixelBuffer pixelBuffer) { DrawTextInCorner (pixelBuffer); CVReturn error; if (pixelBuffer != null) { int frameWidth = (int)pixelBuffer.Width; int frameHeight = (int)pixelBuffer.Height; if (videoTextureCache == null) { Console.WriteLine ("No video texture cache"); return; } CleanUpTextures (); CVAttachmentMode attachmentMode; var colorAttachments = pixelBuffer.GetAttachment <NSString> (CVImageBuffer.YCbCrMatrixKey, out attachmentMode); if (colorAttachments == CVImageBuffer.YCbCrMatrix_ITU_R_601_4) preferredConversion = colorConversion601; else preferredConversion = colorConversion709; GL.ActiveTexture (TextureUnit.Texture0); lumaTexture = videoTextureCache.TextureFromImage (pixelBuffer, true, All.RedExt, frameWidth, frameHeight, All.RedExt, DataType.UnsignedByte, 0, out error); if (lumaTexture == null) Console.WriteLine ("Error at CVOpenGLESTextureCach.TextureFromImage"); GL.BindTexture (lumaTexture.Target, lumaTexture.Name); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.ActiveTexture (TextureUnit.Texture1); chromaTexture = videoTextureCache.TextureFromImage (pixelBuffer, true, All.RgExt, frameWidth / 2, frameHeight / 2, All.RgExt, DataType.UnsignedByte, 1, out error); if (chromaTexture == null) Console.WriteLine ("Error at CVOpenGLESTextureCach.TextureFromImage"); GL.BindTexture (chromaTexture.Target, chromaTexture.Name); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.BindFramebuffer (FramebufferTarget.Framebuffer, frameBufferHandle); GL.Viewport (0, 0, backingWidth, backingHeight); } GL.ClearColor (0f, 0f, 0f, 1f); GL.Clear (ClearBufferMask.ColorBufferBit); GL.UseProgram (Program); GL.Uniform1 (uniforms [(int)UniformIndex.RotationAngle], 0f); GL.UniformMatrix3 (uniforms [(int)UniformIndex.ColorConversionMatrix], 1, false, preferredConversion); CGRect vertexSamplingRect = AVUtilities.WithAspectRatio (Bounds, PresentationRect); var normalizedSamplingSize = new CGSize (0f, 0f); var cropScaleAmount = new CGSize (vertexSamplingRect.Width / Bounds.Width, vertexSamplingRect.Height / Bounds.Height); if (cropScaleAmount.Width > cropScaleAmount.Height) { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Height / cropScaleAmount.Width; } else { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Width / cropScaleAmount.Height; } float[] quadVertexData = { -1f * (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, -1f * (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, }; GL.VertexAttribPointer ((int)AttributeIndex.Vertex, 2, VertexAttribPointerType.Float, false, 0, quadVertexData); GL.EnableVertexAttribArray ((int)AttributeIndex.Vertex); var textureSamplingRect = new CGRect (0, 0, 1, 1); float[] quadTextureData = { (float)textureSamplingRect.GetMinX (), (float)textureSamplingRect.GetMaxY (), (float)textureSamplingRect.GetMaxX (), (float)textureSamplingRect.GetMaxY (), (float)textureSamplingRect.GetMinX (), (float)textureSamplingRect.GetMinY (), (float)textureSamplingRect.GetMaxX (), (float)textureSamplingRect.GetMinY () }; GL.VertexAttribPointer ((int)AttributeIndex.TextureCoordinates, 2, VertexAttribPointerType.Float, false, 0, quadTextureData); GL.EnableVertexAttribArray ((int)AttributeIndex.TextureCoordinates); GL.DrawArrays (BeginMode.TriangleStrip, 0, 4); GL.BindRenderbuffer (RenderbufferTarget.Renderbuffer, colorBufferHandle); context.PresentRenderBuffer ((int)RenderbufferTarget.Renderbuffer); }
public void DisplayPixelBuffer(CVPixelBuffer pixelBuffer) { DrawTextInCorner(pixelBuffer); CVReturn error; if (pixelBuffer != null) { int frameWidth = (int)pixelBuffer.Width; int frameHeight = (int)pixelBuffer.Height; if (videoTextureCache == null) { Console.WriteLine("No video texture cache"); return; } CleanUpTextures(); CVAttachmentMode attachmentMode; var colorAttachments = pixelBuffer.GetAttachment <NSString> (CVImageBuffer.YCbCrMatrixKey, out attachmentMode); if (colorAttachments == CVImageBuffer.YCbCrMatrix_ITU_R_601_4) { preferredConversion = colorConversion601; } else { preferredConversion = colorConversion709; } GL.ActiveTexture(TextureUnit.Texture0); lumaTexture = videoTextureCache.TextureFromImage(pixelBuffer, true, All.RedExt, frameWidth, frameHeight, All.RedExt, DataType.UnsignedByte, 0, out error); if (lumaTexture == null) { Console.WriteLine("Error at CVOpenGLESTextureCach.TextureFromImage"); } GL.BindTexture(lumaTexture.Target, lumaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.ActiveTexture(TextureUnit.Texture1); chromaTexture = videoTextureCache.TextureFromImage(pixelBuffer, true, All.RgExt, frameWidth / 2, frameHeight / 2, All.RgExt, DataType.UnsignedByte, 1, out error); if (chromaTexture == null) { Console.WriteLine("Error at CVOpenGLESTextureCach.TextureFromImage"); } GL.BindTexture(chromaTexture.Target, chromaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.BindFramebuffer(FramebufferTarget.Framebuffer, frameBufferHandle); GL.Viewport(0, 0, backingWidth, backingHeight); } GL.ClearColor(0f, 0f, 0f, 1f); GL.Clear(ClearBufferMask.ColorBufferBit); GL.UseProgram(Program); GL.Uniform1(uniforms [(int)UniformIndex.RotationAngle], 0f); GL.UniformMatrix3(uniforms [(int)UniformIndex.ColorConversionMatrix], 1, false, preferredConversion); CGRect vertexSamplingRect = AVUtilities.WithAspectRatio(Bounds, PresentationRect); var normalizedSamplingSize = new CGSize(0f, 0f); var cropScaleAmount = new CGSize(vertexSamplingRect.Width / Bounds.Width, vertexSamplingRect.Height / Bounds.Height); if (cropScaleAmount.Width > cropScaleAmount.Height) { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Height / cropScaleAmount.Width; } else { normalizedSamplingSize.Width = 1f; normalizedSamplingSize.Height = cropScaleAmount.Width / cropScaleAmount.Height; } float[] quadVertexData = { -1f * (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, -1f * (float)normalizedSamplingSize.Height, -1f * (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, (float)normalizedSamplingSize.Width, (float)normalizedSamplingSize.Height, }; GL.VertexAttribPointer((int)AttributeIndex.Vertex, 2, VertexAttribPointerType.Float, false, 0, quadVertexData); GL.EnableVertexAttribArray((int)AttributeIndex.Vertex); var textureSamplingRect = new CGRect(0, 0, 1, 1); float[] quadTextureData = { (float)textureSamplingRect.GetMinX(), (float)textureSamplingRect.GetMaxY(), (float)textureSamplingRect.GetMaxX(), (float)textureSamplingRect.GetMaxY(), (float)textureSamplingRect.GetMinX(), (float)textureSamplingRect.GetMinY(), (float)textureSamplingRect.GetMaxX(), (float)textureSamplingRect.GetMinY() }; GL.VertexAttribPointer((int)AttributeIndex.TextureCoordinates, 2, VertexAttribPointerType.Float, false, 0, quadTextureData); GL.EnableVertexAttribArray((int)AttributeIndex.TextureCoordinates); GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, colorBufferHandle); context.PresentRenderBuffer((int)RenderbufferTarget.Renderbuffer); }
public override void RenderPixelBuffer(MonoTouch.CoreVideo.CVPixelBuffer destinationPixelBuffer, MonoTouch.CoreVideo.CVPixelBuffer foregroundPixelBuffer, MonoTouch.CoreVideo.CVPixelBuffer backgroundPixelBuffer, float tween) { EAGLContext.SetCurrentContext(CurrentContext); if (foregroundPixelBuffer != null || backgroundPixelBuffer != null) { CVOpenGLESTexture foregroundLumaTexture = LumaTextureForPixelBuffer(foregroundPixelBuffer); CVOpenGLESTexture foregroundChromaTexture = ChromaTextureForPixelBuffer(foregroundPixelBuffer); CVOpenGLESTexture backgroundLumaTexture = LumaTextureForPixelBuffer(backgroundPixelBuffer); CVOpenGLESTexture backgroundChromaTexture = ChromaTextureForPixelBuffer(backgroundPixelBuffer); CVOpenGLESTexture destLumaTexture = LumaTextureForPixelBuffer(destinationPixelBuffer); CVOpenGLESTexture destChromaTexture = ChromaTextureForPixelBuffer(destinationPixelBuffer); GL.UseProgram(ProgramY); // Set the render transform float[] preferredRenderTransform = { RenderTransform.xx, RenderTransform.xy, RenderTransform.x0, 0.0f, RenderTransform.yx, RenderTransform.yy, RenderTransform.y0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; GL.UniformMatrix4(Uniforms [(int)Uniform.Render_Transform_Y], 1, false, preferredRenderTransform); GL.BindFramebuffer(FramebufferTarget.Framebuffer, OffscreenBufferHandle); GL.Viewport(0, 0, destinationPixelBuffer.Width, destinationPixelBuffer.Height); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(foregroundLumaTexture.Target, foregroundLumaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.ActiveTexture(TextureUnit.Texture1); GL.BindTexture(backgroundLumaTexture.Target, backgroundLumaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); // Attach the destination texture as a color attachment to the off screen frame buffer GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, destLumaTexture.Target, destLumaTexture.Name, 0); if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) { Console.Error.WriteLine("Failed to make complete framebuffer object " + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)); foregroundLumaTexture.Dispose(); foregroundChromaTexture.Dispose(); backgroundLumaTexture.Dispose(); backgroundChromaTexture.Dispose(); destLumaTexture.Dispose(); destChromaTexture.Dispose(); VideoTextureCache.Flush(0); EAGLContext.SetCurrentContext(null); return; } GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); float[] quadVertexData1 = { -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, }; // texture data varies from 0 -> 1, whereas vertex data varies from -1 -> 1 float[] quadTextureData1 = { 0.5f + quadVertexData1 [0] / 2, 0.5f + quadVertexData1 [1] / 2, 0.5f + quadVertexData1 [2] / 2, 0.5f + quadVertexData1 [3] / 2, 0.5f + quadVertexData1 [4] / 2, 0.5f + quadVertexData1 [5] / 2, 0.5f + quadVertexData1 [6] / 2, 0.5f + quadVertexData1 [7] / 2, }; GL.Uniform1(Uniforms [(int)Uniform.Y], 0); GL.VertexAttribPointer((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1); GL.EnableVertexAttribArray((int)Attrib.Vertex_Y); GL.VertexAttribPointer((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1); GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y); // Blend function to draw the foreground frame GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); // Draw the foreground frame GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.Uniform1(Uniforms [(int)Uniform.Y], 1); GL.VertexAttribPointer((int)Attrib.Vertex_Y, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1); GL.EnableVertexAttribArray((int)Attrib.Vertex_Y); GL.VertexAttribPointer((int)Attrib.TexCoord_Y, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1); GL.EnableVertexAttribArray((int)Attrib.TexCoord_Y); // Blend function to draw the background frame GL.BlendColor(0, 0, 0, tween); GL.BlendFunc(BlendingFactorSrc.ConstantAlpha, BlendingFactorDest.OneMinusConstantAlpha); // Draw the background frame GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); // Perform similar operations as above for the UV plane GL.UseProgram(ProgramUV); GL.UniformMatrix4(Uniforms [(int)Uniform.Render_Transform_UV], 1, false, preferredRenderTransform); GL.ActiveTexture(TextureUnit.Texture2); GL.BindTexture(foregroundChromaTexture.Target, foregroundChromaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.ActiveTexture(TextureUnit.Texture3); GL.BindTexture(backgroundChromaTexture.Target, backgroundChromaTexture.Name); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)All.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)All.ClampToEdge); GL.Viewport(0, 0, destinationPixelBuffer.Width, destinationPixelBuffer.Height); // Attach the destination texture as a color attachment to the off screen frame buffer GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferSlot.ColorAttachment0, destChromaTexture.Target, destChromaTexture.Name, 0); if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete) { Console.Error.WriteLine("Failed to make complete framebuffer object " + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer)); foregroundLumaTexture.Dispose(); foregroundChromaTexture.Dispose(); backgroundLumaTexture.Dispose(); backgroundChromaTexture.Dispose(); destLumaTexture.Dispose(); destChromaTexture.Dispose(); this.VideoTextureCache.Flush(0); EAGLContext.SetCurrentContext(null); return; } GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); GL.Uniform1(Uniforms [(int)Uniform.UV], 2); GL.VertexAttribPointer((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1); GL.EnableVertexAttribArray((int)Attrib.Vertex_UV); GL.VertexAttribPointer((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1); GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV); // Blend function to draw the foreground frame GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); // Draw the foreground frame GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.Uniform1(Uniforms [(int)Uniform.UV], 3); GL.VertexAttribPointer((int)Attrib.Vertex_UV, 2, VertexAttribPointerType.Float, false, 0, quadVertexData1); GL.EnableVertexAttribArray((int)Attrib.Vertex_UV); GL.VertexAttribPointer((int)Attrib.TexCoord_UV, 2, VertexAttribPointerType.Float, false, 0, quadTextureData1); GL.EnableVertexAttribArray((int)Attrib.TexCoord_UV); // Blend function to draw the background frame GL.BlendColor(0, 0, 0, tween); GL.BlendFunc(BlendingFactorSrc.ConstantAlpha, BlendingFactorDest.OneMinusConstantAlpha); // Draw the background frame GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.Flush(); foregroundLumaTexture.Dispose(); foregroundChromaTexture.Dispose(); backgroundLumaTexture.Dispose(); backgroundChromaTexture.Dispose(); destLumaTexture.Dispose(); destChromaTexture.Dispose(); this.VideoTextureCache.Flush(0); EAGLContext.SetCurrentContext(null); } }
public override void DidOutputSampleBuffer (AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection) { try { using (var pixelBuffer = sampleBuffer.GetImageBuffer () as CVPixelBuffer){ int width = (int) pixelBuffer.Width; int height = (int) pixelBuffer.Height; if (container.ripple == null || width != textureWidth || height != textureHeight){ textureWidth = width; textureHeight = height; container.SetupRipple (textureWidth, textureHeight); } CleanupTextures (); // Y-plane GL.ActiveTexture(TextureUnit.Texture0); All re = (All) 0x1903; // GL_RED_EXT, RED component from ARB OpenGL extension CVReturn status; lumaTexture = container.videoTextureCache.TextureFromImage (pixelBuffer, true, re, textureWidth, textureHeight, re, DataType.UnsignedByte, 0, out status); if (lumaTexture == null){ Console.WriteLine ("Error creating luma texture: {0}", status); return; } GL.BindTexture (lumaTexture.Target, lumaTexture.Name); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) All.ClampToEdge); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) All.ClampToEdge); // UV Plane GL.ActiveTexture (TextureUnit.Texture1); re = (All) 0x8227; // GL_RG_EXT, RED GREEN component from ARB OpenGL extension chromaTexture = container.videoTextureCache.TextureFromImage (pixelBuffer, true, re, textureWidth/2, textureHeight/2, re, DataType.UnsignedByte, 1, out status); if (chromaTexture == null){ Console.WriteLine ("Error creating chroma texture: {0}", status); return; } GL.BindTexture (chromaTexture.Target, chromaTexture.Name); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) All.ClampToEdge); GL.TexParameter (TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) All.ClampToEdge); } } finally { sampleBuffer.Dispose (); } }