| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright 2017 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/RTCMTLVideoView.h" | 11 #import "WebRTC/RTCMTLVideoView.h" | 
| 12 | 12 | 
| 13 #import <Metal/Metal.h> | 13 #import <Metal/Metal.h> | 
| 14 #import <MetalKit/MetalKit.h> | 14 #import <MetalKit/MetalKit.h> | 
| 15 | 15 | 
| 16 #import "WebRTC/RTCLogging.h" | 16 #import "WebRTC/RTCLogging.h" | 
| 17 #import "WebRTC/RTCVideoFrame.h" | 17 #import "WebRTC/RTCVideoFrame.h" | 
| 18 | 18 | 
| 19 #import "RTCMTLNV12Renderer.h" | 19 #import "RTCMTLNV12Renderer.h" | 
| 20 | 20 | 
| 21 // To avoid unreconized symbol linker errors, we're taking advantage of the objc
      runtime. |  | 
| 22 // Linking errors occur when compiling for architectures that don't support Meta
     l. |  | 
| 23 #define MTKViewClass NSClassFromString(@"MTKView") |  | 
| 24 #define RTCMTLNV12RendererClass NSClassFromString(@"RTCMTLNV12Renderer") |  | 
| 25 |  | 
| 26 @interface RTCMTLVideoView () <MTKViewDelegate> | 21 @interface RTCMTLVideoView () <MTKViewDelegate> | 
| 27 @property(nonatomic, strong) RTCMTLNV12Renderer *renderer; | 22 @property(nonatomic, strong) id<RTCMTLRenderer> renderer; | 
| 28 @property(nonatomic, strong) MTKView *metalView; | 23 @property(nonatomic, strong) MTKView *metalView; | 
| 29 @property(atomic, strong) RTCVideoFrame *videoFrame; | 24 @property(atomic, strong) RTCVideoFrame *videoFrame; | 
| 30 @end | 25 @end | 
| 31 | 26 | 
| 32 @implementation RTCMTLVideoView | 27 @implementation RTCMTLVideoView { | 
|  | 28   id<RTCMTLRenderer> _renderer; | 
|  | 29 } | 
| 33 | 30 | 
| 34 @synthesize renderer = _renderer; | 31 @synthesize renderer = _renderer; | 
| 35 @synthesize metalView = _metalView; | 32 @synthesize metalView = _metalView; | 
| 36 @synthesize videoFrame = _videoFrame; | 33 @synthesize videoFrame = _videoFrame; | 
| 37 | 34 | 
| 38 - (instancetype)initWithFrame:(CGRect)frameRect { | 35 - (instancetype)initWithFrame:(CGRect)frameRect { | 
| 39   self = [super initWithFrame:frameRect]; | 36   self = [super initWithFrame:frameRect]; | 
| 40   if (self) { | 37   if (self) { | 
| 41     [self configure]; | 38     [self configure]; | 
| 42   } | 39   } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 54 #pragma mark - Private | 51 #pragma mark - Private | 
| 55 | 52 | 
| 56 + (BOOL)isMetalAvailable { | 53 + (BOOL)isMetalAvailable { | 
| 57 #if defined(RTC_SUPPORTS_METAL) | 54 #if defined(RTC_SUPPORTS_METAL) | 
| 58   return YES; | 55   return YES; | 
| 59 #else | 56 #else | 
| 60   return NO; | 57   return NO; | 
| 61 #endif | 58 #endif | 
| 62 } | 59 } | 
| 63 | 60 | 
| 64 + (MTKView *)createMetalView:(CGRect)frame { |  | 
| 65   MTKView *view = [[MTKViewClass alloc] initWithFrame:frame]; |  | 
| 66   return view; |  | 
| 67 } |  | 
| 68 |  | 
| 69 + (RTCMTLNV12Renderer *)createMetalRenderer { |  | 
| 70   RTCMTLNV12Renderer *renderer = [[RTCMTLNV12RendererClass alloc] init]; |  | 
| 71   return renderer; |  | 
| 72 } |  | 
| 73 |  | 
| 74 - (void)configure { | 61 - (void)configure { | 
| 75   if (![RTCMTLVideoView isMetalAvailable]) { | 62   if ([RTCMTLVideoView isMetalAvailable]) { | 
| 76     RTCLog("Metal unavailable"); | 63     _metalView = [[MTKView alloc] initWithFrame:self.bounds]; | 
| 77     return; | 64     [self addSubview:_metalView]; | 
| 78   } |  | 
| 79 |  | 
| 80   _metalView = [RTCMTLVideoView createMetalView:self.bounds]; |  | 
| 81   _renderer = [RTCMTLVideoView createMetalRenderer]; |  | 
| 82 |  | 
| 83   if ([self configureMetalRenderer]) { |  | 
| 84     [self configureMetalView]; |  | 
| 85   } else { |  | 
| 86     _renderer = nil; |  | 
| 87     RTCLogError("Metal configuration falied."); |  | 
| 88   } |  | 
| 89 } |  | 
| 90 |  | 
| 91 - (BOOL)configureMetalRenderer { |  | 
| 92   return [_renderer addRenderingDestination:_metalView]; |  | 
| 93 } |  | 
| 94 |  | 
| 95 - (void)configureMetalView { |  | 
| 96   if (_metalView) { |  | 
| 97     _metalView.delegate = self; | 65     _metalView.delegate = self; | 
| 98     [self addSubview:_metalView]; |  | 
| 99     _metalView.contentMode = UIViewContentModeScaleAspectFit; | 66     _metalView.contentMode = UIViewContentModeScaleAspectFit; | 
| 100     _metalView.translatesAutoresizingMaskIntoConstraints = NO; | 67     _metalView.translatesAutoresizingMaskIntoConstraints = NO; | 
| 101     UILayoutGuide *margins = self.layoutMarginsGuide; | 68     UILayoutGuide *margins = self.layoutMarginsGuide; | 
| 102     [_metalView.topAnchor constraintEqualToAnchor:margins.topAnchor].active = YE
     S; | 69     [_metalView.topAnchor constraintEqualToAnchor:margins.topAnchor].active = YE
     S; | 
| 103     [_metalView.bottomAnchor constraintEqualToAnchor:margins.bottomAnchor].activ
     e = YES; | 70     [_metalView.bottomAnchor constraintEqualToAnchor:margins.bottomAnchor].activ
     e = YES; | 
| 104     [_metalView.leftAnchor constraintEqualToAnchor:margins.leftAnchor].active = 
     YES; | 71     [_metalView.leftAnchor constraintEqualToAnchor:margins.leftAnchor].active = 
     YES; | 
| 105     [_metalView.rightAnchor constraintEqualToAnchor:margins.rightAnchor].active 
     = YES; | 72     [_metalView.rightAnchor constraintEqualToAnchor:margins.rightAnchor].active 
     = YES; | 
|  | 73 | 
|  | 74     _renderer = [[RTCMTLNV12Renderer alloc] init]; | 
|  | 75     if (![(RTCMTLNV12Renderer *)_renderer addRenderingDestination:_metalView]) { | 
|  | 76       _renderer = nil; | 
|  | 77     }; | 
|  | 78   } else { | 
|  | 79     RTCLogError("Metal configuration falied."); | 
| 106   } | 80   } | 
| 107 } | 81 } | 
| 108 |  | 
| 109 #pragma mark - MTKViewDelegate methods | 82 #pragma mark - MTKViewDelegate methods | 
| 110 | 83 | 
| 111 - (void)drawInMTKView:(nonnull MTKView *)view { | 84 - (void)drawInMTKView:(nonnull MTKView *)view { | 
| 112   NSAssert(view == self.metalView, @"Receiving draw callbacks from foreign insta
     nce."); | 85   NSAssert(view == self.metalView, @"Receiving draw callbacks from foreign insta
     nce."); | 
| 113   [self.renderer drawFrame:self.videoFrame]; | 86   [_renderer drawFrame:self.videoFrame]; | 
| 114 } | 87 } | 
| 115 | 88 | 
| 116 - (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size { | 89 - (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size { | 
| 117 } | 90 } | 
| 118 | 91 | 
| 119 #pragma mark - RTCVideoRenderer | 92 #pragma mark - RTCVideoRenderer | 
| 120 | 93 | 
| 121 - (void)setSize:(CGSize)size { | 94 - (void)setSize:(CGSize)size { | 
| 122   self.metalView.drawableSize = size; | 95   _metalView.drawableSize = size; | 
| 123   [self.metalView draw]; | 96   [_metalView draw]; | 
| 124 } | 97 } | 
| 125 | 98 | 
| 126 - (void)renderFrame:(nullable RTCVideoFrame *)frame { | 99 - (void)renderFrame:(nullable RTCVideoFrame *)frame { | 
| 127   if (frame == nil) { | 100   if (frame == nil) { | 
| 128     RTCLogInfo(@"Incoming frame is nil. Exiting render callback."); | 101     RTCLogInfo(@"Incoming frame is nil. Exiting render callback."); | 
| 129     return; | 102     return; | 
| 130   } | 103   } | 
| 131   self.videoFrame = frame; | 104   self.videoFrame = frame; | 
| 132 } | 105 } | 
| 133 | 106 | 
| 134 @end | 107 @end | 
| OLD | NEW | 
|---|