From b4ad603b47f269626585cca717cc53c7e944a8c4 Mon Sep 17 00:00:00 2001 From: magjed Date: Sat, 17 Dec 2016 23:50:17 -0800 Subject: [PATCH] Put iOS H264 High profile under a field trial H264 High profile is causing problems for some downstream apps. Therefore, put it behind a field trial instead. BUG=webrtc:6337 Review-Url: https://codereview.webrtc.org/2580963004 Cr-Commit-Position: refs/heads/master@{#15663} --- .../objc/Framework/Classes/RTCFieldTrials.mm | 1 + .../Classes/videotoolboxvideocodecfactory.cc | 62 ++++++++++++------- .../Classes/videotoolboxvideocodecfactory.h | 4 +- .../Framework/Headers/WebRTC/RTCFieldTrials.h | 1 + 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/webrtc/sdk/objc/Framework/Classes/RTCFieldTrials.mm b/webrtc/sdk/objc/Framework/Classes/RTCFieldTrials.mm index 224f7fd595..89cf3c8ea0 100644 --- a/webrtc/sdk/objc/Framework/Classes/RTCFieldTrials.mm +++ b/webrtc/sdk/objc/Framework/Classes/RTCFieldTrials.mm @@ -20,6 +20,7 @@ NSString * const kRTCFieldTrialAudioSendSideBweKey = @"WebRTC-Audio-SendSideBwe" NSString * const kRTCFieldTrialFlexFec03Key = @"WebRTC-FlexFEC-03"; NSString * const kRTCFieldTrialImprovedBitrateEstimateKey = @"WebRTC-ImprovedBitrateEstimate"; NSString * const kRTCFieldTrialTrendlineFilterKey = @"WebRTC-BweTrendlineFilter"; +NSString * const kRTCFieldTrialH264HighProfileKey = @"WebRTC-H264HighProfile"; NSString * const kRTCFieldTrialEnabledValue = @"Enabled"; static std::unique_ptr gFieldTrialInitString; diff --git a/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.cc b/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.cc index b94194fe53..40273991be 100644 --- a/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.cc +++ b/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.cc @@ -12,37 +12,23 @@ #include "webrtc/base/logging.h" #include "webrtc/common_video/h264/profile_level_id.h" #include "webrtc/media/base/codec.h" -#include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h" +#include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" +#include "webrtc/system_wrappers/include/field_trial.h" namespace webrtc { +namespace { +const char kHighProfileExperiment[] = "WebRTC-H264HighProfile"; + +bool IsHighProfileEnabled() { + return field_trial::FindFullName(kHighProfileExperiment) == "Enabled"; +} +} + // VideoToolboxVideoEncoderFactory VideoToolboxVideoEncoderFactory::VideoToolboxVideoEncoderFactory() { - // 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; - - 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); } VideoToolboxVideoEncoderFactory::~VideoToolboxVideoEncoderFactory() {} @@ -65,6 +51,34 @@ void VideoToolboxVideoEncoderFactory::DestroyVideoEncoder( const std::vector& 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_; } diff --git a/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h b/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h index 51007106ae..8acd9dd533 100644 --- a/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h +++ b/webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h @@ -28,7 +28,9 @@ class VideoToolboxVideoEncoderFactory const std::vector& supported_codecs() const override; private: - std::vector supported_codecs_; + // TODO(magjed): Mutable because it depends on a field trial and it is + // recalculated every call to supported_codecs(). + mutable std::vector supported_codecs_; }; class VideoToolboxVideoDecoderFactory diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h index ee997888c1..60c51d8a2b 100644 --- a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h +++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCFieldTrials.h @@ -16,6 +16,7 @@ RTC_EXTERN NSString * const kRTCFieldTrialAudioSendSideBweKey; RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03Key; RTC_EXTERN NSString * const kRTCFieldTrialImprovedBitrateEstimateKey; +RTC_EXTERN NSString * const kRTCFieldTrialH264HighProfileKey; /** The valid value for field trials above. */ RTC_EXTERN NSString * const kRTCFieldTrialEnabledValue;