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

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

Issue 2862543002: Split iOS sdk in to separate targets (Closed)
Patch Set: rebase and minor fixes 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
(Empty)
1 /*
2 * Copyright 2015 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 <Foundation/Foundation.h>
12
13 #if !TARGET_OS_IPHONE
14
15 #import "WebRTC/RTCNSGLVideoView.h"
16
17 #import <AppKit/NSOpenGL.h>
18 #import <CoreVideo/CVDisplayLink.h>
19 #import <OpenGL/gl3.h>
20
21 #import "RTCShader+Private.h"
22 #import "WebRTC/RTCLogging.h"
23 #import "WebRTC/RTCVideoFrame.h"
24
25 @interface RTCNSGLVideoView ()
26 // |videoFrame| is set when we receive a frame from a worker thread and is read
27 // from the display link callback so atomicity is required.
28 @property(atomic, strong) RTCVideoFrame *videoFrame;
29 @property(atomic, strong) id<RTCShader> i420Shader;
30
31 - (void)drawFrame;
32 @end
33
34 static CVReturn OnDisplayLinkFired(CVDisplayLinkRef displayLink,
35 const CVTimeStamp *now,
36 const CVTimeStamp *outputTime,
37 CVOptionFlags flagsIn,
38 CVOptionFlags *flagsOut,
39 void *displayLinkContext) {
40 RTCNSGLVideoView *view = (__bridge RTCNSGLVideoView *)displayLinkContext;
41 [view drawFrame];
42 return kCVReturnSuccess;
43 }
44
45 @implementation RTCNSGLVideoView {
46 CVDisplayLinkRef _displayLink;
47 RTCVideoFrame *_lastDrawnFrame;
48 }
49
50 @synthesize delegate = _delegate;
51 @synthesize videoFrame = _videoFrame;
52 @synthesize i420Shader = _i420Shader;
53
54 - (void)dealloc {
55 [self teardownDisplayLink];
56 }
57
58 - (void)drawRect:(NSRect)rect {
59 [self drawFrame];
60 }
61
62 - (void)reshape {
63 [super reshape];
64 NSRect frame = [self frame];
65 CGLLockContext([[self openGLContext] CGLContextObj]);
66 glViewport(0, 0, frame.size.width, frame.size.height);
67 CGLUnlockContext([[self openGLContext] CGLContextObj]);
68 }
69
70 - (void)lockFocus {
71 NSOpenGLContext *context = [self openGLContext];
72 [super lockFocus];
73 if ([context view] != self) {
74 [context setView:self];
75 }
76 [context makeCurrentContext];
77 }
78
79 - (void)prepareOpenGL {
80 [super prepareOpenGL];
81 [self ensureGLContext];
82 glDisable(GL_DITHER);
83 [self setupDisplayLink];
84 }
85
86 - (void)clearGLContext {
87 [self ensureGLContext];
88 self.i420Shader = nil;
89 [super clearGLContext];
90 }
91
92 #pragma mark - RTCVideoRenderer
93
94 // These methods may be called on non-main thread.
95 - (void)setSize:(CGSize)size {
96 dispatch_async(dispatch_get_main_queue(), ^{
97 [self.delegate videoView:self didChangeVideoSize:size];
98 });
99 }
100
101 - (void)renderFrame:(RTCVideoFrame *)frame {
102 self.videoFrame = frame;
103 }
104
105 #pragma mark - Private
106
107 - (void)drawFrame {
108 RTCVideoFrame *frame = self.videoFrame;
109 if (!frame || frame == _lastDrawnFrame) {
110 return;
111 }
112 // This method may be called from CVDisplayLink callback which isn't on the
113 // main thread so we have to lock the GL context before drawing.
114 NSOpenGLContext *context = [self openGLContext];
115 CGLLockContext([context CGLContextObj]);
116
117 [self ensureGLContext];
118 glClear(GL_COLOR_BUFFER_BIT);
119
120 // Rendering native CVPixelBuffer is not supported on OS X.
121 frame = [frame newI420VideoFrame];
122 if (!self.i420Shader) {
123 self.i420Shader = [[RTCI420Shader alloc] initWithContext:context];
124 }
125 if (self.i420Shader && [self.i420Shader drawFrame:frame]) {
126 [context flushBuffer];
127 _lastDrawnFrame = frame;
128 } else {
129 RTCLog(@"Failed to draw frame.");
130 }
131 CGLUnlockContext([context CGLContextObj]);
132 }
133
134 - (void)setupDisplayLink {
135 if (_displayLink) {
136 return;
137 }
138 // Synchronize buffer swaps with vertical refresh rate.
139 GLint swapInt = 1;
140 [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
141
142 // Create display link.
143 CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
144 CVDisplayLinkSetOutputCallback(_displayLink,
145 &OnDisplayLinkFired,
146 (__bridge void *)self);
147 // Set the display link for the current renderer.
148 CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
149 CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
150 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(
151 _displayLink, cglContext, cglPixelFormat);
152 CVDisplayLinkStart(_displayLink);
153 }
154
155 - (void)teardownDisplayLink {
156 if (!_displayLink) {
157 return;
158 }
159 CVDisplayLinkRelease(_displayLink);
160 _displayLink = NULL;
161 }
162
163 - (void)ensureGLContext {
164 NSOpenGLContext* context = [self openGLContext];
165 NSAssert(context, @"context shouldn't be nil");
166 if ([NSOpenGLContext currentContext] != context) {
167 [context makeCurrentContext];
168 }
169 }
170
171 @end
172
173 #endif // !TARGET_OS_IPHONE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698