ObjC: Add support for injectable native audio and video codecs

The native interface is added in the private file
webrtc/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h.

BUG=webrtc:8093

Review-Url: https://codereview.webrtc.org/3012443002
Cr-Original-Commit-Position: refs/heads/master@{#19576}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: b8853ca8d351864a2396e0bdf677f61ad166a4b6
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index cf31fe9..77b9d39 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -310,6 +310,7 @@
 
     rtc_static_library("peerconnectionfactory_objc") {
       sources = [
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm",
         "objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm",
@@ -331,6 +332,8 @@
         ":videotoolbox_objc",
         ":videotracksource_objc",
         "../api:video_frame_api",
+        "../api/audio_codecs:builtin_audio_decoder_factory",
+        "../api/audio_codecs:builtin_audio_encoder_factory",
         "../api/video_codecs:video_codecs_api",
         "../media:rtc_audio_video",
         "../media:rtc_media_base",
@@ -353,6 +356,7 @@
       defines = [ "HAVE_NO_MEDIA" ]
 
       sources = [
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm",
       ]
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h
new file mode 100644
index 0000000..fb3068a
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h
@@ -0,0 +1,49 @@
+/*
+ *  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 "WebRTC/RTCPeerConnectionFactory.h"
+
+#include "webrtc/rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+class AudioEncoderFactory;
+class AudioDecoderFactory;
+
+}  // namespace webrtc
+
+namespace cricket {
+
+class WebRtcVideoEncoderFactory;
+class WebRtcVideoDecoderFactory;
+
+}  // namespace cricket
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * This class extension exposes methods that work directly with injectable C++ components.
+ */
+@interface RTCPeerConnectionFactory ()
+
+/* Initialize object with injectable native audio/video encoder/decoder factories */
+- (instancetype)initWithNativeAudioEncoderFactory:
+                    (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
+                        nativeAudioDecoderFactory:
+                            (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
+                        nativeVideoEncoderFactory:
+                            (nullable cricket::WebRtcVideoEncoderFactory *)videoEncoderFactory
+                        nativeVideoDecoderFactory:
+                            (nullable cricket::WebRtcVideoDecoderFactory *)videoDecoderFactory
+    NS_DESIGNATED_INITIALIZER;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
index dffacb6..48d788f 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#import "RTCPeerConnectionFactory+Native.h"
 #import "RTCPeerConnectionFactory+Private.h"
 
 #import "NSString+StdString.h"
@@ -22,12 +23,16 @@
 #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.
+#include "webrtc/api/audio_codecs/builtin_audio_decoder_factory.h"  // nogncheck
+#include "webrtc/api/audio_codecs/builtin_audio_encoder_factory.h"  // nogncheck
 #endif
 
 #include "Video/objcvideotracksource.h"
-#include "VideoToolbox/objc_video_decoder_factory.h"
-#include "VideoToolbox/objc_video_encoder_factory.h"
 #include "webrtc/api/videosourceproxy.h"
 // Adding the nogncheck to disable the including header check.
 // The no-media version PeerConnectionFactory doesn't depend on media related
@@ -47,15 +52,47 @@
 
 - (instancetype)init {
 #ifdef HAVE_NO_MEDIA
-  return [self initWithEncoderFactory:nil decoderFactory:nil];
+  return [self initWithNativeAudioEncoderFactory:nil
+                       nativeAudioDecoderFactory:nil
+                       nativeVideoEncoderFactory:nil
+                       nativeVideoDecoderFactory:nil];
 #else
-  return [self initWithEncoderFactory:[[RTCVideoEncoderFactoryH264 alloc] init]
-                       decoderFactory:[[RTCVideoDecoderFactoryH264 alloc] init]];
+  return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
+                       nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
+                       nativeVideoEncoderFactory:new webrtc::ObjCVideoEncoderFactory(
+                                                     [[RTCVideoEncoderFactoryH264 alloc] init])
+                       nativeVideoDecoderFactory:new webrtc::ObjCVideoDecoderFactory(
+                                                     [[RTCVideoDecoderFactoryH264 alloc] init])];
 #endif
 }
 
 - (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
                         decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory {
+#ifdef HAVE_NO_MEDIA
+  return [self initWithNativeAudioEncoderFactory:nil
+                       nativeAudioDecoderFactory:nil
+                       nativeVideoEncoderFactory:nil
+                       nativeVideoDecoderFactory:nil];
+#else
+  cricket::WebRtcVideoEncoderFactory *native_encoder_factory =
+      encoderFactory ? new webrtc::ObjCVideoEncoderFactory(encoderFactory) : nullptr;
+  cricket::WebRtcVideoDecoderFactory *native_decoder_factory =
+      decoderFactory ? new webrtc::ObjCVideoDecoderFactory(decoderFactory) : nullptr;
+  return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
+                       nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
+                       nativeVideoEncoderFactory:native_encoder_factory
+                       nativeVideoDecoderFactory:native_decoder_factory];
+#endif
+}
+
+- (instancetype)initWithNativeAudioEncoderFactory:
+                    (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
+                        nativeAudioDecoderFactory:
+                            (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
+                        nativeVideoEncoderFactory:
+                            (nullable cricket::WebRtcVideoEncoderFactory *)videoEncoderFactory
+                        nativeVideoDecoderFactory:
+                            (nullable cricket::WebRtcVideoDecoderFactory *)videoDecoderFactory {
   if (self = [super init]) {
     _networkThread = rtc::Thread::CreateWithSocketServer();
     BOOL result = _networkThread->Start();
@@ -83,23 +120,16 @@
         std::unique_ptr<webrtc::CallFactoryInterface>(),
         std::unique_ptr<webrtc::RtcEventLogFactoryInterface>());
 #else
-    cricket::WebRtcVideoEncoderFactory *platform_encoder_factory = nullptr;
-    cricket::WebRtcVideoDecoderFactory *platform_decoder_factory = nullptr;
-    if (encoderFactory) {
-      platform_encoder_factory = new webrtc::ObjCVideoEncoderFactory(encoderFactory);
-    }
-    if (decoderFactory) {
-      platform_decoder_factory = new webrtc::ObjCVideoDecoderFactory(decoderFactory);
-    }
-
     // Ownership of encoder/decoder factories is passed on to the
     // peerconnectionfactory, that handles deleting them.
     _nativeFactory = webrtc::CreatePeerConnectionFactory(_networkThread.get(),
                                                          _workerThread.get(),
                                                          _signalingThread.get(),
-                                                         nullptr,
-                                                         platform_encoder_factory,
-                                                         platform_decoder_factory);
+                                                         nullptr,  // audio device module
+                                                         audioEncoderFactory,
+                                                         audioDecoderFactory,
+                                                         videoEncoderFactory,
+                                                         videoDecoderFactory);
 #endif
     NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
   }
diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnectionFactory.h b/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnectionFactory.h
index c29b3c9..42acbfc 100644
--- a/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnectionFactory.h
+++ b/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnectionFactory.h
@@ -35,8 +35,7 @@
 
 /* Initialize object with injectable video encoder/decoder factories */
 - (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
-                        decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory
-    NS_DESIGNATED_INITIALIZER;
+                        decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory;
 
 /** Initialize an RTCAudioSource with constraints. */
 - (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints;