Injectable Obj-C video codecs
Initial CL for this effort, with a working RTCVideoEncoder/Decoder for H264
(wrapping the VideoToolbox codec).
Some notes / things left to do:
- There are some hard-coded references to codec types that are supported by
webrtc::VideoCodec, cricket::VideoCodec, webrtc::CodecSpecificInfo etc
since we need to convert to/from these types in ObjCVideoEncoder/Decoder.
These types would need to be more codec agnostic to avoid this.
- Most interfaces are borrowed from the design document for injectable
codecs in Android. Some data in the corresponding C++ classes is discarded
when converting to the Obj-C version, since it has fewer fields. I have not
verified whether all data that we do keep is needed, or whether we might be
losing anything useful in these conversions.
- Implement the VideoToolbox codec code directly in the RTCVideoEncoderH264
classes, instead of wrapping webrtc::H264VideoToolboxEncoder / decoder.
Eliminates converting between ObjC/C++ types outside the ObjCVideoEncoder/
Decoder wrapper classes.
- List the injected codec factory's supported codecs in the list of codecs in
AppRTCMobile.
BUG=webrtc:7924
R=magjed@webrtc.org
Review-Url: https://codereview.webrtc.org/2966023002 .
Cr-Commit-Position: refs/heads/master@{#18928}
This commit is contained in:
@ -310,6 +310,11 @@ if (is_ios || is_mac) {
|
|||||||
sources = [
|
sources = [
|
||||||
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm",
|
"objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCVideoCodecH264.mm",
|
||||||
|
"objc/Framework/Classes/PeerConnection/objc_video_decoder_factory.h",
|
||||||
|
"objc/Framework/Classes/PeerConnection/objc_video_decoder_factory.mm",
|
||||||
|
"objc/Framework/Classes/PeerConnection/objc_video_encoder_factory.h",
|
||||||
|
"objc/Framework/Classes/PeerConnection/objc_video_encoder_factory.mm",
|
||||||
]
|
]
|
||||||
|
|
||||||
public_configs = [ ":objc_common_config" ]
|
public_configs = [ ":objc_common_config" ]
|
||||||
@ -326,11 +331,16 @@ if (is_ios || is_mac) {
|
|||||||
":objc_peerconnectionfactory_base",
|
":objc_peerconnectionfactory_base",
|
||||||
":objc_video",
|
":objc_video",
|
||||||
":objc_videotoolbox",
|
":objc_videotoolbox",
|
||||||
|
":objc_videotracksource",
|
||||||
"../api:video_frame_api",
|
"../api:video_frame_api",
|
||||||
|
"../api/video_codecs:video_codecs_api",
|
||||||
"../base:rtc_base",
|
"../base:rtc_base",
|
||||||
|
"../media:rtc_audio_video",
|
||||||
"../media:rtc_media_base",
|
"../media:rtc_media_base",
|
||||||
|
"../modules:module_api",
|
||||||
"../pc:create_pc_factory",
|
"../pc:create_pc_factory",
|
||||||
"../pc:peerconnection",
|
"../pc:peerconnection",
|
||||||
|
"../system_wrappers:field_trial_api",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +387,7 @@ if (is_ios || is_mac) {
|
|||||||
"objc/Framework/Classes/PeerConnection/RTCDataChannel.mm",
|
"objc/Framework/Classes/PeerConnection/RTCDataChannel.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCDataChannelConfiguration+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCDataChannelConfiguration+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCDataChannelConfiguration.mm",
|
"objc/Framework/Classes/PeerConnection/RTCDataChannelConfiguration.mm",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCEncodedImage.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCIceCandidate+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCIceCandidate+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCIceCandidate.mm",
|
"objc/Framework/Classes/PeerConnection/RTCIceCandidate.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCIceServer+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCIceServer+Private.h",
|
||||||
@ -402,6 +413,7 @@ if (is_ios || is_mac) {
|
|||||||
"objc/Framework/Classes/PeerConnection/RTCRtpCodecParameters.mm",
|
"objc/Framework/Classes/PeerConnection/RTCRtpCodecParameters.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters.mm",
|
"objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters.mm",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCRtpFragmentationHeader.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCRtpParameters+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCRtpParameters+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm",
|
"objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h",
|
||||||
@ -413,6 +425,8 @@ if (is_ios || is_mac) {
|
|||||||
"objc/Framework/Classes/PeerConnection/RTCSessionDescription.mm",
|
"objc/Framework/Classes/PeerConnection/RTCSessionDescription.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCTracing.mm",
|
"objc/Framework/Classes/PeerConnection/RTCTracing.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCVideoCapturer.m",
|
"objc/Framework/Classes/PeerConnection/RTCVideoCapturer.m",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCVideoCodec+Private.h",
|
||||||
|
"objc/Framework/Classes/PeerConnection/RTCVideoCodec.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm",
|
"objc/Framework/Classes/PeerConnection/RTCVideoFrame.mm",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h",
|
"objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter+Private.h",
|
||||||
"objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h",
|
"objc/Framework/Classes/PeerConnection/RTCVideoRendererAdapter.h",
|
||||||
@ -473,6 +487,7 @@ if (is_ios || is_mac) {
|
|||||||
"../base:rtc_base",
|
"../base:rtc_base",
|
||||||
"../common_video",
|
"../common_video",
|
||||||
"../media:rtc_media_base",
|
"../media:rtc_media_base",
|
||||||
|
"../modules:module_api",
|
||||||
"../pc:peerconnection",
|
"../pc:peerconnection",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -548,6 +563,8 @@ if (is_ios || is_mac) {
|
|||||||
|
|
||||||
common_objc_headers = [
|
common_objc_headers = [
|
||||||
"objc/Framework/Headers/WebRTC/RTCAudioSession.h",
|
"objc/Framework/Headers/WebRTC/RTCAudioSession.h",
|
||||||
|
"objc/Framework/Headers/WebRTC/RTCVideoCodec.h",
|
||||||
|
"objc/Framework/Headers/WebRTC/RTCVideoCodecFactory.h",
|
||||||
"objc/Framework/Headers/WebRTC/RTCAudioSessionConfiguration.h",
|
"objc/Framework/Headers/WebRTC/RTCAudioSessionConfiguration.h",
|
||||||
"objc/Framework/Headers/WebRTC/RTCAVFoundationVideoSource.h",
|
"objc/Framework/Headers/WebRTC/RTCAVFoundationVideoSource.h",
|
||||||
"objc/Framework/Headers/WebRTC/RTCAudioSource.h",
|
"objc/Framework/Headers/WebRTC/RTCAudioSource.h",
|
||||||
@ -589,6 +606,7 @@ if (is_ios || is_mac) {
|
|||||||
"objc/Framework/Headers/WebRTC/RTCVideoTrack.h",
|
"objc/Framework/Headers/WebRTC/RTCVideoTrack.h",
|
||||||
"objc/Framework/Headers/WebRTC/RTCVideoViewShading.h",
|
"objc/Framework/Headers/WebRTC/RTCVideoViewShading.h",
|
||||||
"objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h",
|
"objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h",
|
||||||
|
"objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h",
|
||||||
"objc/Framework/Headers/WebRTC/WebRTC.h",
|
"objc/Framework/Headers/WebRTC/WebRTC.h",
|
||||||
]
|
]
|
||||||
if (rtc_use_metal_rendering) {
|
if (rtc_use_metal_rendering) {
|
||||||
|
|||||||
@ -11,8 +11,6 @@
|
|||||||
#ifndef WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
#ifndef WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
||||||
#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
||||||
|
|
||||||
#if defined(WEBRTC_IOS)
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -33,6 +31,7 @@ std::string GetThreadInfo();
|
|||||||
// Example: <NSThread: 0x170066d80>{number = 1, name = main}
|
// Example: <NSThread: 0x170066d80>{number = 1, name = main}
|
||||||
std::string GetCurrentThreadDescription();
|
std::string GetCurrentThreadDescription();
|
||||||
|
|
||||||
|
#if defined(WEBRTC_IOS)
|
||||||
// Returns the current name of the operating system.
|
// Returns the current name of the operating system.
|
||||||
std::string GetSystemName();
|
std::string GetSystemName();
|
||||||
|
|
||||||
@ -46,6 +45,7 @@ double GetSystemVersion();
|
|||||||
// Returns the device type.
|
// Returns the device type.
|
||||||
// Examples: ”iPhone” and ”iPod touch”.
|
// Examples: ”iPhone” and ”iPod touch”.
|
||||||
std::string GetDeviceType();
|
std::string GetDeviceType();
|
||||||
|
#endif // defined(WEBRTC_IOS)
|
||||||
|
|
||||||
// Returns a more detailed device name.
|
// Returns a more detailed device name.
|
||||||
// Examples: "iPhone 5s (GSM)" and "iPhone 6 Plus".
|
// Examples: "iPhone 5s (GSM)" and "iPhone 6 Plus".
|
||||||
@ -65,12 +65,12 @@ std::string GetOSVersionString();
|
|||||||
// Returns the number of processing cores available on the device.
|
// Returns the number of processing cores available on the device.
|
||||||
int GetProcessorCount();
|
int GetProcessorCount();
|
||||||
|
|
||||||
|
#if defined(WEBRTC_IOS)
|
||||||
// Indicates whether Low Power Mode is enabled on the iOS device.
|
// Indicates whether Low Power Mode is enabled on the iOS device.
|
||||||
bool GetLowPowerModeEnabled();
|
bool GetLowPowerModeEnabled();
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace ios
|
} // namespace ios
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // defined(WEBRTC_IOS)
|
|
||||||
|
|
||||||
#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_HELPERS_H_
|
||||||
|
|||||||
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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/RTCVideoCodec.h"
|
||||||
|
|
||||||
|
#import "RTCVideoCodec+Private.h"
|
||||||
|
|
||||||
|
@implementation RTCEncodedImage
|
||||||
|
|
||||||
|
@synthesize buffer = _buffer;
|
||||||
|
@synthesize encodedWidth = _encodedWidth;
|
||||||
|
@synthesize encodedHeight = _encodedHeight;
|
||||||
|
@synthesize timeStamp = _timeStamp;
|
||||||
|
@synthesize captureTimeMs = _captureTimeMs;
|
||||||
|
@synthesize ntpTimeMs = _ntpTimeMs;
|
||||||
|
@synthesize isTimingFrame = _isTimingFrame;
|
||||||
|
@synthesize encodeStartMs = _encodeStartMs;
|
||||||
|
@synthesize encodeFinishMs = _encodeFinishMs;
|
||||||
|
@synthesize frameType = _frameType;
|
||||||
|
@synthesize rotation = _rotation;
|
||||||
|
@synthesize completeFrame = _completeFrame;
|
||||||
|
@synthesize qp = _qp;
|
||||||
|
|
||||||
|
- (instancetype)initWithEncodedImage:(webrtc::EncodedImage)encodedImage {
|
||||||
|
if (self = [super init]) {
|
||||||
|
// Wrap the buffer in NSData without copying, do not take ownership.
|
||||||
|
_buffer = [NSData dataWithBytesNoCopy:encodedImage._buffer
|
||||||
|
length:encodedImage._length
|
||||||
|
freeWhenDone:NO];
|
||||||
|
_encodedWidth = encodedImage._encodedWidth;
|
||||||
|
_encodedHeight = encodedImage._encodedHeight;
|
||||||
|
_timeStamp = encodedImage._timeStamp;
|
||||||
|
_captureTimeMs = encodedImage.capture_time_ms_;
|
||||||
|
_ntpTimeMs = encodedImage.ntp_time_ms_;
|
||||||
|
_isTimingFrame = encodedImage.timing_.is_timing_frame;
|
||||||
|
_encodeStartMs = encodedImage.timing_.encode_start_ms;
|
||||||
|
_encodeFinishMs = encodedImage.timing_.encode_finish_ms;
|
||||||
|
_frameType = (RTCFrameType)encodedImage._frameType;
|
||||||
|
_rotation = encodedImage.rotation_;
|
||||||
|
_completeFrame = encodedImage._completeFrame;
|
||||||
|
_qp = encodedImage.qp_ == -1 ? nil : @(encodedImage.qp_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (webrtc::EncodedImage)toCpp {
|
||||||
|
// Return the pointer without copying.
|
||||||
|
webrtc::EncodedImage encodedImage(
|
||||||
|
(uint8_t *)_buffer.bytes, (size_t)_buffer.length, (size_t)_buffer.length);
|
||||||
|
encodedImage._encodedWidth = _encodedWidth;
|
||||||
|
encodedImage._encodedHeight = _encodedHeight;
|
||||||
|
encodedImage._timeStamp = _timeStamp;
|
||||||
|
encodedImage.capture_time_ms_ = _captureTimeMs;
|
||||||
|
encodedImage.ntp_time_ms_ = _ntpTimeMs;
|
||||||
|
encodedImage.timing_.is_timing_frame = _isTimingFrame;
|
||||||
|
encodedImage.timing_.encode_start_ms = _encodeStartMs;
|
||||||
|
encodedImage.timing_.encode_finish_ms = _encodeFinishMs;
|
||||||
|
encodedImage._frameType = webrtc::FrameType(_frameType);
|
||||||
|
encodedImage.rotation_ = webrtc::VideoRotation(_rotation);
|
||||||
|
encodedImage._completeFrame = _completeFrame;
|
||||||
|
encodedImage.qp_ = _qp ? _qp.intValue : -1;
|
||||||
|
|
||||||
|
return encodedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#import "RTCPeerConnectionFactory+Private.h"
|
#import "RTCPeerConnectionFactory+Private.h"
|
||||||
|
|
||||||
#import "NSString+StdString.h"
|
#import "NSString+StdString.h"
|
||||||
|
#import "RTCAVFoundationVideoSource+Private.h"
|
||||||
#import "RTCAudioSource+Private.h"
|
#import "RTCAudioSource+Private.h"
|
||||||
#import "RTCAudioTrack+Private.h"
|
#import "RTCAudioTrack+Private.h"
|
||||||
#import "RTCMediaConstraints+Private.h"
|
#import "RTCMediaConstraints+Private.h"
|
||||||
@ -18,11 +19,15 @@
|
|||||||
#import "RTCPeerConnection+Private.h"
|
#import "RTCPeerConnection+Private.h"
|
||||||
#import "RTCVideoSource+Private.h"
|
#import "RTCVideoSource+Private.h"
|
||||||
#import "RTCVideoTrack+Private.h"
|
#import "RTCVideoTrack+Private.h"
|
||||||
#import "RTCAVFoundationVideoSource+Private.h"
|
|
||||||
#import "WebRTC/RTCLogging.h"
|
#import "WebRTC/RTCLogging.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||||
|
#ifndef HAVE_NO_MEDIA
|
||||||
|
#import "WebRTC/RTCVideoCodecH264.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "PeerConnection/objc_video_decoder_factory.h"
|
||||||
|
#include "PeerConnection/objc_video_encoder_factory.h"
|
||||||
#include "Video/objcvideotracksource.h"
|
#include "Video/objcvideotracksource.h"
|
||||||
#include "VideoToolbox/videocodecfactory.h"
|
|
||||||
#include "webrtc/api/videosourceproxy.h"
|
#include "webrtc/api/videosourceproxy.h"
|
||||||
// Adding the nogncheck to disable the including header check.
|
// Adding the nogncheck to disable the including header check.
|
||||||
// The no-media version PeerConnectionFactory doesn't depend on media related
|
// The no-media version PeerConnectionFactory doesn't depend on media related
|
||||||
@ -41,7 +46,17 @@
|
|||||||
@synthesize nativeFactory = _nativeFactory;
|
@synthesize nativeFactory = _nativeFactory;
|
||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
if ((self = [super init])) {
|
#ifdef HAVE_NO_MEDIA
|
||||||
|
return [self initWithEncoderFactory:nil decoderFactory:nil];
|
||||||
|
#else
|
||||||
|
return [self initWithEncoderFactory:[[RTCVideoEncoderFactoryH264 alloc] init]
|
||||||
|
decoderFactory:[[RTCVideoDecoderFactoryH264 alloc] init]];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
|
||||||
|
decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory {
|
||||||
|
if (self = [super init]) {
|
||||||
_networkThread = rtc::Thread::CreateWithSocketServer();
|
_networkThread = rtc::Thread::CreateWithSocketServer();
|
||||||
BOOL result = _networkThread->Start();
|
BOOL result = _networkThread->Start();
|
||||||
NSAssert(result, @"Failed to start network thread.");
|
NSAssert(result, @"Failed to start network thread.");
|
||||||
@ -68,8 +83,14 @@
|
|||||||
std::unique_ptr<webrtc::CallFactoryInterface>(),
|
std::unique_ptr<webrtc::CallFactoryInterface>(),
|
||||||
std::unique_ptr<webrtc::RtcEventLogFactoryInterface>());
|
std::unique_ptr<webrtc::RtcEventLogFactoryInterface>());
|
||||||
#else
|
#else
|
||||||
const auto encoder_factory = new webrtc::VideoToolboxVideoEncoderFactory();
|
cricket::WebRtcVideoEncoderFactory *encoder_factory = nullptr;
|
||||||
const auto decoder_factory = new webrtc::VideoToolboxVideoDecoderFactory();
|
cricket::WebRtcVideoDecoderFactory *decoder_factory = nullptr;
|
||||||
|
if (encoderFactory) {
|
||||||
|
encoder_factory = new webrtc::ObjCVideoEncoderFactory(encoderFactory);
|
||||||
|
}
|
||||||
|
if (decoderFactory) {
|
||||||
|
decoder_factory = new webrtc::ObjCVideoDecoderFactory(decoderFactory);
|
||||||
|
}
|
||||||
|
|
||||||
// Ownership of encoder/decoder factories is passed on to the
|
// Ownership of encoder/decoder factories is passed on to the
|
||||||
// peerconnectionfactory, that handles deleting them.
|
// peerconnectionfactory, that handles deleting them.
|
||||||
|
|||||||
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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/RTCVideoCodec.h"
|
||||||
|
|
||||||
|
#include "webrtc/modules/include/module_common_types.h"
|
||||||
|
|
||||||
|
@implementation RTCRtpFragmentationHeader
|
||||||
|
|
||||||
|
@synthesize fragmentationOffset = _fragmentationOffset;
|
||||||
|
@synthesize fragmentationLength = _fragmentationLength;
|
||||||
|
@synthesize fragmentationTimeDiff = _fragmentationTimeDiff;
|
||||||
|
@synthesize fragmentationPlType = _fragmentationPlType;
|
||||||
|
|
||||||
|
- (instancetype)initWithFragmentationHeader:
|
||||||
|
(const webrtc::RTPFragmentationHeader *__nullable)fragmentationHeader {
|
||||||
|
if (self = [super init]) {
|
||||||
|
if (fragmentationHeader) {
|
||||||
|
int count = fragmentationHeader->fragmentationVectorSize;
|
||||||
|
NSMutableArray *offsets = [NSMutableArray array];
|
||||||
|
NSMutableArray *lengths = [NSMutableArray array];
|
||||||
|
NSMutableArray *timeDiffs = [NSMutableArray array];
|
||||||
|
NSMutableArray *plTypes = [NSMutableArray array];
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
[offsets addObject:@(fragmentationHeader->fragmentationOffset[i])];
|
||||||
|
[lengths addObject:@(fragmentationHeader->fragmentationLength[i])];
|
||||||
|
[timeDiffs addObject:@(fragmentationHeader->fragmentationTimeDiff[i])];
|
||||||
|
[plTypes addObject:@(fragmentationHeader->fragmentationPlType[i])];
|
||||||
|
}
|
||||||
|
_fragmentationOffset = [offsets copy];
|
||||||
|
_fragmentationLength = [lengths copy];
|
||||||
|
_fragmentationTimeDiff = [timeDiffs copy];
|
||||||
|
_fragmentationPlType = [plTypes copy];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (webrtc::RTPFragmentationHeader *)toCpp {
|
||||||
|
webrtc::RTPFragmentationHeader *fragmentationHeader = new webrtc::RTPFragmentationHeader;
|
||||||
|
fragmentationHeader->VerifyAndAllocateFragmentationHeader(_fragmentationOffset.count);
|
||||||
|
for (NSUInteger i = 0; i < _fragmentationOffset.count; ++i) {
|
||||||
|
fragmentationHeader->fragmentationOffset[i] = (size_t)_fragmentationOffset[i].unsignedIntValue;
|
||||||
|
fragmentationHeader->fragmentationLength[i] = (size_t)_fragmentationLength[i].unsignedIntValue;
|
||||||
|
fragmentationHeader->fragmentationTimeDiff[i] =
|
||||||
|
(uint16_t)_fragmentationOffset[i].unsignedIntValue;
|
||||||
|
fragmentationHeader->fragmentationPlType[i] = (uint8_t)_fragmentationOffset[i].unsignedIntValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragmentationHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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/RTCVideoCodec.h"
|
||||||
|
|
||||||
|
#import "WebRTC/RTCVideoCodecH264.h"
|
||||||
|
|
||||||
|
#include "webrtc/common_video/include/video_frame.h"
|
||||||
|
#include "webrtc/media/base/codec.h"
|
||||||
|
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/* Interfaces for converting to/from internal C++ formats. */
|
||||||
|
@interface RTCEncodedImage ()
|
||||||
|
|
||||||
|
- (instancetype)initWithEncodedImage:(webrtc::EncodedImage)encodedImage;
|
||||||
|
- (webrtc::EncodedImage)toCpp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface RTCVideoEncoderSettings ()
|
||||||
|
|
||||||
|
- (instancetype)initWithVideoCodec:(const webrtc::VideoCodec *__nullable)videoCodec;
|
||||||
|
- (webrtc::VideoCodec *)toCpp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface RTCCodecSpecificInfoH264 ()
|
||||||
|
|
||||||
|
- (webrtc::CodecSpecificInfo)toCpp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface RTCRtpFragmentationHeader ()
|
||||||
|
|
||||||
|
- (instancetype)initWithFragmentationHeader:
|
||||||
|
(const webrtc::RTPFragmentationHeader *__nullable)fragmentationHeader;
|
||||||
|
- (webrtc::RTPFragmentationHeader *)toCpp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface RTCVideoCodecInfo ()
|
||||||
|
|
||||||
|
- (instancetype)initWithVideoCodec:(cricket::VideoCodec)videoCodec;
|
||||||
|
- (cricket::VideoCodec)toCpp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* 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/RTCVideoCodec.h"
|
||||||
|
|
||||||
|
#import "RTCVideoCodec+Private.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||||
|
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/Common/helpers.h"
|
||||||
|
|
||||||
|
@implementation RTCVideoCodecInfo
|
||||||
|
|
||||||
|
@synthesize payload = _payload;
|
||||||
|
@synthesize name = _name;
|
||||||
|
@synthesize parameters = _parameters;
|
||||||
|
|
||||||
|
- (instancetype)initWithPayload:(int)payload
|
||||||
|
name:(NSString *)name
|
||||||
|
parameters:(NSDictionary<NSString *, NSString *> *)parameters {
|
||||||
|
if (self = [super init]) {
|
||||||
|
_payload = payload;
|
||||||
|
_name = name;
|
||||||
|
_parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithVideoCodec:(cricket::VideoCodec)videoCodec {
|
||||||
|
NSMutableDictionary *params = [NSMutableDictionary dictionary];
|
||||||
|
for (auto it = videoCodec.params.begin(); it != videoCodec.params.end(); ++it) {
|
||||||
|
[params setObject:webrtc::ios::NSStringFromStdString(it->second)
|
||||||
|
forKey:webrtc::ios::NSStringFromStdString(it->first)];
|
||||||
|
}
|
||||||
|
return [self initWithPayload:videoCodec.id
|
||||||
|
name:webrtc::ios::NSStringFromStdString(videoCodec.name)
|
||||||
|
parameters:params];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (cricket::VideoCodec)toCpp {
|
||||||
|
cricket::VideoCodec codec(webrtc::ios::StdStringFromNSString(_name));
|
||||||
|
for (NSString *paramKey in [_parameters allKeys]) {
|
||||||
|
codec.SetParam(webrtc::ios::StdStringFromNSString(paramKey),
|
||||||
|
webrtc::ios::StdStringFromNSString(_parameters[paramKey]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation RTCVideoEncoderSettings
|
||||||
|
|
||||||
|
@synthesize name = _name;
|
||||||
|
@synthesize width = _width;
|
||||||
|
@synthesize height = _height;
|
||||||
|
@synthesize startBitrate = _startBitrate;
|
||||||
|
@synthesize maxBitrate = _maxBitrate;
|
||||||
|
@synthesize minBitrate = _minBitrate;
|
||||||
|
@synthesize targetBitrate = _targetBitrate;
|
||||||
|
@synthesize maxFramerate = _maxFramerate;
|
||||||
|
@synthesize qpMax = _qpMax;
|
||||||
|
|
||||||
|
- (instancetype)initWithVideoCodec:(const webrtc::VideoCodec *__nullable)videoCodec {
|
||||||
|
if (self = [super init]) {
|
||||||
|
if (videoCodec) {
|
||||||
|
rtc::Optional<const char *> codecName = CodecTypeToPayloadName(videoCodec->codecType);
|
||||||
|
if (codecName) {
|
||||||
|
_name = [NSString stringWithUTF8String:codecName.value()];
|
||||||
|
}
|
||||||
|
|
||||||
|
_width = videoCodec->width;
|
||||||
|
_height = videoCodec->height;
|
||||||
|
_startBitrate = videoCodec->startBitrate;
|
||||||
|
_maxBitrate = videoCodec->maxBitrate;
|
||||||
|
_minBitrate = videoCodec->minBitrate;
|
||||||
|
_targetBitrate = videoCodec->targetBitrate;
|
||||||
|
_maxFramerate = videoCodec->maxFramerate;
|
||||||
|
_qpMax = videoCodec->qpMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (webrtc::VideoCodec *)toCpp {
|
||||||
|
webrtc::VideoCodec *codecSettings = new webrtc::VideoCodec;
|
||||||
|
|
||||||
|
rtc::Optional<webrtc::VideoCodecType> codecType =
|
||||||
|
webrtc::PayloadNameToCodecType(webrtc::ios::StdStringFromNSString(_name));
|
||||||
|
if (codecType) {
|
||||||
|
codecSettings->codecType = codecType.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
codecSettings->width = _width;
|
||||||
|
codecSettings->height = _height;
|
||||||
|
codecSettings->startBitrate = _startBitrate;
|
||||||
|
codecSettings->maxBitrate = _maxBitrate;
|
||||||
|
codecSettings->minBitrate = _minBitrate;
|
||||||
|
codecSettings->targetBitrate = _targetBitrate;
|
||||||
|
codecSettings->maxFramerate = _maxFramerate;
|
||||||
|
codecSettings->qpMax = _qpMax;
|
||||||
|
|
||||||
|
return codecSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* 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/RTCVideoCodecH264.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#import "RTCVideoCodec+Private.h"
|
||||||
|
#import "WebRTC/RTCVideoCodec.h"
|
||||||
|
#import "WebRTC/RTCVideoFrame.h"
|
||||||
|
#import "WebRTC/RTCVideoFrameBuffer.h"
|
||||||
|
|
||||||
|
#include "webrtc/base/timeutils.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h"
|
||||||
|
#include "webrtc/system_wrappers/include/field_trial.h"
|
||||||
|
|
||||||
|
const size_t kDefaultPayloadSize = 1440;
|
||||||
|
|
||||||
|
const char kHighProfileExperiment[] = "WebRTC-H264HighProfile";
|
||||||
|
|
||||||
|
bool IsHighProfileEnabled() {
|
||||||
|
return webrtc::field_trial::IsEnabled(kHighProfileExperiment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// H264 specific settings.
|
||||||
|
@implementation RTCCodecSpecificInfoH264
|
||||||
|
|
||||||
|
@synthesize packetizationMode = _packetizationMode;
|
||||||
|
|
||||||
|
- (webrtc::CodecSpecificInfo)toCpp {
|
||||||
|
webrtc::CodecSpecificInfo codecSpecificInfo;
|
||||||
|
codecSpecificInfo.codecType = webrtc::kVideoCodecH264;
|
||||||
|
codecSpecificInfo.codec_name = "H264";
|
||||||
|
codecSpecificInfo.codecSpecific.H264.packetization_mode =
|
||||||
|
(webrtc::H264PacketizationMode)_packetizationMode;
|
||||||
|
|
||||||
|
return codecSpecificInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class H264VideoToolboxEncodeCompleteCallback : public webrtc::EncodedImageCallback {
|
||||||
|
public:
|
||||||
|
Result OnEncodedImage(const webrtc::EncodedImage &encoded_image,
|
||||||
|
const webrtc::CodecSpecificInfo *codec_specific_info,
|
||||||
|
const webrtc::RTPFragmentationHeader *fragmentation) {
|
||||||
|
RTCEncodedImage *image = [[RTCEncodedImage alloc] initWithEncodedImage:encoded_image];
|
||||||
|
|
||||||
|
RTCCodecSpecificInfoH264 *info = [[RTCCodecSpecificInfoH264 alloc] init];
|
||||||
|
info.packetizationMode =
|
||||||
|
(RTCH264PacketizationMode)codec_specific_info->codecSpecific.H264.packetization_mode;
|
||||||
|
|
||||||
|
RTCRtpFragmentationHeader *header =
|
||||||
|
[[RTCRtpFragmentationHeader alloc] initWithFragmentationHeader:fragmentation];
|
||||||
|
|
||||||
|
callback(image, info, header);
|
||||||
|
return Result(Result::OK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RTCVideoEncoderCallback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
class H264VideoToolboxDecodeCompleteCallback : public webrtc::DecodedImageCallback {
|
||||||
|
public:
|
||||||
|
int32_t Decoded(webrtc::VideoFrame &decodedImage) {
|
||||||
|
rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer =
|
||||||
|
decodedImage.video_frame_buffer();
|
||||||
|
id<RTCVideoFrameBuffer> rtcFrameBuffer;
|
||||||
|
rtc::scoped_refptr<webrtc::ObjCFrameBuffer> objc_frame_buffer(
|
||||||
|
static_cast<webrtc::ObjCFrameBuffer *>(video_frame_buffer.get()));
|
||||||
|
rtcFrameBuffer = (id<RTCVideoFrameBuffer>)objc_frame_buffer->wrapped_frame_buffer();
|
||||||
|
|
||||||
|
RTCVideoFrame *videoFrame = [[RTCVideoFrame alloc]
|
||||||
|
initWithBuffer:rtcFrameBuffer
|
||||||
|
rotation:static_cast<RTCVideoRotation>(decodedImage.rotation())
|
||||||
|
timeStampNs:decodedImage.timestamp_us() * rtc::kNumNanosecsPerMicrosec];
|
||||||
|
videoFrame.timeStamp = decodedImage.timestamp();
|
||||||
|
|
||||||
|
callback(videoFrame);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTCVideoDecoderCallback callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Encoder.
|
||||||
|
@implementation RTCVideoEncoderH264 {
|
||||||
|
webrtc::H264VideoToolboxEncoder *_videoToolboxEncoder;
|
||||||
|
H264VideoToolboxEncodeCompleteCallback *_toolboxCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithCodecInfo:(RTCVideoCodecInfo *)codecInfo {
|
||||||
|
if (self = [super init]) {
|
||||||
|
cricket::VideoCodec codec = [codecInfo toCpp];
|
||||||
|
_videoToolboxEncoder = new webrtc::H264VideoToolboxEncoder(codec);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setCallback:(RTCVideoEncoderCallback)callback {
|
||||||
|
_toolboxCallback = new H264VideoToolboxEncodeCompleteCallback();
|
||||||
|
_toolboxCallback->callback = callback;
|
||||||
|
_videoToolboxEncoder->RegisterEncodeCompleteCallback(_toolboxCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)initEncodeWithSettings:(RTCVideoEncoderSettings *)settings
|
||||||
|
numberOfCores:(int)numberOfCores {
|
||||||
|
webrtc::VideoCodec *codecSettings = [settings toCpp];
|
||||||
|
_videoToolboxEncoder->InitEncode(codecSettings, numberOfCores, kDefaultPayloadSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)releaseEncode {
|
||||||
|
_videoToolboxEncoder->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encode:(RTCVideoFrame *)frame
|
||||||
|
codecSpecificInfo:(id<RTCCodecSpecificInfo>)info
|
||||||
|
frameTypes:(NSArray<NSNumber *> *)frameTypes {
|
||||||
|
rtc::scoped_refptr<webrtc::VideoFrameBuffer> frameBuffer =
|
||||||
|
new rtc::RefCountedObject<webrtc::ObjCFrameBuffer>(frame.buffer);
|
||||||
|
webrtc::VideoFrame videoFrame(frameBuffer,
|
||||||
|
(webrtc::VideoRotation)frame.rotation,
|
||||||
|
frame.timeStampNs / rtc::kNumNanosecsPerMicrosec);
|
||||||
|
videoFrame.set_timestamp(frame.timeStamp);
|
||||||
|
|
||||||
|
// Handle types than can be converted into one of webrtc::CodecSpecificInfo's hard coded cases.
|
||||||
|
webrtc::CodecSpecificInfo codecSpecificInfo;
|
||||||
|
if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) {
|
||||||
|
codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info toCpp];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<webrtc::FrameType> nativeFrameTypes;
|
||||||
|
for (NSNumber *frameType in frameTypes) {
|
||||||
|
RTCFrameType rtcFrameType = (RTCFrameType)frameType.unsignedIntegerValue;
|
||||||
|
nativeFrameTypes.push_back((webrtc::FrameType)rtcFrameType);
|
||||||
|
}
|
||||||
|
|
||||||
|
_videoToolboxEncoder->Encode(videoFrame, &codecSpecificInfo, &nativeFrameTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)setBitrate:(uint32_t)bitrateKbit framerate:(uint32_t)framerate {
|
||||||
|
return _videoToolboxEncoder->SetRates(bitrateKbit, framerate) == WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
// Decoder.
|
||||||
|
@implementation RTCVideoDecoderH264 {
|
||||||
|
webrtc::H264VideoToolboxDecoder *_videoToolboxDecoder;
|
||||||
|
H264VideoToolboxDecodeCompleteCallback *_toolboxCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
cricket::VideoCodec codec(cricket::kH264CodecName);
|
||||||
|
_videoToolboxDecoder = new webrtc::H264VideoToolboxDecoder();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)initDecodeWithSettings:(RTCVideoEncoderSettings *)settings numberOfCores:(int)numberOfCores {
|
||||||
|
webrtc::VideoCodec *codecSettings = [settings toCpp];
|
||||||
|
return _videoToolboxDecoder->InitDecode(codecSettings, numberOfCores);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setCallback:(RTCVideoDecoderCallback)callback {
|
||||||
|
_toolboxCallback = new H264VideoToolboxDecodeCompleteCallback();
|
||||||
|
_toolboxCallback->callback = callback;
|
||||||
|
_videoToolboxDecoder->RegisterDecodeCompleteCallback(_toolboxCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int32_t)releaseDecode {
|
||||||
|
return _videoToolboxDecoder->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)decode:(RTCEncodedImage *)encodedImage
|
||||||
|
missingFrames:(BOOL)missingFrames
|
||||||
|
fragmentationHeader:(RTCRtpFragmentationHeader *)fragmentationHeader
|
||||||
|
codecSpecificInfo:(__nullable id<RTCCodecSpecificInfo>)info
|
||||||
|
renderTimeMs:(int64_t)renderTimeMs {
|
||||||
|
webrtc::EncodedImage image = [encodedImage toCpp];
|
||||||
|
|
||||||
|
// Handle types than can be converted into one of webrtc::CodecSpecificInfo's hard coded cases.
|
||||||
|
webrtc::CodecSpecificInfo codecSpecificInfo;
|
||||||
|
if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) {
|
||||||
|
codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info toCpp];
|
||||||
|
}
|
||||||
|
|
||||||
|
webrtc::RTPFragmentationHeader *header = [fragmentationHeader toCpp];
|
||||||
|
|
||||||
|
return _videoToolboxDecoder->Decode(
|
||||||
|
image, missingFrames, header, &codecSpecificInfo, renderTimeMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
// Encoder factory.
|
||||||
|
@implementation RTCVideoEncoderFactoryH264
|
||||||
|
|
||||||
|
- (NSArray<RTCVideoCodecInfo *> *)supportedCodecs {
|
||||||
|
NSMutableArray<RTCVideoCodecInfo *> *codecs = [NSMutableArray array];
|
||||||
|
NSString *codecName = [NSString stringWithUTF8String:cricket::kH264CodecName];
|
||||||
|
|
||||||
|
if (IsHighProfileEnabled()) {
|
||||||
|
NSDictionary<NSString *, NSString *> *constrainedHighParams = @{
|
||||||
|
@"profile-level-id" : @"640c1f", // Level 3.1 Constrained High.
|
||||||
|
@"level-asymmetry-allowed" : @"1",
|
||||||
|
@"packetization-mode" : @"1",
|
||||||
|
};
|
||||||
|
RTCVideoCodecInfo *constrainedHighInfo =
|
||||||
|
[[RTCVideoCodecInfo alloc] initWithPayload:0
|
||||||
|
name:codecName
|
||||||
|
parameters:constrainedHighParams];
|
||||||
|
[codecs addObject:constrainedHighInfo];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDictionary<NSString *, NSString *> *constrainedBaselineParams = @{
|
||||||
|
@"profile-level-id" : @"42e01f", // Level 3.1 Constrained Baseline.
|
||||||
|
@"level-asymmetry-allowed" : @"1",
|
||||||
|
@"packetization-mode" : @"1",
|
||||||
|
};
|
||||||
|
RTCVideoCodecInfo *constrainedBaselineInfo =
|
||||||
|
[[RTCVideoCodecInfo alloc] initWithPayload:0
|
||||||
|
name:codecName
|
||||||
|
parameters:constrainedBaselineParams];
|
||||||
|
[codecs addObject:constrainedBaselineInfo];
|
||||||
|
|
||||||
|
return [codecs copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id<RTCVideoEncoder>)createEncoder:(RTCVideoCodecInfo *)info {
|
||||||
|
return [[RTCVideoEncoderH264 alloc] initWithCodecInfo:info];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
// Decoder factory.
|
||||||
|
@implementation RTCVideoDecoderFactoryH264
|
||||||
|
|
||||||
|
- (id<RTCVideoDecoder>)createDecoder:(RTCVideoCodecInfo *)info {
|
||||||
|
return [[RTCVideoDecoderH264 alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<RTCVideoCodecInfo *> *)supportedCodecs {
|
||||||
|
NSString *codecName = [NSString stringWithUTF8String:cricket::kH264CodecName];
|
||||||
|
return @[ [[RTCVideoCodecInfo alloc] initWithPayload:0 name:codecName parameters:@{}] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@ -17,6 +17,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@synthesize buffer = _buffer;
|
@synthesize buffer = _buffer;
|
||||||
|
@synthesize timeStamp;
|
||||||
|
|
||||||
- (int)width {
|
- (int)width {
|
||||||
return _buffer.width;
|
return _buffer.width;
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_DECODER_FACTORY_H_
|
||||||
|
#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_DECODER_FACTORY_H_
|
||||||
|
|
||||||
|
#include "webrtc/media/base/codec.h"
|
||||||
|
#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
|
||||||
|
|
||||||
|
@protocol RTCVideoDecoderFactory;
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class ObjCVideoDecoderFactory : public cricket::WebRtcVideoDecoderFactory {
|
||||||
|
public:
|
||||||
|
explicit ObjCVideoDecoderFactory(id<RTCVideoDecoderFactory>);
|
||||||
|
~ObjCVideoDecoderFactory();
|
||||||
|
|
||||||
|
id<RTCVideoDecoderFactory> wrapped_decoder_factory() const;
|
||||||
|
|
||||||
|
webrtc::VideoDecoder* CreateVideoDecoder(
|
||||||
|
webrtc::VideoCodecType type) override;
|
||||||
|
void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
id<RTCVideoDecoderFactory> decoder_factory_;
|
||||||
|
std::vector<cricket::VideoCodec> supported_codecs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_DECODER_FACTORY_H_
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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 "webrtc/sdk/objc/Framework/Classes/PeerConnection/objc_video_decoder_factory.h"
|
||||||
|
|
||||||
|
#import "RTCVideoCodec+Private.h"
|
||||||
|
#import "WebRTC/RTCVideoCodec.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecH264.h"
|
||||||
|
#import "WebRTC/RTCVideoFrame.h"
|
||||||
|
#import "WebRTC/RTCVideoFrameBuffer.h"
|
||||||
|
|
||||||
|
#include "webrtc/api/video_codecs/video_decoder.h"
|
||||||
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/base/timeutils.h"
|
||||||
|
#include "webrtc/modules/include/module_common_types.h"
|
||||||
|
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||||
|
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class ObjCVideoDecoder : public VideoDecoder {
|
||||||
|
public:
|
||||||
|
ObjCVideoDecoder(id<RTCVideoDecoder> decoder) : decoder_(decoder) {}
|
||||||
|
~ObjCVideoDecoder() {}
|
||||||
|
|
||||||
|
int32_t InitDecode(const VideoCodec *codec_settings, int32_t number_of_cores) {
|
||||||
|
RTCVideoEncoderSettings *settings =
|
||||||
|
[[RTCVideoEncoderSettings alloc] initWithVideoCodec:codec_settings];
|
||||||
|
return [decoder_ initDecodeWithSettings: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] initWithEncodedImage:input_image];
|
||||||
|
RTCRtpFragmentationHeader *header =
|
||||||
|
[[RTCRtpFragmentationHeader alloc] initWithFragmentationHeader: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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[decoder_ decode:encodedImage
|
||||||
|
missingFrames:missing_frames
|
||||||
|
fragmentationHeader:header
|
||||||
|
codecSpecificInfo:rtcCodecSpecificInfo
|
||||||
|
renderTimeMs:render_time_ms];
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_ releaseDecode]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
id<RTCVideoDecoder> decoder_;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ObjCVideoDecoderFactory::ObjCVideoDecoderFactory(id<RTCVideoDecoderFactory> decoder_factory)
|
||||||
|
: decoder_factory_(decoder_factory) {}
|
||||||
|
|
||||||
|
ObjCVideoDecoderFactory::~ObjCVideoDecoderFactory() {}
|
||||||
|
|
||||||
|
id<RTCVideoDecoderFactory> ObjCVideoDecoderFactory::wrapped_decoder_factory() const {
|
||||||
|
return decoder_factory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoDecoder *ObjCVideoDecoderFactory::CreateVideoDecoder(VideoCodecType type) {
|
||||||
|
const rtc::Optional<const char *> codec_name = CodecTypeToPayloadName(type);
|
||||||
|
if (!codec_name) {
|
||||||
|
LOG(LS_ERROR) << "Invalid codec type: " << type;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *codecName = [NSString stringWithUTF8String:codec_name.value()];
|
||||||
|
for (RTCVideoCodecInfo *codecInfo in decoder_factory_.supportedCodecs) {
|
||||||
|
if ([codecName isEqualToString:codecInfo.name]) {
|
||||||
|
id<RTCVideoDecoder> decoder = [decoder_factory_ createDecoder:codecInfo];
|
||||||
|
return new ObjCVideoDecoder(decoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjCVideoDecoderFactory::DestroyVideoDecoder(VideoDecoder *decoder) {
|
||||||
|
delete decoder;
|
||||||
|
decoder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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 WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_ENCODER_FACTORY_H_
|
||||||
|
#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_ENCODER_FACTORY_H_
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
|
||||||
|
|
||||||
|
@protocol RTCVideoEncoderFactory;
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
class ObjCVideoEncoderFactory : public cricket::WebRtcVideoEncoderFactory {
|
||||||
|
public:
|
||||||
|
explicit ObjCVideoEncoderFactory(id<RTCVideoEncoderFactory>);
|
||||||
|
~ObjCVideoEncoderFactory();
|
||||||
|
|
||||||
|
id<RTCVideoEncoderFactory> wrapped_encoder_factory() const;
|
||||||
|
|
||||||
|
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_;
|
||||||
|
mutable std::vector<cricket::VideoCodec> supported_codecs_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_PEERCONNECTION_OBJC_VIDEO_ENCODER_FACTORY_H_
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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 "webrtc/sdk/objc/Framework/Classes/PeerConnection/objc_video_encoder_factory.h"
|
||||||
|
|
||||||
|
#import "RTCVideoCodec+Private.h"
|
||||||
|
#import "WebRTC/RTCVideoCodec.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecFactory.h"
|
||||||
|
#import "WebRTC/RTCVideoCodecH264.h"
|
||||||
|
#import "WebRTC/RTCVideoFrame.h"
|
||||||
|
#import "WebRTC/RTCVideoFrameBuffer.h"
|
||||||
|
|
||||||
|
#include "webrtc/api/video/video_frame.h"
|
||||||
|
#include "webrtc/api/video_codecs/video_encoder.h"
|
||||||
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/base/timeutils.h"
|
||||||
|
#include "webrtc/modules/include/module_common_types.h"
|
||||||
|
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||||
|
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/Common/helpers.h"
|
||||||
|
#include "webrtc/sdk/objc/Framework/Classes/Video/objc_frame_buffer.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class ObjCVideoEncoder : public VideoEncoder {
|
||||||
|
public:
|
||||||
|
ObjCVideoEncoder(id<RTCVideoEncoder> encoder) : encoder_(encoder) {}
|
||||||
|
~ObjCVideoEncoder() {}
|
||||||
|
|
||||||
|
int32_t InitEncode(const VideoCodec *codec_settings,
|
||||||
|
int32_t number_of_cores,
|
||||||
|
size_t max_payload_size) {
|
||||||
|
RTCVideoEncoderSettings *settings =
|
||||||
|
[[RTCVideoEncoderSettings alloc] initWithVideoCodec:codec_settings];
|
||||||
|
[encoder_ initEncodeWithSettings:settings numberOfCores:number_of_cores];
|
||||||
|
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t RegisterEncodeCompleteCallback(EncodedImageCallback *callback) {
|
||||||
|
[encoder_ setCallback:^(RTCEncodedImage *frame,
|
||||||
|
id<RTCCodecSpecificInfo> info,
|
||||||
|
RTCRtpFragmentationHeader *header) {
|
||||||
|
EncodedImage encodedImage = [frame toCpp];
|
||||||
|
|
||||||
|
// Handle types than can be converted into one of webrtc::CodecSpecificInfo's hard coded
|
||||||
|
// cases.
|
||||||
|
CodecSpecificInfo codecSpecificInfo;
|
||||||
|
if ([info isKindOfClass:[RTCCodecSpecificInfoH264 class]]) {
|
||||||
|
codecSpecificInfo = [(RTCCodecSpecificInfoH264 *)info toCpp];
|
||||||
|
}
|
||||||
|
|
||||||
|
RTPFragmentationHeader *fragmentationHeader = [header toCpp];
|
||||||
|
callback->OnEncodedImage(encodedImage, &codecSpecificInfo, fragmentationHeader);
|
||||||
|
}];
|
||||||
|
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Release() {
|
||||||
|
[encoder_ releaseEncode];
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t Encode(const VideoFrame &frame,
|
||||||
|
const CodecSpecificInfo *codec_specific_info,
|
||||||
|
const std::vector<FrameType> *frame_types) {
|
||||||
|
RTC_CHECK(frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative);
|
||||||
|
|
||||||
|
id<RTCVideoFrameBuffer> frame_buffer =
|
||||||
|
static_cast<ObjCFrameBuffer *>(frame.video_frame_buffer().get())->wrapped_frame_buffer();
|
||||||
|
RTCVideoFrame *rtcFrame =
|
||||||
|
[[RTCVideoFrame alloc] initWithBuffer:frame_buffer
|
||||||
|
rotation:RTCVideoRotation(frame.rotation())
|
||||||
|
timeStampNs:frame.timestamp_us() * rtc::kNumNanosecsPerMicrosec];
|
||||||
|
rtcFrame.timeStamp = frame.timestamp();
|
||||||
|
|
||||||
|
// webrtc::CodecSpecificInfo only handles a hard coded list of codecs
|
||||||
|
id<RTCCodecSpecificInfo> rtcCodecSpecificInfo = nil;
|
||||||
|
if (codec_specific_info) {
|
||||||
|
if (strcmp(codec_specific_info->codec_name, "H264") == 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)))];
|
||||||
|
}
|
||||||
|
|
||||||
|
[encoder_ encode:rtcFrame codecSpecificInfo:rtcCodecSpecificInfo frameTypes:rtcFrameTypes];
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) {
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SetRates(uint32_t bitrate, uint32_t framerate) {
|
||||||
|
if ([encoder_ setBitrate:bitrate framerate:framerate]) {
|
||||||
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
|
} else {
|
||||||
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupportsNativeHandle() const { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
id<RTCVideoEncoder> encoder_;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ObjCVideoEncoderFactory::ObjCVideoEncoderFactory(id<RTCVideoEncoderFactory> encoder_factory)
|
||||||
|
: encoder_factory_(encoder_factory) {}
|
||||||
|
|
||||||
|
ObjCVideoEncoderFactory::~ObjCVideoEncoderFactory() {}
|
||||||
|
|
||||||
|
id<RTCVideoEncoderFactory> ObjCVideoEncoderFactory::wrapped_encoder_factory() const {
|
||||||
|
return encoder_factory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
webrtc::VideoEncoder *ObjCVideoEncoderFactory::CreateVideoEncoder(
|
||||||
|
const cricket::VideoCodec &codec) {
|
||||||
|
RTCVideoCodecInfo *info = [[RTCVideoCodecInfo alloc] initWithVideoCodec:codec];
|
||||||
|
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) {
|
||||||
|
cricket::VideoCodec codec = [supportedCodec toCpp];
|
||||||
|
supported_codecs_.push_back(codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
return supported_codecs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjCVideoEncoderFactory::DestroyVideoEncoder(webrtc::VideoEncoder *encoder) {
|
||||||
|
delete encoder;
|
||||||
|
encoder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
@ -24,11 +24,19 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
@class RTCVideoSource;
|
@class RTCVideoSource;
|
||||||
@class RTCVideoTrack;
|
@class RTCVideoTrack;
|
||||||
@protocol RTCPeerConnectionDelegate;
|
@protocol RTCPeerConnectionDelegate;
|
||||||
|
@protocol RTCVideoEncoderFactory;
|
||||||
|
@protocol RTCVideoDecoderFactory;
|
||||||
|
|
||||||
RTC_EXPORT
|
RTC_EXPORT
|
||||||
@interface RTCPeerConnectionFactory : NSObject
|
@interface RTCPeerConnectionFactory : NSObject
|
||||||
|
|
||||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
/* Initialize object with default H264 video encoder/decoder factories */
|
||||||
|
- (instancetype)init;
|
||||||
|
|
||||||
|
/* Initialize object with injectable video encoder/decoder factories */
|
||||||
|
- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
|
||||||
|
decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory
|
||||||
|
NS_DESIGNATED_INITIALIZER;
|
||||||
|
|
||||||
/** Initialize an RTCAudioSource with constraints. */
|
/** Initialize an RTCAudioSource with constraints. */
|
||||||
- (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints;
|
- (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints;
|
||||||
|
|||||||
137
webrtc/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h
Normal file
137
webrtc/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodec.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* 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 <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <WebRTC/RTCMacros.h>
|
||||||
|
|
||||||
|
@class RTCVideoFrame;
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/** Represents an encoded frame's type. */
|
||||||
|
typedef NS_ENUM(NSUInteger, RTCFrameType) {
|
||||||
|
EmptyFrame,
|
||||||
|
VideoFrameKey,
|
||||||
|
VideoFrameDelta,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Represents an encoded frame. Corresponds to webrtc::EncodedImage. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCEncodedImage : NSObject
|
||||||
|
|
||||||
|
@property(nonatomic, retain) NSData *buffer;
|
||||||
|
@property(nonatomic, assign) int encodedWidth;
|
||||||
|
@property(nonatomic, assign) int encodedHeight;
|
||||||
|
@property(nonatomic, assign) uint32_t timeStamp;
|
||||||
|
@property(nonatomic, assign) long captureTimeMs;
|
||||||
|
@property(nonatomic, assign) long ntpTimeMs;
|
||||||
|
@property(nonatomic, assign) BOOL isTimingFrame;
|
||||||
|
@property(nonatomic, assign) long encodeStartMs;
|
||||||
|
@property(nonatomic, assign) long encodeFinishMs;
|
||||||
|
@property(nonatomic, assign) RTCFrameType frameType;
|
||||||
|
@property(nonatomic, assign) int rotation;
|
||||||
|
@property(nonatomic, assign) BOOL completeFrame;
|
||||||
|
@property(nonatomic, retain) NSNumber *qp;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Information for header. Corresponds to webrtc::RTPFragmentationHeader. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCRtpFragmentationHeader : NSObject
|
||||||
|
|
||||||
|
@property(nonatomic, retain) NSArray<NSNumber *> *fragmentationOffset;
|
||||||
|
@property(nonatomic, retain) NSArray<NSNumber *> *fragmentationLength;
|
||||||
|
@property(nonatomic, retain) NSArray<NSNumber *> *fragmentationTimeDiff;
|
||||||
|
@property(nonatomic, retain) NSArray<NSNumber *> *fragmentationPlType;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Implement this protocol to pass codec specific info from the encoder.
|
||||||
|
* Corresponds to webrtc::CodecSpecificInfo.
|
||||||
|
*/
|
||||||
|
RTC_EXPORT
|
||||||
|
@protocol RTCCodecSpecificInfo <NSObject>
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Callback block for encoder. */
|
||||||
|
typedef void (^RTCVideoEncoderCallback)(RTCEncodedImage *frame,
|
||||||
|
id<RTCCodecSpecificInfo> info,
|
||||||
|
RTCRtpFragmentationHeader *header);
|
||||||
|
|
||||||
|
/** Callback block for decoder. */
|
||||||
|
typedef void (^RTCVideoDecoderCallback)(RTCVideoFrame *frame);
|
||||||
|
|
||||||
|
/** Settings for encoder. Corresponds to webrtc::VideoCodec. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoEncoderSettings : NSObject
|
||||||
|
|
||||||
|
@property(nonatomic, retain) NSString *name;
|
||||||
|
|
||||||
|
@property(nonatomic, assign) unsigned short width;
|
||||||
|
@property(nonatomic, assign) unsigned short height;
|
||||||
|
|
||||||
|
@property(nonatomic, assign) unsigned int startBitrate; // kilobits/sec.
|
||||||
|
@property(nonatomic, assign) unsigned int maxBitrate;
|
||||||
|
@property(nonatomic, assign) unsigned int minBitrate;
|
||||||
|
@property(nonatomic, assign) unsigned int targetBitrate;
|
||||||
|
|
||||||
|
@property(nonatomic, assign) uint32_t maxFramerate;
|
||||||
|
|
||||||
|
@property(nonatomic, assign) unsigned int qpMax;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Holds information to identify a codec. Corresponds to cricket::VideoCodec. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoCodecInfo : NSObject
|
||||||
|
|
||||||
|
- (instancetype)initWithPayload:(int)payload
|
||||||
|
name:(NSString *)name
|
||||||
|
parameters:(NSDictionary<NSString *, NSString *> *)parameters;
|
||||||
|
|
||||||
|
@property(nonatomic, readonly) int payload;
|
||||||
|
@property(nonatomic, readonly) NSString *name;
|
||||||
|
@property(nonatomic, readonly) NSDictionary<NSString *, NSString *> *parameters;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Protocol for encoder implementations. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@protocol RTCVideoEncoder <NSObject>
|
||||||
|
|
||||||
|
- (instancetype)initWithCodecInfo:(RTCVideoCodecInfo *)codecInfo;
|
||||||
|
- (void)setCallback:(RTCVideoEncoderCallback)callback;
|
||||||
|
- (void)initEncodeWithSettings:(RTCVideoEncoderSettings *)settings numberOfCores:(int)numberOfCores;
|
||||||
|
- (void)releaseEncode;
|
||||||
|
- (void)encode:(RTCVideoFrame *)frame
|
||||||
|
codecSpecificInfo:(id<RTCCodecSpecificInfo>)info
|
||||||
|
frameTypes:(NSArray<NSNumber *> *)frameTypes;
|
||||||
|
- (BOOL)setBitrate:(uint32_t)bitrateKbit framerate:(uint32_t)framerate;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Protocol for decoder implementations. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@protocol RTCVideoDecoder <NSObject>
|
||||||
|
|
||||||
|
- (void)setCallback:(RTCVideoDecoderCallback)callback;
|
||||||
|
- (int)initDecodeWithSettings:(RTCVideoEncoderSettings *)settings numberOfCores:(int)numberOfCores;
|
||||||
|
- (int32_t)releaseDecode;
|
||||||
|
- (int)decode:(RTCEncodedImage *)encodedImage
|
||||||
|
missingFrames:(BOOL)missingFrames
|
||||||
|
fragmentationHeader:(RTCRtpFragmentationHeader *)fragmentationHeader
|
||||||
|
codecSpecificInfo:(__nullable id<RTCCodecSpecificInfo>)info
|
||||||
|
renderTimeMs:(int64_t)renderTimeMs;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <WebRTC/RTCMacros.h>
|
||||||
|
#import <WebRTC/RTCVideoCodec.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
/** RTCVideoEncoderFactory is an Objective-C version of cricket::WebRtcVideoEncoderFactory. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@protocol RTCVideoEncoderFactory <NSObject>
|
||||||
|
|
||||||
|
- (id<RTCVideoEncoder>)createEncoder:(RTCVideoCodecInfo *)info;
|
||||||
|
- (NSArray<RTCVideoCodecInfo *> *)supportedCodecs;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** RTCVideoDecoderFactory is an Objective-C version of cricket::WebRtcVideoDecoderFactory. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@protocol RTCVideoDecoderFactory <NSObject>
|
||||||
|
|
||||||
|
- (id<RTCVideoDecoder>)createDecoder:(RTCVideoCodecInfo *)info;
|
||||||
|
- (NSArray<RTCVideoCodecInfo *> *)supportedCodecs;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
47
webrtc/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h
Normal file
47
webrtc/sdk/objc/Framework/Headers/WebRTC/RTCVideoCodecH264.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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 <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <WebRTC/RTCMacros.h>
|
||||||
|
#import <WebRTC/RTCVideoCodecFactory.h>
|
||||||
|
|
||||||
|
/** Class for H264 specific config. */
|
||||||
|
typedef NS_ENUM(NSUInteger, RTCH264PacketizationMode) {
|
||||||
|
NonInterleaved = 0, // Mode 1 - STAP-A, FU-A is allowed
|
||||||
|
SingleNalUnit // Mode 0 - only single NALU allowed
|
||||||
|
};
|
||||||
|
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCCodecSpecificInfoH264 : NSObject<RTCCodecSpecificInfo>
|
||||||
|
|
||||||
|
@property(nonatomic, assign) RTCH264PacketizationMode packetizationMode;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Encoder. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoEncoderH264 : NSObject<RTCVideoEncoder>
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Decoder. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoDecoderH264 : NSObject<RTCVideoDecoder>
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Encoder factory. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoEncoderFactoryH264 : NSObject<RTCVideoEncoderFactory>
|
||||||
|
@end
|
||||||
|
|
||||||
|
/** Decoder factory. */
|
||||||
|
RTC_EXPORT
|
||||||
|
@interface RTCVideoDecoderFactoryH264 : NSObject<RTCVideoDecoderFactory>
|
||||||
|
@end
|
||||||
@ -51,6 +51,9 @@ RTC_EXPORT
|
|||||||
/** Timestamp in nanoseconds. */
|
/** Timestamp in nanoseconds. */
|
||||||
@property(nonatomic, readonly) int64_t timeStampNs;
|
@property(nonatomic, readonly) int64_t timeStampNs;
|
||||||
|
|
||||||
|
/** Timestamp 90 kHz. */
|
||||||
|
@property(nonatomic, assign) int32_t timeStamp;
|
||||||
|
|
||||||
/** The native handle should be a pixel buffer on iOS. */
|
/** The native handle should be a pixel buffer on iOS. */
|
||||||
@property(nonatomic, readonly)
|
@property(nonatomic, readonly)
|
||||||
CVPixelBufferRef nativeHandle DEPRECATED_MSG_ATTRIBUTE("use buffer instead");
|
CVPixelBufferRef nativeHandle DEPRECATED_MSG_ATTRIBUTE("use buffer instead");
|
||||||
|
|||||||
@ -46,6 +46,9 @@
|
|||||||
#import <WebRTC/RTCSSLAdapter.h>
|
#import <WebRTC/RTCSSLAdapter.h>
|
||||||
#import <WebRTC/RTCSessionDescription.h>
|
#import <WebRTC/RTCSessionDescription.h>
|
||||||
#import <WebRTC/RTCTracing.h>
|
#import <WebRTC/RTCTracing.h>
|
||||||
|
#import <WebRTC/RTCVideoCodec.h>
|
||||||
|
#import <WebRTC/RTCVideoCodecFactory.h>
|
||||||
|
#import <WebRTC/RTCVideoCodecH264.h>
|
||||||
#import <WebRTC/RTCVideoFrame.h>
|
#import <WebRTC/RTCVideoFrame.h>
|
||||||
#import <WebRTC/RTCVideoRenderer.h>
|
#import <WebRTC/RTCVideoRenderer.h>
|
||||||
#import <WebRTC/RTCVideoSource.h>
|
#import <WebRTC/RTCVideoSource.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user