From 9823ee47d38530f05baedc704428dc18953ffa80 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 7 Mar 2018 10:32:03 +0100 Subject: [PATCH] Fix native api in preparation for native_api example. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add native api conversions for video frames and video renderer. This also requires some changes to sdk/BUILD to avoid cyclic dependencies. Bug: webrtc:8832 Change-Id: Ibf21e63bdcae195dcb61d63f9262e6a8dc4fa790 Reviewed-on: https://webrtc-review.googlesource.com/57142 Commit-Queue: Anders Carlsson Reviewed-by: Kári Helgason Cr-Commit-Position: refs/heads/master@{#22340} --- examples/BUILD.gn | 1 + modules/video_coding/BUILD.gn | 2 +- sdk/BUILD.gn | 141 ++++++++++++++---- .../RTCPeerConnectionFactory.mm | 10 +- .../Classes/PeerConnection/RTCVideoFrame.mm | 35 +---- .../PeerConnection/RTCVideoRendererAdapter.mm | 5 +- .../PeerConnection/RTCVideoSource+Private.h | 3 + .../Classes/PeerConnection/RTCVideoSource.mm | 21 ++- .../api/video_frame.h} | 18 +-- sdk/objc/Framework/Native/api/video_frame.mm | 21 +++ .../Framework/Native/api/video_frame_buffer.h | 5 +- .../Native/api/video_frame_buffer.mm | 9 +- .../Framework/Native/api/video_renderer.h | 28 ++++ .../Framework/Native/api/video_renderer.mm | 23 +++ .../Framework/Native/src/objc_frame_buffer.h | 3 + .../Framework/Native/src/objc_frame_buffer.mm | 9 ++ .../Native/src/objc_video_decoder_factory.h | 7 +- .../Native/src/objc_video_decoder_factory.mm | 6 +- .../Native/src/objc_video_encoder_factory.h | 5 +- .../Native/src/objc_video_encoder_factory.mm | 14 +- .../Framework/Native/src/objc_video_frame.h | 24 +++ .../Framework/Native/src/objc_video_frame.mm | 28 ++++ .../Native/src/objc_video_renderer.h | 36 +++++ .../Native/src/objc_video_renderer.mm | 37 +++++ .../src/objc_video_track_source.h} | 4 +- .../src/objc_video_track_source.mm} | 23 ++- 26 files changed, 393 insertions(+), 125 deletions(-) rename sdk/objc/Framework/{Classes/PeerConnection/RTCVideoFrame+Private.h => Native/api/video_frame.h} (55%) create mode 100644 sdk/objc/Framework/Native/api/video_frame.mm create mode 100644 sdk/objc/Framework/Native/api/video_renderer.h create mode 100644 sdk/objc/Framework/Native/api/video_renderer.mm create mode 100644 sdk/objc/Framework/Native/src/objc_video_frame.h create mode 100644 sdk/objc/Framework/Native/src/objc_video_frame.mm create mode 100644 sdk/objc/Framework/Native/src/objc_video_renderer.h create mode 100644 sdk/objc/Framework/Native/src/objc_video_renderer.mm rename sdk/objc/Framework/{Classes/Video/objcvideotracksource.h => Native/src/objc_video_track_source.h} (94%) rename sdk/objc/Framework/{Classes/Video/objcvideotracksource.mm => Native/src/objc_video_track_source.mm} (79%) diff --git a/examples/BUILD.gn b/examples/BUILD.gn index c6940e8d9b..65fc9379c3 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -274,6 +274,7 @@ if (is_ios || (is_mac && target_cpu != "x86")) { "../sdk:peerconnectionfactory_base_objc", "../sdk:videocapture_objc", "../sdk:videocodec_objc", + "../sdk:videosource_objc", ] } libs = [ "QuartzCore.framework" ] diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 1b3dbe8edf..2feb1db2e6 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -514,8 +514,8 @@ if (rtc_include_tests) { "../../sdk:native_api", "../../sdk:peerconnectionfactory_base_objc", "../../sdk:videocodec_objc", + "../../sdk:videosource_objc", "../../sdk:videotoolbox_objc", - "../../sdk:videotracksource_objc", ] if (!build_with_chromium && is_clang) { diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 9c86306d6c..1ef7de2744 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -121,17 +121,17 @@ if (is_ios || is_mac) { } } - # Keep videotracksource related code in a separate target so that we can - # build PeerConnectionFactory without audio/video support when that's called - # for. - rtc_static_library("videotracksource_objc") { + rtc_static_library("videosource_objc") { sources = [ - "objc/Framework/Classes/Video/objcvideotracksource.h", - "objc/Framework/Classes/Video/objcvideotracksource.mm", + "objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h", + "objc/Framework/Classes/PeerConnection/RTCVideoSource.mm", + "objc/Framework/Headers/WebRTC/RTCVideoSource.h", ] deps = [ ":common_objc", + ":mediasource_objc", + ":native_video", ":videoframebuffer_objc", "../api:libjingle_peerconnection_api", "../api:video_frame_api", @@ -153,17 +153,12 @@ if (is_ios || is_mac) { rtc_static_library("videoframebuffer_objc") { sources = [ - "objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm", "objc/Framework/Classes/Video/RTCCVPixelBuffer.mm", "objc/Framework/Classes/Video/RTCI420Buffer+Private.h", "objc/Framework/Classes/Video/RTCI420Buffer.mm", "objc/Framework/Headers/WebRTC/RTCVideoFrame.h", "objc/Framework/Headers/WebRTC/RTCVideoFrameBuffer.h", - "objc/Framework/Native/api/video_frame_buffer.h", - "objc/Framework/Native/api/video_frame_buffer.mm", - "objc/Framework/Native/src/objc_frame_buffer.h", - "objc/Framework/Native/src/objc_frame_buffer.mm", ] deps = [ ":common_objc", @@ -214,7 +209,7 @@ if (is_ios || is_mac) { ":mediaconstraints_objc", ":native_video", ":videoframebuffer_objc", - ":videotracksource_objc", + ":videosource_objc", "../api:libjingle_peerconnection_api", "../api:optional", "../api:video_frame_api", @@ -291,6 +286,7 @@ if (is_ios || is_mac) { ":peerconnectionfactory_base_objc", ":video_objc", ":videoframebuffer_objc", + ":videorenderer_objc", "../api:video_frame_api", "../rtc_base:checks", "../rtc_base:rtc_base_approved", @@ -398,7 +394,7 @@ if (is_ios || is_mac) { } deps = [ - ":native_video", + ":wrapped_native_codec_objc", "../modules/video_coding:webrtc_vp8", "../system_wrappers:metrics_default", ] @@ -419,7 +415,7 @@ if (is_ios || is_mac) { } deps = [ - ":native_video", + ":wrapped_native_codec_objc", "../modules/video_coding:webrtc_vp9", "../system_wrappers:metrics_default", ] @@ -476,6 +472,53 @@ if (is_ios || is_mac) { ] } + rtc_source_set("videorenderer_objc") { + sources = [ + "objc/Framework/Headers/WebRTC/RTCVideoRenderer.h", + ] + + configs += [ "..:common_objc" ] + visibility = [ "*" ] + public_configs = [ ":common_config_objc" ] + } + + rtc_static_library("videorendereradapter_objc") { + sources = [ + "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h", + "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h", + "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm", + ] + + configs += [ "..:common_objc" ] + visibility = [ "*" ] + public_configs = [ ":common_config_objc" ] + + deps = [ + ":common_objc", + ":native_api", + ":videoframebuffer_objc", + ":videorenderer_objc", + "../api:libjingle_peerconnection_api", + ] + } + + rtc_static_library("mediasource_objc") { + sources = [ + "objc/Framework/Classes/PeerConnection/RTCMediaSource+Private.h", + "objc/Framework/Classes/PeerConnection/RTCMediaSource.mm", + "objc/Framework/Headers/WebRTC/RTCMediaSource.h", + ] + + configs += [ "..:common_objc" ] + public_configs = [ ":common_config_objc" ] + + deps = [ + ":common_objc", + "../api:libjingle_peerconnection_api", + "../rtc_base:checks", + ] + } + rtc_static_library("peerconnectionfactory_base_objc") { sources = [ "objc/Framework/Classes/PeerConnection/RTCAudioSource+Private.h", @@ -499,8 +542,6 @@ if (is_ios || is_mac) { "objc/Framework/Classes/PeerConnection/RTCIntervalRange.mm", "objc/Framework/Classes/PeerConnection/RTCLegacyStatsReport+Private.h", "objc/Framework/Classes/PeerConnection/RTCLegacyStatsReport.mm", - "objc/Framework/Classes/PeerConnection/RTCMediaSource+Private.h", - "objc/Framework/Classes/PeerConnection/RTCMediaSource.mm", "objc/Framework/Classes/PeerConnection/RTCMediaStream+Private.h", "objc/Framework/Classes/PeerConnection/RTCMediaStream.mm", "objc/Framework/Classes/PeerConnection/RTCMediaStreamTrack+Private.h", @@ -534,11 +575,6 @@ if (is_ios || is_mac) { "objc/Framework/Classes/PeerConnection/RTCSessionDescription+Private.h", "objc/Framework/Classes/PeerConnection/RTCSessionDescription.mm", "objc/Framework/Classes/PeerConnection/RTCTracing.mm", - "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h", - "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h", - "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm", - "objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h", - "objc/Framework/Classes/PeerConnection/RTCVideoSource.mm", "objc/Framework/Classes/PeerConnection/RTCVideoTrack+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoTrack.mm", "objc/Framework/Headers/WebRTC/RTCAudioSource.h", @@ -551,7 +587,6 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCIceServer.h", "objc/Framework/Headers/WebRTC/RTCIntervalRange.h", "objc/Framework/Headers/WebRTC/RTCLegacyStatsReport.h", - "objc/Framework/Headers/WebRTC/RTCMediaSource.h", "objc/Framework/Headers/WebRTC/RTCMediaStream.h", "objc/Framework/Headers/WebRTC/RTCMediaStreamTrack.h", "objc/Framework/Headers/WebRTC/RTCMetrics.h", @@ -568,8 +603,6 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCSSLAdapter.h", "objc/Framework/Headers/WebRTC/RTCSessionDescription.h", "objc/Framework/Headers/WebRTC/RTCTracing.h", - "objc/Framework/Headers/WebRTC/RTCVideoRenderer.h", - "objc/Framework/Headers/WebRTC/RTCVideoSource.h", "objc/Framework/Headers/WebRTC/RTCVideoTrack.h", ] @@ -586,12 +619,15 @@ if (is_ios || is_mac) { deps = [ ":common_objc", ":mediaconstraints_objc", + ":mediasource_objc", ":native_api", ":native_video", ":video_objc", ":videocodec_objc", ":videoframebuffer_objc", - ":videotracksource_objc", + ":videorenderer_objc", + ":videorendereradapter_objc", + ":videosource_objc", "../api:libjingle_peerconnection_api", "../api:video_frame_api", "../api/video_codecs:video_codecs_api", @@ -625,8 +661,8 @@ if (is_ios || is_mac) { ":common_objc", ":framework_objc", ":videocapture_objc", + ":videosource_objc", ":videotoolbox_objc", - ":videotracksource_objc", "../../system_wrappers:system_wrappers_default", "../media:rtc_media_base", "../modules:module_api", @@ -712,8 +748,8 @@ if (is_ios || is_mac) { ":videocapture_objc", ":videocodec_objc", ":videoframebuffer_objc", + ":videosource_objc", ":videotoolbox_objc", - ":videotracksource_objc", "../../system_wrappers:system_wrappers_default", "../media:rtc_media_base", "../modules:module_api", @@ -857,6 +893,31 @@ if (is_ios || is_mac) { } } + rtc_static_library("wrapped_native_codec_objc") { + sources = [ + "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h", + "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm", + "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h", + "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm", + ] + + configs += [ "..:common_objc" ] + public_configs = [ ":common_config_objc" ] + + if (!build_with_chromium && is_clang) { + # Suppress warnings from the Chromium Clang plugin + # (bugs.webrtc.org/163). + suppressed_configs += [ "//build/config/clang:find_bad_constructs" ] + } + + deps = [ + ":common_objc", + ":videocodec_objc", + "../api/video_codecs:video_codecs_api", + "../media:rtc_media_base", + ] + } + # The native API is currently experimental and may change without notice. rtc_static_library("native_api") { visibility = [ "*" ] @@ -865,6 +926,12 @@ if (is_ios || is_mac) { "objc/Framework/Native/api/video_decoder_factory.mm", "objc/Framework/Native/api/video_encoder_factory.h", "objc/Framework/Native/api/video_encoder_factory.mm", + "objc/Framework/Native/api/video_frame.h", + "objc/Framework/Native/api/video_frame.mm", + "objc/Framework/Native/api/video_frame_buffer.h", + "objc/Framework/Native/api/video_frame_buffer.mm", + "objc/Framework/Native/api/video_renderer.h", + "objc/Framework/Native/api/video_renderer.mm", ] configs += [ "..:common_objc" ] @@ -881,6 +948,8 @@ if (is_ios || is_mac) { ":native_video", ":videocodec_objc", ":videoframebuffer_objc", + ":videorenderer_objc", + "../api:video_frame_api", "../api/video_codecs:video_codecs_api", "../common_video", "../rtc_base:rtc_base", @@ -889,14 +958,18 @@ if (is_ios || is_mac) { rtc_static_library("native_video") { sources = [ - "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h", - "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm", - "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h", - "objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm", + "objc/Framework/Native/src/objc_frame_buffer.h", + "objc/Framework/Native/src/objc_frame_buffer.mm", "objc/Framework/Native/src/objc_video_decoder_factory.h", "objc/Framework/Native/src/objc_video_decoder_factory.mm", "objc/Framework/Native/src/objc_video_encoder_factory.h", "objc/Framework/Native/src/objc_video_encoder_factory.mm", + "objc/Framework/Native/src/objc_video_frame.h", + "objc/Framework/Native/src/objc_video_frame.mm", + "objc/Framework/Native/src/objc_video_renderer.h", + "objc/Framework/Native/src/objc_video_renderer.mm", + "objc/Framework/Native/src/objc_video_track_source.h", + "objc/Framework/Native/src/objc_video_track_source.mm", ] configs += [ "..:common_objc" ] @@ -913,8 +986,10 @@ if (is_ios || is_mac) { ":common_objc", ":videocodec_objc", ":videoframebuffer_objc", - ":videotracksource_objc", + ":videorenderer_objc", + ":wrapped_native_codec_objc", "../api:video_frame_api", + "../api:video_frame_api_i420", "../api/video_codecs:video_codecs_api", "../common_video", "../media:rtc_audio_video", @@ -964,7 +1039,7 @@ if (is_ios || is_mac) { ":video_toolbox_cc", ":videocodec_objc", ":videoframebuffer_objc", - ":videotracksource_objc", + ":videosource_objc", "../api:video_frame_api", "../api/video_codecs:video_codecs_api", "../common_video", diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm index ab1d620ff5..31ba49e596 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm @@ -38,8 +38,6 @@ #include "sdk/objc/Framework/Native/src/objc_video_encoder_factory.h" #endif -#include "Video/objcvideotracksource.h" -#include "api/videosourceproxy.h" // Adding the nogncheck to disable the including header check. // The no-media version PeerConnectionFactory doesn't depend on media related // C++ target. @@ -232,12 +230,8 @@ } - (RTCVideoSource *)videoSource { - rtc::scoped_refptr objcVideoTrackSource( - new rtc::RefCountedObject()); - return [[RTCVideoSource alloc] - initWithNativeVideoSource:webrtc::VideoTrackSourceProxy::Create(_signalingThread.get(), - _workerThread.get(), - objcVideoTrackSource)]; + return [[RTCVideoSource alloc] initWithSignalingThread:_signalingThread.get() + workerThread:_workerThread.get()]; } - (RTCVideoTrack *)videoTrackWithSource:(RTCVideoSource *)source diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm index f5d7195c21..9a5d3065d6 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm @@ -8,23 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#import "RTCVideoFrame+Private.h" - #import "WebRTC/RTCVideoFrame.h" + #import "WebRTC/RTCVideoFrameBuffer.h" -#include "api/video/video_frame.h" -#include "rtc_base/timeutils.h" -#include "sdk/objc/Framework/Native/api/video_frame_buffer.h" -#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h" - -id nativeToRtcFrameBuffer( - const rtc::scoped_refptr &buffer) { - return buffer->type() == webrtc::VideoFrameBuffer::Type::kNative ? - static_cast(buffer.get())->wrapped_frame_buffer() : - [[RTCI420Buffer alloc] initWithFrameBuffer:buffer->ToI420()]; -} - @implementation RTCVideoFrame { RTCVideoRotation _rotation; int64_t _timeStampNs; @@ -94,24 +81,4 @@ id nativeToRtcFrameBuffer( return self; } -- (instancetype)initWithNativeVideoFrame:(const webrtc::VideoFrame &)frame { - if (self = [self initWithBuffer:nativeToRtcFrameBuffer(frame.video_frame_buffer()) - rotation:RTCVideoRotation(frame.rotation()) - timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]) { - self.timeStamp = frame.timestamp(); - } - - return self; -} - -- (webrtc::VideoFrame)nativeVideoFrame { - rtc::scoped_refptr frameBuffer = - webrtc::ObjCToNativeVideoFrameBuffer(self.buffer); - webrtc::VideoFrame videoFrame(frameBuffer, - (webrtc::VideoRotation)self.rotation, - self.timeStampNs / rtc::kNumNanosecsPerMicrosec); - videoFrame.set_timestamp(self.timeStamp); - return videoFrame; -} - @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm index 639d060308..f5c4f011f5 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm @@ -9,13 +9,14 @@ */ #import "RTCI420Buffer+Private.h" -#import "RTCVideoFrame+Private.h" #import "RTCVideoRendererAdapter+Private.h" #import "WebRTC/RTCVideoFrame.h" #import "WebRTC/RTCVideoFrameBuffer.h" #include +#include "sdk/objc/Framework/Native/api/video_frame.h" + namespace webrtc { class VideoRendererAdapter @@ -27,7 +28,7 @@ class VideoRendererAdapter } void OnFrame(const webrtc::VideoFrame& nativeVideoFrame) override { - RTCVideoFrame* videoFrame = [[RTCVideoFrame alloc] initWithNativeVideoFrame:nativeVideoFrame]; + RTCVideoFrame* videoFrame = NativeToObjCVideoFrame(nativeVideoFrame); CGSize current_size = (videoFrame.rotation % 180 == 0) ? CGSizeMake(videoFrame.width, videoFrame.height) diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h index 1f34e047c2..bd424840d0 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource+Private.h @@ -35,6 +35,9 @@ NS_ASSUME_NONNULL_BEGIN (rtc::scoped_refptr)nativeMediaSource type:(RTCMediaSourceType)type NS_UNAVAILABLE; +- (instancetype)initWithSignalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread; + @end NS_ASSUME_NONNULL_END diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource.mm index fccf92e2e2..f380af4558 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoSource.mm @@ -12,16 +12,16 @@ #include "api/videosourceproxy.h" #include "rtc_base/checks.h" -#include "sdk/objc/Framework/Classes/Video/objcvideotracksource.h" +#include "sdk/objc/Framework/Native/src/objc_video_track_source.h" -static webrtc::ObjcVideoTrackSource *getObjcVideoSource( +static webrtc::ObjCVideoTrackSource *getObjCVideoSource( const rtc::scoped_refptr nativeSource) { webrtc::VideoTrackSourceProxy *proxy_source = static_cast(nativeSource.get()); - return static_cast(proxy_source->internal()); + return static_cast(proxy_source->internal()); } -// TODO(magjed): Refactor this class and target ObjcVideoTrackSource only once +// TODO(magjed): Refactor this class and target ObjCVideoTrackSource only once // RTCAVFoundationVideoSource is gone. See http://crbug/webrtc/7177 for more // info. @implementation RTCVideoSource { @@ -45,17 +45,26 @@ static webrtc::ObjcVideoTrackSource *getObjcVideoSource( return nil; } +- (instancetype)initWithSignalingThread:(rtc::Thread *)signalingThread + workerThread:(rtc::Thread *)workerThread { + rtc::scoped_refptr objCVideoTrackSource( + new rtc::RefCountedObject()); + + return [self initWithNativeVideoSource:webrtc::VideoTrackSourceProxy::Create( + signalingThread, workerThread, objCVideoTrackSource)]; +} + - (NSString *)description { NSString *stateString = [[self class] stringForState:self.state]; return [NSString stringWithFormat:@"RTCVideoSource( %p ): %@", self, stateString]; } - (void)capturer:(RTCVideoCapturer *)capturer didCaptureVideoFrame:(RTCVideoFrame *)frame { - getObjcVideoSource(_nativeVideoSource)->OnCapturedFrame(frame); + getObjCVideoSource(_nativeVideoSource)->OnCapturedFrame(frame); } - (void)adaptOutputFormatToWidth:(int)width height:(int)height fps:(int)fps { - getObjcVideoSource(_nativeVideoSource)->OnOutputFormatRequest(width, height, fps); + getObjCVideoSource(_nativeVideoSource)->OnOutputFormatRequest(width, height, fps); } #pragma mark - Private diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h b/sdk/objc/Framework/Native/api/video_frame.h similarity index 55% rename from sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h rename to sdk/objc/Framework/Native/api/video_frame.h index 7fd2247d17..c64d6fc28a 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h +++ b/sdk/objc/Framework/Native/api/video_frame.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * Copyright 2018 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 @@ -8,19 +8,17 @@ * be found in the AUTHORS file in the root of the source tree. */ -#import "RTCI420Buffer+Private.h" +#ifndef SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_FRAME_H_ +#define SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_FRAME_H_ + #import "WebRTC/RTCVideoFrame.h" -#import "WebRTC/RTCVideoFrameBuffer.h" #include "api/video/video_frame.h" -NS_ASSUME_NONNULL_BEGIN +namespace webrtc { -@interface RTCVideoFrame () +RTCVideoFrame* NativeToObjCVideoFrame(const VideoFrame& frame); -- (instancetype)initWithNativeVideoFrame:(const webrtc::VideoFrame &)frame; -- (webrtc::VideoFrame)nativeVideoFrame; +} // namespace webrtc -@end - -NS_ASSUME_NONNULL_END +#endif // SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_FRAME_H_ diff --git a/sdk/objc/Framework/Native/api/video_frame.mm b/sdk/objc/Framework/Native/api/video_frame.mm new file mode 100644 index 0000000000..7fe9124bee --- /dev/null +++ b/sdk/objc/Framework/Native/api/video_frame.mm @@ -0,0 +1,21 @@ +/* + * Copyright 2018 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. + */ + +#include "sdk/objc/Framework/Native/api/video_frame.h" + +#include "sdk/objc/Framework/Native/src/objc_video_frame.h" + +namespace webrtc { + +RTCVideoFrame* NativeToObjCVideoFrame(const VideoFrame& frame) { + return ToObjCVideoFrame(frame); +} + +} // namespace webrtc diff --git a/sdk/objc/Framework/Native/api/video_frame_buffer.h b/sdk/objc/Framework/Native/api/video_frame_buffer.h index 6790308346..1009c76bb7 100644 --- a/sdk/objc/Framework/Native/api/video_frame_buffer.h +++ b/sdk/objc/Framework/Native/api/video_frame_buffer.h @@ -18,9 +18,12 @@ namespace webrtc { -rtc::scoped_refptr ObjCToNativeVideoFrameBuffer( +rtc::scoped_refptr ObjCToNativeVideoFrameBuffer( id objc_video_frame_buffer); +id NativeToObjCVideoFrameBuffer( + const rtc::scoped_refptr& buffer); + } // namespace webrtc #endif // SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_FRAME_BUFFER_H_ diff --git a/sdk/objc/Framework/Native/api/video_frame_buffer.mm b/sdk/objc/Framework/Native/api/video_frame_buffer.mm index 17978e4106..149c22a01e 100644 --- a/sdk/objc/Framework/Native/api/video_frame_buffer.mm +++ b/sdk/objc/Framework/Native/api/video_frame_buffer.mm @@ -14,9 +14,14 @@ namespace webrtc { -rtc::scoped_refptr ObjCToNativeVideoFrameBuffer( +rtc::scoped_refptr ObjCToNativeVideoFrameBuffer( id objc_video_frame_buffer) { - return new rtc::RefCountedObject(objc_video_frame_buffer); + return new rtc::RefCountedObject(objc_video_frame_buffer); +} + +id NativeToObjCVideoFrameBuffer( + const rtc::scoped_refptr &buffer) { + return ToObjCVideoFrameBuffer(buffer); } } // namespace webrtc diff --git a/sdk/objc/Framework/Native/api/video_renderer.h b/sdk/objc/Framework/Native/api/video_renderer.h new file mode 100644 index 0000000000..712a3def15 --- /dev/null +++ b/sdk/objc/Framework/Native/api/video_renderer.h @@ -0,0 +1,28 @@ +/* + * Copyright 2018 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. + */ + +#ifndef SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_RENDERER_H_ +#define SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_RENDERER_H_ + +#import "WebRTC/RTCVideoRenderer.h" + +#include + +#include "api/video/video_frame.h" +#include "api/videosinkinterface.h" + +namespace webrtc { + +std::unique_ptr> ObjCToNativeVideoRenderer( + id objc_video_renderer); + +} // namespace webrtc + +#endif // SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_RENDERER_H_ diff --git a/sdk/objc/Framework/Native/api/video_renderer.mm b/sdk/objc/Framework/Native/api/video_renderer.mm new file mode 100644 index 0000000000..3fb5539f95 --- /dev/null +++ b/sdk/objc/Framework/Native/api/video_renderer.mm @@ -0,0 +1,23 @@ +/* + * Copyright 2018 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. + */ + +#include "sdk/objc/Framework/Native/api/video_renderer.h" + +#include "rtc_base/ptr_util.h" +#include "sdk/objc/Framework/Native/src/objc_video_renderer.h" + +namespace webrtc { + +std::unique_ptr> ObjCToNativeVideoRenderer( + id objc_video_renderer) { + return rtc::MakeUnique(objc_video_renderer); +} + +} // namespace webrtc diff --git a/sdk/objc/Framework/Native/src/objc_frame_buffer.h b/sdk/objc/Framework/Native/src/objc_frame_buffer.h index 94980fa367..dc9784a17d 100644 --- a/sdk/objc/Framework/Native/src/objc_frame_buffer.h +++ b/sdk/objc/Framework/Native/src/objc_frame_buffer.h @@ -39,6 +39,9 @@ class ObjCFrameBuffer : public VideoFrameBuffer { int height_; }; +id ToObjCVideoFrameBuffer( + const rtc::scoped_refptr& buffer); + } // namespace webrtc #endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_ diff --git a/sdk/objc/Framework/Native/src/objc_frame_buffer.mm b/sdk/objc/Framework/Native/src/objc_frame_buffer.mm index 74b96b458f..b943414046 100644 --- a/sdk/objc/Framework/Native/src/objc_frame_buffer.mm +++ b/sdk/objc/Framework/Native/src/objc_frame_buffer.mm @@ -11,6 +11,7 @@ #include "sdk/objc/Framework/Native/src/objc_frame_buffer.h" #import "WebRTC/RTCVideoFrameBuffer.h" +#import "sdk/objc/Framework/Classes/Video/RTCI420Buffer+Private.h" namespace webrtc { @@ -75,4 +76,12 @@ id ObjCFrameBuffer::wrapped_frame_buffer() const { return frame_buffer_; } +id ToObjCVideoFrameBuffer(const rtc::scoped_refptr& buffer) { + if (buffer->type() == VideoFrameBuffer::Type::kNative) { + return static_cast(buffer.get())->wrapped_frame_buffer(); + } else { + return [[RTCI420Buffer alloc] initWithFrameBuffer:buffer->ToI420()]; + } +} + } // namespace webrtc diff --git a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h index e6242e4081..fdd6feb168 100644 --- a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h +++ b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h @@ -34,12 +34,11 @@ class ObjCVideoDecoderFactory : public VideoDecoderFactory, const SdpVideoFormat& format) override; // Needed for WebRtcVideoDecoderFactory interface. - webrtc::VideoDecoder* CreateVideoDecoderWithParams( + VideoDecoder* CreateVideoDecoderWithParams( const cricket::VideoCodec& codec, cricket::VideoDecoderParams params) override; - webrtc::VideoDecoder* CreateVideoDecoder( - webrtc::VideoCodecType type) override; - void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override; + VideoDecoder* CreateVideoDecoder(VideoCodecType type) override; + void DestroyVideoDecoder(VideoDecoder* decoder) override; private: id decoder_factory_; diff --git a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm index fb3131642b..0525fae4eb 100644 --- a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm +++ b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm @@ -10,14 +10,14 @@ #include "sdk/objc/Framework/Native/src/objc_video_decoder_factory.h" -#import "NSString+StdString.h" -#import "RTCVideoCodec+Private.h" -#import "RTCWrappedNativeVideoDecoder.h" #import "WebRTC/RTCVideoCodec.h" #import "WebRTC/RTCVideoCodecFactory.h" #import "WebRTC/RTCVideoCodecH264.h" #import "WebRTC/RTCVideoFrame.h" #import "WebRTC/RTCVideoFrameBuffer.h" +#import "sdk/objc/Framework/Classes/Common/NSString+StdString.h" +#import "sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h" +#import "sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" diff --git a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h index a50188d11b..42ffd53c02 100644 --- a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h +++ b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h @@ -36,10 +36,9 @@ class ObjCVideoEncoderFactory : public VideoEncoderFactory, CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; // Needed for WebRtcVideoEncoderFactory interface. - webrtc::VideoEncoder* CreateVideoEncoder( - const cricket::VideoCodec& codec) override; + VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override; const std::vector& supported_codecs() const override; - void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override; + void DestroyVideoEncoder(VideoEncoder* encoder) override; private: id encoder_factory_; diff --git a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm index 548a3336f1..59356f74d4 100644 --- a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm +++ b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm @@ -12,16 +12,13 @@ #include -#import "NSString+StdString.h" -#import "RTCI420Buffer+Private.h" -#import "RTCVideoCodec+Private.h" -#import "RTCVideoFrame+Private.h" -#import "RTCWrappedNativeVideoEncoder.h" #import "WebRTC/RTCVideoCodec.h" #import "WebRTC/RTCVideoCodecFactory.h" #import "WebRTC/RTCVideoCodecH264.h" -#import "WebRTC/RTCVideoFrame.h" -#import "WebRTC/RTCVideoFrameBuffer.h" +#import "sdk/objc/Framework/Classes/Common/NSString+StdString.h" +#import "sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h" +#import "sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h" +#import "sdk/objc/Framework/Classes/Video/RTCI420Buffer+Private.h" #include "api/video/video_frame.h" #include "api/video_codecs/sdp_video_format.h" @@ -31,6 +28,7 @@ #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/logging.h" #include "sdk/objc/Framework/Classes/Common/helpers.h" +#include "sdk/objc/Framework/Native/src/objc_video_frame.h" namespace webrtc { @@ -92,7 +90,7 @@ class ObjCVideoEncoder : public VideoEncoder { [rtcFrameTypes addObject:@(RTCFrameType(frame_types->at(i)))]; } - return [encoder_ encode:[[RTCVideoFrame alloc] initWithNativeVideoFrame:frame] + return [encoder_ encode:ToObjCVideoFrame(frame) codecSpecificInfo:rtcCodecSpecificInfo frameTypes:rtcFrameTypes]; } diff --git a/sdk/objc/Framework/Native/src/objc_video_frame.h b/sdk/objc/Framework/Native/src/objc_video_frame.h new file mode 100644 index 0000000000..e3ef3df8af --- /dev/null +++ b/sdk/objc/Framework/Native/src/objc_video_frame.h @@ -0,0 +1,24 @@ +/* + * Copyright 2018 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. + */ + +#ifndef SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_FRAME_H_ +#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_FRAME_H_ + +#import "WebRTC/RTCVideoFrame.h" + +#include "api/video/video_frame.h" + +namespace webrtc { + +RTCVideoFrame* ToObjCVideoFrame(const VideoFrame& frame); + +} // namespace webrtc + +#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_FRAME_H_ diff --git a/sdk/objc/Framework/Native/src/objc_video_frame.mm b/sdk/objc/Framework/Native/src/objc_video_frame.mm new file mode 100644 index 0000000000..f0eee193dc --- /dev/null +++ b/sdk/objc/Framework/Native/src/objc_video_frame.mm @@ -0,0 +1,28 @@ +/* + * Copyright 2018 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. + */ + +#include "sdk/objc/Framework/Native/src/objc_video_frame.h" + +#include "rtc_base/timeutils.h" +#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h" + +namespace webrtc { + +RTCVideoFrame *ToObjCVideoFrame(const VideoFrame &frame) { + RTCVideoFrame *videoFrame = + [[RTCVideoFrame alloc] initWithBuffer:ToObjCVideoFrameBuffer(frame.video_frame_buffer()) + rotation:RTCVideoRotation(frame.rotation()) + timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]; + videoFrame.timeStamp = frame.timestamp(); + + return videoFrame; +} + +} // namespace webrtc diff --git a/sdk/objc/Framework/Native/src/objc_video_renderer.h b/sdk/objc/Framework/Native/src/objc_video_renderer.h new file mode 100644 index 0000000000..a71f6fdfc5 --- /dev/null +++ b/sdk/objc/Framework/Native/src/objc_video_renderer.h @@ -0,0 +1,36 @@ +/* + * Copyright 2018 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. + */ + +#ifndef SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_RENDERER_H_ +#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_RENDERER_H_ + +#import +#import + +#include "api/video/video_frame.h" +#include "api/videosinkinterface.h" + +@protocol RTCVideoRenderer; + +namespace webrtc { + +class ObjCVideoRenderer : public rtc::VideoSinkInterface { + public: + ObjCVideoRenderer(id renderer); + void OnFrame(const VideoFrame& nativeVideoFrame) override; + + private: + id renderer_; + CGSize size_; +}; + +} // namespace webrtc + +#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_RENDERER_H_ diff --git a/sdk/objc/Framework/Native/src/objc_video_renderer.mm b/sdk/objc/Framework/Native/src/objc_video_renderer.mm new file mode 100644 index 0000000000..aa8f023068 --- /dev/null +++ b/sdk/objc/Framework/Native/src/objc_video_renderer.mm @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#include "sdk/objc/Framework/Native/src/objc_video_renderer.h" + +#import "WebRTC/RTCVideoFrame.h" +#import "WebRTC/RTCVideoRenderer.h" + +#include "sdk/objc/Framework/Native/src/objc_video_frame.h" + +namespace webrtc { + +ObjCVideoRenderer::ObjCVideoRenderer(id renderer) + : renderer_(renderer), size_(CGSizeZero) {} + +void ObjCVideoRenderer::OnFrame(const VideoFrame& nativeVideoFrame) { + RTCVideoFrame* videoFrame = ToObjCVideoFrame(nativeVideoFrame); + + CGSize current_size = (videoFrame.rotation % 180 == 0) ? + CGSizeMake(videoFrame.width, videoFrame.height) : + CGSizeMake(videoFrame.height, videoFrame.width); + + if (!CGSizeEqualToSize(size_, current_size)) { + size_ = current_size; + [renderer_ setSize:size_]; + } + [renderer_ renderFrame:videoFrame]; +} + +} // namespace webrtc diff --git a/sdk/objc/Framework/Classes/Video/objcvideotracksource.h b/sdk/objc/Framework/Native/src/objc_video_track_source.h similarity index 94% rename from sdk/objc/Framework/Classes/Video/objcvideotracksource.h rename to sdk/objc/Framework/Native/src/objc_video_track_source.h index 656fd66118..8b0daebf66 100644 --- a/sdk/objc/Framework/Classes/Video/objcvideotracksource.h +++ b/sdk/objc/Framework/Native/src/objc_video_track_source.h @@ -19,9 +19,9 @@ RTC_FWD_DECL_OBJC_CLASS(RTCVideoFrame); namespace webrtc { -class ObjcVideoTrackSource : public rtc::AdaptedVideoTrackSource { +class ObjCVideoTrackSource : public rtc::AdaptedVideoTrackSource { public: - ObjcVideoTrackSource(); + ObjCVideoTrackSource(); // This class can not be used for implementing screen casting. Hopefully, this // function will be removed before we add that to iOS/Mac. diff --git a/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm b/sdk/objc/Framework/Native/src/objc_video_track_source.mm similarity index 79% rename from sdk/objc/Framework/Classes/Video/objcvideotracksource.mm rename to sdk/objc/Framework/Native/src/objc_video_track_source.mm index d67f610f92..72ed1bb140 100644 --- a/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm +++ b/sdk/objc/Framework/Native/src/objc_video_track_source.mm @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "sdk/objc/Framework/Classes/Video/objcvideotracksource.h" +#include "sdk/objc/Framework/Native/src/objc_video_track_source.h" #import "WebRTC/RTCVideoFrame.h" #import "WebRTC/RTCVideoFrameBuffer.h" @@ -18,14 +18,14 @@ namespace webrtc { -ObjcVideoTrackSource::ObjcVideoTrackSource() {} +ObjCVideoTrackSource::ObjCVideoTrackSource() {} -void ObjcVideoTrackSource::OnOutputFormatRequest(int width, int height, int fps) { +void ObjCVideoTrackSource::OnOutputFormatRequest(int width, int height, int fps) { cricket::VideoFormat format(width, height, cricket::VideoFormat::FpsToInterval(fps), 0); video_adapter()->OnOutputFormatRequest(format); } -void ObjcVideoTrackSource::OnCapturedFrame(RTCVideoFrame* frame) { +void ObjCVideoTrackSource::OnCapturedFrame(RTCVideoFrame *frame) { const int64_t timestamp_us = frame.timeStampNs / rtc::kNumNanosecsPerMicrosec; const int64_t translated_timestamp_us = timestamp_aligner_.TranslateTimestamp(timestamp_us, rtc::TimeMicros()); @@ -36,8 +36,15 @@ void ObjcVideoTrackSource::OnCapturedFrame(RTCVideoFrame* frame) { int crop_height; int crop_x; int crop_y; - if (!AdaptFrame(frame.width, frame.height, timestamp_us, &adapted_width, &adapted_height, - &crop_width, &crop_height, &crop_x, &crop_y)) { + if (!AdaptFrame(frame.width, + frame.height, + timestamp_us, + &adapted_width, + &adapted_height, + &crop_width, + &crop_height, + &crop_x, + &crop_y)) { return; } @@ -67,13 +74,13 @@ void ObjcVideoTrackSource::OnCapturedFrame(RTCVideoFrame* frame) { // Applying rotation is only supported for legacy reasons and performance is // not critical here. - webrtc::VideoRotation rotation = static_cast(frame.rotation); + VideoRotation rotation = static_cast(frame.rotation); if (apply_rotation() && rotation != kVideoRotation_0) { buffer = I420Buffer::Rotate(*buffer->ToI420(), rotation); rotation = kVideoRotation_0; } - OnFrame(webrtc::VideoFrame(buffer, rotation, translated_timestamp_us)); + OnFrame(VideoFrame(buffer, rotation, translated_timestamp_us)); } } // namespace webrtc