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

Unified Diff: webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.mm

Issue 2842453002: ObjC: Split out I420 texture uploading into separate class (Closed)
Patch Set: Make uploadFrameToTextures return void Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.mm
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCI420Shader.mm b/webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.mm
similarity index 50%
copy from webrtc/sdk/objc/Framework/Classes/RTCI420Shader.mm
copy to webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.mm
index 3c3ffa72f003c5a9267584bed12cb85f718b34b8..d263c75e939713e0ffbd41d1924fbf6087a18976 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCI420Shader.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.mm
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ * Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
@@ -8,66 +8,40 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#import "RTCShader.h"
-
-#include <vector>
+#import "RTCI420TextureCache.h"
#import "RTCShader+Private.h"
-#import "WebRTC/RTCLogging.h"
-#import "WebRTC/RTCVideoFrame.h"
-#include "webrtc/base/optional.h"
+#include <vector>
-// |kNumTextures| must not exceed 8, which is the limit in OpenGLES2. Two sets
-// of 3 textures are used here, one for each of the Y, U and V planes. Having
-// two sets alleviates CPU blockage in the event that the GPU is asked to render
-// to a texture that is already in use.
+// Two sets of 3 textures are used here, one for each of the Y, U and V planes. Having two sets
+// alleviates CPU blockage in the event that the GPU is asked to render to a texture that is already
+// in use.
static const GLsizei kNumTextureSets = 2;
static const GLsizei kNumTexturesPerSet = 3;
static const GLsizei kNumTextures = kNumTexturesPerSet * kNumTextureSets;
-// Fragment shader converts YUV values from input textures into a final RGB
-// pixel. The conversion formula is from http://www.fourcc.org/fccyvrgb.php.
-static const char kI420FragmentShaderSource[] =
- SHADER_VERSION
- "precision highp float;"
- FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
- "uniform lowp sampler2D s_textureY;\n"
- "uniform lowp sampler2D s_textureU;\n"
- "uniform lowp sampler2D s_textureV;\n"
- FRAGMENT_SHADER_OUT
- "void main() {\n"
- " float y, u, v, r, g, b;\n"
- " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
- " u = " FRAGMENT_SHADER_TEXTURE "(s_textureU, v_texcoord).r;\n"
- " v = " FRAGMENT_SHADER_TEXTURE "(s_textureV, v_texcoord).r;\n"
- " u = u - 0.5;\n"
- " v = v - 0.5;\n"
- " r = y + 1.403 * v;\n"
- " g = y - 0.344 * u - 0.714 * v;\n"
- " b = y + 1.770 * u;\n"
- " " FRAGMENT_SHADER_COLOR " = vec4(r, g, b, 1.0);\n"
- " }\n";
-
-@implementation RTCI420Shader {
+@implementation RTCI420TextureCache {
BOOL _hasUnpackRowLength;
GLint _currentTextureSet;
// Handles for OpenGL constructs.
GLuint _textures[kNumTextures];
- GLuint _i420Program;
- GLuint _vertexArray;
- GLuint _vertexBuffer;
- GLint _ySampler;
- GLint _uSampler;
- GLint _vSampler;
- // Store current rotation and only upload new vertex data when rotation
- // changes.
- rtc::Optional<RTCVideoRotation> _currentRotation;
- // Used to create a non-padded plane for GPU upload when we receive padded
- // frames.
+ // Used to create a non-padded plane for GPU upload when we receive padded frames.
std::vector<uint8_t> _planeBuffer;
}
+- (GLuint)yTexture {
+ return _textures[_currentTextureSet * kNumTexturesPerSet];
+}
+
+- (GLuint)uTexture {
+ return _textures[_currentTextureSet * kNumTexturesPerSet + 1];
+}
+
+- (GLuint)vTexture {
+ return _textures[_currentTextureSet * kNumTexturesPerSet + 2];
+}
+
- (instancetype)initWithContext:(GlContextType *)context {
if (self = [super init]) {
#if TARGET_OS_IPHONE
@@ -76,35 +50,17 @@ static const char kI420FragmentShaderSource[] =
_hasUnpackRowLength = YES;
#endif
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- if (![self setupI420Program] || ![self setupTextures] ||
- !RTCSetupVerticesForProgram(_i420Program, &_vertexBuffer, &_vertexArray)) {
- RTCLog(@"Failed to initialize RTCI420Shader.");
- self = nil;
- }
+
+ [self setupTextures];
}
return self;
}
- (void)dealloc {
- glDeleteProgram(_i420Program);
glDeleteTextures(kNumTextures, _textures);
- glDeleteBuffers(1, &_vertexBuffer);
- glDeleteVertexArrays(1, &_vertexArray);
-}
-
-- (BOOL)setupI420Program {
- _i420Program = RTCCreateProgramFromFragmentSource(kI420FragmentShaderSource);
- if (!_i420Program) {
- return NO;
- }
- _ySampler = glGetUniformLocation(_i420Program, "s_textureY");
- _uSampler = glGetUniformLocation(_i420Program, "s_textureU");
- _vSampler = glGetUniformLocation(_i420Program, "s_textureV");
-
- return (_ySampler >= 0 && _uSampler >= 0 && _vSampler >= 0);
}
-- (BOOL)setupTextures {
+- (void)setupTextures {
glGenTextures(kNumTextures, _textures);
// Set parameters for each of the textures we created.
for (GLsizei i = 0; i < kNumTextures; i++) {
@@ -114,39 +70,15 @@ static const char kI420FragmentShaderSource[] =
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
- return YES;
-}
-
-- (BOOL)drawFrame:(RTCVideoFrame*)frame {
- glUseProgram(_i420Program);
- if (![self updateTextureDataForFrame:frame]) {
- return NO;
- }
-#if !TARGET_OS_IPHONE
- glBindVertexArray(_vertexArray);
-#endif
- glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
- if (!_currentRotation || frame.rotation != *_currentRotation) {
- _currentRotation = rtc::Optional<RTCVideoRotation>(frame.rotation);
- RTCSetVertexData(*_currentRotation);
- }
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- return YES;
}
- (void)uploadPlane:(const uint8_t *)plane
- sampler:(GLint)sampler
- offset:(GLint)offset
+ texture:(GLuint)texture
width:(size_t)width
height:(size_t)height
stride:(int32_t)stride {
- glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + offset));
- glBindTexture(GL_TEXTURE_2D, _textures[offset]);
+ glBindTexture(GL_TEXTURE_2D, texture);
- // When setting texture sampler uniforms, the texture index is used not
- // the texture handle.
- glUniform1i(sampler, offset);
const uint8_t *uploadPlane = plane;
if ((size_t)stride != width) {
if (_hasUnpackRowLength) {
@@ -184,9 +116,8 @@ static const char kI420FragmentShaderSource[] =
uploadPlane);
}
-- (BOOL)updateTextureDataForFrame:(RTCVideoFrame *)frame {
- GLint textureOffset = _currentTextureSet * 3;
- NSAssert(textureOffset + 3 <= kNumTextures, @"invalid offset");
+- (void)uploadFrameToTextures:(RTCVideoFrame *)frame {
+ _currentTextureSet = (_currentTextureSet + 1) % kNumTextureSets;
const int chromaWidth = (frame.width + 1) / 2;
const int chromaHeight = (frame.height + 1) / 2;
@@ -197,28 +128,22 @@ static const char kI420FragmentShaderSource[] =
}
[self uploadPlane:frame.dataY
- sampler:_ySampler
- offset:textureOffset
+ texture:self.yTexture
width:frame.width
height:frame.height
stride:frame.strideY];
[self uploadPlane:frame.dataU
- sampler:_uSampler
- offset:textureOffset + 1
+ texture:self.uTexture
width:chromaWidth
height:chromaHeight
stride:frame.strideU];
[self uploadPlane:frame.dataV
- sampler:_vSampler
- offset:textureOffset + 2
+ texture:self.vTexture
width:chromaWidth
height:chromaHeight
stride:frame.strideV];
-
- _currentTextureSet = (_currentTextureSet + 1) % kNumTextureSets;
- return YES;
}
@end
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/RTCI420TextureCache.h ('k') | webrtc/sdk/objc/Framework/Classes/RTCOpenGLDefines.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698