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}
This commit is contained in:
Anders Carlsson 2018-02-01 15:47:05 +01:00 committed by Commit Bot
parent bc3b782813
commit 3ff50fba59
24 changed files with 700 additions and 34 deletions

View File

@ -462,6 +462,7 @@ if (rtc_include_tests) {
"../../modules:module_api",
"../../rtc_base:rtc_base_approved",
"../../sdk:common_objc",
"../../sdk:native_api",
"../../sdk:peerconnection_objc",
"../../sdk:peerconnectionfactory_objc",
"../../sdk:videotoolbox_objc",

View File

@ -11,18 +11,17 @@
#include "modules/video_coding/codecs/test/objc_codec_h264_test.h"
#import "WebRTC/RTCVideoCodecH264.h"
#include "rtc_base/ptr_util.h"
#include "sdk/objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h"
#include "sdk/objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h"
#include "sdk/objc/Framework/Native/api/video_decoder_factory.h"
#include "sdk/objc/Framework/Native/api/video_encoder_factory.h"
namespace webrtc {
std::unique_ptr<VideoEncoderFactory> CreateObjCEncoderFactory() {
return rtc::MakeUnique<ObjCVideoEncoderFactory>([[RTCVideoEncoderFactoryH264 alloc] init]);
return ObjCToNativeVideoEncoderFactory([[RTCVideoEncoderFactoryH264 alloc] init]);
}
std::unique_ptr<VideoDecoderFactory> CreateObjCDecoderFactory() {
return rtc::MakeUnique<ObjCVideoDecoderFactory>([[RTCVideoDecoderFactoryH264 alloc] init]);
return ObjCToNativeVideoDecoderFactory([[RTCVideoDecoderFactoryH264 alloc] init]);
}
} // namespace webrtc

View File

@ -127,8 +127,6 @@ if (is_ios || is_mac) {
"objc/Framework/Classes/Video/RTCCVPixelBuffer.mm",
"objc/Framework/Classes/Video/RTCI420Buffer+Private.h",
"objc/Framework/Classes/Video/RTCI420Buffer.mm",
"objc/Framework/Classes/Video/objc_frame_buffer.h",
"objc/Framework/Classes/Video/objc_frame_buffer.mm",
"objc/Framework/Classes/Video/objcvideotracksource.h",
"objc/Framework/Classes/Video/objcvideotracksource.mm",
"objc/Framework/Headers/WebRTC/RTCVideoFrameBuffer.h",
@ -136,6 +134,7 @@ if (is_ios || is_mac) {
deps = [
":common_objc",
":native_video",
"../api:libjingle_peerconnection_api",
"../api:video_frame_api",
"../api:video_frame_api_i420",
@ -195,6 +194,7 @@ if (is_ios || is_mac) {
deps = [
":common_objc",
":native_video",
":videotracksource_objc",
"../api:libjingle_peerconnection_api",
"../api:optional",
@ -343,6 +343,8 @@ if (is_ios || is_mac) {
":common_objc",
":corevideoframebuffer_objc",
":default_codec_factory_objc",
":native_api",
":native_video",
":peerconnectionfactory_base_objc",
":video_objc",
":videotoolbox_objc",
@ -442,6 +444,8 @@ if (is_ios || is_mac) {
}
deps = [
":native_api",
":native_video",
":peerconnectionfactory_base_objc",
"../api:libjingle_peerconnection_api",
"../api:peerconnection_and_implicit_call_api",
@ -573,6 +577,8 @@ if (is_ios || is_mac) {
deps = [
":common_objc",
":corevideoframebuffer_objc",
":native_api",
":native_video",
":videotracksource_objc",
"../api:libjingle_peerconnection_api",
"../api:peerconnection_and_implicit_call_api",
@ -691,6 +697,7 @@ if (is_ios || is_mac) {
defines = [ "GTEST_RELATIVE_PATH" ]
deps = [
":common_objc",
":native_video",
":peerconnection_objc",
":peerconnectionfactory_objc",
":videotoolbox_objc",
@ -833,6 +840,70 @@ if (is_ios || is_mac) {
}
}
# The native API is currently experimental and may change without notice.
rtc_static_library("native_api") {
visibility = [ "*" ]
sources = [
"objc/Framework/Native/api/video_decoder_factory.h",
"objc/Framework/Native/api/video_decoder_factory.mm",
"objc/Framework/Native/api/video_encoder_factory.h",
"objc/Framework/Native/api/video_encoder_factory.mm",
"objc/Framework/Native/api/video_frame_buffer.h",
"objc/Framework/Native/api/video_frame_buffer.mm",
]
configs += [ "..:common_objc" ]
public_configs = [ ":common_config_objc" ]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin
# (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
":native_video",
"../api/video_codecs:video_codecs_api",
"../common_video",
"../rtc_base:rtc_base",
]
}
rtc_static_library("native_video") {
sources = [
"objc/Framework/Native/src/objc_frame_buffer.h",
"objc/Framework/Native/src/objc_frame_buffer.mm",
"objc/Framework/Native/src/objc_video_decoder_factory.h",
"objc/Framework/Native/src/objc_video_decoder_factory.mm",
"objc/Framework/Native/src/objc_video_encoder_factory.h",
"objc/Framework/Native/src/objc_video_encoder_factory.mm",
]
configs += [ "..:common_objc" ]
public_configs = [ ":common_config_objc" ]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin
# (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
":common_objc",
"../api:video_frame_api",
"../api/video_codecs:video_codecs_api",
"../common_video",
"../media:rtc_audio_video",
"../media:rtc_media_base",
"../modules:module_api",
"../modules/video_coding:video_codec_interface",
"../rtc_base:checks",
"../rtc_base:rtc_base",
]
}
rtc_static_library("rtc_sdk_objc") {
complete_static_lib = true
deps = [
@ -893,10 +964,6 @@ if (is_ios || is_mac) {
sources = [
"objc/Framework/Classes/VideoToolbox/RTCVideoDecoderH264.mm",
"objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm",
"objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.h",
"objc/Framework/Classes/VideoToolbox/objc_video_decoder_factory.mm",
"objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.h",
"objc/Framework/Classes/VideoToolbox/objc_video_encoder_factory.mm",
"objc/Framework/Headers/WebRTC/RTCVideoFrameBuffer.h",
]
@ -904,6 +971,7 @@ if (is_ios || is_mac) {
deps = [
":common_objc",
":native_api",
":video_objc",
":video_toolbox_cc",
":videotracksource_objc",

View File

@ -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()

View File

@ -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";

View File

@ -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

View File

@ -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 @@ id<RTCVideoFrameBuffer> nativeToRtcFrameBuffer(
- (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);

View File

@ -13,7 +13,6 @@
#import "RTCVideoRendererAdapter+Private.h"
#import "WebRTC/RTCVideoFrame.h"
#import "WebRTC/RTCVideoFrameBuffer.h"
#import "objc_frame_buffer.h"
#include <memory>

View File

@ -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 {

View File

@ -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 {

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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 @@ class ObjCFrameBuffer : public VideoFrameBuffer {
} // namespace webrtc
#endif // SDK_OBJC_FRAMEWORK_CLASSES_VIDEO_OBJC_FRAME_BUFFER_H_
#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_

View File

@ -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"

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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"

View File

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