From 7e04281870274e5c3b216a91c865349c9b6c7a3e Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 5 Oct 2017 16:55:38 +0200 Subject: [PATCH] Injectable software video codecs in Obj-C. When injecting video codec factories in the Obj-C SDK, use the new peer connection API that uses webrtc::Video{De,En}CoderFactory classes and does not automatically add internal software codecs. Instead the injected factory can support internal VP8 and VP9 codecs through the included Obj-C classes RTCVideo{De,En}coderVP{8,9}. When not explicitly injecting any video codec factory, the old code path is still used and injects only H264 as an external codec and the internal codec factory is used. Bug: webrtc:7925 Change-Id: I657d30dfde71da9c0be341e213ab9f97a04caa58 Reviewed-on: https://webrtc-review.googlesource.com/3620 Commit-Queue: Anders Carlsson Reviewed-by: Magnus Jedvert Cr-Commit-Position: refs/heads/master@{#20175} --- examples/BUILD.gn | 4 + examples/objc/AppRTCMobile/ARDAppClient.m | 7 +- .../AppRTCMobile/ARDVideoDecoderFactory.h | 16 +++ .../AppRTCMobile/ARDVideoDecoderFactory.m | 39 +++++++ .../AppRTCMobile/ARDVideoEncoderFactory.h | 16 +++ .../AppRTCMobile/ARDVideoEncoderFactory.m | 64 +++++++++++ sdk/BUILD.gn | 16 ++- sdk/objc/DEPS | 4 +- .../RTCPeerConnectionFactory+Native.h | 23 +++- .../RTCPeerConnectionFactory.mm | 100 ++++++++++++------ .../PeerConnection/RTCVideoCodec+Private.h | 9 +- .../Classes/PeerConnection/RTCVideoCodec.mm | 55 +++++----- .../PeerConnection/RTCVideoCodecH264.mm | 7 +- .../PeerConnection/RTCVideoCodecVP8.mm | 41 +++++++ .../PeerConnection/RTCVideoCodecVP9.mm | 41 +++++++ .../PeerConnection/RTCVideoEncoderSettings.mm | 15 +++ .../PeerConnection/RTCVideoFrame+Private.h | 27 +++++ .../Classes/PeerConnection/RTCVideoFrame.mm | 32 ++++++ .../PeerConnection/RTCVideoRendererAdapter.mm | 15 +-- .../RTCWrappedNativeVideoDecoder.h | 24 +++++ .../RTCWrappedNativeVideoDecoder.mm | 63 +++++++++++ .../RTCWrappedNativeVideoEncoder.h | 25 +++++ .../RTCWrappedNativeVideoEncoder.mm | 71 +++++++++++++ .../VideoToolbox/RTCVideoEncoderH264.mm | 6 +- .../VideoToolbox/objc_video_decoder_factory.h | 17 ++- .../objc_video_decoder_factory.mm | 38 ++++++- .../VideoToolbox/objc_video_encoder_factory.h | 14 ++- .../objc_video_encoder_factory.mm | 65 ++++++++---- .../Framework/Headers/WebRTC/RTCVideoCodec.h | 14 --- .../Headers/WebRTC/RTCVideoCodecFactory.h | 8 +- .../Headers/WebRTC/RTCVideoCodecH264.h | 13 +++ .../Headers/WebRTC/RTCVideoDecoderVP8.h | 25 +++++ .../Headers/WebRTC/RTCVideoDecoderVP9.h | 25 +++++ .../Headers/WebRTC/RTCVideoEncoderVP8.h | 25 +++++ .../Headers/WebRTC/RTCVideoEncoderVP9.h | 25 +++++ 35 files changed, 856 insertions(+), 133 deletions(-) create mode 100644 examples/objc/AppRTCMobile/ARDVideoDecoderFactory.h create mode 100644 examples/objc/AppRTCMobile/ARDVideoDecoderFactory.m create mode 100644 examples/objc/AppRTCMobile/ARDVideoEncoderFactory.h create mode 100644 examples/objc/AppRTCMobile/ARDVideoEncoderFactory.m create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h create mode 100644 sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm create mode 100644 sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h create mode 100644 sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h create mode 100644 sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP8.h create mode 100644 sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP9.h diff --git a/examples/BUILD.gn b/examples/BUILD.gn index c976512b09..8f7ce889c8 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -233,6 +233,10 @@ if (is_ios || (is_mac && target_cpu != "x86")) { "objc/AppRTCMobile/ARDTURNClient+Internal.h", "objc/AppRTCMobile/ARDTURNClient.h", "objc/AppRTCMobile/ARDTURNClient.m", + "objc/AppRTCMobile/ARDVideoDecoderFactory.h", + "objc/AppRTCMobile/ARDVideoDecoderFactory.m", + "objc/AppRTCMobile/ARDVideoEncoderFactory.h", + "objc/AppRTCMobile/ARDVideoEncoderFactory.m", "objc/AppRTCMobile/ARDWebSocketChannel.h", "objc/AppRTCMobile/ARDWebSocketChannel.m", "objc/AppRTCMobile/RTCIceCandidate+JSON.h", diff --git a/examples/objc/AppRTCMobile/ARDAppClient.m b/examples/objc/AppRTCMobile/ARDAppClient.m index c699381842..2dfc617637 100644 --- a/examples/objc/AppRTCMobile/ARDAppClient.m +++ b/examples/objc/AppRTCMobile/ARDAppClient.m @@ -32,6 +32,8 @@ #import "ARDSignalingMessage.h" #import "ARDTURNClient+Internal.h" #import "ARDUtilities.h" +#import "ARDVideoDecoderFactory.h" +#import "ARDVideoEncoderFactory.h" #import "ARDWebSocketChannel.h" #import "RTCIceCandidate+JSON.h" #import "RTCSessionDescription+JSON.h" @@ -163,7 +165,10 @@ static int const kKbpsMultiplier = 1000; } - (void)configure { - _factory = [[RTCPeerConnectionFactory alloc] init]; + ARDVideoDecoderFactory *decoderFactory = [[ARDVideoDecoderFactory alloc] init]; + ARDVideoEncoderFactory *encoderFactory = [[ARDVideoEncoderFactory alloc] init]; + _factory = [[RTCPeerConnectionFactory alloc] initWithEncoderFactory:encoderFactory + decoderFactory:decoderFactory]; _messageQueue = [NSMutableArray array]; _iceServers = [NSMutableArray array]; _fileLogger = [[RTCFileLogger alloc] init]; diff --git a/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.h b/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.h new file mode 100644 index 0000000000..bc8be99214 --- /dev/null +++ b/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.h @@ -0,0 +1,16 @@ +/* + * Copyright 2017 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 +#import "WebRTC/RTCVideoCodecFactory.h" + +@interface ARDVideoDecoderFactory : NSObject + +@end diff --git a/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.m b/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.m new file mode 100644 index 0000000000..172635ebb4 --- /dev/null +++ b/examples/objc/AppRTCMobile/ARDVideoDecoderFactory.m @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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 "ARDVideoDecoderFactory.h" + +#import "WebRTC/RTCVideoCodecH264.h" +#import "WebRTC/RTCVideoDecoderVP8.h" +#import "WebRTC/RTCVideoDecoderVP9.h" + +@implementation ARDVideoDecoderFactory + +- (id)createDecoder:(RTCVideoCodecInfo *)info { + if ([info.name isEqualToString:@"H264"]) { + return [[RTCVideoDecoderH264 alloc] init]; + } else if ([info.name isEqualToString:@"VP8"]) { + return [RTCVideoDecoderVP8 vp8Decoder]; + } else if ([info.name isEqualToString:@"VP9"]) { + return [RTCVideoDecoderVP9 vp9Decoder]; + } + + return nil; +} + +- (NSArray *)supportedCodecs { + return @[ + [[RTCVideoCodecInfo alloc] initWithName:@"H264" parameters:nil], + [[RTCVideoCodecInfo alloc] initWithName:@"VP8" parameters:nil], + [[RTCVideoCodecInfo alloc] initWithName:@"VP9" parameters:nil] + ]; +} + +@end diff --git a/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.h b/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.h new file mode 100644 index 0000000000..9927ce4161 --- /dev/null +++ b/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.h @@ -0,0 +1,16 @@ +/* + * Copyright 2017 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 +#import "WebRTC/RTCVideoCodecFactory.h" + +@interface ARDVideoEncoderFactory : NSObject + +@end diff --git a/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.m b/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.m new file mode 100644 index 0000000000..a895011a72 --- /dev/null +++ b/examples/objc/AppRTCMobile/ARDVideoEncoderFactory.m @@ -0,0 +1,64 @@ +/* + * Copyright 2017 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 "ARDVideoEncoderFactory.h" + +#import "WebRTC/RTCVideoCodecH264.h" +#import "WebRTC/RTCVideoEncoderVP8.h" +#import "WebRTC/RTCVideoEncoderVP9.h" + +static NSString *kLevel31ConstrainedHigh = @"640c1f"; +static NSString *kLevel31ConstrainedBaseline = @"42e01f"; + +@implementation ARDVideoEncoderFactory + +- (id)createEncoder:(RTCVideoCodecInfo *)info { + if ([info.name isEqualToString:@"H264"]) { + return [[RTCVideoEncoderH264 alloc] initWithCodecInfo:info]; + } else if ([info.name isEqualToString:@"VP8"]) { + return [RTCVideoEncoderVP8 vp8Encoder]; + } else if ([info.name isEqualToString:@"VP9"]) { + return [RTCVideoEncoderVP9 vp9Encoder]; + } + + return nil; +} + +- (NSArray *)supportedCodecs { + NSMutableArray *codecs = [NSMutableArray array]; + + NSDictionary *constrainedHighParams = @{ + @"profile-level-id" : kLevel31ConstrainedHigh, + @"level-asymmetry-allowed" : @"1", + @"packetization-mode" : @"1", + }; + RTCVideoCodecInfo *constrainedHighInfo = + [[RTCVideoCodecInfo alloc] initWithName:@"H264" parameters:constrainedHighParams]; + [codecs addObject:constrainedHighInfo]; + + NSDictionary *constrainedBaselineParams = @{ + @"profile-level-id" : kLevel31ConstrainedBaseline, + @"level-asymmetry-allowed" : @"1", + @"packetization-mode" : @"1", + }; + RTCVideoCodecInfo *constrainedBaselineInfo = + [[RTCVideoCodecInfo alloc] initWithName:@"H264" parameters:constrainedBaselineParams]; + [codecs addObject:constrainedBaselineInfo]; + + RTCVideoCodecInfo *vp8Info = [[RTCVideoCodecInfo alloc] initWithName:@"VP8" parameters:nil]; + [codecs addObject:vp8Info]; + + RTCVideoCodecInfo *vp9Info = [[RTCVideoCodecInfo alloc] initWithName:@"VP9" parameters:nil]; + [codecs addObject:vp9Info]; + + return [codecs copy]; +} + +@end diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index e24ae4acdc..ffc1e8da03 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -434,7 +434,10 @@ if (is_ios || is_mac) { "objc/Framework/Classes/PeerConnection/RTCVideoCapturer.m", "objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm", + "objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm", + "objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm", "objc/Framework/Classes/PeerConnection/RTCVideoEncoderSettings.mm", + "objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm", "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h", @@ -443,6 +446,10 @@ if (is_ios || is_mac) { "objc/Framework/Classes/PeerConnection/RTCVideoSource.mm", "objc/Framework/Classes/PeerConnection/RTCVideoTrack+Private.h", "objc/Framework/Classes/PeerConnection/RTCVideoTrack.mm", + "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/Headers/WebRTC/RTCAVFoundationVideoSource.h", "objc/Framework/Headers/WebRTC/RTCAudioSource.h", "objc/Framework/Headers/WebRTC/RTCAudioTrack.h", @@ -493,9 +500,12 @@ if (is_ios || is_mac) { ":corevideoframebuffer_objc", ":videotracksource_objc", "../api:video_frame_api", + "../api/video_codecs:video_codecs_api", "../common_video", "../media:rtc_media_base", "../modules:module_api", + "../modules/video_coding:webrtc_vp8", + "../modules/video_coding:webrtc_vp9", "../pc:peerconnection", "../rtc_base:rtc_base", ] @@ -621,6 +631,11 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCSessionDescription.h", "objc/Framework/Headers/WebRTC/RTCTracing.h", "objc/Framework/Headers/WebRTC/RTCVideoCapturer.h", + "objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h", + "objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h", + "objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h", + "objc/Framework/Headers/WebRTC/RTCVideoEncoderVP8.h", + "objc/Framework/Headers/WebRTC/RTCVideoEncoderVP9.h", "objc/Framework/Headers/WebRTC/RTCVideoFrame.h", "objc/Framework/Headers/WebRTC/RTCVideoFrameBuffer.h", "objc/Framework/Headers/WebRTC/RTCVideoRenderer.h", @@ -628,7 +643,6 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCVideoTrack.h", "objc/Framework/Headers/WebRTC/RTCVideoViewShading.h", "objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h", - "objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h", "objc/Framework/Headers/WebRTC/WebRTC.h", ] if (rtc_use_metal_rendering) { diff --git a/sdk/objc/DEPS b/sdk/objc/DEPS index 634cabeee0..d0a5c328c1 100644 --- a/sdk/objc/DEPS +++ b/sdk/objc/DEPS @@ -15,4 +15,6 @@ include_rules = [ "+modules/video_coding", "+pc", "+system_wrappers", -] \ No newline at end of file + "+modules/audio_device", + "+modules/audio_processing", +] diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h index a4122de96f..5763151087 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h @@ -16,6 +16,8 @@ namespace webrtc { class AudioEncoderFactory; class AudioDecoderFactory; +class VideoEncoderFactory; +class VideoDecoderFactory; } // namespace webrtc @@ -33,16 +35,31 @@ NS_ASSUME_NONNULL_BEGIN */ @interface RTCPeerConnectionFactory () +- (instancetype)initNative NS_DESIGNATED_INITIALIZER; + +/* Initializer used when WebRTC is compiled with no media support */ +- (instancetype)initWithNoMedia; + /* Initialize object with injectable native audio/video encoder/decoder factories */ - (instancetype)initWithNativeAudioEncoderFactory: (rtc::scoped_refptr)audioEncoderFactory nativeAudioDecoderFactory: (rtc::scoped_refptr)audioDecoderFactory nativeVideoEncoderFactory: - (nullable cricket::WebRtcVideoEncoderFactory *)videoEncoderFactory + (std::unique_ptr)videoEncoderFactory nativeVideoDecoderFactory: - (nullable cricket::WebRtcVideoDecoderFactory *)videoDecoderFactory - NS_DESIGNATED_INITIALIZER; + (std::unique_ptr)videoDecoderFactory; + +/* Initialize object with legacy injectable native audio/video encoder/decoder factories + TODO(andersc): Remove this when backwards compatiblity is no longer needed. + */ +- (instancetype) + initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr)audioDecoderFactory + legacyNativeVideoEncoderFactory:(cricket::WebRtcVideoEncoderFactory*)videoEncoderFactory + legacyNativeVideoDecoderFactory:(cricket::WebRtcVideoDecoderFactory*)videoDecoderFactory; @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm index 594ee95775..34d21a56f4 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm @@ -28,8 +28,10 @@ #import "WebRTC/RTCVideoCodecH264.h" // The no-media version PeerConnectionFactory doesn't depend on these files, but the gn check tool // is not smart enough to take the #ifdef into account. -#include "api/audio_codecs/builtin_audio_decoder_factory.h" // nogncheck -#include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck +#include "api/audio_codecs/builtin_audio_decoder_factory.h" // nogncheck +#include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck +#include "modules/audio_device/include/audio_device.h" // nogncheck +#include "modules/audio_processing/include/audio_processing.h" // nogncheck #endif #include "Video/objcvideotracksource.h" @@ -52,16 +54,13 @@ - (instancetype)init { #ifdef HAVE_NO_MEDIA - return [self initWithNativeAudioEncoderFactory:nil - nativeAudioDecoderFactory:nil - nativeVideoEncoderFactory:nil - nativeVideoDecoderFactory:nil]; + return [self initWithNoMedia]; #else return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() - nativeVideoEncoderFactory:new webrtc::ObjCVideoEncoderFactory( + legacyNativeVideoEncoderFactory:new webrtc::ObjCVideoEncoderFactory( [[RTCVideoEncoderFactoryH264 alloc] init]) - nativeVideoDecoderFactory:new webrtc::ObjCVideoDecoderFactory( + legacyNativeVideoDecoderFactory:new webrtc::ObjCVideoDecoderFactory( [[RTCVideoDecoderFactoryH264 alloc] init])]; #endif } @@ -69,30 +68,24 @@ - (instancetype)initWithEncoderFactory:(nullable id)encoderFactory decoderFactory:(nullable id)decoderFactory { #ifdef HAVE_NO_MEDIA - return [self initWithNativeAudioEncoderFactory:nil - nativeAudioDecoderFactory:nil - nativeVideoEncoderFactory:nil - nativeVideoDecoderFactory:nil]; + return [self initWithNoMedia]; #else - cricket::WebRtcVideoEncoderFactory *native_encoder_factory = - encoderFactory ? new webrtc::ObjCVideoEncoderFactory(encoderFactory) : nullptr; - cricket::WebRtcVideoDecoderFactory *native_decoder_factory = - decoderFactory ? new webrtc::ObjCVideoDecoderFactory(decoderFactory) : nullptr; + std::unique_ptr native_encoder_factory; + std::unique_ptr native_decoder_factory; + if (encoderFactory) { + native_encoder_factory.reset(new webrtc::ObjCVideoEncoderFactory(encoderFactory)); + } + if (decoderFactory) { + native_decoder_factory.reset(new webrtc::ObjCVideoDecoderFactory(decoderFactory)); + } return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() - nativeVideoEncoderFactory:native_encoder_factory - nativeVideoDecoderFactory:native_decoder_factory]; + nativeVideoEncoderFactory:std::move(native_encoder_factory) + nativeVideoDecoderFactory:std::move(native_decoder_factory)]; #endif } -- (instancetype)initWithNativeAudioEncoderFactory: - (rtc::scoped_refptr)audioEncoderFactory - nativeAudioDecoderFactory: - (rtc::scoped_refptr)audioDecoderFactory - nativeVideoEncoderFactory: - (nullable cricket::WebRtcVideoEncoderFactory *)videoEncoderFactory - nativeVideoDecoderFactory: - (nullable cricket::WebRtcVideoDecoderFactory *)videoDecoderFactory { +- (instancetype)initNative { if (self = [super init]) { _networkThread = rtc::Thread::CreateWithSocketServer(); BOOL result = _networkThread->Start(); @@ -105,7 +98,12 @@ _signalingThread = rtc::Thread::Create(); result = _signalingThread->Start(); NSAssert(result, @"Failed to start signaling thread."); -#ifdef HAVE_NO_MEDIA + } + return self; +} + +- (instancetype)initWithNoMedia { + if (self = [self initNative]) { _nativeFactory = webrtc::CreateModularPeerConnectionFactory( _networkThread.get(), _workerThread.get(), @@ -113,9 +111,51 @@ std::unique_ptr(), std::unique_ptr(), std::unique_ptr()); + NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); + } + return self; +} + +- (instancetype)initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr)audioDecoderFactory + nativeVideoEncoderFactory: + (std::unique_ptr)videoEncoderFactory + nativeVideoDecoderFactory: + (std::unique_ptr)videoDecoderFactory { +#ifdef HAVE_NO_MEDIA + return [self initWithNoMedia]; #else - // Ownership of encoder/decoder factories is passed on to the - // peerconnectionfactory, that handles deleting them. + if (self = [self initNative]) { + _nativeFactory = webrtc::CreatePeerConnectionFactory(_networkThread.get(), + _workerThread.get(), + _signalingThread.get(), + nullptr, // audio device module + audioEncoderFactory, + audioDecoderFactory, + std::move(videoEncoderFactory), + std::move(videoDecoderFactory), + nullptr, // audio mixer + nullptr // audio processing + ); + NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); + } + return self; +#endif +} + +- (instancetype) + initWithNativeAudioEncoderFactory: + (rtc::scoped_refptr)audioEncoderFactory + nativeAudioDecoderFactory: + (rtc::scoped_refptr)audioDecoderFactory + legacyNativeVideoEncoderFactory:(cricket::WebRtcVideoEncoderFactory *)videoEncoderFactory + legacyNativeVideoDecoderFactory:(cricket::WebRtcVideoDecoderFactory *)videoDecoderFactory { +#ifdef HAVE_NO_MEDIA + return [self initWithNoMedia]; +#else + if (self = [self initNative]) { _nativeFactory = webrtc::CreatePeerConnectionFactory(_networkThread.get(), _workerThread.get(), _signalingThread.get(), @@ -124,10 +164,10 @@ audioDecoderFactory, videoEncoderFactory, videoDecoderFactory); -#endif NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); } return self; +#endif } - (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints { diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h index 1edaf15a9c..97ee5138ad 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h @@ -12,6 +12,7 @@ #import "WebRTC/RTCVideoCodecH264.h" +#include "api/video_codecs/sdp_video_format.h" #include "common_video/include/video_frame.h" #include "media/base/codec.h" #include "modules/video_coding/include/video_codec_interface.h" @@ -29,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN @interface RTCVideoEncoderSettings () - (instancetype)initWithNativeVideoCodec:(const webrtc::VideoCodec *__nullable)videoCodec; +- (webrtc::VideoCodec)nativeVideoCodec; @end @@ -48,10 +50,11 @@ NS_ASSUME_NONNULL_BEGIN @interface RTCVideoCodecInfo () +- (instancetype)initWithNativeSdpVideoFormat:(webrtc::SdpVideoFormat)format; +- (webrtc::SdpVideoFormat)nativeSdpVideoFormat; + +/* TODO(andersc): These are deprecated, remove when no longer in use. */ - (instancetype)initWithNativeVideoCodec:(cricket::VideoCodec)videoCodec; -- (instancetype)initWithPayload:(NSInteger)payload - name:(NSString *)name - parameters:(NSDictionary *)parameters; - (cricket::VideoCodec)nativeVideoCodec; @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm index 3e4c3162a1..df5946df81 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm @@ -16,7 +16,6 @@ @implementation RTCVideoCodecInfo -@synthesize payload = _payload; @synthesize name = _name; @synthesize parameters = _parameters; @@ -27,7 +26,6 @@ - (instancetype)initWithName:(NSString *)name parameters:(nullable NSDictionary *)parameters { if (self = [super init]) { - _payload = 0; _name = name; _parameters = (parameters ? parameters : @{}); } @@ -35,40 +33,22 @@ return self; } -- (instancetype)initWithNativeVideoCodec:(cricket::VideoCodec)videoCodec { +- (instancetype)initWithNativeSdpVideoFormat:(webrtc::SdpVideoFormat)format { NSMutableDictionary *params = [NSMutableDictionary dictionary]; - for (auto it = videoCodec.params.begin(); it != videoCodec.params.end(); ++it) { + for (auto it = format.parameters.begin(); it != format.parameters.end(); ++it) { [params setObject:[NSString stringForStdString:it->second] forKey:[NSString stringForStdString:it->first]]; } - return [self initWithPayload:videoCodec.id - name:[NSString stringForStdString:videoCodec.name] - parameters:params]; + return [self initWithName:[NSString stringForStdString:format.name] parameters:params]; } -- (instancetype)initWithPayload:(NSInteger)payload - name:(NSString *)name - parameters:(NSDictionary *)parameters { - if (self = [self initWithName:name parameters:parameters]) { - _payload = payload; - } - - return self; -} - -- (cricket::VideoCodec)nativeVideoCodec { - cricket::VideoCodec codec([NSString stdStringForString:_name]); - for (NSString *paramKey in _parameters.allKeys) { - codec.SetParam([NSString stdStringForString:paramKey], - [NSString stdStringForString:_parameters[paramKey]]); - } - - return codec; +- (instancetype)initWithNativeVideoCodec:(cricket::VideoCodec)videoCodec { + return [self + initWithNativeSdpVideoFormat:webrtc::SdpVideoFormat(videoCodec.name, videoCodec.params)]; } - (BOOL)isEqualToCodecInfo:(RTCVideoCodecInfo *)info { if (!info || - self.payload != info.payload || ![self.name isEqualToString:info.name] || ![self.parameters isEqualToDictionary:info.parameters]) { return NO; @@ -85,7 +65,28 @@ } - (NSUInteger)hash { - return [self.name hash] ^ self.payload ^ [self.parameters hash]; + return [self.name hash] ^ [self.parameters hash]; +} + +- (webrtc::SdpVideoFormat)nativeSdpVideoFormat { + std::map parameters; + for (NSString *paramKey in _parameters.allKeys) { + std::string key = [NSString stdStringForString:paramKey]; + std::string value = [NSString stdStringForString:_parameters[paramKey]]; + parameters[key] = value; + } + + return webrtc::SdpVideoFormat([NSString stdStringForString:_name], parameters); +} + +- (cricket::VideoCodec)nativeVideoCodec { + cricket::VideoCodec codec([NSString stdStringForString:_name]); + for (NSString *paramKey in _parameters.allKeys) { + codec.SetParam([NSString stdStringForString:paramKey], + [NSString stdStringForString:_parameters[paramKey]]); + } + + return codec; } @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm index 1a09fe158b..b5322b601a 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm @@ -20,6 +20,7 @@ #include "system_wrappers/include/field_trial.h" const char kHighProfileExperiment[] = "WebRTC-H264HighProfile"; +static NSString *kH264CodecName = @"H264"; static NSString *kLevel31ConstrainedHigh = @"640c1f"; static NSString *kLevel31ConstrainedBaseline = @"42e01f"; @@ -35,7 +36,7 @@ bool IsHighProfileEnabled() { - (webrtc::CodecSpecificInfo)nativeCodecSpecificInfo { webrtc::CodecSpecificInfo codecSpecificInfo; codecSpecificInfo.codecType = webrtc::kVideoCodecH264; - codecSpecificInfo.codec_name = "H264"; + codecSpecificInfo.codec_name = [kH264CodecName cStringUsingEncoding:NSUTF8StringEncoding]; codecSpecificInfo.codecSpecific.H264.packetization_mode = (webrtc::H264PacketizationMode)_packetizationMode; @@ -49,7 +50,7 @@ bool IsHighProfileEnabled() { - (NSArray *)supportedCodecs { NSMutableArray *codecs = [NSMutableArray array]; - NSString *codecName = [NSString stringWithUTF8String:cricket::kH264CodecName]; + NSString *codecName = kH264CodecName; if (IsHighProfileEnabled()) { NSDictionary *constrainedHighParams = @{ @@ -88,7 +89,7 @@ bool IsHighProfileEnabled() { } - (NSArray *)supportedCodecs { - NSString *codecName = [NSString stringWithUTF8String:cricket::kH264CodecName]; + NSString *codecName = kH264CodecName; return @[ [[RTCVideoCodecInfo alloc] initWithName:codecName parameters:nil] ]; } diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm new file mode 100644 index 0000000000..fa785f4ca4 --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP8.mm @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 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 + +#import "RTCWrappedNativeVideoDecoder.h" +#import "RTCWrappedNativeVideoEncoder.h" +#import "WebRTC/RTCVideoDecoderVP8.h" +#import "WebRTC/RTCVideoEncoderVP8.h" + +#include "modules/video_coding/codecs/vp8/include/vp8.h" + +#pragma mark - Encoder + +@implementation RTCVideoEncoderVP8 + ++ (id)vp8Encoder { + return [[RTCWrappedNativeVideoEncoder alloc] + initWithNativeEncoder:std::unique_ptr(webrtc::VP8Encoder::Create())]; +} + +@end + +#pragma mark - Decoder + +@implementation RTCVideoDecoderVP8 + ++ (id)vp8Decoder { + return [[RTCWrappedNativeVideoDecoder alloc] + initWithNativeDecoder:std::unique_ptr(webrtc::VP8Decoder::Create())]; +} + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm new file mode 100644 index 0000000000..60fe54f6cb --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecVP9.mm @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017 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 + +#import "RTCWrappedNativeVideoDecoder.h" +#import "RTCWrappedNativeVideoEncoder.h" +#import "WebRTC/RTCVideoDecoderVP9.h" +#import "WebRTC/RTCVideoEncoderVP9.h" + +#include "modules/video_coding/codecs/vp9/include/vp9.h" + +#pragma mark - Encoder + +@implementation RTCVideoEncoderVP9 + ++ (id)vp9Encoder { + return [[RTCWrappedNativeVideoEncoder alloc] + initWithNativeEncoder:std::unique_ptr(webrtc::VP9Encoder::Create())]; +} + +@end + +#pragma mark - Decoder + +@implementation RTCVideoDecoderVP9 + ++ (id)vp9Decoder { + return [[RTCWrappedNativeVideoDecoder alloc] + initWithNativeDecoder:std::unique_ptr(webrtc::VP9Decoder::Create())]; +} + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoEncoderSettings.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoEncoderSettings.mm index 0fb8e46f2e..95233ec4ba 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoEncoderSettings.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoEncoderSettings.mm @@ -48,4 +48,19 @@ return self; } +- (webrtc::VideoCodec)nativeVideoCodec { + webrtc::VideoCodec videoCodec; + videoCodec.width = _width; + videoCodec.height = _height; + videoCodec.startBitrate = _startBitrate; + videoCodec.maxBitrate = _maxBitrate; + videoCodec.minBitrate = _minBitrate; + videoCodec.targetBitrate = _targetBitrate; + videoCodec.maxBitrate = _maxBitrate; + videoCodec.qpMax = _qpMax; + videoCodec.mode = (webrtc::VideoCodecMode)_mode; + + return videoCodec; +} + @end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h new file mode 100644 index 0000000000..43d3fbf68e --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 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 "RTCI420Buffer+Private.h" +#import "WebRTC/RTCVideoFrame.h" +#import "WebRTC/RTCVideoFrameBuffer.h" + +#include "api/video/video_frame.h" +#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCVideoFrame () + +- (instancetype)initWithNativeVideoFrame:(const webrtc::VideoFrame &)frame; +- (webrtc::VideoFrame)nativeVideoFrame; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm index cf4216e825..19dd2452cd 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm @@ -8,9 +8,21 @@ * 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" + +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; @@ -80,4 +92,24 @@ 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 = + new rtc::RefCountedObject(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 736803b913..79cc1a71dd 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm @@ -9,6 +9,7 @@ */ #import "RTCI420Buffer+Private.h" +#import "RTCVideoFrame+Private.h" #import "RTCVideoRendererAdapter+Private.h" #import "WebRTC/RTCVideoFrame.h" #import "WebRTC/RTCVideoFrameBuffer.h" @@ -27,19 +28,7 @@ class VideoRendererAdapter } void OnFrame(const webrtc::VideoFrame& nativeVideoFrame) override { - rtc::scoped_refptr video_frame_buffer = nativeVideoFrame.video_frame_buffer(); - id rtc_frame_buffer; - if (video_frame_buffer->type() == VideoFrameBuffer::Type::kNative) { - rtc::scoped_refptr objc_frame_buffer( - static_cast(video_frame_buffer.get())); - rtc_frame_buffer = (id)objc_frame_buffer->wrapped_frame_buffer(); - } else { - rtc_frame_buffer = [[RTCI420Buffer alloc] initWithFrameBuffer:video_frame_buffer->ToI420()]; - } - RTCVideoFrame* videoFrame = [[RTCVideoFrame alloc] - initWithBuffer:rtc_frame_buffer - rotation:static_cast(nativeVideoFrame.rotation()) - timeStampNs:nativeVideoFrame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]; + RTCVideoFrame* videoFrame = [[RTCVideoFrame alloc] initWithNativeVideoFrame:nativeVideoFrame]; CGSize current_size = (videoFrame.rotation % 180 == 0) ? CGSizeMake(videoFrame.width, videoFrame.height) diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h new file mode 100644 index 0000000000..74cfaeb861 --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017 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 + +#import "WebRTC/RTCVideoCodec.h" +#include "api/video_codecs/video_decoder.h" +#include "media/base/codec.h" + +@interface RTCWrappedNativeVideoDecoder : NSObject + +- (instancetype)initWithNativeDecoder:(std::unique_ptr)decoder; + +/* This moves the ownership of the wrapped decoder to the caller. */ +- (std::unique_ptr)releaseWrappedDecoder; + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm new file mode 100644 index 0000000000..7d82c5b8e3 --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoDecoder.mm @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017 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 + +#import "NSString+StdString.h" +#import "RTCWrappedNativeVideoDecoder.h" + +@implementation RTCWrappedNativeVideoDecoder { + std::unique_ptr _wrappedDecoder; +} + +- (instancetype)initWithNativeDecoder:(std::unique_ptr)decoder { + if (self = [super init]) { + _wrappedDecoder = std::move(decoder); + } + + return self; +} + +- (std::unique_ptr)releaseWrappedDecoder { + return std::move(_wrappedDecoder); +} + +#pragma mark - RTCVideoDecoder + +- (void)setCallback:(RTCVideoDecoderCallback)callback { + RTC_NOTREACHED(); +} + +- (NSInteger)startDecodeWithSettings:(RTCVideoEncoderSettings *)settings + numberOfCores:(int)numberOfCores { + RTC_NOTREACHED(); + return 0; +} + +- (NSInteger)releaseDecoder { + RTC_NOTREACHED(); + return 0; +} + +- (NSInteger)decode:(RTCEncodedImage *)encodedImage + missingFrames:(BOOL)missingFrames + fragmentationHeader:(RTCRtpFragmentationHeader *)fragmentationHeader + codecSpecificInfo:(__nullable id)info + renderTimeMs:(int64_t)renderTimeMs { + RTC_NOTREACHED(); + return 0; +} + +- (NSString *)implementationName { + RTC_NOTREACHED(); + return nil; +} + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h new file mode 100644 index 0000000000..5b95d33eba --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 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 + +#import "WebRTC/RTCVideoCodec.h" +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_encoder.h" +#include "media/base/codec.h" + +@interface RTCWrappedNativeVideoEncoder : NSObject + +- (instancetype)initWithNativeEncoder:(std::unique_ptr)encoder; + +/* This moves the ownership of the wrapped encoder to the caller. */ +- (std::unique_ptr)releaseWrappedEncoder; + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm new file mode 100644 index 0000000000..9d2f81b3cc --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCWrappedNativeVideoEncoder.mm @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 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 + +#import "NSString+StdString.h" +#import "RTCWrappedNativeVideoEncoder.h" + +@implementation RTCWrappedNativeVideoEncoder { + std::unique_ptr _wrappedEncoder; +} + +- (instancetype)initWithNativeEncoder:(std::unique_ptr)encoder { + if (self = [super init]) { + _wrappedEncoder = std::move(encoder); + } + + return self; +} + +- (std::unique_ptr)releaseWrappedEncoder { + return std::move(_wrappedEncoder); +} + +#pragma mark - RTCVideoEncoder + +- (void)setCallback:(RTCVideoEncoderCallback)callback { + RTC_NOTREACHED(); +} + +- (NSInteger)startEncodeWithSettings:(RTCVideoEncoderSettings *)settings + numberOfCores:(int)numberOfCores { + RTC_NOTREACHED(); + return 0; +} + +- (NSInteger)releaseEncoder { + RTC_NOTREACHED(); + return 0; +} + +- (NSInteger)encode:(RTCVideoFrame *)frame + codecSpecificInfo:(id)info + frameTypes:(NSArray *)frameTypes { + RTC_NOTREACHED(); + return 0; +} + +- (int)setBitrate:(uint32_t)bitrateKbit framerate:(uint32_t)framerate { + RTC_NOTREACHED(); + return 0; +} + +- (NSString *)implementationName { + RTC_NOTREACHED(); + return nil; +} + +- (RTCVideoEncoderQpThresholds *)scalingSettings { + RTC_NOTREACHED(); + return nil; +} + +@end diff --git a/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm b/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm index a953ce035f..7a6629ed36 100644 --- a/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm +++ b/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm @@ -169,9 +169,9 @@ void compressionOutputCallback(void *encoder, // specific VideoToolbox profile for the specified level, AutoLevel will be // returned. The user must initialize the encoder with a resolution and // framerate conforming to the selected H264 level regardless. -CFStringRef ExtractProfile(const cricket::VideoCodec &codec) { +CFStringRef ExtractProfile(webrtc::SdpVideoFormat videoFormat) { const rtc::Optional profile_level_id = - webrtc::H264::ParseSdpProfileLevelId(codec.params); + webrtc::H264::ParseSdpProfileLevelId(videoFormat.parameters); RTC_DCHECK(profile_level_id); switch (profile_level_id->profile) { case webrtc::H264::kProfileConstrainedBaseline: @@ -302,7 +302,7 @@ CFStringRef ExtractProfile(const cricket::VideoCodec &codec) { _bitrateAdjuster.reset(new webrtc::BitrateAdjuster( webrtc::Clock::GetRealTimeClock(), .5, .95)); _packetizationMode = RTCH264PacketizationModeNonInterleaved; - _profile = ExtractProfile([codecInfo nativeVideoCodec]); + _profile = ExtractProfile([codecInfo nativeSdpVideoFormat]); LOG(LS_INFO) << "Using profile " << CFStringToString(_profile); RTC_CHECK([codecInfo.name isEqualToString:@"H264"]); diff --git a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h index 93510e755d..a0106ff83f 100644 --- a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h +++ b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h @@ -11,6 +11,7 @@ #ifndef SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_DECODER_FACTORY_H_ #define SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_DECODER_FACTORY_H_ +#include "api/video_codecs/video_decoder_factory.h" #include "media/base/codec.h" #include "media/engine/webrtcvideodecoderfactory.h" @@ -18,22 +19,30 @@ namespace webrtc { -class ObjCVideoDecoderFactory : public cricket::WebRtcVideoDecoderFactory { +// TODO(andersc): Remove the inheritance from cricket::WebRtcVideoDecoderFactory +// when the legacy path in [RTCPeerConnectionFactory init] is no longer needed. +class ObjCVideoDecoderFactory : public VideoDecoderFactory, + public cricket::WebRtcVideoDecoderFactory { public: explicit ObjCVideoDecoderFactory(id); ~ObjCVideoDecoderFactory(); id wrapped_decoder_factory() const; - VideoDecoder* CreateVideoDecoderWithParams( + std::vector GetSupportedFormats() const override; + std::unique_ptr CreateVideoDecoder( + const SdpVideoFormat& format) override; + + // Needed for WebRtcVideoDecoderFactory interface. + webrtc::VideoDecoder* CreateVideoDecoderWithParams( const cricket::VideoCodec& codec, cricket::VideoDecoderParams params) override; - + webrtc::VideoDecoder* CreateVideoDecoder( + webrtc::VideoCodecType type) override; void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override; private: id decoder_factory_; - std::vector supported_codecs_; }; } // namespace webrtc diff --git a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.mm b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.mm index e20f1ae5c0..ab615a3968 100644 --- a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.mm +++ b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.mm @@ -12,12 +12,14 @@ #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" +#include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "modules/include/module_common_types.h" #include "modules/video_coding/include/video_codec_interface.h" @@ -103,19 +105,47 @@ id ObjCVideoDecoderFactory::wrapped_decoder_factory() co return decoder_factory_; } -VideoDecoder *ObjCVideoDecoderFactory::CreateVideoDecoderWithParams( - const cricket::VideoCodec &codec, cricket::VideoDecoderParams params) { - NSString *codecName = [NSString stringWithUTF8String:codec.name.c_str()]; +std::unique_ptr ObjCVideoDecoderFactory::CreateVideoDecoder( + const SdpVideoFormat &format) { + NSString *codecName = [NSString stringWithUTF8String:format.name.c_str()]; for (RTCVideoCodecInfo *codecInfo in decoder_factory_.supportedCodecs) { if ([codecName isEqualToString:codecInfo.name]) { id decoder = [decoder_factory_ createDecoder:codecInfo]; - return new ObjCVideoDecoder(decoder); + + if ([decoder isKindOfClass:[RTCWrappedNativeVideoDecoder class]]) { + return [(RTCWrappedNativeVideoDecoder *)decoder releaseWrappedDecoder]; + } else { + return std::unique_ptr(new ObjCVideoDecoder(decoder)); + } } } return nullptr; } +std::vector ObjCVideoDecoderFactory::GetSupportedFormats() const { + std::vector supported_formats; + for (RTCVideoCodecInfo *supportedCodec in decoder_factory_.supportedCodecs) { + SdpVideoFormat format = [supportedCodec nativeSdpVideoFormat]; + supported_formats.push_back(format); + } + + return supported_formats; +} + +// WebRtcVideoDecoderFactory + +VideoDecoder *ObjCVideoDecoderFactory::CreateVideoDecoderWithParams( + const cricket::VideoCodec &codec, cricket::VideoDecoderParams params) { + return CreateVideoDecoder(SdpVideoFormat(codec.name, codec.params)).release(); +} + +VideoDecoder *ObjCVideoDecoderFactory::CreateVideoDecoder(VideoCodecType type) { + // This is implemented to avoid hiding an overloaded virtual function + RTC_NOTREACHED(); + return nullptr; +} + void ObjCVideoDecoderFactory::DestroyVideoDecoder(VideoDecoder *decoder) { delete decoder; decoder = nullptr; diff --git a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h index cb8dda6a0a..6cdfc56f54 100644 --- a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h +++ b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h @@ -13,19 +13,29 @@ #import +#include "api/video_codecs/video_encoder_factory.h" #include "media/engine/webrtcvideoencoderfactory.h" @protocol RTCVideoEncoderFactory; namespace webrtc { -class ObjCVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory { +// TODO(andersc): Remove the inheritance from cricket::WebRtcVideoEncoderFactory +// when the legacy path in [RTCPeerConnectionFactory init] is no longer needed. +class ObjCVideoEncoderFactory : public VideoEncoderFactory, + public cricket::WebRtcVideoEncoderFactory { public: explicit ObjCVideoEncoderFactory(id); ~ObjCVideoEncoderFactory(); id wrapped_encoder_factory() const; + std::vector GetSupportedFormats() const override; + std::unique_ptr CreateVideoEncoder( + const SdpVideoFormat& format) override; + CodecInfo QueryVideoEncoder(const SdpVideoFormat& format) const override; + + // Needed for WebRtcVideoEncoderFactory interface. webrtc::VideoEncoder* CreateVideoEncoder( const cricket::VideoCodec& codec) override; const std::vector& supported_codecs() const override; @@ -33,6 +43,8 @@ class ObjCVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory { private: id encoder_factory_; + + // Needed for WebRtcVideoEncoderFactory interface. mutable std::vector supported_codecs_; }; diff --git a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm index 230719ec6d..f78b74b182 100644 --- a/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm +++ b/sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm @@ -15,6 +15,8 @@ #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" @@ -22,12 +24,12 @@ #import "WebRTC/RTCVideoFrameBuffer.h" #include "api/video/video_frame.h" +#include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_encoder.h" #include "modules/include/module_common_types.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/logging.h" -#include "rtc_base/timeutils.h" #include "sdk/objc/Framework/Classes/Common/helpers.h" #include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h" @@ -35,21 +37,6 @@ namespace webrtc { namespace { -id nativeToRtcFrameBuffer(const rtc::scoped_refptr &buffer) { - return buffer->type() == VideoFrameBuffer::Type::kNative ? - static_cast(buffer.get())->wrapped_frame_buffer() : - [[RTCI420Buffer alloc] initWithFrameBuffer:buffer->ToI420()]; -} - -RTCVideoFrame *nativeToRtcFrame(const VideoFrame &frame) { - RTCVideoFrame *rtcFrame = - [[RTCVideoFrame alloc] initWithBuffer:nativeToRtcFrameBuffer(frame.video_frame_buffer()) - rotation:RTCVideoRotation(frame.rotation()) - timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec]; - rtcFrame.timeStamp = frame.timestamp(); - return rtcFrame; -} - class ObjCVideoEncoder : public VideoEncoder { public: ObjCVideoEncoder(id encoder) @@ -69,7 +56,7 @@ class ObjCVideoEncoder : public VideoEncoder { RTCRtpFragmentationHeader *_Nonnull header) { EncodedImage encodedImage = [frame nativeEncodedImage]; - // Handle types than can be converted into one of CodecSpecificInfo's hard coded cases. + // Handle types that can be converted into one of CodecSpecificInfo's hard coded cases. CodecSpecificInfo codecSpecificInfo; if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) { codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info nativeCodecSpecificInfo]; @@ -106,7 +93,7 @@ class ObjCVideoEncoder : public VideoEncoder { [rtcFrameTypes addObject:@(RTCFrameType(frame_types->at(i)))]; } - return [encoder_ encode:nativeToRtcFrame(frame) + return [encoder_ encode:[[RTCVideoFrame alloc] initWithNativeVideoFrame:frame] codecSpecificInfo:rtcCodecSpecificInfo frameTypes:rtcFrameTypes]; } @@ -143,8 +130,44 @@ id ObjCVideoEncoderFactory::wrapped_encoder_factory() co return encoder_factory_; } +std::vector ObjCVideoEncoderFactory::GetSupportedFormats() const { + std::vector supported_formats; + for (RTCVideoCodecInfo *supportedCodec in encoder_factory_.supportedCodecs) { + SdpVideoFormat format = [supportedCodec nativeSdpVideoFormat]; + supported_formats.push_back(format); + } + + return supported_formats; +} + +VideoEncoderFactory::CodecInfo ObjCVideoEncoderFactory::QueryVideoEncoder( + const SdpVideoFormat &format) const { + // TODO(andersc): This is a hack until we figure out how this should be done properly. + NSString *formatName = [NSString stringForStdString:format.name]; + NSSet *wrappedSoftwareFormats = [NSSet setWithObjects:@"VP8", @"VP9", nil]; + + CodecInfo codec_info; + codec_info.is_hardware_accelerated = ![wrappedSoftwareFormats containsObject:formatName]; + codec_info.has_internal_source = false; + return codec_info; +} + +std::unique_ptr ObjCVideoEncoderFactory::CreateVideoEncoder( + const SdpVideoFormat &format) { + RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeSdpVideoFormat:format]; + id encoder = [encoder_factory_ createEncoder:info]; + if ([encoder isKindOfClass:[RTCWrappedNativeVideoEncoder class]]) { + return [(RTCWrappedNativeVideoEncoder *)encoder releaseWrappedEncoder]; + } else { + return std::unique_ptr(new ObjCVideoEncoder(encoder)); + } +} + +// WebRtcVideoEncoderFactory + VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder(const cricket::VideoCodec &codec) { - RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeVideoCodec:codec]; + RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] + initWithNativeSdpVideoFormat:SdpVideoFormat(codec.name, codec.params)]; id encoder = [encoder_factory_ createEncoder:info]; return new ObjCVideoEncoder(encoder); } @@ -152,8 +175,8 @@ VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder(const cricket::VideoCo const std::vector &ObjCVideoEncoderFactory::supported_codecs() const { supported_codecs_.clear(); for (RTCVideoCodecInfo *supportedCodec in encoder_factory_.supportedCodecs) { - cricket::VideoCodec codec = [supportedCodec nativeVideoCodec]; - supported_codecs_.push_back(codec); + SdpVideoFormat format = [supportedCodec nativeSdpVideoFormat]; + supported_codecs_.push_back(cricket::VideoCodec(format)); } return supported_codecs_; diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h index bcfb87fc6c..ad56a5dea9 100644 --- a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h @@ -69,19 +69,6 @@ RTC_EXPORT @end -/** Class for H264 specific config. */ -typedef NS_ENUM(NSUInteger, RTCH264PacketizationMode) { - RTCH264PacketizationModeNonInterleaved = 0, // Mode 1 - STAP-A, FU-A is allowed - RTCH264PacketizationModeSingleNalUnit // Mode 0 - only single NALU allowed -}; - -RTC_EXPORT -@interface RTCCodecSpecificInfoH264 : NSObject - -@property(nonatomic, assign) RTCH264PacketizationMode packetizationMode; - -@end - /** Callback block for encoder. */ typedef BOOL (^RTCVideoEncoderCallback)(RTCEncodedImage *frame, id info, @@ -109,7 +96,6 @@ RTC_EXPORT - (BOOL)isEqualToCodecInfo:(RTCVideoCodecInfo *)info; -@property(nonatomic, readonly) NSInteger payload; @property(nonatomic, readonly) NSString *name; @property(nonatomic, readonly) NSDictionary *parameters; diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecFactory.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecFactory.h index 42842eb020..aa5f746398 100644 --- a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecFactory.h +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecFactory.h @@ -15,21 +15,21 @@ NS_ASSUME_NONNULL_BEGIN -/** RTCVideoEncoderFactory is an Objective-C version of cricket::WebRtcVideoEncoderFactory. */ +/** RTCVideoEncoderFactory is an Objective-C version of webrtc::VideoEncoderFactory. */ RTC_EXPORT @protocol RTCVideoEncoderFactory - (id)createEncoder:(RTCVideoCodecInfo *)info; -- (NSArray *)supportedCodecs; +- (NSArray *)supportedCodecs; // TODO(andersc): "supportedFormats" instead? @end -/** RTCVideoDecoderFactory is an Objective-C version of cricket::WebRtcVideoDecoderFactory. */ +/** RTCVideoDecoderFactory is an Objective-C version of webrtc::VideoDecoderFactory. */ RTC_EXPORT @protocol RTCVideoDecoderFactory - (id)createDecoder:(RTCVideoCodecInfo *)info; -- (NSArray *)supportedCodecs; +- (NSArray *)supportedCodecs; // TODO(andersc): "supportedFormats" instead? @end diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h index 449fcbba1b..1c307ebe84 100644 --- a/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h @@ -13,6 +13,19 @@ #import #import +/** Class for H264 specific config. */ +typedef NS_ENUM(NSUInteger, RTCH264PacketizationMode) { + RTCH264PacketizationModeNonInterleaved = 0, // Mode 1 - STAP-A, FU-A is allowed + RTCH264PacketizationModeSingleNalUnit // Mode 0 - only single NALU allowed +}; + +RTC_EXPORT +@interface RTCCodecSpecificInfoH264 : NSObject + +@property(nonatomic, assign) RTCH264PacketizationMode packetizationMode; + +@end + /** Encoder. */ RTC_EXPORT @interface RTCVideoEncoderH264 : NSObject diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h new file mode 100644 index 0000000000..962b6312f7 --- /dev/null +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP8.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 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 + +#import +#import + +RTC_EXPORT +@interface RTCVideoDecoderVP8 : NSObject + +/* This returns a VP8 decoder that can be returned from a RTCVideoDecoderFactory injected into + * RTCPeerConnectionFactory. Even though it implements the RTCVideoDecoder protocol, it can not be + * used independently from the RTCPeerConnectionFactory. + */ ++ (id)vp8Decoder; + +@end diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h new file mode 100644 index 0000000000..faf66ef065 --- /dev/null +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoDecoderVP9.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 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 + +#import +#import + +RTC_EXPORT +@interface RTCVideoDecoderVP9 : NSObject + +/* This returns a VP9 decoder that can be returned from a RTCVideoDecoderFactory injected into + * RTCPeerConnectionFactory. Even though it implements the RTCVideoDecoder protocol, it can not be + * used independently from the RTCPeerConnectionFactory. + */ ++ (id)vp9Decoder; + +@end diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP8.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP8.h new file mode 100644 index 0000000000..e63b24dde7 --- /dev/null +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP8.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 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 + +#import +#import + +RTC_EXPORT +@interface RTCVideoEncoderVP8 : NSObject + +/* This returns a VP8 encoder that can be returned from a RTCVideoEncoderFactory injected into + * RTCPeerConnectionFactory. Even though it implements the RTCVideoEncoder protocol, it can not be + * used independently from the RTCPeerConnectionFactory. + */ ++ (id)vp8Encoder; + +@end diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP9.h b/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP9.h new file mode 100644 index 0000000000..cef8c82e96 --- /dev/null +++ b/sdk/objc/Framework/Headers/WebRTC/RTCVideoEncoderVP9.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 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 + +#import +#import + +RTC_EXPORT +@interface RTCVideoEncoderVP9 : NSObject + +/* This returns a VP9 encoder that can be returned from a RTCVideoEncoderFactory injected into + * RTCPeerConnectionFactory. Even though it implements the RTCVideoEncoder protocol, it can not be + * used independently from the RTCPeerConnectionFactory. + */ ++ (id)vp9Encoder; + +@end