/* * 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 "RTCVideoRendererAdapter+Private.h" #import "RTCVideoFrame+Private.h" #include #include "webrtc/media/engine/webrtcvideoframe.h" namespace webrtc { class VideoRendererAdapter : public rtc::VideoSinkInterface { public: VideoRendererAdapter(RTCVideoRendererAdapter* adapter) { adapter_ = adapter; size_ = CGSizeZero; } void OnFrame(const cricket::VideoFrame& nativeVideoFrame) override { RTCVideoFrame *videoFrame = nil; // Rotation of native handles is unsupported right now. Convert to CPU // I420 buffer for rotation before calling the rotation method otherwise // it will hit a DCHECK. if (nativeVideoFrame.rotation() != webrtc::kVideoRotation_0 && nativeVideoFrame.video_frame_buffer()->native_handle()) { rtc::scoped_refptr i420Buffer = nativeVideoFrame.video_frame_buffer()->NativeToI420Buffer(); std::unique_ptr cpuFrame( new cricket::WebRtcVideoFrame(i420Buffer, nativeVideoFrame.rotation(), nativeVideoFrame.timestamp_us())); const cricket::VideoFrame *rotatedFrame = cpuFrame->GetCopyWithRotationApplied(); videoFrame = [[RTCVideoFrame alloc] initWithNativeFrame:rotatedFrame]; } else { const cricket::VideoFrame *rotatedFrame = nativeVideoFrame.GetCopyWithRotationApplied(); videoFrame = [[RTCVideoFrame alloc] initWithNativeFrame:rotatedFrame]; } CGSize current_size = CGSizeMake(videoFrame.width, videoFrame.height); if (!CGSizeEqualToSize(size_, current_size)) { size_ = current_size; [adapter_.videoRenderer setSize:size_]; } [adapter_.videoRenderer renderFrame:videoFrame]; } private: __weak RTCVideoRendererAdapter *adapter_; CGSize size_; }; } @implementation RTCVideoRendererAdapter { std::unique_ptr _adapter; } @synthesize videoRenderer = _videoRenderer; - (instancetype)initWithNativeRenderer:(id)videoRenderer { NSParameterAssert(videoRenderer); if (self = [super init]) { _videoRenderer = videoRenderer; _adapter.reset(new webrtc::VideoRendererAdapter(self)); } return self; } - (rtc::VideoSinkInterface *)nativeVideoRenderer { return _adapter.get(); } @end