| Index: webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm
|
| diff --git a/webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm b/webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm
|
| index 0e221bfd112606090915f69862611e8a7223f50d..c0769c05cda4f3e169bee3a29cbfd8c28ddc299f 100644
|
| --- a/webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm
|
| +++ b/webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm
|
| @@ -10,12 +10,7 @@
|
|
|
| #import "RTCShader.h"
|
|
|
| -// Native CVPixelBufferRef rendering is only supported on iPhone because it
|
| -// depends on CVOpenGLESTextureCacheCreate.
|
| -#if TARGET_OS_IPHONE
|
| -
|
| -#import <CoreVideo/CVOpenGLESTextureCache.h>
|
| -
|
| +#import "RTCNV12TextureCache.h"
|
| #import "RTCShader+Private.h"
|
| #import "WebRTC/RTCLogging.h"
|
| #import "WebRTC/RTCVideoFrame.h"
|
| @@ -47,7 +42,7 @@ static const char kNV12FragmentShaderSource[] =
|
| GLuint _nv12Program;
|
| GLint _ySampler;
|
| GLint _uvSampler;
|
| - CVOpenGLESTextureCacheRef _textureCache;
|
| + RTCNV12TextureCache *_textureCache;
|
| // Store current rotation and only upload new vertex data when rotation
|
| // changes.
|
| rtc::Optional<RTCVideoRotation> _currentRotation;
|
| @@ -55,7 +50,8 @@ static const char kNV12FragmentShaderSource[] =
|
|
|
| - (instancetype)initWithContext:(GlContextType *)context {
|
| if (self = [super init]) {
|
| - if (![self setupNV12Program] || ![self setupTextureCacheWithContext:context] ||
|
| + _textureCache = [[RTCNV12TextureCache alloc] initWithContext:context];
|
| + if (!_textureCache || ![self setupNV12Program] ||
|
| !RTCSetupVerticesForProgram(_nv12Program, &_vertexBuffer, nullptr)) {
|
| RTCLog(@"Failed to initialize RTCNativeNV12Shader.");
|
| self = nil;
|
| @@ -67,10 +63,6 @@ static const char kNV12FragmentShaderSource[] =
|
| - (void)dealloc {
|
| glDeleteProgram(_nv12Program);
|
| glDeleteBuffers(1, &_vertexBuffer);
|
| - if (_textureCache) {
|
| - CFRelease(_textureCache);
|
| - _textureCache = nullptr;
|
| - }
|
| }
|
|
|
| - (BOOL)setupNV12Program {
|
| @@ -84,75 +76,21 @@ static const char kNV12FragmentShaderSource[] =
|
| return (_ySampler >= 0 && _uvSampler >= 0);
|
| }
|
|
|
| -- (BOOL)setupTextureCacheWithContext:(GlContextType *)context {
|
| - CVReturn ret = CVOpenGLESTextureCacheCreate(
|
| - kCFAllocatorDefault, NULL,
|
| -#if COREVIDEO_USE_EAGLCONTEXT_CLASS_IN_API
|
| - context,
|
| -#else
|
| - (__bridge void *)context,
|
| -#endif
|
| - NULL, &_textureCache);
|
| - return ret == kCVReturnSuccess;
|
| -}
|
| -
|
| - (BOOL)drawFrame:(RTCVideoFrame *)frame {
|
| - CVPixelBufferRef pixelBuffer = frame.nativeHandle;
|
| - RTC_CHECK(pixelBuffer);
|
| glUseProgram(_nv12Program);
|
| - const OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
|
| - RTC_CHECK(pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ||
|
| - pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
|
| - << "Unsupported native pixel format: " << pixelFormat;
|
| + if (![_textureCache uploadFrameToTextures:frame]) {
|
| + return NO;
|
| + }
|
|
|
| // Y-plane.
|
| - const int lumaWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
|
| - const int lumaHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
|
| -
|
| - CVOpenGLESTextureRef lumaTexture = nullptr;
|
| glActiveTexture(GL_TEXTURE0);
|
| glUniform1i(_ySampler, 0);
|
| - CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(
|
| - kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D,
|
| - RTC_PIXEL_FORMAT, lumaWidth, lumaHeight, RTC_PIXEL_FORMAT,
|
| - GL_UNSIGNED_BYTE, 0, &lumaTexture);
|
| - if (ret != kCVReturnSuccess) {
|
| - CFRelease(lumaTexture);
|
| - return NO;
|
| - }
|
| -
|
| - RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
|
| - CVOpenGLESTextureGetTarget(lumaTexture));
|
| - glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(lumaTexture));
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + glBindTexture(GL_TEXTURE_2D, _textureCache.yTexture);
|
|
|
| // UV-plane.
|
| - const int chromaWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
|
| - const int chromeHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
|
| -
|
| - CVOpenGLESTextureRef chromaTexture = nullptr;
|
| glActiveTexture(GL_TEXTURE1);
|
| glUniform1i(_uvSampler, 1);
|
| - ret = CVOpenGLESTextureCacheCreateTextureFromImage(
|
| - kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D,
|
| - GL_LUMINANCE_ALPHA, chromaWidth, chromeHeight, GL_LUMINANCE_ALPHA,
|
| - GL_UNSIGNED_BYTE, 1, &chromaTexture);
|
| - if (ret != kCVReturnSuccess) {
|
| - CFRelease(chromaTexture);
|
| - CFRelease(lumaTexture);
|
| - return NO;
|
| - }
|
| -
|
| - RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
|
| - CVOpenGLESTextureGetTarget(chromaTexture));
|
| - glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chromaTexture));
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
| + glBindTexture(GL_TEXTURE_2D, _textureCache.uvTexture);
|
|
|
| glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
|
| if (!_currentRotation || frame.rotation != *_currentRotation) {
|
| @@ -161,11 +99,9 @@ static const char kNV12FragmentShaderSource[] =
|
| }
|
| glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
| - CFRelease(chromaTexture);
|
| - CFRelease(lumaTexture);
|
| + [_textureCache releaseTextures];
|
|
|
| return YES;
|
| }
|
|
|
| @end
|
| -#endif // TARGET_OS_IPHONE
|
|
|