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:
committed by
Commit Bot
parent
bc3b782813
commit
3ff50fba59
44
sdk/objc/Framework/Native/src/objc_frame_buffer.h
Normal file
44
sdk/objc/Framework/Native/src/objc_frame_buffer.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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_FRAME_BUFFER_H_
|
||||
#define SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_
|
||||
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
|
||||
#include "common_video/include/video_frame_buffer.h"
|
||||
|
||||
@protocol RTCVideoFrameBuffer;
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class ObjCFrameBuffer : public VideoFrameBuffer {
|
||||
public:
|
||||
explicit ObjCFrameBuffer(id<RTCVideoFrameBuffer>);
|
||||
~ObjCFrameBuffer() override;
|
||||
|
||||
Type type() const override;
|
||||
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
|
||||
rtc::scoped_refptr<I420BufferInterface> ToI420() override;
|
||||
|
||||
id<RTCVideoFrameBuffer> wrapped_frame_buffer() const;
|
||||
|
||||
private:
|
||||
id<RTCVideoFrameBuffer> frame_buffer_;
|
||||
int width_;
|
||||
int height_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // SDK_OBJC_FRAMEWORK_NATIVE_SRC_OBJC_FRAME_BUFFER_H_
|
||||
78
sdk/objc/Framework/Native/src/objc_frame_buffer.mm
Normal file
78
sdk/objc/Framework/Native/src/objc_frame_buffer.mm
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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_frame_buffer.h"
|
||||
|
||||
#import "WebRTC/RTCVideoFrameBuffer.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
/** ObjCFrameBuffer that conforms to I420BufferInterface by wrapping RTCI420Buffer */
|
||||
class ObjCI420FrameBuffer : public I420BufferInterface {
|
||||
public:
|
||||
explicit ObjCI420FrameBuffer(id<RTCI420Buffer> frame_buffer)
|
||||
: frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {}
|
||||
~ObjCI420FrameBuffer() override{};
|
||||
|
||||
int width() const override { return width_; }
|
||||
|
||||
int height() const override { return height_; }
|
||||
|
||||
const uint8_t* DataY() const override { return frame_buffer_.dataY; }
|
||||
|
||||
const uint8_t* DataU() const override { return frame_buffer_.dataU; }
|
||||
|
||||
const uint8_t* DataV() const override { return frame_buffer_.dataV; }
|
||||
|
||||
int StrideY() const override { return frame_buffer_.strideY; }
|
||||
|
||||
int StrideU() const override { return frame_buffer_.strideU; }
|
||||
|
||||
int StrideV() const override { return frame_buffer_.strideV; }
|
||||
|
||||
private:
|
||||
id<RTCI420Buffer> frame_buffer_;
|
||||
int width_;
|
||||
int height_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ObjCFrameBuffer::ObjCFrameBuffer(id<RTCVideoFrameBuffer> frame_buffer)
|
||||
: frame_buffer_(frame_buffer), width_(frame_buffer.width), height_(frame_buffer.height) {}
|
||||
|
||||
ObjCFrameBuffer::~ObjCFrameBuffer() {}
|
||||
|
||||
VideoFrameBuffer::Type ObjCFrameBuffer::type() const {
|
||||
return Type::kNative;
|
||||
}
|
||||
|
||||
int ObjCFrameBuffer::width() const {
|
||||
return width_;
|
||||
}
|
||||
|
||||
int ObjCFrameBuffer::height() const {
|
||||
return height_;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<I420BufferInterface> ObjCFrameBuffer::ToI420() {
|
||||
rtc::scoped_refptr<I420BufferInterface> buffer =
|
||||
new rtc::RefCountedObject<ObjCI420FrameBuffer>([frame_buffer_ toI420]);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
id<RTCVideoFrameBuffer> ObjCFrameBuffer::wrapped_frame_buffer() const {
|
||||
return frame_buffer_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
50
sdk/objc/Framework/Native/src/objc_video_decoder_factory.h
Normal file
50
sdk/objc/Framework/Native/src/objc_video_decoder_factory.h
Normal 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_
|
||||
154
sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm
Normal file
154
sdk/objc/Framework/Native/src/objc_video_decoder_factory.mm
Normal 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
|
||||
53
sdk/objc/Framework/Native/src/objc_video_encoder_factory.h
Normal file
53
sdk/objc/Framework/Native/src/objc_video_encoder_factory.h
Normal 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_
|
||||
190
sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm
Normal file
190
sdk/objc/Framework/Native/src/objc_video_encoder_factory.mm
Normal 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
|
||||
Reference in New Issue
Block a user