Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/RTCNativeNV12Shader.mm

Issue 2202823004: iOS: Add support for rendering native CVPixelBuffers directly (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #import "RTCShader.h"
12
13 #import <CoreVideo/CVOpenGLESTextureCache.h>
14
15 #import "RTCShader+Private.h"
16 #import "WebRTC/RTCVideoFrame.h"
17
18 #include "webrtc/base/checks.h"
19
20 // Native CVPixelBufferRef rendering is only supported on iPhone because it
21 // depends on CVOpenGLESTextureCacheCreate.
22 #if TARGET_OS_IPHONE
23 static const char kNV12FragmentShaderSource[] =
24 SHADER_VERSION
25 "precision mediump float;"
26 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
27 "uniform lowp sampler2D s_textureY;\n"
28 "uniform lowp sampler2D s_textureUV;\n"
29 FRAGMENT_SHADER_OUT
30 "void main() {\n"
31 " mediump float y;\n"
32 " mediump vec2 uv;\n"
33 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
34 " uv = " FRAGMENT_SHADER_TEXTURE "(s_textureUV, v_texcoord).ra -\n"
35 " vec2(0.5, 0.5);\n"
36 " " FRAGMENT_SHADER_COLOR " = vec4(y + 1.403 * uv.y,\n"
37 " y - 0.344 * uv.x - 0.714 * uv.y,\n"
38 " y + 1.770 * uv.x,\n"
39 " 1.0);\n"
40 " }\n";
41
42 @implementation RTCNativeNV12Shader {
43 GLuint _vertexBuffer;
44 GLuint _nv12Program;
45 GLint _ySampler;
46 GLint _uvSampler;
47 CVOpenGLESTextureCacheRef _textureCache;
48 }
49
50 - (instancetype)initWithContext:(GlContextType *)context {
51 if (self = [super init]) {
52 if (![self setupNV12Program] || ![self setupTextureCacheWithContext:context] ||
53 !RTCSetupVerticesForProgram(_nv12Program, &_vertexBuffer, nullptr)) {
54 self = nil;
55 }
56 }
57 return self;
58 }
59
60 - (void)dealloc {
61 if (_nv12Program != 0) {
sakal 2016/08/03 10:52:59 These if statements are unnecessary. OpenGL silent
tkchin_webrtc 2016/08/03 17:53:19 Done.
62 glDeleteProgram(_nv12Program);
63 }
64 if (_vertexBuffer != 0) {
65 glDeleteBuffers(1, &_vertexBuffer);
66 }
67 if (_textureCache) {
68 CFRelease(_textureCache);
69 _textureCache = nullptr;
70 }
71 }
72
73 - (BOOL)setupNV12Program {
74 _nv12Program = RTCCreateProgramFromFragmentSource(kNV12FragmentShaderSource);
75 if (!_nv12Program) {
76 return NO;
77 }
78 _ySampler = glGetUniformLocation(_nv12Program, "s_textureY");
79 _uvSampler = glGetUniformLocation(_nv12Program, "s_textureUV");
80
81 return (_ySampler >= 0 && _uvSampler >= 0);
82 }
83
84 - (BOOL)setupTextureCacheWithContext:(GlContextType *)context {
85 CVReturn ret = CVOpenGLESTextureCacheCreate(
86 kCFAllocatorDefault, NULL,
87 #if COREVIDEO_USE_EAGLCONTEXT_CLASS_IN_API
88 context,
89 #else
90 (__bridge void *)context,
91 #endif
92 NULL, &_textureCache);
93 return ret == kCVReturnSuccess;
94 }
95
96 - (BOOL)drawFrame:(RTCVideoFrame *)frame {
97 CVPixelBufferRef pixelBuffer = frame.nativeHandle;
98 RTC_CHECK(pixelBuffer);
99 glUseProgram(_nv12Program);
100 const OSType pixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
101 RTC_CHECK(pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ||
102 pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
103 << "Unsupported native pixel format: " << pixelFormat;
104
105 // Y-plane.
106 const int lumaWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
107 const int lumaHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
108
109 CVOpenGLESTextureRef lumaTexture = nullptr;
110 glActiveTexture(GL_TEXTURE0);
111 glUniform1i(_ySampler, 0);
112 CVReturn ret = CVOpenGLESTextureCacheCreateTextureFromImage(
113 kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D,
114 RTC_PIXEL_FORMAT, lumaWidth, lumaHeight, RTC_PIXEL_FORMAT,
115 GL_UNSIGNED_BYTE, 0, &lumaTexture);
116 if (ret != kCVReturnSuccess) {
117 CFRelease(lumaTexture);
118 return NO;
119 }
120
121 RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
122 CVOpenGLESTextureGetTarget(lumaTexture));
123 glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(lumaTexture));
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
128
129 // UV-plane.
130 const int chromaWidth = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
131 const int chromeHeight = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
132
133 CVOpenGLESTextureRef chromaTexture = nullptr;
134 glActiveTexture(GL_TEXTURE1);
135 glUniform1i(_uvSampler, 1);
136 ret = CVOpenGLESTextureCacheCreateTextureFromImage(
137 kCFAllocatorDefault, _textureCache, pixelBuffer, NULL, GL_TEXTURE_2D,
138 GL_LUMINANCE_ALPHA, chromaWidth, chromeHeight, GL_LUMINANCE_ALPHA,
139 GL_UNSIGNED_BYTE, 1, &chromaTexture);
140 if (ret != kCVReturnSuccess) {
141 CFRelease(chromaTexture);
142 CFRelease(lumaTexture);
143 return NO;
144 }
145
146 RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
147 CVOpenGLESTextureGetTarget(chromaTexture));
148 glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chromaTexture));
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
153
154 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
155 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
156
157 CFRelease(chromaTexture);
158 CFRelease(lumaTexture);
159
160 return YES;
161 }
162
163 @end
164 #endif // TARGET_OS_IPHONE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698