Reland of Injectable Obj-C video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2980173002/ )

Reason for revert:
Relanding after fixing issues with no video.

Original issue's description:
> Revert of Injectable Obj-C video codecs (patchset #2 id:370001 of https://codereview.webrtc.org/2979983002/ )
>
> Reason for revert:
> Still having problems with no video. Reverting.
> Once no video is visible, no video is available from then on even if the callee app is in the foreground.
>
>
> Original issue's description:
> > Reland of Injectable Obj-C video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2979973002/ )
> >
> > Reason for revert:
> > Fix the broken build file
> >
> > Original issue's description:
> > > Revert of Injectable Obj-C video codecs (patchset #3 id:400001 of https://codereview.webrtc.org/2981583002/ )
> > >
> > > Reason for revert:
> > > Breaks bots. Build file incorrect.
> > >
> > > Original issue's description:
> > > > Reland of Injectable Obj-C video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2975963002/ )
> > > >
> > > > Reason for revert:
> > > > New CL for fixing the issues
> > > >
> > > > Original issue's description:
> > > > > Revert of Injectable Obj-C video codecs (patchset #8 id:140001 of https://codereview.webrtc.org/2966023002/ )
> > > > >
> > > > > Reason for revert:
> > > > > Causes no video in certain scenarios. Please come up with a test plan or unit test to prevent such problems in the future.
> > > > >
> > > > > Original issue's description:
> > > > > > 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}
> > > > > > Committed: a0349c138d
> > > > >
> > > > > TBR=magjed@webrtc.org,andersc@webrtc.org
> > > > > # Not skipping CQ checks because original CL landed more than 1 days ago.
> > > > > BUG=webrtc:7924
> > > > > NOTRY=true
> > > > >
> > > > > Review-Url: https://codereview.webrtc.org/2975963002
> > > > > Cr-Commit-Position: refs/heads/master@{#18979}
> > > > > Committed: 1095ada7ad
> > > >
> > > > R=magjed@webrtc.org
> > > > TBR=tkchin@webrtc.org
> > > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > > NOPRESUBMIT=true
> > > > NOTREECHECKS=true
> > > > NOTRY=true
> > > > BUG=webrtc:7924
> > > >
> > > > Review-Url: https://codereview.webrtc.org/2981583002 .
> > > > Cr-Commit-Position: refs/heads/master@{#19002}
> > > > Committed: a5f1de1e65
> > >
> > > TBR=magjed@webrtc.org,tkchin@webrtc.org,jtteh@webrtc.org,andersc@webrtc.org
> > > # Skipping CQ checks because original CL landed less than 1 days ago.
> > > NOPRESUBMIT=true
> > > NOTREECHECKS=true
> > > NOTRY=true
> > > BUG=webrtc:7924
> > >
> > > Review-Url: https://codereview.webrtc.org/2979973002
> > > Cr-Commit-Position: refs/heads/master@{#19004}
> > > Committed: 81d40ee149
> >
> > TBR=magjed@webrtc.org,tkchin@webrtc.org,jtteh@webrtc.org,sprang@webrtc.org
> > BUG=webrtc:7924
> >
> > Review-Url: https://codereview.webrtc.org/2979983002
> > Cr-Commit-Position: refs/heads/master@{#19005}
> > Committed: 732a3437da
>
> TBR=magjed@webrtc.org,tkchin@webrtc.org,sprang@webrtc.org,haysc@webrtc.org,andersc@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=webrtc:7924
>
> Review-Url: https://codereview.webrtc.org/2980173002
> Cr-Commit-Position: refs/heads/master@{#19036}
> Committed: 860f729816

TBR=magjed@webrtc.org,tkchin@webrtc.org,sprang@webrtc.org,haysc@webrtc.org,andersc@webrtc.org,jtteh@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:7924

Review-Url: https://codereview.webrtc.org/2977213002
Cr-Commit-Position: refs/heads/master@{#19135}
This commit is contained in:
kthelgason
2017-07-25 07:55:58 -07:00
committed by Commit Bot
parent 83377270dc
commit fb143127d7
24 changed files with 1506 additions and 173 deletions

View File

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

View File

@ -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/VideoToolbox/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/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/rtc_base/logging.h"
#include "webrtc/rtc_base/timeutils.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() { [decoder_ destroy]; }
int32_t InitDecode(const VideoCodec *codec_settings, int32_t number_of_cores) {
RTCVideoEncoderSettings *settings =
[[RTCVideoEncoderSettings alloc] initWithVideoCodec: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] 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;
}
}
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]; }
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

View File

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

View File

@ -0,0 +1,149 @@
/*
* 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/VideoToolbox/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/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/rtc_base/logging.h"
#include "webrtc/rtc_base/timeutils.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() { [encoder_ destroy]; }
int32_t InitEncode(const VideoCodec *codec_settings,
int32_t number_of_cores,
size_t max_payload_size) {
RTCVideoEncoderSettings *settings =
[[RTCVideoEncoderSettings alloc] initWithVideoCodec:codec_settings];
return [encoder_ startEncodeWithSettings:settings numberOfCores:number_of_cores];
}
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];
}
std::unique_ptr<webrtc::RTPFragmentationHeader> fragmentationHeader = [header toCpp];
callback->OnEncodedImage(encodedImage, &codecSpecificInfo, fragmentationHeader.release());
}];
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) {
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)))];
}
return
[encoder_ encode:rtcFrame 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) {
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

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2016 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_VIDEOTOOLBOX_VIDEOCODECFACTORY_H_
#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_VIDEOCODECFACTORY_H_
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
namespace webrtc {
class VideoToolboxVideoEncoderFactory
: public cricket::WebRtcVideoEncoderFactory {
public:
VideoToolboxVideoEncoderFactory();
~VideoToolboxVideoEncoderFactory();
// WebRtcVideoEncoderFactory implementation.
VideoEncoder* CreateVideoEncoder(const cricket::VideoCodec& codec) override;
void DestroyVideoEncoder(VideoEncoder* encoder) override;
const std::vector<cricket::VideoCodec>& supported_codecs() const override;
private:
// TODO(magjed): Mutable because it depends on a field trial and it is
// recalculated every call to supported_codecs().
mutable std::vector<cricket::VideoCodec> supported_codecs_;
};
class VideoToolboxVideoDecoderFactory
: public cricket::WebRtcVideoDecoderFactory {
public:
VideoToolboxVideoDecoderFactory();
~VideoToolboxVideoDecoderFactory();
// WebRtcVideoDecoderFactory implementation.
VideoDecoder* CreateVideoDecoder(VideoCodecType type) override;
void DestroyVideoDecoder(VideoDecoder* decoder) override;
private:
std::vector<cricket::VideoCodec> supported_codecs_;
};
} // namespace webrtc
#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_VIDEOCODECFACTORY_H_

View File

@ -1,106 +0,0 @@
/*
* Copyright 2015 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/VideoToolbox/videocodecfactory.h"
#include "webrtc/common_video/h264/profile_level_id.h"
#include "webrtc/media/base/codec.h"
#include "webrtc/rtc_base/logging.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"
namespace webrtc {
namespace {
const char kHighProfileExperiment[] = "WebRTC-H264HighProfile";
bool IsHighProfileEnabled() {
return field_trial::IsEnabled(kHighProfileExperiment);
}
}
// VideoToolboxVideoEncoderFactory
VideoToolboxVideoEncoderFactory::VideoToolboxVideoEncoderFactory() {}
VideoToolboxVideoEncoderFactory::~VideoToolboxVideoEncoderFactory() {}
VideoEncoder* VideoToolboxVideoEncoderFactory::CreateVideoEncoder(
const cricket::VideoCodec& codec) {
if (FindMatchingCodec(supported_codecs_, codec)) {
LOG(LS_INFO) << "Creating HW encoder for " << codec.name;
return new H264VideoToolboxEncoder(codec);
}
LOG(LS_INFO) << "No HW encoder found for codec " << codec.name;
return nullptr;
}
void VideoToolboxVideoEncoderFactory::DestroyVideoEncoder(VideoEncoder* encoder) {
delete encoder;
encoder = nullptr;
}
const std::vector<cricket::VideoCodec>& VideoToolboxVideoEncoderFactory::supported_codecs() const {
supported_codecs_.clear();
// TODO(magjed): Enumerate actual level instead of using hardcoded level 3.1.
// Level 3.1 is 1280x720@30fps which is enough for now.
const H264::Level level = H264::kLevel3_1;
if (IsHighProfileEnabled()) {
cricket::VideoCodec constrained_high(cricket::kH264CodecName);
const H264::ProfileLevelId constrained_high_profile(H264::kProfileConstrainedHigh, level);
constrained_high.SetParam(cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(constrained_high_profile));
constrained_high.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
constrained_high.SetParam(cricket::kH264FmtpPacketizationMode, "1");
supported_codecs_.push_back(constrained_high);
}
cricket::VideoCodec constrained_baseline(cricket::kH264CodecName);
const H264::ProfileLevelId constrained_baseline_profile(H264::kProfileConstrainedBaseline, level);
constrained_baseline.SetParam(cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(constrained_baseline_profile));
constrained_baseline.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
constrained_baseline.SetParam(cricket::kH264FmtpPacketizationMode, "1");
supported_codecs_.push_back(constrained_baseline);
return supported_codecs_;
}
// VideoToolboxVideoDecoderFactory
VideoToolboxVideoDecoderFactory::VideoToolboxVideoDecoderFactory() {
supported_codecs_.push_back(cricket::VideoCodec("H264"));
}
VideoToolboxVideoDecoderFactory::~VideoToolboxVideoDecoderFactory() {}
VideoDecoder* VideoToolboxVideoDecoderFactory::CreateVideoDecoder(VideoCodecType type) {
const rtc::Optional<const char*> codec_name = CodecTypeToPayloadName(type);
if (!codec_name) {
LOG(LS_ERROR) << "Invalid codec type: " << type;
return nullptr;
}
const cricket::VideoCodec codec(*codec_name);
if (FindMatchingCodec(supported_codecs_, codec)) {
LOG(LS_INFO) << "Creating HW decoder for " << codec.name;
return new H264VideoToolboxDecoder();
}
LOG(LS_INFO) << "No HW decoder found for codec " << codec.name;
return nullptr;
}
void VideoToolboxVideoDecoderFactory::DestroyVideoDecoder(VideoDecoder* decoder) {
delete decoder;
decoder = nullptr;
}
} // namespace webrtc