Create experimental Obj-C++ API.
This can be used to wrap Objective-C components in C++ classes, so users
can use the WebRTC C++ API directly together with the iOS specific
components provided by our SDK.
Bug: webrtc:8832
Change-Id: I6d34f7ec62d51df8d3a5340a2e17d30ae73e13e8
Reviewed-on: https://webrtc-review.googlesource.com/46162
Commit-Queue: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21850}
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
index ec9d16c..e304068 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
@@ -24,8 +24,6 @@
#import "WebRTC/RTCLogging.h"
#import "WebRTC/RTCVideoCodecFactory.h"
#ifndef HAVE_NO_MEDIA
-#include "VideoToolbox/objc_video_decoder_factory.h"
-#include "VideoToolbox/objc_video_encoder_factory.h"
#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.
@@ -34,6 +32,11 @@
#include "media/engine/convert_legacy_video_factory.h" // nogncheck
#include "modules/audio_device/include/audio_device.h" // nogncheck
#include "modules/audio_processing/include/audio_processing.h" // nogncheck
+
+#include "sdk/objc/Framework/Native/api/video_decoder_factory.h"
+#include "sdk/objc/Framework/Native/api/video_encoder_factory.h"
+#include "sdk/objc/Framework/Native/src/objc_video_decoder_factory.h"
+#include "sdk/objc/Framework/Native/src/objc_video_encoder_factory.h"
#endif
#include "Video/objcvideotracksource.h"
@@ -61,15 +64,16 @@
#elif !defined(USE_BUILTIN_SW_CODECS)
return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
- nativeVideoEncoderFactory:std::unique_ptr<webrtc::VideoEncoderFactory>(
- new webrtc::ObjCVideoEncoderFactory(
- [[RTCVideoEncoderFactoryH264 alloc] init]))
- nativeVideoDecoderFactory:std::unique_ptr<webrtc::VideoDecoderFactory>(
- new webrtc::ObjCVideoDecoderFactory(
- [[RTCVideoDecoderFactoryH264 alloc] init]))
+ nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory(
+ [[RTCVideoEncoderFactoryH264 alloc] init])
+ nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory(
+ [[RTCVideoDecoderFactoryH264 alloc] init])
audioDeviceModule:nullptr
audioProcessingModule:nullptr];
#else
+ // Here we construct webrtc::ObjCVideoEncoderFactory directly because we rely
+ // on the fact that they inherit from both webrtc::VideoEncoderFactory and
+ // cricket::WebRtcVideoEncoderFactory.
return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
legacyNativeVideoEncoderFactory:new webrtc::ObjCVideoEncoderFactory(
@@ -89,10 +93,10 @@
std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory;
std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory;
if (encoderFactory) {
- native_encoder_factory.reset(new webrtc::ObjCVideoEncoderFactory(encoderFactory));
+ native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory);
}
if (decoderFactory) {
- native_decoder_factory.reset(new webrtc::ObjCVideoDecoderFactory(decoderFactory));
+ native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory);
}
return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
index f862453..402e09f 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm
@@ -16,7 +16,6 @@
#import "WebRTC/RTCVideoCodec.h"
#include "rtc_base/timeutils.h"
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
#include "system_wrappers/include/field_trial.h"
const char kHighProfileExperiment[] = "WebRTC-H264HighProfile";
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h
index 43d3fbf..7fd2247 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame+Private.h
@@ -13,7 +13,6 @@
#import "WebRTC/RTCVideoFrameBuffer.h"
#include "api/video/video_frame.h"
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
NS_ASSUME_NONNULL_BEGIN
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm
index 19dd245..f5d7195 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm
@@ -15,6 +15,8 @@
#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<RTCVideoFrameBuffer> nativeToRtcFrameBuffer(
const rtc::scoped_refptr<webrtc::VideoFrameBuffer> &buffer) {
@@ -104,7 +106,7 @@
- (webrtc::VideoFrame)nativeVideoFrame {
rtc::scoped_refptr<webrtc::VideoFrameBuffer> frameBuffer =
- new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(self.buffer);
+ webrtc::ObjCToNativeVideoFrameBuffer(self.buffer);
webrtc::VideoFrame videoFrame(frameBuffer,
(webrtc::VideoRotation)self.rotation,
self.timeStampNs / rtc::kNumNanosecsPerMicrosec);
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm
index 79cc1a7..639d060 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.mm
@@ -13,7 +13,6 @@
#import "RTCVideoRendererAdapter+Private.h"
#import "WebRTC/RTCVideoFrame.h"
#import "WebRTC/RTCVideoFrameBuffer.h"
-#import "objc_frame_buffer.h"
#include <memory>
diff --git a/sdk/objc/Framework/Classes/Video/avfoundationvideocapturer.mm b/sdk/objc/Framework/Classes/Video/avfoundationvideocapturer.mm
index 77cb88b..50b4f10 100644
--- a/sdk/objc/Framework/Classes/Video/avfoundationvideocapturer.mm
+++ b/sdk/objc/Framework/Classes/Video/avfoundationvideocapturer.mm
@@ -24,7 +24,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/thread.h"
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
namespace webrtc {
diff --git a/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm b/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm
index eca8852..d67f610 100644
--- a/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm
+++ b/sdk/objc/Framework/Classes/Video/objcvideotracksource.mm
@@ -14,7 +14,7 @@
#import "WebRTC/RTCVideoFrameBuffer.h"
#include "api/video/i420_buffer.h"
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
namespace webrtc {
diff --git a/sdk/objc/Framework/Native/api/video_decoder_factory.h b/sdk/objc/Framework/Native/api/video_decoder_factory.h
new file mode 100644
index 0000000..9fda6a9
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_decoder_factory.h
@@ -0,0 +1,27 @@
+/*
+ * 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_DECODER_FACTORY_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_DECODER_FACTORY_H_
+
+#include <memory>
+
+#import "WebRTC/RTCVideoCodecFactory.h"
+
+#include "api/video_codecs/video_decoder_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoDecoderFactory> ObjCToNativeVideoDecoderFactory(
+ id<RTCVideoDecoderFactory> objc_video_decoder_factory);
+
+} // namespace webrtc
+
+#endif // SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_DECODER_FACTORY_H_
diff --git a/sdk/objc/Framework/Native/api/video_decoder_factory.mm b/sdk/objc/Framework/Native/api/video_decoder_factory.mm
new file mode 100644
index 0000000..4d5a711
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_decoder_factory.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_decoder_factory.h"
+
+#include "rtc_base/ptr_util.h"
+#include "sdk/objc/Framework/Native/src/objc_video_decoder_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoDecoderFactory> ObjCToNativeVideoDecoderFactory(
+ id<RTCVideoDecoderFactory> objc_video_decoder_factory) {
+ return rtc::MakeUnique<ObjCVideoDecoderFactory>(objc_video_decoder_factory);
+}
+
+} // namespace webrtc
diff --git a/sdk/objc/Framework/Native/api/video_encoder_factory.h b/sdk/objc/Framework/Native/api/video_encoder_factory.h
new file mode 100644
index 0000000..865a707
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_encoder_factory.h
@@ -0,0 +1,27 @@
+/*
+ * 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_ENCODER_FACTORY_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_ENCODER_FACTORY_H_
+
+#include <memory>
+
+#import "WebRTC/RTCVideoCodecFactory.h"
+
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoEncoderFactory> ObjCToNativeVideoEncoderFactory(
+ id<RTCVideoEncoderFactory> objc_video_encoder_factory);
+
+} // namespace webrtc
+
+#endif // SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_ENCODER_FACTORY_H_
diff --git a/sdk/objc/Framework/Native/api/video_encoder_factory.mm b/sdk/objc/Framework/Native/api/video_encoder_factory.mm
new file mode 100644
index 0000000..e92c25d
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_encoder_factory.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_encoder_factory.h"
+
+#include "rtc_base/ptr_util.h"
+#include "sdk/objc/Framework/Native/src/objc_video_encoder_factory.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoEncoderFactory> ObjCToNativeVideoEncoderFactory(
+ id<RTCVideoEncoderFactory> objc_video_encoder_factory) {
+ return rtc::MakeUnique<ObjCVideoEncoderFactory>(objc_video_encoder_factory);
+}
+
+} // namespace webrtc
diff --git a/sdk/objc/Framework/Native/api/video_frame_buffer.h b/sdk/objc/Framework/Native/api/video_frame_buffer.h
new file mode 100644
index 0000000..6790308
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_frame_buffer.h
@@ -0,0 +1,26 @@
+/*
+ * 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_FRAME_BUFFER_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_API_VIDEO_FRAME_BUFFER_H_
+
+#import "WebRTC/RTCVideoFrameBuffer.h"
+
+#include "common_video/include/video_frame_buffer.h"
+#include "rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<webrtc::VideoFrameBuffer> ObjCToNativeVideoFrameBuffer(
+ id<RTCVideoFrameBuffer> objc_video_frame_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
new file mode 100644
index 0000000..17978e4
--- /dev/null
+++ b/sdk/objc/Framework/Native/api/video_frame_buffer.mm
@@ -0,0 +1,22 @@
+/*
+ * 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_buffer.h"
+
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
+
+namespace webrtc {
+
+rtc::scoped_refptr<webrtc::VideoFrameBuffer> ObjCToNativeVideoFrameBuffer(
+ id<RTCVideoFrameBuffer> objc_video_frame_buffer) {
+ return new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(objc_video_frame_buffer);
+}
+
+} // namespace webrtc
diff --git a/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h b/sdk/objc/Framework/Native/src/objc_frame_buffer.h
similarity index 84%
rename from sdk/objc/Framework/Classes/Video/objc_frame_buffer.h
rename to sdk/objc/Framework/Native/src/objc_frame_buffer.h
index 85a89e6..94980fa 100644
--- a/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h
+++ b/sdk/objc/Framework/Native/src/objc_frame_buffer.h
@@ -8,8 +8,8 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef SDK_OBJC_FRAMEWORK_CLASSES_VIDEO_OBJC_FRAME_BUFFER_H_
-#define SDK_OBJC_FRAMEWORK_CLASSES_VIDEO_OBJC_FRAME_BUFFER_H_
+#ifndef SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_
#import <CoreVideo/CoreVideo.h>
@@ -41,4 +41,4 @@
} // namespace webrtc
-#endif // SDK_OBJC_FRAMEWORK_CLASSES_VIDEO_OBJC_FRAME_BUFFER_H_
+#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_
diff --git a/sdk/objc/Framework/Classes/Video/objc_frame_buffer.mm b/sdk/objc/Framework/Native/src/objc_frame_buffer.mm
similarity index 96%
rename from sdk/objc/Framework/Classes/Video/objc_frame_buffer.mm
rename to sdk/objc/Framework/Native/src/objc_frame_buffer.mm
index 3658562..74b96b4 100644
--- a/sdk/objc/Framework/Classes/Video/objc_frame_buffer.mm
+++ b/sdk/objc/Framework/Native/src/objc_frame_buffer.mm
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
#import "WebRTC/RTCVideoFrameBuffer.h"
diff --git a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h
new file mode 100644
index 0000000..e6242e4
--- /dev/null
+++ b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_DECODER_FACTORY_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_DECODER_FACTORY_H_
+
+#include "api/video_codecs/video_decoder_factory.h"
+#include "media/base/codec.h"
+#include "media/engine/webrtcvideodecoderfactory.h"
+
+@protocol RTCVideoDecoderFactory;
+
+namespace webrtc {
+
+// 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<RTCVideoDecoderFactory>);
+ ~ObjCVideoDecoderFactory();
+
+ id<RTCVideoDecoderFactory> wrapped_decoder_factory() const;
+
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override;
+ std::unique_ptr<VideoDecoder> 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<RTCVideoDecoderFactory> decoder_factory_;
+};
+
+} // namespace webrtc
+
+#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_DECODER_FACTORY_H_
diff --git a/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm
new file mode 100644
index 0000000..fb31316
--- /dev/null
+++ b/sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+#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"
+
+#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"
+#include "modules/video_coding/include/video_error_codes.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/timeutils.h"
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
+
+namespace webrtc {
+
+namespace {
+class ObjCVideoDecoder : public VideoDecoder {
+ public:
+ ObjCVideoDecoder(id<RTCVideoDecoder> decoder)
+ : decoder_(decoder), implementation_name_([decoder implementationName].stdString) {}
+
+ int32_t InitDecode(const VideoCodec *codec_settings, int32_t number_of_cores) {
+ RTCVideoEncoderSettings *settings =
+ [[RTCVideoEncoderSettings alloc] initWithNativeVideoCodec:codec_settings];
+ return [decoder_ startDecodeWithSettings:settings numberOfCores:number_of_cores];
+ }
+
+ int32_t Decode(const EncodedImage &input_image,
+ bool missing_frames,
+ const RTPFragmentationHeader *fragmentation,
+ const CodecSpecificInfo *codec_specific_info = NULL,
+ int64_t render_time_ms = -1) {
+ RTCEncodedImage *encodedImage =
+ [[RTCEncodedImage alloc] initWithNativeEncodedImage:input_image];
+ RTCRtpFragmentationHeader *header =
+ [[RTCRtpFragmentationHeader alloc] initWithNativeFragmentationHeader:fragmentation];
+
+ // webrtc::CodecSpecificInfo only handles a hard coded list of codecs
+ id<RTCCodecSpecificInfo> rtcCodecSpecificInfo = nil;
+ if (codec_specific_info) {
+ if (codec_specific_info->codecType == kVideoCodecH264) {
+ RTCCodecSpecificInfoH264 *h264Info = [[RTCCodecSpecificInfoH264 alloc] init];
+ h264Info.packetizationMode =
+ (RTCH264PacketizationMode)codec_specific_info->codecSpecific.H264.packetization_mode;
+ rtcCodecSpecificInfo = h264Info;
+ }
+ }
+
+ return [decoder_ decode:encodedImage
+ missingFrames:missing_frames
+ fragmentationHeader:header
+ codecSpecificInfo:rtcCodecSpecificInfo
+ renderTimeMs:render_time_ms];
+ }
+
+ int32_t RegisterDecodeCompleteCallback(DecodedImageCallback *callback) {
+ [decoder_ setCallback:^(RTCVideoFrame *frame) {
+ const rtc::scoped_refptr<VideoFrameBuffer> buffer =
+ new rtc::RefCountedObject<ObjCFrameBuffer>(frame.buffer);
+ VideoFrame videoFrame(buffer,
+ (uint32_t)(frame.timeStampNs / rtc::kNumNanosecsPerMicrosec),
+ 0,
+ (VideoRotation)frame.rotation);
+ videoFrame.set_timestamp(frame.timeStamp);
+
+ callback->Decoded(videoFrame);
+ }];
+
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t Release() { return [decoder_ releaseDecoder]; }
+
+ const char *ImplementationName() const { return implementation_name_.c_str(); }
+
+ private:
+ id<RTCVideoDecoder> decoder_;
+ const std::string implementation_name_;
+};
+} // namespace
+
+ObjCVideoDecoderFactory::ObjCVideoDecoderFactory(id<RTCVideoDecoderFactory> decoder_factory)
+ : decoder_factory_(decoder_factory) {}
+
+ObjCVideoDecoderFactory::~ObjCVideoDecoderFactory() {}
+
+id<RTCVideoDecoderFactory> ObjCVideoDecoderFactory::wrapped_decoder_factory() const {
+ return decoder_factory_;
+}
+
+std::unique_ptr<VideoDecoder> 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<RTCVideoDecoder> decoder = [decoder_factory_ createDecoder:codecInfo];
+
+ if ([decoder isKindOfClass:[RTCWrappedNativeVideoDecoder class]]) {
+ return [(RTCWrappedNativeVideoDecoder *)decoder releaseWrappedDecoder];
+ } else {
+ return std::unique_ptr<ObjCVideoDecoder>(new ObjCVideoDecoder(decoder));
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+std::vector<SdpVideoFormat> ObjCVideoDecoderFactory::GetSupportedFormats() const {
+ std::vector<SdpVideoFormat> 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;
+}
+
+} // namespace webrtc
diff --git a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h
new file mode 100644
index 0000000..a50188d
--- /dev/null
+++ b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_ENCODER_FACTORY_H_
+#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_ENCODER_FACTORY_H_
+
+#import <Foundation/Foundation.h>
+
+#include "api/video_codecs/video_encoder_factory.h"
+#include "media/engine/webrtcvideoencoderfactory.h"
+
+@protocol RTCVideoEncoderFactory;
+
+namespace webrtc {
+
+// 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<RTCVideoEncoderFactory>);
+ ~ObjCVideoEncoderFactory();
+
+ id<RTCVideoEncoderFactory> wrapped_encoder_factory() const;
+
+ std::vector<SdpVideoFormat> GetSupportedFormats() const override;
+ std::unique_ptr<VideoEncoder> 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<cricket::VideoCodec>& supported_codecs() const override;
+ void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
+
+ private:
+ id<RTCVideoEncoderFactory> encoder_factory_;
+
+ // Needed for WebRtcVideoEncoderFactory interface.
+ mutable std::vector<cricket::VideoCodec> supported_codecs_;
+};
+
+} // namespace webrtc
+
+#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_VIDEO_ENCODER_FACTORY_H_
diff --git a/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm
new file mode 100644
index 0000000..4c0fcee
--- /dev/null
+++ b/sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+#include "sdk/objc/Framework/Native/src/objc_video_encoder_factory.h"
+
+#include <string>
+
+#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"
+
+#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 "sdk/objc/Framework/Classes/Common/helpers.h"
+
+namespace webrtc {
+
+namespace {
+
+class ObjCVideoEncoder : public VideoEncoder {
+ public:
+ ObjCVideoEncoder(id<RTCVideoEncoder> encoder)
+ : encoder_(encoder), implementation_name_([encoder implementationName].stdString) {}
+
+ int32_t InitEncode(const VideoCodec *codec_settings,
+ int32_t number_of_cores,
+ size_t max_payload_size) {
+ RTCVideoEncoderSettings *settings =
+ [[RTCVideoEncoderSettings alloc] initWithNativeVideoCodec:codec_settings];
+ return [encoder_ startEncodeWithSettings:settings numberOfCores:number_of_cores];
+ }
+
+ int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) {
+ [encoder_ setCallback:^BOOL(RTCEncodedImage *_Nonnull frame,
+ id<RTCCodecSpecificInfo> _Nonnull info,
+ RTCRtpFragmentationHeader *_Nonnull header) {
+ EncodedImage encodedImage = [frame nativeEncodedImage];
+
+ // 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];
+ }
+
+ std::unique_ptr<RTPFragmentationHeader> fragmentationHeader =
+ [header createNativeFragmentationHeader];
+ EncodedImageCallback::Result res =
+ callback->OnEncodedImage(encodedImage, &codecSpecificInfo, fragmentationHeader.get());
+ return res.error == EncodedImageCallback::Result::OK;
+ }];
+
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t Release() { return [encoder_ releaseEncoder]; }
+
+ int32_t Encode(const VideoFrame &frame,
+ const CodecSpecificInfo *codec_specific_info,
+ const std::vector<FrameType> *frame_types) {
+ // CodecSpecificInfo only handles a hard coded list of codecs
+ id<RTCCodecSpecificInfo> rtcCodecSpecificInfo = nil;
+ if (codec_specific_info) {
+ if (strcmp(codec_specific_info->codec_name, cricket::kH264CodecName) == 0) {
+ RTCCodecSpecificInfoH264 *h264Info = [[RTCCodecSpecificInfoH264 alloc] init];
+ h264Info.packetizationMode =
+ (RTCH264PacketizationMode)codec_specific_info->codecSpecific.H264.packetization_mode;
+ rtcCodecSpecificInfo = h264Info;
+ }
+ }
+
+ NSMutableArray<NSNumber *> *rtcFrameTypes = [NSMutableArray array];
+ for (size_t i = 0; i < frame_types->size(); ++i) {
+ [rtcFrameTypes addObject:@(RTCFrameType(frame_types->at(i)))];
+ }
+
+ return [encoder_ encode:[[RTCVideoFrame alloc] initWithNativeVideoFrame:frame]
+ codecSpecificInfo:rtcCodecSpecificInfo
+ frameTypes:rtcFrameTypes];
+ }
+
+ int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) { return WEBRTC_VIDEO_CODEC_OK; }
+
+ int32_t SetRates(uint32_t bitrate, uint32_t framerate) {
+ return [encoder_ setBitrate:bitrate framerate:framerate];
+ }
+
+ bool SupportsNativeHandle() const { return true; }
+
+ VideoEncoder::ScalingSettings GetScalingSettings() const {
+ RTCVideoEncoderQpThresholds *qp_thresholds = [encoder_ scalingSettings];
+ return qp_thresholds ?
+ ScalingSettings(true /* enabled */, qp_thresholds.low, qp_thresholds.high) :
+ ScalingSettings(false /* enabled */);
+ }
+
+ const char *ImplementationName() const { return implementation_name_.c_str(); }
+
+ private:
+ id<RTCVideoEncoder> encoder_;
+ const std::string implementation_name_;
+};
+} // namespace
+
+ObjCVideoEncoderFactory::ObjCVideoEncoderFactory(id<RTCVideoEncoderFactory> encoder_factory)
+ : encoder_factory_(encoder_factory) {}
+
+ObjCVideoEncoderFactory::~ObjCVideoEncoderFactory() {}
+
+id<RTCVideoEncoderFactory> ObjCVideoEncoderFactory::wrapped_encoder_factory() const {
+ return encoder_factory_;
+}
+
+std::vector<SdpVideoFormat> ObjCVideoEncoderFactory::GetSupportedFormats() const {
+ std::vector<SdpVideoFormat> 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:kRTCVideoCodecVp8Name, kRTCVideoCodecVp9Name, nil];
+
+ CodecInfo codec_info;
+ codec_info.is_hardware_accelerated = ![wrappedSoftwareFormats containsObject:formatName];
+ codec_info.has_internal_source = false;
+ return codec_info;
+}
+
+std::unique_ptr<VideoEncoder> ObjCVideoEncoderFactory::CreateVideoEncoder(
+ const SdpVideoFormat &format) {
+ RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithNativeSdpVideoFormat:format];
+ id<RTCVideoEncoder> encoder = [encoder_factory_ createEncoder:info];
+ if ([encoder isKindOfClass:[RTCWrappedNativeVideoEncoder class]]) {
+ return [(RTCWrappedNativeVideoEncoder *)encoder releaseWrappedEncoder];
+ } else {
+ return std::unique_ptr<ObjCVideoEncoder>(new ObjCVideoEncoder(encoder));
+ }
+}
+
+// WebRtcVideoEncoderFactory
+
+VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder(const cricket::VideoCodec &codec) {
+ RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc]
+ initWithNativeSdpVideoFormat:SdpVideoFormat(codec.name, codec.params)];
+ id<RTCVideoEncoder> encoder = [encoder_factory_ createEncoder:info];
+ return new ObjCVideoEncoder(encoder);
+}
+
+const std::vector<cricket::VideoCodec> &ObjCVideoEncoderFactory::supported_codecs() const {
+ supported_codecs_.clear();
+ for (RTCVideoCodecInfo *supportedCodec in encoder_factory_.supportedCodecs) {
+ SdpVideoFormat format = [supportedCodec nativeSdpVideoFormat];
+ supported_codecs_.push_back(cricket::VideoCodec(format));
+ }
+
+ return supported_codecs_;
+}
+
+void ObjCVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder *encoder) {
+ delete encoder;
+ encoder = nullptr;
+}
+
+} // namespace webrtc
diff --git a/sdk/objc/Framework/UnitTests/objc_video_decoder_factory_tests.mm b/sdk/objc/Framework/UnitTests/objc_video_decoder_factory_tests.mm
index d98b12a..67916eb 100644
--- a/sdk/objc/Framework/UnitTests/objc_video_decoder_factory_tests.mm
+++ b/sdk/objc/Framework/UnitTests/objc_video_decoder_factory_tests.mm
@@ -11,7 +11,7 @@
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
-#include "sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h"
+#include "sdk/objc/Framework/Native/src/objc_video_decoder_factory.h"
#import "WebRTC/RTCVideoCodec.h"
#import "WebRTC/RTCVideoCodecFactory.h"
diff --git a/sdk/objc/Framework/UnitTests/objc_video_encoder_factory_tests.mm b/sdk/objc/Framework/UnitTests/objc_video_encoder_factory_tests.mm
index 1a3588c..b3925be 100644
--- a/sdk/objc/Framework/UnitTests/objc_video_encoder_factory_tests.mm
+++ b/sdk/objc/Framework/UnitTests/objc_video_encoder_factory_tests.mm
@@ -11,7 +11,7 @@
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
-#include "sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h"
+#include "sdk/objc/Framework/Native/src/objc_video_encoder_factory.h"
#import "WebRTC/RTCVideoCodec.h"
#import "WebRTC/RTCVideoCodecFactory.h"
@@ -20,7 +20,7 @@
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/gunit.h"
-#include "sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
+#include "sdk/objc/Framework/Native/src/objc_frame_buffer.h"
id<RTCVideoEncoderFactory> CreateEncoderFactoryReturning(int return_code) {
id encoderMock = OCMProtocolMock(@protocol(RTCVideoEncoder));