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));