OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #import "RTCShader.h" | 11 #import "RTCShader.h" |
12 | 12 |
13 // Native CVPixelBufferRef rendering is only supported on iPhone because it | 13 // Native CVPixelBufferRef rendering is only supported on iPhone because it |
14 // depends on CVOpenGLESTextureCacheCreate. | 14 // depends on CVOpenGLESTextureCacheCreate. |
15 #if TARGET_OS_IPHONE | 15 #if TARGET_OS_IPHONE |
16 | 16 |
17 #import <CoreVideo/CVOpenGLESTextureCache.h> | 17 #import <CoreVideo/CVOpenGLESTextureCache.h> |
18 | 18 |
19 #import "RTCShader+Private.h" | 19 #import "RTCShader+Private.h" |
20 #import "WebRTC/RTCVideoFrame.h" | 20 #import "WebRTC/RTCVideoFrame.h" |
21 | 21 |
22 #include "webrtc/base/checks.h" | 22 #include "webrtc/base/checks.h" |
| 23 #include "webrtc/base/optional.h" |
| 24 #include "webrtc/common_video/rotation.h" |
23 | 25 |
24 static const char kNV12FragmentShaderSource[] = | 26 static const char kNV12FragmentShaderSource[] = |
25 SHADER_VERSION | 27 SHADER_VERSION |
26 "precision mediump float;" | 28 "precision mediump float;" |
27 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n" | 29 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n" |
28 "uniform lowp sampler2D s_textureY;\n" | 30 "uniform lowp sampler2D s_textureY;\n" |
29 "uniform lowp sampler2D s_textureUV;\n" | 31 "uniform lowp sampler2D s_textureUV;\n" |
30 FRAGMENT_SHADER_OUT | 32 FRAGMENT_SHADER_OUT |
31 "void main() {\n" | 33 "void main() {\n" |
32 " mediump float y;\n" | 34 " mediump float y;\n" |
33 " mediump vec2 uv;\n" | 35 " mediump vec2 uv;\n" |
34 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n" | 36 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n" |
35 " uv = " FRAGMENT_SHADER_TEXTURE "(s_textureUV, v_texcoord).ra -\n" | 37 " uv = " FRAGMENT_SHADER_TEXTURE "(s_textureUV, v_texcoord).ra -\n" |
36 " vec2(0.5, 0.5);\n" | 38 " vec2(0.5, 0.5);\n" |
37 " " FRAGMENT_SHADER_COLOR " = vec4(y + 1.403 * uv.y,\n" | 39 " " FRAGMENT_SHADER_COLOR " = vec4(y + 1.403 * uv.y,\n" |
38 " y - 0.344 * uv.x - 0.714 * uv.y,\n" | 40 " y - 0.344 * uv.x - 0.714 * uv.y,\n" |
39 " y + 1.770 * uv.x,\n" | 41 " y + 1.770 * uv.x,\n" |
40 " 1.0);\n" | 42 " 1.0);\n" |
41 " }\n"; | 43 " }\n"; |
42 | 44 |
43 @implementation RTCNativeNV12Shader { | 45 @implementation RTCNativeNV12Shader { |
44 GLuint _vertexBuffer; | 46 GLuint _vertexBuffer; |
45 GLuint _nv12Program; | 47 GLuint _nv12Program; |
46 GLint _ySampler; | 48 GLint _ySampler; |
47 GLint _uvSampler; | 49 GLint _uvSampler; |
48 CVOpenGLESTextureCacheRef _textureCache; | 50 CVOpenGLESTextureCacheRef _textureCache; |
| 51 // Store current rotation and only upload new vertex data when rotation |
| 52 // changes. |
| 53 rtc::Optional<webrtc::VideoRotation> _currentRotation; |
49 } | 54 } |
50 | 55 |
51 - (instancetype)initWithContext:(GlContextType *)context { | 56 - (instancetype)initWithContext:(GlContextType *)context { |
52 if (self = [super init]) { | 57 if (self = [super init]) { |
53 if (![self setupNV12Program] || ![self setupTextureCacheWithContext:context]
|| | 58 if (![self setupNV12Program] || ![self setupTextureCacheWithContext:context]
|| |
54 !RTCSetupVerticesForProgram(_nv12Program, &_vertexBuffer, nullptr)) { | 59 !RTCSetupVerticesForProgram(_nv12Program, &_vertexBuffer, nullptr)) { |
55 self = nil; | 60 self = nil; |
56 } | 61 } |
57 } | 62 } |
58 return self; | 63 return self; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 147 |
143 RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), | 148 RTC_CHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), |
144 CVOpenGLESTextureGetTarget(chromaTexture)); | 149 CVOpenGLESTextureGetTarget(chromaTexture)); |
145 glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chromaTexture)); | 150 glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(chromaTexture)); |
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 153 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 154 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
150 | 155 |
151 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); | 156 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); |
| 157 if (!_currentRotation || frame.rotation != *_currentRotation) { |
| 158 _currentRotation = rtc::Optional<webrtc::VideoRotation>( |
| 159 static_cast<webrtc::VideoRotation>(frame.rotation)); |
| 160 RTCSetVertexData(*_currentRotation); |
| 161 } |
152 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 162 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
153 | 163 |
154 CFRelease(chromaTexture); | 164 CFRelease(chromaTexture); |
155 CFRelease(lumaTexture); | 165 CFRelease(lumaTexture); |
156 | 166 |
157 return YES; | 167 return YES; |
158 } | 168 } |
159 | 169 |
160 @end | 170 @end |
161 #endif // TARGET_OS_IPHONE | 171 #endif // TARGET_OS_IPHONE |
OLD | NEW |