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

Side by Side Diff: webrtc/api/objc/RTCEAGLVideoView.m

Issue 1542473003: Move Objective-C video renderers to webrtc/api/objc. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@updateI420Frame
Patch Set: Created 5 years 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 * libjingle 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 * Copyright 2014 Google Inc.
4 * 3 *
5 * Redistribution and use in source and binary forms, with or without 4 * Use of this source code is governed by a BSD-style license
6 * modification, are permitted provided that the following conditions are met: 5 * that can be found in the LICENSE file in the root of the source
7 * 6 * tree. An additional intellectual property rights grant can be found
8 * 1. Redistributions of source code must retain the above copyright notice, 7 * in the file PATENTS. All contributing project authors may
9 * this list of conditions and the following disclaimer. 8 * be found in the AUTHORS file in the root of the source tree.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 9 */
27 10
28 #if !defined(__has_feature) || !__has_feature(objc_arc)
29 #error "This file requires ARC support."
30 #endif
31
32 #import "RTCEAGLVideoView.h" 11 #import "RTCEAGLVideoView.h"
33 12
34 #import <GLKit/GLKit.h> 13 #import <GLKit/GLKit.h>
35 14
36 #import "RTCI420Frame.h" 15 #import "RTCI420Frame.h"
37 #import "RTCOpenGLVideoRenderer.h" 16 #import "RTCOpenGLVideoRenderer.h"
38 17
39 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen 18 // RTCDisplayLinkTimer wraps a CADisplayLink and is set to fire every two screen
40 // refreshes, which should be 30fps. We wrap the display link in order to avoid 19 // refreshes, which should be 30fps. We wrap the display link in order to avoid
41 // a retain cycle since CADisplayLink takes a strong reference onto its target. 20 // a retain cycle since CADisplayLink takes a strong reference onto its target.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 // when the drawable size would be empty which would result in the 79 // when the drawable size would be empty which would result in the
101 // error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT. -[GLKView display] is 80 // error GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT. -[GLKView display] is
102 // the method that will trigger the binding of the render 81 // the method that will trigger the binding of the render
103 // buffer. Because the standard behaviour of -[UIView setNeedsDisplay] 82 // buffer. Because the standard behaviour of -[UIView setNeedsDisplay]
104 // is disabled for the reasons above, the RTCEAGLVideoView maintains 83 // is disabled for the reasons above, the RTCEAGLVideoView maintains
105 // its own |isDirty| flag. 84 // its own |isDirty| flag.
106 85
107 @interface RTCEAGLVideoView () <GLKViewDelegate> 86 @interface RTCEAGLVideoView () <GLKViewDelegate>
108 // |i420Frame| is set when we receive a frame from a worker thread and is read 87 // |i420Frame| is set when we receive a frame from a worker thread and is read
109 // from the display link callback so atomicity is required. 88 // from the display link callback so atomicity is required.
110 @property(atomic, strong) RTCI420Frame* i420Frame; 89 @property(atomic, strong) RTCI420Frame *i420Frame;
111 @property(nonatomic, readonly) GLKView* glkView; 90 @property(nonatomic, readonly) GLKView *glkView;
112 @property(nonatomic, readonly) RTCOpenGLVideoRenderer* glRenderer; 91 @property(nonatomic, readonly) RTCOpenGLVideoRenderer *glRenderer;
113 @end 92 @end
114 93
115 @implementation RTCEAGLVideoView { 94 @implementation RTCEAGLVideoView {
116 RTCDisplayLinkTimer* _timer; 95 RTCDisplayLinkTimer *_timer;
117 GLKView* _glkView; 96 GLKView *_glkView;
118 RTCOpenGLVideoRenderer* _glRenderer; 97 RTCOpenGLVideoRenderer *_glRenderer;
119 // This flag should only be set and read on the main thread (e.g. by 98 // This flag should only be set and read on the main thread (e.g. by
120 // setNeedsDisplay) 99 // setNeedsDisplay)
121 BOOL _isDirty; 100 BOOL _isDirty;
122 } 101 }
123 102
124 - (instancetype)initWithFrame:(CGRect)frame { 103 - (instancetype)initWithFrame:(CGRect)frame {
125 if (self = [super initWithFrame:frame]) { 104 if (self = [super initWithFrame:frame]) {
126 [self configure]; 105 [self configure];
127 } 106 }
128 return self; 107 return self;
129 } 108 }
130 109
131 - (instancetype)initWithCoder:(NSCoder *)aDecoder { 110 - (instancetype)initWithCoder:(NSCoder *)aDecoder {
132 if (self = [super initWithCoder:aDecoder]) { 111 if (self = [super initWithCoder:aDecoder]) {
133 [self configure]; 112 [self configure];
134 } 113 }
135 return self; 114 return self;
136 } 115 }
137 116
138 - (void)configure { 117 - (void)configure {
139 EAGLContext* glContext = 118 EAGLContext *glContext =
140 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; 119 [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
141 if (!glContext) { 120 if (!glContext) {
142 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 121 glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
143 } 122 }
144 _glRenderer = [[RTCOpenGLVideoRenderer alloc] initWithContext:glContext]; 123 _glRenderer = [[RTCOpenGLVideoRenderer alloc] initWithContext:glContext];
145 124
146 // GLKView manages a framebuffer for us. 125 // GLKView manages a framebuffer for us.
147 _glkView = [[GLKView alloc] initWithFrame:CGRectZero 126 _glkView = [[GLKView alloc] initWithFrame:CGRectZero
148 context:glContext]; 127 context:glContext];
149 _glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; 128 _glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
(...skipping 14 matching lines...) Expand all
164 name:UIApplicationWillResignActiveNotification 143 name:UIApplicationWillResignActiveNotification
165 object:nil]; 144 object:nil];
166 [notificationCenter addObserver:self 145 [notificationCenter addObserver:self
167 selector:@selector(didBecomeActive) 146 selector:@selector(didBecomeActive)
168 name:UIApplicationDidBecomeActiveNotification 147 name:UIApplicationDidBecomeActiveNotification
169 object:nil]; 148 object:nil];
170 149
171 // Frames are received on a separate thread, so we poll for current frame 150 // Frames are received on a separate thread, so we poll for current frame
172 // using a refresh rate proportional to screen refresh frequency. This 151 // using a refresh rate proportional to screen refresh frequency. This
173 // occurs on the main thread. 152 // occurs on the main thread.
174 __weak RTCEAGLVideoView* weakSelf = self; 153 __weak RTCEAGLVideoView *weakSelf = self;
175 _timer = [[RTCDisplayLinkTimer alloc] initWithTimerHandler:^{ 154 _timer = [[RTCDisplayLinkTimer alloc] initWithTimerHandler:^{
176 RTCEAGLVideoView* strongSelf = weakSelf; 155 RTCEAGLVideoView *strongSelf = weakSelf;
177 [strongSelf displayLinkTimerDidFire]; 156 [strongSelf displayLinkTimerDidFire];
178 }]; 157 }];
179 [self setupGL]; 158 [self setupGL];
180 } 159 }
181 160
182 - (void)dealloc { 161 - (void)dealloc {
183 [[NSNotificationCenter defaultCenter] removeObserver:self]; 162 [[NSNotificationCenter defaultCenter] removeObserver:self];
184 UIApplicationState appState = 163 UIApplicationState appState =
185 [UIApplication sharedApplication].applicationState; 164 [UIApplication sharedApplication].applicationState;
186 if (appState == UIApplicationStateActive) { 165 if (appState == UIApplicationStateActive) {
(...skipping 16 matching lines...) Expand all
203 182
204 - (void)layoutSubviews { 183 - (void)layoutSubviews {
205 [super layoutSubviews]; 184 [super layoutSubviews];
206 _glkView.frame = self.bounds; 185 _glkView.frame = self.bounds;
207 } 186 }
208 187
209 #pragma mark - GLKViewDelegate 188 #pragma mark - GLKViewDelegate
210 189
211 // This method is called when the GLKView's content is dirty and needs to be 190 // This method is called when the GLKView's content is dirty and needs to be
212 // redrawn. This occurs on main thread. 191 // redrawn. This occurs on main thread.
213 - (void)glkView:(GLKView*)view drawInRect:(CGRect)rect { 192 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
214 // The renderer will draw the frame to the framebuffer corresponding to the 193 // The renderer will draw the frame to the framebuffer corresponding to the
215 // one used by |view|. 194 // one used by |view|.
216 [_glRenderer drawFrame:self.i420Frame]; 195 [_glRenderer drawFrame:self.i420Frame];
217 } 196 }
218 197
219 #pragma mark - RTCVideoRenderer 198 #pragma mark - RTCVideoRenderer
220 199
221 // These methods may be called on non-main thread. 200 // These methods may be called on non-main thread.
222 - (void)setSize:(CGSize)size { 201 - (void)setSize:(CGSize)size {
223 __weak RTCEAGLVideoView* weakSelf = self; 202 __weak RTCEAGLVideoView *weakSelf = self;
224 dispatch_async(dispatch_get_main_queue(), ^{ 203 dispatch_async(dispatch_get_main_queue(), ^{
225 RTCEAGLVideoView* strongSelf = weakSelf; 204 RTCEAGLVideoView *strongSelf = weakSelf;
226 [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size]; 205 [strongSelf.delegate videoView:strongSelf didChangeVideoSize:size];
227 }); 206 });
228 } 207 }
229 208
230 - (void)renderFrame:(RTCI420Frame*)frame { 209 - (void)renderFrame:(RTCI420Frame *)frame {
231 self.i420Frame = frame; 210 self.i420Frame = frame;
232 } 211 }
233 212
234 #pragma mark - Private 213 #pragma mark - Private
235 214
236 - (void)displayLinkTimerDidFire { 215 - (void)displayLinkTimerDidFire {
237 // Don't render unless video frame have changed or the view content 216 // Don't render unless video frame have changed or the view content
238 // has explicitly been marked dirty. 217 // has explicitly been marked dirty.
239 if (!_isDirty && _glRenderer.lastDrawnFrame == self.i420Frame) { 218 if (!_isDirty && _glRenderer.lastDrawnFrame == self.i420Frame) {
240 return; 219 return;
(...skipping 27 matching lines...) Expand all
268 247
269 - (void)didBecomeActive { 248 - (void)didBecomeActive {
270 [self setupGL]; 249 [self setupGL];
271 } 250 }
272 251
273 - (void)willResignActive { 252 - (void)willResignActive {
274 [self teardownGL]; 253 [self teardownGL];
275 } 254 }
276 255
277 @end 256 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698