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

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/RTCEAGLVideoView.m

Issue 2869143002: iOS: Add interface for injecting custom shaders (Closed)
Patch Set: Address comments. Created 3 years, 7 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
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 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 "WebRTC/RTCEAGLVideoView.h" 11 #import "WebRTC/RTCEAGLVideoView.h"
12 12
13 #import <GLKit/GLKit.h> 13 #import <GLKit/GLKit.h>
14 14
15 #import "RTCShader+Private.h" 15 #import "RTCI420TextureCache.h"
16 #import "RTCNV12TextureCache.h"
17 #import "RTCDefaultShaderDelegate.h"
16 #import "WebRTC/RTCLogging.h" 18 #import "WebRTC/RTCLogging.h"
17 #import "WebRTC/RTCVideoFrame.h" 19 #import "WebRTC/RTCVideoFrame.h"
18 20
19 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen 21 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen
20 // refreshes, which should be 30fps. We wrap the display link in order to avoid 22 // refreshes, which should be 30fps. We wrap the display link in order to avoid
21 // a retain cycle since CADisplayLink takes a strong reference onto its target. 23 // a retain cycle since CADisplayLink takes a strong reference onto its target.
22 // The timer is paused by default. 24 // The timer is paused by default.
23 @interface RTCDisplayLinkTimer : NSObject 25 @interface RTCDisplayLinkTimer : NSObject
24 26
25 @property(nonatomic) BOOL isPaused; 27 @property(nonatomic) BOOL isPaused;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 @property(atomic, strong) RTCVideoFrame *videoFrame; 92 @property(atomic, strong) RTCVideoFrame *videoFrame;
91 @property(nonatomic, readonly) GLKView *glkView; 93 @property(nonatomic, readonly) GLKView *glkView;
92 @end 94 @end
93 95
94 @implementation RTCEAGLVideoView { 96 @implementation RTCEAGLVideoView {
95 RTCDisplayLinkTimer *_timer; 97 RTCDisplayLinkTimer *_timer;
96 EAGLContext *_glContext; 98 EAGLContext *_glContext;
97 // This flag should only be set and read on the main thread (e.g. by 99 // This flag should only be set and read on the main thread (e.g. by
98 // setNeedsDisplay) 100 // setNeedsDisplay)
99 BOOL _isDirty; 101 BOOL _isDirty;
100 id<RTCShader> _i420Shader; 102 RTCDefaultShaderDelegate *_defaultShaderDelegate;
daniela-webrtc 2017/05/11 17:31:20 I find this slightly confusing. When is the defau
magjed_webrtc 2017/05/25 14:26:45 I added a comment: |_defaultShaderDelegate| is use
101 id<RTCShader> _nv12Shader; 103 __weak id<RTCVideoViewShaderDelegate> _shaderDelegate;
104 RTCNV12TextureCache* _nv12TextureCache;
105 RTCI420TextureCache* _i420TextureCache;
102 RTCVideoFrame *_lastDrawnFrame; 106 RTCVideoFrame *_lastDrawnFrame;
103 } 107 }
104 108
105 @synthesize delegate = _delegate; 109 @synthesize delegate = _delegate;
106 @synthesize videoFrame = _videoFrame; 110 @synthesize videoFrame = _videoFrame;
107 @synthesize glkView = _glkView; 111 @synthesize glkView = _glkView;
108 112
109 - (instancetype)initWithFrame:(CGRect)frame { 113 - (instancetype)initWithFrame:(CGRect)frame {
114 _defaultShaderDelegate = [[RTCDefaultShaderDelegate alloc] init];
115 return [self initWithFrame:frame shaderDelegate:_defaultShaderDelegate];
116 }
117
118 - (instancetype)initWithCoder:(NSCoder *)aDecoder {
119 _defaultShaderDelegate = [[RTCDefaultShaderDelegate alloc] init];
120 return [self initWithCoder:aDecoder shaderDelegate:_defaultShaderDelegate];
121 }
122
123 - (instancetype)initWithFrame:(CGRect)frame
124 shaderDelegate:(id<RTCVideoViewShaderDelegate>)shaderDelegate {
110 if (self = [super initWithFrame:frame]) { 125 if (self = [super initWithFrame:frame]) {
126 _shaderDelegate = shaderDelegate;
111 [self configure]; 127 [self configure];
112 } 128 }
113 return self; 129 return self;
114 } 130 }
115 131
116 - (instancetype)initWithCoder:(NSCoder *)aDecoder { 132 - (instancetype)initWithCoder:(NSCoder *)aDecoder
133 shaderDelegate:(id<RTCVideoViewShaderDelegate>)shaderDelegate {
117 if (self = [super initWithCoder:aDecoder]) { 134 if (self = [super initWithCoder:aDecoder]) {
135 _shaderDelegate = shaderDelegate;
118 [self configure]; 136 [self configure];
119 } 137 }
120 return self; 138 return self;
121 } 139 }
122 140
123 - (void)configure { 141 - (void)configure {
124 EAGLContext *glContext = 142 EAGLContext *glContext =
125 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; 143 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
126 if (!glContext) { 144 if (!glContext) {
127 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 145 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 // redrawn. This occurs on main thread. 218 // redrawn. This occurs on main thread.
201 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 219 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
202 // The renderer will draw the frame to the framebuffer corresponding to the 220 // The renderer will draw the frame to the framebuffer corresponding to the
203 // one used by |view|. 221 // one used by |view|.
204 RTCVideoFrame *frame = self.videoFrame; 222 RTCVideoFrame *frame = self.videoFrame;
205 if (!frame || frame == _lastDrawnFrame) { 223 if (!frame || frame == _lastDrawnFrame) {
206 return; 224 return;
207 } 225 }
208 [self ensureGLContext]; 226 [self ensureGLContext];
209 glClear(GL_COLOR_BUFFER_BIT); 227 glClear(GL_COLOR_BUFFER_BIT);
210 id<RTCShader> shader = nil;
211 if (frame.nativeHandle) { 228 if (frame.nativeHandle) {
212 if (!_nv12Shader) { 229 if (!_nv12TextureCache) {
213 _nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_glContext]; 230 _nv12TextureCache = [[RTCNV12TextureCache alloc] initWithContext:_glContex t];
214 } 231 }
215 shader = _nv12Shader; 232 if (_nv12TextureCache) {
233 [_nv12TextureCache uploadFrameToTextures:frame];
234 [_shaderDelegate videoView:self
daniela-webrtc 2017/05/11 17:31:20 What if this is nil? Shouldn't the defaultDelegate
235 didReceiveFrameWithRotation:frame.rotation
236 yPlane:_nv12TextureCache.yTexture
237 uvPlane:_nv12TextureCache.uvTexture];
238 [_nv12TextureCache releaseTextures];
239 }
216 } else { 240 } else {
217 if (!_i420Shader) { 241 if (!_i420TextureCache) {
218 _i420Shader = [[RTCI420Shader alloc] initWithContext:_glContext]; 242 _i420TextureCache = [[RTCI420TextureCache alloc] initWithContext:_glContex t];
219 } 243 }
220 shader = _i420Shader; 244 [_i420TextureCache uploadFrameToTextures:frame];
221 } 245 [_shaderDelegate videoView:self
222 if (shader && [shader drawFrame:frame]) { 246 didReceiveFrameWithRotation:frame.rotation
223 _lastDrawnFrame = frame; 247 yPlane:_i420TextureCache.yTexture
224 } else { 248 uPlane:_i420TextureCache.uTexture
225 RTCLog(@"Failed to draw frame."); 249 vPlane:_i420TextureCache.vTexture];
226 } 250 }
227 } 251 }
228 252
229 #pragma mark - RTCVideoRenderer 253 #pragma mark - RTCVideoRenderer
230 254
231 // These methods may be called on non-main thread. 255 // These methods may be called on non-main thread.
232 - (void)setSize:(CGSize)size { 256 - (void)setSize:(CGSize)size {
233 __weak RTCEAGLVideoView *weakSelf = self; 257 __weak RTCEAGLVideoView *weakSelf = self;
234 dispatch_async(dispatch_get_main_queue(), ^{ 258 dispatch_async(dispatch_get_main_queue(), ^{
235 RTCEAGLVideoView *strongSelf = weakSelf; 259 RTCEAGLVideoView *strongSelf = weakSelf;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 [self ensureGLContext]; 292 [self ensureGLContext];
269 glDisable(GL_DITHER); 293 glDisable(GL_DITHER);
270 _timer.isPaused = NO; 294 _timer.isPaused = NO;
271 } 295 }
272 296
273 - (void)teardownGL { 297 - (void)teardownGL {
274 self.videoFrame = nil; 298 self.videoFrame = nil;
275 _timer.isPaused = YES; 299 _timer.isPaused = YES;
276 [_glkView deleteDrawable]; 300 [_glkView deleteDrawable];
277 [self ensureGLContext]; 301 [self ensureGLContext];
278 _i420Shader = nil; 302 _nv12TextureCache = nil;
279 _nv12Shader = nil; 303 _i420TextureCache = nil;
304 _defaultShaderDelegate = nil;
280 } 305 }
281 306
282 - (void)didBecomeActive { 307 - (void)didBecomeActive {
283 [self setupGL]; 308 [self setupGL];
284 } 309 }
285 310
286 - (void)willResignActive { 311 - (void)willResignActive {
287 [self teardownGL]; 312 [self teardownGL];
288 } 313 }
289 314
290 - (void)ensureGLContext { 315 - (void)ensureGLContext {
291 NSAssert(_glContext, @"context shouldn't be nil"); 316 NSAssert(_glContext, @"context shouldn't be nil");
292 if ([EAGLContext currentContext] != _glContext) { 317 if ([EAGLContext currentContext] != _glContext) {
293 [EAGLContext setCurrentContext:_glContext]; 318 [EAGLContext setCurrentContext:_glContext];
294 } 319 }
295 } 320 }
296 321
297 @end 322 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698