2016-01-11 13:47:11 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright 2015 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
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#import "RTCOpenGLVideoRenderer.h"
|
|
|
|
|
|
2016-08-08 03:10:07 -07:00
|
|
|
#import "RTCShader+Private.h"
|
2016-04-27 01:54:20 -07:00
|
|
|
#import "WebRTC/RTCVideoFrame.h"
|
2016-01-11 13:47:11 -08:00
|
|
|
|
|
|
|
|
@implementation RTCOpenGLVideoRenderer {
|
2016-08-08 03:10:07 -07:00
|
|
|
GlContextType *_context;
|
2016-01-11 13:47:11 -08:00
|
|
|
BOOL _isInitialized;
|
2016-08-08 03:10:07 -07:00
|
|
|
id<RTCShader> _i420Shader;
|
|
|
|
|
id<RTCShader> _nv12Shader;
|
2016-01-11 13:47:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@synthesize lastDrawnFrame = _lastDrawnFrame;
|
|
|
|
|
|
|
|
|
|
+ (void)initialize {
|
|
|
|
|
// Disable dithering for performance.
|
|
|
|
|
glDisable(GL_DITHER);
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-08 03:10:07 -07:00
|
|
|
- (instancetype)initWithContext:(GlContextType *)context {
|
2016-01-11 13:47:11 -08:00
|
|
|
NSAssert(context != nil, @"context cannot be nil");
|
|
|
|
|
if (self = [super init]) {
|
|
|
|
|
_context = context;
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL)drawFrame:(RTCVideoFrame *)frame {
|
2016-08-08 03:10:07 -07:00
|
|
|
if (!_isInitialized || !frame || frame == _lastDrawnFrame) {
|
2016-01-11 13:47:11 -08:00
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
[self ensureGLContext];
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2016-08-08 03:10:07 -07:00
|
|
|
id<RTCShader> shader = nil;
|
|
|
|
|
#if TARGET_OS_IPHONE
|
|
|
|
|
if (frame.nativeHandle) {
|
|
|
|
|
if (!_nv12Shader) {
|
|
|
|
|
_nv12Shader = [[RTCNativeNV12Shader alloc] initWithContext:_context];
|
2016-01-11 13:47:11 -08:00
|
|
|
}
|
2016-08-08 03:10:07 -07:00
|
|
|
shader = _nv12Shader;
|
|
|
|
|
#else
|
|
|
|
|
// Rendering native CVPixelBuffer is not supported on OS X.
|
|
|
|
|
if (false) {
|
2016-01-11 13:47:11 -08:00
|
|
|
#endif
|
2016-08-08 03:10:07 -07:00
|
|
|
} else {
|
|
|
|
|
if (!_i420Shader) {
|
|
|
|
|
_i420Shader = [[RTCI420Shader alloc] initWithContext:_context];
|
|
|
|
|
}
|
|
|
|
|
shader = _i420Shader;
|
|
|
|
|
}
|
|
|
|
|
if (!shader || ![shader drawFrame:frame]) {
|
|
|
|
|
return NO;
|
2016-01-11 13:47:11 -08:00
|
|
|
}
|
2016-08-08 03:10:07 -07:00
|
|
|
|
2016-01-11 13:47:11 -08:00
|
|
|
#if !TARGET_OS_IPHONE
|
|
|
|
|
[_context flushBuffer];
|
|
|
|
|
#endif
|
|
|
|
|
_lastDrawnFrame = frame;
|
2016-08-08 03:10:07 -07:00
|
|
|
|
2016-01-11 13:47:11 -08:00
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setupGL {
|
|
|
|
|
if (_isInitialized) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
[self ensureGLContext];
|
|
|
|
|
_isInitialized = YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)teardownGL {
|
|
|
|
|
if (!_isInitialized) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
[self ensureGLContext];
|
2016-08-08 03:10:07 -07:00
|
|
|
_i420Shader = nil;
|
|
|
|
|
_nv12Shader = nil;
|
2016-01-11 13:47:11 -08:00
|
|
|
_isInitialized = NO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Private
|
|
|
|
|
|
|
|
|
|
- (void)ensureGLContext {
|
|
|
|
|
NSAssert(_context, @"context shouldn't be nil");
|
|
|
|
|
#if TARGET_OS_IPHONE
|
|
|
|
|
if ([EAGLContext currentContext] != _context) {
|
|
|
|
|
[EAGLContext setCurrentContext:_context];
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if ([NSOpenGLContext currentContext] != _context) {
|
|
|
|
|
[_context makeCurrentContext];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|