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

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

Issue 2869143002: iOS: Add interface for injecting custom shaders (Closed)
Patch Set: Rebase Created 3 years, 6 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 2017 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 "RTCDefaultShader.h"
12
13 #if TARGET_OS_IPHONE
14 #import <OpenGLES/ES3/gl.h>
15 #else
16 #import <OpenGL/gl3.h>
17 #endif
18
19 #import "RTCOpenGLDefines.h"
20 #import "RTCShader.h"
21 #import "WebRTC/RTCLogging.h"
22
23 #include "webrtc/base/optional.h"
24
25 static const int kYTextureUnit = 0;
26 static const int kUTextureUnit = 1;
27 static const int kVTextureUnit = 2;
28 static const int kUvTextureUnit = 1;
29
30 // Fragment shader converts YUV values from input textures into a final RGB
31 // pixel. The conversion formula is from http://www.fourcc.org/fccyvrgb.php.
32 static const char kI420FragmentShaderSource[] =
33 SHADER_VERSION
34 "precision highp float;"
35 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
36 "uniform lowp sampler2D s_textureY;\n"
37 "uniform lowp sampler2D s_textureU;\n"
38 "uniform lowp sampler2D s_textureV;\n"
39 FRAGMENT_SHADER_OUT
40 "void main() {\n"
41 " float y, u, v, r, g, b;\n"
42 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
43 " u = " FRAGMENT_SHADER_TEXTURE "(s_textureU, v_texcoord).r;\n"
44 " v = " FRAGMENT_SHADER_TEXTURE "(s_textureV, v_texcoord).r;\n"
45 " u = u - 0.5;\n"
46 " v = v - 0.5;\n"
47 " r = y + 1.403 * v;\n"
48 " g = y - 0.344 * u - 0.714 * v;\n"
49 " b = y + 1.770 * u;\n"
50 " " FRAGMENT_SHADER_COLOR " = vec4(r, g, b, 1.0);\n"
51 " }\n";
52
53 static const char kNV12FragmentShaderSource[] =
54 SHADER_VERSION
55 "precision mediump float;"
56 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
57 "uniform lowp sampler2D s_textureY;\n"
58 "uniform lowp sampler2D s_textureUV;\n"
59 FRAGMENT_SHADER_OUT
60 "void main() {\n"
61 " mediump float y;\n"
62 " mediump vec2 uv;\n"
63 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
64 " uv = " FRAGMENT_SHADER_TEXTURE "(s_textureUV, v_texcoord).ra -\n"
65 " vec2(0.5, 0.5);\n"
66 " " FRAGMENT_SHADER_COLOR " = vec4(y + 1.403 * uv.y,\n"
67 " y - 0.344 * uv.x - 0.714 * uv.y,\n"
68 " y + 1.770 * uv.x,\n"
69 " 1.0);\n"
70 " }\n";
71
72 @implementation RTCDefaultShader {
73 GLuint _vertexBuffer;
74 GLuint _vertexArray;
75 // Store current rotation and only upload new vertex data when rotation change s.
76 rtc::Optional<RTCVideoRotation> _currentRotation;
77
78 GLuint _i420Program;
79 GLuint _nv12Program;
80 }
81
82 - (void)dealloc {
83 glDeleteProgram(_i420Program);
84 glDeleteProgram(_nv12Program);
85 glDeleteBuffers(1, &_vertexBuffer);
86 glDeleteVertexArrays(1, &_vertexArray);
87 }
88
89 - (BOOL)createAndSetupI420Program {
90 NSAssert(!_i420Program, @"I420 program already created");
91 _i420Program = RTCCreateProgramFromFragmentSource(kI420FragmentShaderSource);
92 if (!_i420Program) {
93 return NO;
94 }
95 GLint ySampler = glGetUniformLocation(_i420Program, "s_textureY");
96 GLint uSampler = glGetUniformLocation(_i420Program, "s_textureU");
97 GLint vSampler = glGetUniformLocation(_i420Program, "s_textureV");
98
99 if (ySampler < 0 || uSampler < 0 || vSampler < 0) {
100 RTCLog(@"Failed to get uniform variable locations in I420 shader");
101 glDeleteProgram(_i420Program);
102 _i420Program = 0;
103 return NO;
104 }
105
106 glUseProgram(_i420Program);
107 glUniform1i(ySampler, kYTextureUnit);
108 glUniform1i(uSampler, kUTextureUnit);
109 glUniform1i(vSampler, kVTextureUnit);
110
111 return YES;
112 }
113
114 - (BOOL)createAndSetupNV12Program {
115 NSAssert(!_nv12Program, @"NV12 program already created");
116 _nv12Program = RTCCreateProgramFromFragmentSource(kNV12FragmentShaderSource);
117 if (!_nv12Program) {
118 return NO;
119 }
120 GLint ySampler = glGetUniformLocation(_nv12Program, "s_textureY");
121 GLint uvSampler = glGetUniformLocation(_nv12Program, "s_textureUV");
122
123 if (ySampler < 0 || uvSampler < 0) {
124 RTCLog(@"Failed to get uniform variable locations in NV12 shader");
125 glDeleteProgram(_nv12Program);
126 _nv12Program = 0;
127 return NO;
128 }
129
130 glUseProgram(_nv12Program);
131 glUniform1i(ySampler, kYTextureUnit);
132 glUniform1i(uvSampler, kUvTextureUnit);
133
134 return YES;
135 }
136
137 - (BOOL)prepareVertexBufferWithRotation:(RTCVideoRotation)rotation {
138 if (!_vertexBuffer && !RTCCreateVertexBuffer(&_vertexBuffer, &_vertexArray)) {
139 RTCLog(@"Failed to setup vertex buffer");
140 return NO;
141 }
142 #if !TARGET_OS_IPHONE
143 glBindVertexArray(_vertexArray);
144 #endif
145 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
146 if (!_currentRotation || rotation != *_currentRotation) {
147 _currentRotation = rtc::Optional<RTCVideoRotation>(rotation);
148 RTCSetVertexData(*_currentRotation);
149 }
150 return YES;
151 }
152
153 - (void)applyShadingForFrameWithRotation:(RTCVideoRotation)rotation
154 yPlane:(GLuint)yPlane
155 uPlane:(GLuint)uPlane
156 vPlane:(GLuint)vPlane {
157 if (![self prepareVertexBufferWithRotation:rotation]) {
158 return;
159 }
160
161 if (!_i420Program && ![self createAndSetupI420Program]) {
162 RTCLog(@"Failed to setup I420 program");
163 return;
164 }
165
166 glUseProgram(_i420Program);
167
168 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
169 glBindTexture(GL_TEXTURE_2D, yPlane);
170
171 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUTextureUnit));
172 glBindTexture(GL_TEXTURE_2D, uPlane);
173
174 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kVTextureUnit));
175 glBindTexture(GL_TEXTURE_2D, vPlane);
176
177 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
178 }
179
180 - (void)applyShadingForFrameWithRotation:(RTCVideoRotation)rotation
181 yPlane:(GLuint)yPlane
182 uvPlane:(GLuint)uvPlane {
183 if (![self prepareVertexBufferWithRotation:rotation]) {
184 return;
185 }
186
187 if (!_nv12Program && ![self createAndSetupNV12Program]) {
188 RTCLog(@"Failed to setup NV12 shader");
189 return;
190 }
191
192 glUseProgram(_nv12Program);
193
194 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
195 glBindTexture(GL_TEXTURE_2D, yPlane);
196
197 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUvTextureUnit));
198 glBindTexture(GL_TEXTURE_2D, uvPlane);
199
200 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
201 }
202
203 @end
OLDNEW
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/Video/RTCDefaultShader.h ('k') | webrtc/sdk/objc/Framework/Classes/Video/RTCI420Shader.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698