From eacbaea920797ff751ca83050d140821f5055591 Mon Sep 17 00:00:00 2001 From: magjed Date: Thu, 17 Nov 2016 08:51:59 -0800 Subject: [PATCH] Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ ) Reason for revert: Breaks chromium.fyi test: WebRtcBrowserTest.NegotiateUnsupportedVideoCodec Original issue's description: > Stop using hardcoded payload types for video codecs > > This CL stops using hardcoded payload types for different video codecs > and will dynamically assign them payload types incrementally from 96 to > 127 instead. > > This CL: > * Replaces 'std::vector DefaultVideoCodecList()' in > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for > internally supported software codecs instead. The purpose is to > streamline the payload type assignment in webrtcvideoengine2.cc which > will now have two encoder factories of the same > WebRtcVideoEncoderFactory type; one internal and one external. > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec > instead. > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and > moves the create function to the internal encoder factory instead. > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an > interface without any static functions. > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies > the internal and external codecs and assigns them payload types > incrementally from 96 to 127. > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about > what payload types will be used. > > BUG=webrtc:6677,webrtc:6705 > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org > > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b > Cr-Commit-Position: refs/heads/master@{#15135} TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:6677,webrtc:6705 Review-Url: https://codereview.webrtc.org/2513633002 Cr-Commit-Position: refs/heads/master@{#15140} --- .../android/jni/androidmediaencoder_jni.cc | 51 +-- webrtc/api/webrtcsdp_unittest.cc | 11 +- webrtc/media/BUILD.gn | 2 - webrtc/media/base/mediaconstants.cc | 12 + webrtc/media/base/mediaconstants.h | 12 + webrtc/media/engine/internalencoderfactory.cc | 74 --- webrtc/media/engine/internalencoderfactory.h | 45 -- webrtc/media/engine/payload_type_mapper.cc | 25 +- .../engine/payload_type_mapper_unittest.cc | 24 +- .../videoencodersoftwarefallbackwrapper.cc | 13 +- .../videoencodersoftwarefallbackwrapper.h | 5 +- ...encodersoftwarefallbackwrapper_unittest.cc | 2 +- webrtc/media/engine/webrtcvideoengine2.cc | 231 ++++++---- webrtc/media/engine/webrtcvideoengine2.h | 7 +- .../engine/webrtcvideoengine2_unittest.cc | 423 ++++++++---------- webrtc/video/BUILD.gn | 1 + webrtc/video/end_to_end_tests.cc | 27 +- webrtc/video/video_encoder.cc | 67 +++ webrtc/video/video_quality_test.cc | 9 +- webrtc/video/video_send_stream_tests.cc | 9 +- webrtc/video_encoder.h | 13 + 21 files changed, 541 insertions(+), 522 deletions(-) delete mode 100644 webrtc/media/engine/internalencoderfactory.cc delete mode 100644 webrtc/media/engine/internalencoderfactory.h create mode 100644 webrtc/video/video_encoder.cc diff --git a/webrtc/api/android/jni/androidmediaencoder_jni.cc b/webrtc/api/android/jni/androidmediaencoder_jni.cc index 3fa307d2b6..6fcb0fbe36 100644 --- a/webrtc/api/android/jni/androidmediaencoder_jni.cc +++ b/webrtc/api/android/jni/androidmediaencoder_jni.cc @@ -30,7 +30,6 @@ #include "webrtc/base/timeutils.h" #include "webrtc/common_types.h" #include "webrtc/common_video/h264/h264_bitstream_parser.h" -#include "webrtc/media/engine/internalencoderfactory.h" #include "webrtc/modules/video_coding/include/video_codec_interface.h" #include "webrtc/modules/video_coding/utility/quality_scaler.h" #include "webrtc/modules/video_coding/utility/vp8_header_parser.h" @@ -97,7 +96,7 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder, public: virtual ~MediaCodecVideoEncoder(); MediaCodecVideoEncoder(JNIEnv* jni, - const cricket::VideoCodec& codec, + VideoCodecType codecType, jobject egl_context); // webrtc::VideoEncoder implementation. Everything trampolines to @@ -187,7 +186,7 @@ class MediaCodecVideoEncoder : public webrtc::VideoEncoder, void LogStatistics(bool force_log); // Type of video codec. - const cricket::VideoCodec codec_; + VideoCodecType codecType_; // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to // |codec_thread_| synchronously. @@ -303,9 +302,9 @@ MediaCodecVideoEncoder::~MediaCodecVideoEncoder() { } MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni, - const cricket::VideoCodec& codec, + VideoCodecType codecType, jobject egl_context) - : codec_(codec), + : codecType_(codecType), callback_(NULL), codec_thread_(new Thread()), j_media_codec_video_encoder_class_( @@ -393,10 +392,9 @@ int32_t MediaCodecVideoEncoder::InitEncode( return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } // Factory should guard against other codecs being used with us. - const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name); - RTC_CHECK(codec_settings->codecType == codec_type) + RTC_CHECK(codec_settings->codecType == codecType_) << "Unsupported codec " << codec_settings->codecType << " for " - << codec_type; + << codecType_; if (sw_fallback_required_) { return WEBRTC_VIDEO_CODEC_OK; } @@ -406,9 +404,9 @@ int32_t MediaCodecVideoEncoder::InitEncode( // Scaling is disabled for VP9, but optionally enabled for VP8. // TODO(pbos): Extract automaticResizeOn out of VP8 settings. scale_ = false; - if (codec_type == kVideoCodecVP8) { + if (codecType_ == kVideoCodecVP8) { scale_ = codec_settings->VP8().automaticResizeOn; - } else if (codec_type != kVideoCodecVP9) { + } else if (codecType_ != kVideoCodecVP9) { scale_ = true; } @@ -416,8 +414,8 @@ int32_t MediaCodecVideoEncoder::InitEncode( ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); if (scale_) { - if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecH264) { - quality_scaler_.Init(codec_type, codec_settings->startBitrate, + if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264) { + quality_scaler_.Init(codecType_, codec_settings->startBitrate, codec_settings->width, codec_settings->height, codec_settings->maxFramerate); } else { @@ -524,9 +522,8 @@ bool MediaCodecVideoEncoder::ResetCodecOnCodecThread() { bool MediaCodecVideoEncoder::ProcessHWErrorOnCodecThread( bool reset_if_fallback_unavailable) { ALOGE << "ProcessHWErrorOnCodecThread"; - if (FindMatchingCodec( - cricket::InternalEncoderFactory::GetInstance().supported_codecs(), - codec_)) { + if (VideoEncoder::IsSupportedSoftware( + VideoEncoder::CodecToEncoderType(codecType_))) { ALOGE << "Fallback to SW encoder."; sw_fallback_required_ = true; return false; @@ -553,9 +550,9 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( JNIEnv* jni = AttachCurrentThreadIfNeeded(); ScopedLocalRefFrame local_ref_frame(jni); - const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name); - ALOGD << "InitEncodeOnCodecThread Type: " << (int)codec_type << ", " << width - << " x " << height << ". Bitrate: " << kbps << " kbps. Fps: " << fps; + ALOGD << "InitEncodeOnCodecThread Type: " << (int)codecType_ << ", " << + width << " x " << height << ". Bitrate: " << kbps << + " kbps. Fps: " << fps; if (kbps == 0) { kbps = last_set_bitrate_kbps_; } @@ -594,7 +591,7 @@ int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( // We enforce no extra stride/padding in the format creation step. jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( - jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); + jni, "MediaCodecVideoEncoder$VideoCodecType", codecType_); const bool encode_status = jni->CallBooleanMethod( *j_media_codec_video_encoder_, j_init_encode_method_, j_video_codec_enum, width, height, kbps, fps, @@ -1068,7 +1065,6 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { } // Callback - return encoded frame. - const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name); webrtc::EncodedImageCallback::Result callback_result( webrtc::EncodedImageCallback::Result::OK); if (callback_) { @@ -1087,8 +1083,8 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { webrtc::CodecSpecificInfo info; memset(&info, 0, sizeof(info)); - info.codecType = codec_type; - if (codec_type == kVideoCodecVP8) { + info.codecType = codecType_; + if (codecType_ == kVideoCodecVP8) { info.codecSpecific.VP8.pictureId = picture_id_; info.codecSpecific.VP8.nonReference = false; info.codecSpecific.VP8.simulcastIdx = 0; @@ -1096,7 +1092,7 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { info.codecSpecific.VP8.layerSync = false; info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; info.codecSpecific.VP8.keyIdx = webrtc::kNoKeyIdx; - } else if (codec_type == kVideoCodecVP9) { + } else if (codecType_ == kVideoCodecVP9) { if (key_frame) { gof_idx_ = 0; } @@ -1125,13 +1121,13 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { // Generate a header describing a single fragment. webrtc::RTPFragmentationHeader header; memset(&header, 0, sizeof(header)); - if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecVP9) { + if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecVP9) { header.VerifyAndAllocateFragmentationHeader(1); header.fragmentationOffset[0] = 0; header.fragmentationLength[0] = image->_length; header.fragmentationPlType[0] = 0; header.fragmentationTimeDiff[0] = 0; - if (codec_type == kVideoCodecVP8 && scale_) { + if (codecType_ == kVideoCodecVP8 && scale_) { int qp; if (webrtc::vp8::GetQp(payload, payload_size, &qp)) { current_acc_qp_ += qp; @@ -1139,7 +1135,7 @@ bool MediaCodecVideoEncoder::DeliverPendingOutputs(JNIEnv* jni) { image->qp_ = qp; } } - } else if (codec_type == kVideoCodecH264) { + } else if (codecType_ == kVideoCodecH264) { if (scale_) { h264_bitstream_parser_.ParseBitstream(payload, payload_size); int qp; @@ -1363,7 +1359,8 @@ webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( } if (FindMatchingCodec(supported_codecs_, codec)) { ALOGD << "Create HW video encoder for " << codec.name; - return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), codec, + const VideoCodecType type = cricket::CodecTypeFromName(codec.name); + return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type, egl_context_); } ALOGW << "Can not find HW video encoder for type " << codec.name; diff --git a/webrtc/api/webrtcsdp_unittest.cc b/webrtc/api/webrtcsdp_unittest.cc index 7941323d97..3c6643f2aa 100644 --- a/webrtc/api/webrtcsdp_unittest.cc +++ b/webrtc/api/webrtcsdp_unittest.cc @@ -2083,12 +2083,11 @@ TEST_F(WebRtcSdpTest, SerializeTcpCandidates) { } TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithH264) { - cricket::VideoCodec h264_codec("H264"); - h264_codec.SetParam("profile-level-id", "42e01f"); - h264_codec.SetParam("level-asymmetry-allowed", "1"); - h264_codec.SetParam("packetization-mode", "1"); - video_desc_->AddCodec(h264_codec); - + if (!webrtc::H264Encoder::IsSupported()) + return; + for (const auto& codec : cricket::DefaultVideoCodecList()) { + video_desc_->AddCodec(codec); + } jdesc_.Initialize(desc_.Copy(), kSessionId, kSessionVersion); std::string message = webrtc::SdpSerialize(jdesc_, false); diff --git a/webrtc/media/BUILD.gn b/webrtc/media/BUILD.gn index 590450bd29..c3d173aac8 100644 --- a/webrtc/media/BUILD.gn +++ b/webrtc/media/BUILD.gn @@ -81,8 +81,6 @@ rtc_static_library("rtc_media") { "base/videoframe.h", "base/videosourcebase.cc", "base/videosourcebase.h", - "engine/internalencoderfactory.cc", - "engine/internalencoderfactory.h", "engine/nullwebrtcvideoengine.h", "engine/payload_type_mapper.cc", "engine/payload_type_mapper.h", diff --git a/webrtc/media/base/mediaconstants.cc b/webrtc/media/base/mediaconstants.cc index bce252195a..5acd8cdb01 100644 --- a/webrtc/media/base/mediaconstants.cc +++ b/webrtc/media/base/mediaconstants.cc @@ -108,5 +108,17 @@ const char kH264FmtpLevelAsymmetryAllowed[] = "level-asymmetry-allowed"; const char kH264FmtpPacketizationMode[] = "packetization-mode"; const char kH264ProfileLevelConstrainedBaseline[] = "42e01f"; +const int kDefaultVp8PlType = 100; +const int kDefaultVp9PlType = 101; +const int kDefaultH264PlType = 107; +const int kDefaultRedPlType = 116; +const int kDefaultUlpfecType = 117; +const int kDefaultFlexfecPlType = 118; +const int kDefaultRtxVp8PlType = 96; +const int kDefaultRtxVp9PlType = 97; +const int kDefaultRtxRedPlType = 98; +const int kDefaultRtxH264ConstrainedBaselinePlType = 99; +const int kDefaultRtxH264ConstrainedHighPlType = 102; + const int kDefaultVideoMaxFramerate = 60; } // namespace cricket diff --git a/webrtc/media/base/mediaconstants.h b/webrtc/media/base/mediaconstants.h index 70080c3a08..02a7ba239e 100644 --- a/webrtc/media/base/mediaconstants.h +++ b/webrtc/media/base/mediaconstants.h @@ -130,6 +130,18 @@ extern const char kH264FmtpLevelAsymmetryAllowed[]; extern const char kH264FmtpPacketizationMode[]; extern const char kH264ProfileLevelConstrainedBaseline[]; +extern const int kDefaultVp8PlType; +extern const int kDefaultVp9PlType; +extern const int kDefaultH264PlType; +extern const int kDefaultRedPlType; +extern const int kDefaultUlpfecType; +extern const int kDefaultFlexfecPlType; +extern const int kDefaultRtxVp8PlType; +extern const int kDefaultRtxVp9PlType; +extern const int kDefaultRtxRedPlType; +extern const int kDefaultRtxH264ConstrainedBaselinePlType; +extern const int kDefaultRtxH264ConstrainedHighPlType; + extern const int kDefaultVideoMaxFramerate; } // namespace cricket diff --git a/webrtc/media/engine/internalencoderfactory.cc b/webrtc/media/engine/internalencoderfactory.cc deleted file mode 100644 index f7c80a0324..0000000000 --- a/webrtc/media/engine/internalencoderfactory.cc +++ /dev/null @@ -1,74 +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. - */ - -#include "webrtc/media/engine/internalencoderfactory.h" - -#include - -#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" -#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" -#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" - -namespace cricket { - -// static -WebRtcVideoEncoderFactory& InternalEncoderFactory::GetInstance() { - static InternalEncoderFactory instance; - return instance; -} - -InternalEncoderFactory::InternalEncoderFactory() { - supported_codecs_.push_back(cricket::VideoCodec(kVp8CodecName)); - if (webrtc::VP9Encoder::IsSupported()) - supported_codecs_.push_back(cricket::VideoCodec(kVp9CodecName)); - if (webrtc::H264Encoder::IsSupported()) { - cricket::VideoCodec codec(kH264CodecName); - // TODO(magjed): Move setting these parameters into webrtc::H264Encoder - // instead. - // TODO(hta): Set FMTP parameters for all codecs of type H264. - codec.SetParam(kH264FmtpProfileLevelId, - kH264ProfileLevelConstrainedBaseline); - codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); - codec.SetParam(kH264FmtpPacketizationMode, "1"); - supported_codecs_.push_back(std::move(codec)); - } - - supported_codecs_.push_back(cricket::VideoCodec(kRedCodecName)); - supported_codecs_.push_back(cricket::VideoCodec(kUlpfecCodecName)); -} - -InternalEncoderFactory::~InternalEncoderFactory() {} - -// WebRtcVideoEncoderFactory implementation. -webrtc::VideoEncoder* InternalEncoderFactory::CreateVideoEncoder( - const cricket::VideoCodec& codec) { - switch (CodecTypeFromName(codec.name)) { - case webrtc::kVideoCodecH264: - return webrtc::H264Encoder::Create(); - case webrtc::kVideoCodecVP8: - return webrtc::VP8Encoder::Create(); - case webrtc::kVideoCodecVP9: - return webrtc::VP9Encoder::Create(); - default: - return nullptr; - } -} - -const std::vector& -InternalEncoderFactory::supported_codecs() const { - return supported_codecs_; -} - -void InternalEncoderFactory::DestroyVideoEncoder( - webrtc::VideoEncoder* encoder) { - delete encoder; -} - -} // namespace cricket diff --git a/webrtc/media/engine/internalencoderfactory.h b/webrtc/media/engine/internalencoderfactory.h deleted file mode 100644 index 357bbef383..0000000000 --- a/webrtc/media/engine/internalencoderfactory.h +++ /dev/null @@ -1,45 +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_MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ -#define WEBRTC_MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ - -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/media/engine/webrtcvideoencoderfactory.h" - -namespace cricket { - -class InternalEncoderFactory : public WebRtcVideoEncoderFactory { - public: - static WebRtcVideoEncoderFactory& GetInstance(); - - // WebRtcVideoEncoderFactory implementation. - webrtc::VideoEncoder* CreateVideoEncoder( - const cricket::VideoCodec& codec) override; - const std::vector& supported_codecs() const override; - void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override; - - private: - // Disable overloaded virtual function warning. TODO(magjed): Remove once - // http://crbug/webrtc/6402 is fixed. - using WebRtcVideoEncoderFactory::CreateVideoEncoder; - - InternalEncoderFactory(); - virtual ~InternalEncoderFactory(); - RTC_DISALLOW_COPY_AND_ASSIGN(InternalEncoderFactory); - - std::vector supported_codecs_; -}; - -} // namespace cricket - -#endif // WEBRTC_MEDIA_ENGINE_INTERNALENCODERFACTORY_H_ diff --git a/webrtc/media/engine/payload_type_mapper.cc b/webrtc/media/engine/payload_type_mapper.cc index 0d449c4e43..477c7ab093 100644 --- a/webrtc/media/engine/payload_type_mapper.cc +++ b/webrtc/media/engine/payload_type_mapper.cc @@ -53,18 +53,41 @@ PayloadTypeMapper::PayloadTypeMapper() {{"G729", 8000, 1}, 18}, // Payload type assignments currently used by WebRTC. - // Includes data to reduce collisions (and thus reassignments) + // Includes video and data to reduce collisions (and thus + // reassignments). // RTX codecs mapping to specific video payload types + {{kRtxCodecName, 90000, 0, + {{kCodecParamAssociatedPayloadType, + std::to_string(kDefaultVp8PlType)}}}, + kDefaultRtxVp8PlType}, + {{kRtxCodecName, 90000, 0, + {{kCodecParamAssociatedPayloadType, + std::to_string(kDefaultVp9PlType)}}}, + kDefaultRtxVp9PlType}, + {{kRtxCodecName, 90000, 0, + {{kCodecParamAssociatedPayloadType, + std::to_string(kDefaultRedPlType)}}}, + kDefaultRtxRedPlType}, + {{kRtxCodecName, 90000, 0, + {{kCodecParamAssociatedPayloadType, + std::to_string(kDefaultH264PlType)}}}, + kDefaultRtxH264ConstrainedBaselinePlType}, // Other codecs + {{kVp8CodecName, 90000, 0}, kDefaultVp8PlType}, + {{kVp9CodecName, 90000, 0}, kDefaultVp9PlType}, {{kGoogleRtpDataCodecName, 0, 0}, kGoogleRtpDataCodecPlType}, {{kIlbcCodecName, 8000, 1}, 102}, {{kIsacCodecName, 16000, 1}, 103}, {{kIsacCodecName, 32000, 1}, 104}, {{kCnCodecName, 16000, 1}, 105}, {{kCnCodecName, 32000, 1}, 106}, + {{kH264CodecName, 90000, 0}, kDefaultH264PlType}, {{kGoogleSctpDataCodecName, 0, 0}, kGoogleSctpDataCodecPlType}, {{kOpusCodecName, 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}, 111}, + {{kRedCodecName, 90000, 0}, kDefaultRedPlType}, + {{kUlpfecCodecName, 90000, 0}, kDefaultUlpfecType}, + {{kFlexfecCodecName, 90000, 0}, kDefaultFlexfecPlType}, // TODO(solenberg): Remove the hard coded 16k,32k,48k DTMF once we // assign payload types dynamically for send side as well. {{kDtmfCodecName, 48000, 1}, 110}, diff --git a/webrtc/media/engine/payload_type_mapper_unittest.cc b/webrtc/media/engine/payload_type_mapper_unittest.cc index 628eb0cc91..6ff8c0f658 100644 --- a/webrtc/media/engine/payload_type_mapper_unittest.cc +++ b/webrtc/media/engine/payload_type_mapper_unittest.cc @@ -60,8 +60,28 @@ TEST_F(PayloadTypeMapperTest, StaticPayloadTypes) { } TEST_F(PayloadTypeMapperTest, WebRTCPayloadTypes) { - // Tests that the payload mapper knows about the audio and data formats we've - // been using in WebRTC, with their hard coded values. + // Tests that the payload mapper knows about the formats we've been using in + // WebRTC, with their hard coded values. + auto video_mapping = [this] (const char *name) { + return FindMapping({name, kVideoCodecClockrate, 0}); + }; + EXPECT_EQ(kDefaultVp8PlType, video_mapping(kVp8CodecName)); + EXPECT_EQ(kDefaultVp9PlType, video_mapping(kVp9CodecName)); + EXPECT_EQ(kDefaultH264PlType, video_mapping(kH264CodecName)); + EXPECT_EQ(kDefaultRedPlType, video_mapping(kRedCodecName)); + EXPECT_EQ(kDefaultUlpfecType, video_mapping(kUlpfecCodecName)); + EXPECT_EQ(kDefaultFlexfecPlType, video_mapping(kFlexfecCodecName)); + + auto rtx_mapping = [this] (int payload_type) { + return FindMapping({kRtxCodecName, kVideoCodecClockrate, 0, + {{ kCodecParamAssociatedPayloadType, std::to_string(payload_type)}}}); + }; + EXPECT_EQ(kDefaultRtxVp8PlType, rtx_mapping(kDefaultVp8PlType)); + EXPECT_EQ(kDefaultRtxVp9PlType, rtx_mapping(kDefaultVp9PlType)); + EXPECT_EQ(kDefaultRtxH264ConstrainedBaselinePlType, + rtx_mapping(kDefaultH264PlType)); + EXPECT_EQ(kDefaultRtxRedPlType, rtx_mapping(kDefaultRedPlType)); + auto data_mapping = [this] (const char *name) { return FindMapping({name, 0, 0}); }; diff --git a/webrtc/media/engine/videoencodersoftwarefallbackwrapper.cc b/webrtc/media/engine/videoencodersoftwarefallbackwrapper.cc index 69a483e8b3..cc37a91736 100644 --- a/webrtc/media/engine/videoencodersoftwarefallbackwrapper.cc +++ b/webrtc/media/engine/videoencodersoftwarefallbackwrapper.cc @@ -11,13 +11,12 @@ #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" #include "webrtc/base/logging.h" -#include "webrtc/media/engine/internalencoderfactory.h" #include "webrtc/modules/video_coding/include/video_error_codes.h" namespace webrtc { VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper( - const cricket::VideoCodec& codec, + VideoCodecType codec_type, webrtc::VideoEncoder* encoder) : number_of_cores_(0), max_payload_size_(0), @@ -26,19 +25,17 @@ VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper( channel_parameters_set_(false), packet_loss_(0), rtt_(0), - codec_(codec), + encoder_type_(CodecToEncoderType(codec_type)), encoder_(encoder), callback_(nullptr) {} bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() { - cricket::WebRtcVideoEncoderFactory& internal_factory = - cricket::InternalEncoderFactory::GetInstance(); - if (!FindMatchingCodec(internal_factory.supported_codecs(), codec_)) { + if (!VideoEncoder::IsSupportedSoftware(encoder_type_)) { LOG(LS_WARNING) << "Encoder requesting fallback to codec not supported in software."; return false; } - fallback_encoder_.reset(internal_factory.CreateVideoEncoder(codec_)); + fallback_encoder_.reset(VideoEncoder::Create(encoder_type_)); if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_, max_payload_size_) != WEBRTC_VIDEO_CODEC_OK) { @@ -80,7 +77,7 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( int32_t ret = encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size); - if (ret == WEBRTC_VIDEO_CODEC_OK || codec_.name.empty()) { + if (ret == WEBRTC_VIDEO_CODEC_OK || encoder_type_ == kUnsupportedCodec) { if (fallback_encoder_) fallback_encoder_->Release(); fallback_encoder_.reset(); diff --git a/webrtc/media/engine/videoencodersoftwarefallbackwrapper.h b/webrtc/media/engine/videoencodersoftwarefallbackwrapper.h index 05e815df46..5d81f4ac1e 100644 --- a/webrtc/media/engine/videoencodersoftwarefallbackwrapper.h +++ b/webrtc/media/engine/videoencodersoftwarefallbackwrapper.h @@ -15,7 +15,6 @@ #include #include -#include "webrtc/media/base/codec.h" #include "webrtc/video_encoder.h" namespace webrtc { @@ -25,7 +24,7 @@ namespace webrtc { // hardware restrictions, such as max resolution. class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder { public: - VideoEncoderSoftwareFallbackWrapper(const cricket::VideoCodec& codec, + VideoEncoderSoftwareFallbackWrapper(VideoCodecType codec_type, webrtc::VideoEncoder* encoder); int32_t InitEncode(const VideoCodec* codec_settings, @@ -64,7 +63,7 @@ class VideoEncoderSoftwareFallbackWrapper : public VideoEncoder { uint32_t packet_loss_; int64_t rtt_; - const cricket::VideoCodec codec_; + const EncoderType encoder_type_; webrtc::VideoEncoder* const encoder_; std::unique_ptr fallback_encoder_; diff --git a/webrtc/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc b/webrtc/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc index ca06e9256d..42d6b473cd 100644 --- a/webrtc/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc +++ b/webrtc/media/engine/videoencodersoftwarefallbackwrapper_unittest.cc @@ -28,7 +28,7 @@ const size_t kMaxPayloadSize = 800; class VideoEncoderSoftwareFallbackWrapperTest : public ::testing::Test { protected: VideoEncoderSoftwareFallbackWrapperTest() - : fallback_wrapper_(cricket::VideoCodec("VP8"), &fake_encoder_) {} + : fallback_wrapper_(kVideoCodecVP8, &fake_encoder_) {} class CountingFakeEncoder : public VideoEncoder { public: diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 646ed8e447..c43dff80d3 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -24,13 +24,14 @@ #include "webrtc/call.h" #include "webrtc/common_video/h264/profile_level_id.h" #include "webrtc/media/engine/constants.h" -#include "webrtc/media/engine/internalencoderfactory.h" #include "webrtc/media/engine/simulcast.h" #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" #include "webrtc/media/engine/webrtcmediaengine.h" #include "webrtc/media/engine/webrtcvideoencoderfactory.h" #include "webrtc/media/engine/webrtcvoiceengine.h" +#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" +#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" #include "webrtc/system_wrappers/include/field_trial.h" #include "webrtc/video_decoder.h" #include "webrtc/video_encoder.h" @@ -169,6 +170,13 @@ void AddDefaultFeedbackParams(VideoCodec* codec) { FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); } +static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, + const char* name) { + VideoCodec codec(payload_type, name); + AddDefaultFeedbackParams(&codec); + return codec; +} + static std::string CodecVectorToString(const std::vector& codecs) { std::stringstream out; out << '{'; @@ -384,6 +392,73 @@ static const int kDefaultRtcpReceiverReportSsrc = 1; // Minimum time interval for logging stats. static const int64_t kStatsLogIntervalMs = 10000; +// Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is +// recognized. +// TODO(deadbeef): Should we add RTX codecs for external codecs whose names we +// don't recognize? +void AddCodecAndMaybeRtxCodec(const VideoCodec& codec, + std::vector* codecs) { + codecs->push_back(codec); + int rtx_payload_type = 0; + if (CodecNamesEq(codec.name, kVp8CodecName)) { + rtx_payload_type = kDefaultRtxVp8PlType; + } else if (CodecNamesEq(codec.name, kVp9CodecName)) { + rtx_payload_type = kDefaultRtxVp9PlType; + } else if (CodecNamesEq(codec.name, kH264CodecName)) { + // Parse H264 profile. + const rtc::Optional profile_level_id = + webrtc::H264::ParseSdpProfileLevelId(codec.params); + if (!profile_level_id) + return; + const webrtc::H264::Profile profile = profile_level_id->profile; + // In H.264, we only support rtx for constrained baseline and constrained + // high profile. + if (profile == webrtc::H264::kProfileConstrainedBaseline) { + rtx_payload_type = kDefaultRtxH264ConstrainedBaselinePlType; + } else if (profile == webrtc::H264::kProfileConstrainedHigh) { + rtx_payload_type = kDefaultRtxH264ConstrainedHighPlType; + } else { + return; + } + } else if (CodecNamesEq(codec.name, kRedCodecName)) { + rtx_payload_type = kDefaultRtxRedPlType; + } else { + return; + } + codecs->push_back(VideoCodec::CreateRtxCodec(rtx_payload_type, codec.id)); +} + +std::vector DefaultVideoCodecList() { + std::vector codecs; + AddCodecAndMaybeRtxCodec( + MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), + &codecs); + if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) { + AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( + kDefaultVp9PlType, kVp9CodecName), + &codecs); + } + if (webrtc::H264Encoder::IsSupported() && + webrtc::H264Decoder::IsSupported()) { + VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( + kDefaultH264PlType, kH264CodecName); + // TODO(hta): Move all parameter generation for SDP into the codec + // implementation, for all codecs and parameters. + // TODO(hta): Move selection of profile-level-id to H.264 codec + // implementation. + // TODO(hta): Set FMTP parameters for all codecs of type H264. + codec.SetParam(kH264FmtpProfileLevelId, + kH264ProfileLevelConstrainedBaseline); + codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); + codec.SetParam(kH264FmtpPacketizationMode, "1"); + AddCodecAndMaybeRtxCodec(codec, &codecs); + } + AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), + &codecs); + codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); + return codecs; +} + static std::vector GetSupportedCodecs( const WebRtcVideoEncoderFactory* external_encoder_factory); @@ -559,87 +634,50 @@ void WebRtcVideoEngine2::SetExternalEncoderFactory( video_codecs_ = GetSupportedCodecs(encoder_factory); } -// This is a helper function for AppendVideoCodecs below. It will return the -// first unused dynamic payload type (in the range [96, 127]), or nothing if no -// payload type is unused. -static rtc::Optional NextFreePayloadType( - const std::vector& codecs) { - static const int kFirstDynamicPayloadType = 96; - static const int kLastDynamicPayloadType = 127; - bool is_payload_used[1 + kLastDynamicPayloadType - kFirstDynamicPayloadType] = - {false}; - for (const VideoCodec& codec : codecs) { - if (kFirstDynamicPayloadType <= codec.id && - codec.id <= kLastDynamicPayloadType) { - is_payload_used[codec.id - kFirstDynamicPayloadType] = true; - } - } - for (int i = kFirstDynamicPayloadType; i <= kLastDynamicPayloadType; ++i) { - if (!is_payload_used[i - kFirstDynamicPayloadType]) - return rtc::Optional(i); - } - // No free payload type. - return rtc::Optional(); -} - -// This is a helper function for GetSupportedCodecs below. It will append new -// unique codecs from |input_codecs| to |unified_codecs|. It will add default -// feedback params to the codecs and will also add an associated RTX codec for -// recognized codecs (VP8, VP9, H264, and Red). -static void AppendVideoCodecs(const std::vector& input_codecs, - std::vector* unified_codecs) { - for (VideoCodec codec : input_codecs) { - const rtc::Optional payload_type = - NextFreePayloadType(*unified_codecs); - if (!payload_type) - return; - codec.id = *payload_type; - // TODO(magjed): Move the responsibility of setting these parameters to the - // encoder factories instead. - if (codec.name != kRedCodecName && codec.name != kUlpfecCodecName) - AddDefaultFeedbackParams(&codec); - // Don't add same codec twice. - if (FindMatchingCodec(*unified_codecs, codec)) - continue; - - unified_codecs->push_back(codec); - - // Add associated RTX codec for recognized codecs. - // TODO(deadbeef): Should we add RTX codecs for external codecs whose names - // we don't recognize? - if (CodecNamesEq(codec.name, kVp8CodecName) || - CodecNamesEq(codec.name, kVp9CodecName) || - CodecNamesEq(codec.name, kH264CodecName) || - CodecNamesEq(codec.name, kRedCodecName)) { - const rtc::Optional rtx_payload_type = - NextFreePayloadType(*unified_codecs); - if (!rtx_payload_type) - return; - unified_codecs->push_back( - VideoCodec::CreateRtxCodec(*rtx_payload_type, codec.id)); - } - } -} - static std::vector GetSupportedCodecs( const WebRtcVideoEncoderFactory* external_encoder_factory) { - const std::vector& internal_codecs = - InternalEncoderFactory::GetInstance().supported_codecs(); - LOG(LS_INFO) << "Internally supported codecs: " - << CodecVectorToString(internal_codecs); + std::vector supported_codecs = DefaultVideoCodecList(); - std::vector unified_codecs; - AppendVideoCodecs(internal_codecs, &unified_codecs); - - if (external_encoder_factory != nullptr) { - const std::vector& external_codecs = - external_encoder_factory->supported_codecs(); - AppendVideoCodecs(external_codecs, &unified_codecs); - LOG(LS_INFO) << "Codecs supported by the external encoder factory: " - << CodecVectorToString(external_codecs); + if (external_encoder_factory == nullptr) { + LOG(LS_INFO) << "Supported codecs: " + << CodecVectorToString(supported_codecs); + return supported_codecs; } - return unified_codecs; + std::stringstream out; + const std::vector& codecs = + external_encoder_factory->supported_codecs(); + for (size_t i = 0; i < codecs.size(); ++i) { + VideoCodec codec = codecs[i]; + out << codec.name; + if (i != codecs.size() - 1) { + out << ", "; + } + // Don't add internally-supported codecs twice. + if (FindMatchingCodec(supported_codecs, codec)) + continue; + + // External video encoders are given payloads 120-127. This also means that + // we only support up to 8 external payload types. + // TODO(deadbeef): mediasession.cc already has code to dynamically + // determine a payload type. We should be able to just leave the payload + // type empty and let mediasession determine it. However, currently RTX + // codecs are associated to codecs by payload type, meaning we DO need + // to allocate unique payload types here. So to make this change we would + // need to make RTX codecs associated by name instead. + const int kExternalVideoPayloadTypeBase = 120; + size_t payload_type = kExternalVideoPayloadTypeBase + i; + RTC_DCHECK(payload_type < 128); + codec.id = payload_type; + + AddDefaultFeedbackParams(&codec); + AddCodecAndMaybeRtxCodec(codec, &supported_codecs); + } + LOG(LS_INFO) << "Supported codecs (incl. external codecs): " + << CodecVectorToString(supported_codecs); + LOG(LS_INFO) << "Codecs supported by the external encoder factory: " + << out.str(); + return supported_codecs; } WebRtcVideoChannel2::WebRtcVideoChannel2( @@ -1517,16 +1555,16 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( webrtc::VideoEncoder* encoder, - const cricket::VideoCodec& codec, + webrtc::VideoCodecType type, bool external) : encoder(encoder), external_encoder(nullptr), - codec(codec), + type(type), external(external) { if (external) { external_encoder = encoder; this->encoder = - new webrtc::VideoEncoderSoftwareFallbackWrapper(codec, encoder); + new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); } } @@ -1554,7 +1592,7 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( encoder_sink_(nullptr), parameters_(std::move(config), options, max_bitrate_bps, codec_settings), rtp_parameters_(CreateRtpParametersWithOneEncoding()), - allocated_encoder_(nullptr, cricket::VideoCodec(), false), + allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), sending_(false), last_frame_timestamp_us_(0) { parameters_.config.rtp.max_packet_size = kVideoMtu; @@ -1689,33 +1727,36 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( const VideoCodec& codec) { RTC_DCHECK_RUN_ON(&thread_checker_); + webrtc::VideoCodecType type = CodecTypeFromName(codec.name); + // Do not re-create encoders of the same type. - if (codec == allocated_encoder_.codec && - allocated_encoder_.encoder != nullptr) { + if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { return allocated_encoder_; } - // Try creating external encoder. - if (external_encoder_factory_ != nullptr && - FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { + if (external_encoder_factory_ != NULL) { webrtc::VideoEncoder* encoder = external_encoder_factory_->CreateVideoEncoder(codec); - if (encoder != nullptr) - return AllocatedEncoder(encoder, codec, true /* is_external */); + if (encoder != NULL) { + return AllocatedEncoder(encoder, type, true); + } } - // Try creating internal encoder. - WebRtcVideoEncoderFactory& internal_encoder_factory = - InternalEncoderFactory::GetInstance(); - if (FindMatchingCodec(internal_encoder_factory.supported_codecs(), codec)) { - return AllocatedEncoder(internal_encoder_factory.CreateVideoEncoder(codec), - codec, false /* is_external */); + if (type == webrtc::kVideoCodecVP8) { + return AllocatedEncoder( + webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); + } else if (type == webrtc::kVideoCodecVP9) { + return AllocatedEncoder( + webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); + } else if (type == webrtc::kVideoCodecH264) { + return AllocatedEncoder( + webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); } // This shouldn't happen, we should not be trying to create something we don't // support. RTC_DCHECK(false); - return AllocatedEncoder(NULL, cricket::VideoCodec(), false); + return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); } void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index 546799ec88..28dfb9773a 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -61,6 +61,9 @@ class WebRtcVoiceMediaChannel; struct Device; +// Exposed here for unittests. +std::vector DefaultVideoCodecList(); + class UnsignalledSsrcHandler { public: enum Action { @@ -298,11 +301,11 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { struct AllocatedEncoder { AllocatedEncoder(webrtc::VideoEncoder* encoder, - const cricket::VideoCodec& codec, + webrtc::VideoCodecType type, bool external); webrtc::VideoEncoder* encoder; webrtc::VideoEncoder* external_encoder; - cricket::VideoCodec codec; + webrtc::VideoCodecType type; bool external; }; diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index 70de26711a..19b7d644cd 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -33,6 +33,13 @@ using webrtc::RtpExtension; namespace { static const int kDefaultQpMax = 56; +static const cricket::VideoCodec kVp8Codec(100, "VP8"); +static const cricket::VideoCodec kVp9Codec(101, "VP9"); +static const cricket::VideoCodec kH264Codec(102, "H264"); + +static const cricket::VideoCodec kRedCodec(116, "red"); +static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec"); + static const uint8_t kRedRtxPayloadType = 125; static const uint32_t kSsrcs1[] = {1}; @@ -42,11 +49,6 @@ static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE; static const char kUnsupportedExtensionName[] = "urn:ietf:params:rtp-hdrext:unsupported"; -cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) { - codec.feedback_params = cricket::FeedbackParams(); - return codec; -} - void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) { EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam( cricket::kRtcpFbParamNack, cricket::kParamValueEmpty))); @@ -111,15 +113,19 @@ class WebRtcVideoEngine2Test : public ::testing::Test { std::vector engine_codecs = engine_.codecs(); RTC_DCHECK(!engine_codecs.empty()); bool codec_set = false; - for (const cricket::VideoCodec& codec : engine_codecs) { - if (codec.name == "rtx") { + for (size_t i = 0; i < engine_codecs.size(); ++i) { + if (engine_codecs[i].name == "red") { + default_red_codec_ = engine_codecs[i]; + } else if (engine_codecs[i].name == "ulpfec") { + default_ulpfec_codec_ = engine_codecs[i]; + } else if (engine_codecs[i].name == "rtx") { int associated_payload_type; - if (codec.GetParam(kCodecParamAssociatedPayloadType, - &associated_payload_type)) { - default_apt_rtx_types_[associated_payload_type] = codec.id; + if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType, + &associated_payload_type)) { + default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id; } - } else if (!codec_set && codec.name != "red" && codec.name != "ulpfec") { - default_codec_ = codec; + } else if (!codec_set) { + default_codec_ = engine_codecs[i]; codec_set = true; } } @@ -128,12 +134,9 @@ class WebRtcVideoEngine2Test : public ::testing::Test { } protected: - // Find the codec in the engine with the given name. The codec must be - // present. - cricket::VideoCodec GetEngineCodec(const std::string& name); - VideoMediaChannel* SetUpForExternalEncoderFactory( - cricket::WebRtcVideoEncoderFactory* encoder_factory); + cricket::WebRtcVideoEncoderFactory* encoder_factory, + const std::vector& codecs); VideoMediaChannel* SetUpForExternalDecoderFactory( cricket::WebRtcVideoDecoderFactory* decoder_factory, @@ -148,6 +151,8 @@ class WebRtcVideoEngine2Test : public ::testing::Test { std::unique_ptr call_; WebRtcVideoEngine2 engine_; VideoCodec default_codec_; + VideoCodec default_red_codec_; + VideoCodec default_ulpfec_codec_; std::map default_apt_rtx_types_; }; @@ -235,15 +240,15 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); // Add CVO extension. const int id = 1; - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.extensions.push_back( RtpExtension(RtpExtension::kVideoRotationUri, id)); EXPECT_TRUE(channel->SetSendParameters(parameters)); @@ -267,13 +272,13 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeAddSendStream) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); // Add CVO extension. const int id = 1; - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); parameters.extensions.push_back( RtpExtension(RtpExtension::kVideoRotationUri, id)); EXPECT_TRUE(channel->SetSendParameters(parameters)); @@ -292,9 +297,12 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory.AddSupportedVideoCodecType("VP9"); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc))); // Set capturer. @@ -305,9 +313,6 @@ TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) { // Add CVO extension. const int id = 1; - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); parameters.extensions.push_back( RtpExtension(RtpExtension::kVideoRotationUri, id)); // Also remove the first codec to trigger a codec change as well. @@ -348,9 +353,11 @@ TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) { TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); EXPECT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); @@ -371,8 +378,6 @@ TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) { // Setting codecs of the same type should not reallocate any encoders // (expecting a no-op). - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); EXPECT_TRUE(channel->SetSendParameters(parameters)); EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders()); @@ -411,13 +416,13 @@ TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) { // First figure out what payload types the test codecs got assigned. const std::vector codecs = engine_.codecs(); - // Now search for RTX codecs for them. Expect that they all have associated - // RTX codecs. + // Now search for RTX codecs for them. Expect that Constrained Baseline and + // Constrained High got an associated RTX codec, but not High. EXPECT_TRUE(HasRtxCodec( codecs, FindMatchingCodec(codecs, h264_constrained_baseline)->id)); EXPECT_TRUE(HasRtxCodec( codecs, FindMatchingCodec(codecs, h264_constrained_high)->id)); - EXPECT_TRUE(HasRtxCodec( + EXPECT_FALSE(HasRtxCodec( codecs, FindMatchingCodec(codecs, h264_high)->id)); } @@ -425,11 +430,14 @@ void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse( bool use_external_encoder) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel; FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_)); call_.reset(fake_call); if (use_external_encoder) { - channel.reset(SetUpForExternalEncoderFactory(&encoder_factory)); + channel.reset( + SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs)); } else { engine_.Init(); channel.reset( @@ -437,8 +445,6 @@ void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse( } ASSERT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); EXPECT_TRUE(channel->SetSendParameters(parameters)); EXPECT_TRUE(channel->SetSend(true)); FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0]; @@ -461,9 +467,11 @@ TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) { TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP9"); + std::vector codecs; + codecs.push_back(kVp9Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); EXPECT_TRUE( channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc))); @@ -473,10 +481,12 @@ TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) { TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + std::vector codecs; + codecs.push_back(kVp8Codec); FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_)); call_.reset(fake_call); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); EXPECT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); @@ -526,29 +536,16 @@ TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) { EXPECT_TRUE(channel->RemoveSendStream(kSsrc)); } -cricket::VideoCodec WebRtcVideoEngine2Test::GetEngineCodec( - const std::string& name) { - for (const cricket::VideoCodec& engine_codec : engine_.codecs()) { - if (CodecNamesEq(name, engine_codec.name)) - return engine_codec; - } - // This point should never be reached. - ADD_FAILURE() << "Unrecognized codec name: " << name; - return cricket::VideoCodec(); -} - VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory( - cricket::WebRtcVideoEncoderFactory* encoder_factory) { + cricket::WebRtcVideoEncoderFactory* encoder_factory, + const std::vector& codecs) { engine_.SetExternalEncoderFactory(encoder_factory); engine_.Init(); VideoMediaChannel* channel = engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()); cricket::VideoSendParameters parameters; - // We need to look up the codec in the engine to get the correct payload type. - for (const VideoCodec& codec : encoder_factory->supported_codecs()) - parameters.codecs.push_back(GetEngineCodec(codec.name)); - + parameters.codecs = codecs; EXPECT_TRUE(channel->SetSendParameters(parameters)); return channel; @@ -572,9 +569,11 @@ VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory( TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("VP8"); + std::vector codecs; + codecs.push_back(kVp8Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); std::vector ssrcs = MAKE_VECTOR(kSsrcs3); @@ -611,16 +610,18 @@ TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) { TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("H264"); + std::vector codecs; + codecs.push_back(kH264Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); EXPECT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); ASSERT_EQ(1u, encoder_factory.encoders().size()); cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel->SetSendParameters(parameters)); ASSERT_EQ(0u, encoder_factory.encoders().size()); } @@ -629,15 +630,11 @@ TEST_F(WebRtcVideoEngine2Test, DontUseExternalEncoderFactoryForUnsupportedCodecs) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("H264"); - - engine_.SetExternalEncoderFactory(&encoder_factory); - engine_.Init(); + std::vector codecs; + codecs.push_back(kVp8Codec); std::unique_ptr channel( - engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions())); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - EXPECT_TRUE(channel->SetSendParameters(parameters)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); EXPECT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); @@ -651,14 +648,11 @@ TEST_F(WebRtcVideoEngine2Test, encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory.AddSupportedVideoCodecType("H264"); - engine_.SetExternalEncoderFactory(&encoder_factory); - engine_.Init(); + std::vector codecs; + codecs.push_back(kVp8Codec); std::unique_ptr channel( - engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions())); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - EXPECT_TRUE(channel->SetSendParameters(parameters)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); std::vector ssrcs = MAKE_VECTOR(kSsrcs3); @@ -691,14 +685,11 @@ TEST_F(WebRtcVideoEngine2Test, encoder_factory.AddSupportedVideoCodecType("VP8"); encoder_factory.AddSupportedVideoCodecType("H264"); - engine_.SetExternalEncoderFactory(&encoder_factory); - engine_.Init(); + std::vector codecs; + codecs.push_back(kH264Codec); std::unique_ptr channel( - engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions())); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("H264")); - EXPECT_TRUE(channel->SetSendParameters(parameters)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); EXPECT_TRUE( channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc))); @@ -723,9 +714,11 @@ TEST_F(WebRtcVideoEngine2Test, TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) { cricket::FakeWebRtcVideoEncoderFactory encoder_factory; encoder_factory.AddSupportedVideoCodecType("H264"); + std::vector codecs; + codecs.push_back(kH264Codec); std::unique_ptr channel( - SetUpForExternalEncoderFactory(&encoder_factory)); + SetUpForExternalEncoderFactory(&encoder_factory, codecs)); const std::vector ssrcs = MAKE_VECTOR(kSsrcs3); EXPECT_TRUE( @@ -768,7 +761,7 @@ TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) { cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel( SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); @@ -798,7 +791,7 @@ TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) { cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264); std::vector codecs; - codecs.push_back(GetEngineCodec("H264")); + codecs.push_back(kH264Codec); std::unique_ptr channel( SetUpForExternalDecoderFactory(&decoder_factory, codecs)); @@ -813,17 +806,7 @@ class WebRtcVideoChannel2BaseTest protected: typedef VideoMediaChannelTest Base; - cricket::VideoCodec GetEngineCodec(const std::string& name) { - for (const cricket::VideoCodec& engine_codec : engine_.codecs()) { - if (CodecNamesEq(name, engine_codec.name)) - return engine_codec; - } - // This point should never be reached. - ADD_FAILURE() << "Unrecognized codec name: " << name; - return cricket::VideoCodec(); - } - - cricket::VideoCodec DefaultCodec() override { return GetEngineCodec("VP8"); } + cricket::VideoCodec DefaultCodec() override { return kVp8Codec; } }; // Verifies that id given in stream params is passed to the decoder factory. @@ -831,7 +814,7 @@ TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) { cricket::FakeWebRtcVideoDecoderFactory decoder_factory; decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); std::unique_ptr channel( SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); @@ -882,15 +865,15 @@ WEBRTC_BASE_TEST(RejectEmptyStreamParams); WEBRTC_BASE_TEST(MultipleSendStreams); TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) { - SendAndReceive(GetEngineCodec("VP8")); + SendAndReceive(cricket::VideoCodec(100, "VP8")); } TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) { - SendAndReceive(GetEngineCodec("VP8")); + SendAndReceive(cricket::VideoCodec(100, "VP8")); } TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) { - SendAndReceive(GetEngineCodec("VP8")); + SendAndReceive(cricket::VideoCodec(100, "VP8")); } TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) { @@ -899,7 +882,7 @@ TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) { // initially will use QVGA instead of VGA. // TODO(pbos): Set up the quality scaler so that both senders reliably start // at QVGA, then verify that instead. - cricket::VideoCodec codec = GetEngineCodec("VP8"); + cricket::VideoCodec codec = kVp8Codec; codec.params[kCodecParamStartBitrate] = "1000000"; Base::TwoStreamsSendAndReceive(codec); } @@ -959,7 +942,7 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { int expected_max_bitrate_bps) { auto& codecs = send_parameters_.codecs; codecs.clear(); - codecs.push_back(GetEngineCodec("VP8")); + codecs.push_back(kVp8Codec); codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps; codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps; codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps; @@ -1071,8 +1054,8 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { void TestCpuAdaptation(bool enable_overuse, bool is_screenshare); void TestReceiverLocalSsrcConfiguration(bool receiver_first); - void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type, - bool expect_created_receive_stream); + void TestReceiveUnsignalledSsrcPacket(uint8_t payload_type, + bool expect_created_receive_stream); FakeVideoSendStream* SetDenoisingOption( uint32_t ssrc, @@ -1446,7 +1429,7 @@ TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) { // Verify that REMB is turned off when send(!) codecs without REMB are set. cricket::VideoSendParameters parameters; - parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8"))); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); EXPECT_TRUE(channel_->SetSendParameters(parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -1467,7 +1450,7 @@ TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) { // Verify that transport cc feedback is turned off when send(!) codecs without // transport cc feedback are set. cricket::VideoSendParameters parameters; - parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8"))); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); EXPECT_TRUE(channel_->SetSendParameters(parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -1513,7 +1496,7 @@ TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) { // Verify that NACK is turned off when send(!) codecs without NACK are set. cricket::VideoSendParameters parameters; - parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8"))); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty()); EXPECT_TRUE(channel_->SetSendParameters(parameters)); recv_stream = fake_call_->GetVideoReceiveStreams()[0]; @@ -1538,7 +1521,7 @@ TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) { // earlier. TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); channel_->SetSend(false); @@ -1565,7 +1548,7 @@ TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) { TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) { static const int kScreenshareMinBitrateKbps = 800; - cricket::VideoCodec codec = GetEngineCodec("VP8"); + cricket::VideoCodec codec = kVp8Codec; cricket::VideoSendParameters parameters; parameters.codecs.push_back(codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); @@ -1754,7 +1737,7 @@ TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) { TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); // Single-stream settings should apply with RTX as well (verifies that we @@ -1835,7 +1818,7 @@ TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) { EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capturer.GetSupportedFormats()->front())); cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front(); @@ -1884,7 +1867,7 @@ class Vp9SettingsTest : public WebRtcVideoChannel2Test { TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp9Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); FakeVideoSendStream* stream = SetUpSimulcast(false, false); @@ -1944,7 +1927,7 @@ class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest { protected: void VerifySettings(int num_spatial_layers, int num_temporal_layers) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp9Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); FakeVideoSendStream* stream = SetUpSimulcast(false, false); @@ -2015,7 +1998,7 @@ TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) { } TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) { - cricket::VideoCodec codec = GetEngineCodec("VP8"); + cricket::VideoCodec codec = kVp8Codec; cricket::VideoSendParameters parameters; parameters.codecs.push_back(codec); @@ -2089,7 +2072,7 @@ TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) { } TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) { - cricket::VideoCodec codec = GetEngineCodec("VP8"); + cricket::VideoCodec codec = kVp8Codec; cricket::VideoSendParameters parameters; parameters.codecs.push_back(codec); @@ -2153,7 +2136,7 @@ TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) { void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse, bool is_screenshare) { - cricket::VideoCodec codec = GetEngineCodec("VP8"); + cricket::VideoCodec codec = kVp8Codec; cricket::VideoSendParameters parameters; parameters.codecs.push_back(codec); @@ -2277,8 +2260,8 @@ TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { // Make sure NACK and FEC are enabled on the correct payload types. EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms); - EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type); - EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type); + EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.ulpfec.ulpfec_payload_type); + EXPECT_EQ(default_red_codec_.id, config.rtp.ulpfec.red_payload_type); EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size()); EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]); @@ -2288,7 +2271,7 @@ TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) { TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); FakeVideoSendStream* stream = AddSendStream(); @@ -2300,11 +2283,8 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) { TEST_F(WebRtcVideoChannel2Test, SetSendCodecRejectsRtxWithoutAssociatedPayloadType) { - const int kUnusedPayloadType = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType)); - cricket::VideoSendParameters parameters; - cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx"); + cricket::VideoCodec rtx_codec(96, "rtx"); parameters.codecs.push_back(rtx_codec); EXPECT_FALSE(channel_->SetSendParameters(parameters)) << "RTX codec without associated payload type should be rejected."; @@ -2312,39 +2292,31 @@ TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetSendCodecRejectsRtxWithoutMatchingVideoCodec) { - const int kUnusedPayloadType1 = 126; - const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); - { - cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec( - kUnusedPayloadType1, GetEngineCodec("VP8").id); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(rtx_codec); - ASSERT_TRUE(channel_->SetSendParameters(parameters)); - } - { - cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec( - kUnusedPayloadType1, kUnusedPayloadType2); - cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(rtx_codec); - EXPECT_FALSE(channel_->SetSendParameters(parameters)) - << "RTX without matching video codec should be rejected."; - } + cricket::VideoSendParameters parameters; + cricket::VideoCodec rtx_codec = + cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(rtx_codec); + ASSERT_TRUE(channel_->SetSendParameters(parameters)); + + cricket::VideoCodec rtx_codec2 = + cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1); + parameters.codecs.pop_back(); + parameters.codecs.push_back(rtx_codec2); + EXPECT_FALSE(channel_->SetSendParameters(parameters)) + << "RTX without matching video codec should be rejected."; } TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("ulpfec")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kUlpfecCodec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); FakeVideoSendStream* stream = AddSendStream(); webrtc::VideoSendStream::Config config = stream->GetConfig().Copy(); - EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type); + EXPECT_EQ(kUlpfecCodec.id, config.rtp.ulpfec.ulpfec_payload_type); parameters.codecs.pop_back(); ASSERT_TRUE(channel_->SetSendParameters(parameters)); @@ -2489,7 +2461,7 @@ TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthAndAddSendStream) { TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); channel_->SetSend(true); @@ -2516,7 +2488,7 @@ TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) { TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetSendParameters(parameters)); channel_->SetSend(true); @@ -2550,7 +2522,7 @@ TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) { static const char* kMaxQuantization = "21"; cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization; EXPECT_TRUE(channel_->SetSendParameters(parameters)); EXPECT_EQ(static_cast(atoi(kMaxQuantization)), @@ -2565,7 +2537,7 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { // TODO(pbos): Should we only allow the dynamic range? static const int kIncorrectPayloads[] = {-2, -1, 128, 129}; cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) { parameters.codecs[0].id = kIncorrectPayloads[i]; EXPECT_FALSE(channel_->SetSendParameters(parameters)) @@ -2575,7 +2547,8 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); + // Only the dynamic payload types are valid for video codecs. for (int payload_type = 96; payload_type <= 127; ++payload_type) { parameters.codecs[0].id = payload_type; EXPECT_TRUE(channel_->SetSendParameters(parameters)) @@ -2590,47 +2563,42 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) { TEST_F(WebRtcVideoChannel2Test, SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) { cricket::VideoSendParameters parameters1; - parameters1.codecs.push_back(GetEngineCodec("VP8")); - parameters1.codecs.push_back(GetEngineCodec("VP9")); + parameters1.codecs.push_back(kVp8Codec); + parameters1.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters1)); AddSendStream(); EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams()); cricket::VideoSendParameters parameters2; - parameters2.codecs.push_back(GetEngineCodec("VP8")); + parameters2.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters2)); EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams()); } TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); } // Test that we set our inbound RTX codecs properly. TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) { - const int kUnusedPayloadType1 = 126; - const int kUnusedPayloadType2 = 127; - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1)); - EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2)); - cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx"); + parameters.codecs.push_back(kVp8Codec); + cricket::VideoCodec rtx_codec(96, "rtx"); parameters.codecs.push_back(rtx_codec); EXPECT_FALSE(channel_->SetRecvParameters(parameters)) << "RTX codec without associated payload should be rejected."; - parameters.codecs[1].SetParam("apt", kUnusedPayloadType2); + parameters.codecs[1].SetParam("apt", kVp8Codec.id + 1); EXPECT_FALSE(channel_->SetRecvParameters(parameters)) << "RTX codec with invalid associated payload type should be rejected."; - parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id); + parameters.codecs[1].SetParam("apt", kVp8Codec.id); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); - cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx"); + cricket::VideoCodec rtx_codec2(97, "rtx"); rtx_codec2.SetParam("apt", rtx_codec.id); parameters.codecs.push_back(rtx_codec2); @@ -2641,7 +2609,7 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) { TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); parameters.codecs[0].id = 99; EXPECT_TRUE(channel_->SetRecvParameters(parameters)); } @@ -2659,7 +2627,7 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) { TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); parameters.codecs.push_back(VideoCodec(101, "WTF3")); EXPECT_FALSE(channel_->SetRecvParameters(parameters)); } @@ -2668,34 +2636,34 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) { TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); } TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs. } TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) { cricket::VideoSendParameters send_parameters; - send_parameters.codecs.push_back(GetEngineCodec("VP8")); - send_parameters.codecs.push_back(GetEngineCodec("red")); - send_parameters.codecs.push_back(GetEngineCodec("ulpfec")); + send_parameters.codecs.push_back(kVp8Codec); + send_parameters.codecs.push_back(kRedCodec); + send_parameters.codecs.push_back(kUlpfecCodec); ASSERT_TRUE(channel_->SetSendParameters(send_parameters)); FakeVideoReceiveStream* stream = AddRecvStream(); - EXPECT_EQ(GetEngineCodec("ulpfec").id, + EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type); cricket::VideoRecvParameters recv_parameters; - recv_parameters.codecs.push_back(GetEngineCodec("VP8")); + recv_parameters.codecs.push_back(kVp8Codec); ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; ASSERT_TRUE(stream != NULL); @@ -2705,43 +2673,41 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) { TEST_F(WebRtcVideoChannel2Test, SetSendParamsWithFecEnablesFec) { FakeVideoReceiveStream* stream = AddRecvStream(); - EXPECT_EQ(GetEngineCodec("ulpfec").id, + EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type); cricket::VideoRecvParameters recv_parameters; - recv_parameters.codecs.push_back(GetEngineCodec("VP8")); - recv_parameters.codecs.push_back(GetEngineCodec("red")); - recv_parameters.codecs.push_back(GetEngineCodec("ulpfec")); + recv_parameters.codecs.push_back(kVp8Codec); + recv_parameters.codecs.push_back(kRedCodec); + recv_parameters.codecs.push_back(kUlpfecCodec); ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; ASSERT_TRUE(stream != NULL); - EXPECT_EQ(GetEngineCodec("ulpfec").id, - stream->GetConfig().rtp.ulpfec.ulpfec_payload_type) + EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type) << "FEC should be enabled on the receive stream."; cricket::VideoSendParameters send_parameters; - send_parameters.codecs.push_back(GetEngineCodec("VP8")); - send_parameters.codecs.push_back(GetEngineCodec("red")); - send_parameters.codecs.push_back(GetEngineCodec("ulpfec")); + send_parameters.codecs.push_back(kVp8Codec); + send_parameters.codecs.push_back(kRedCodec); + send_parameters.codecs.push_back(kUlpfecCodec); ASSERT_TRUE(channel_->SetSendParameters(send_parameters)); stream = fake_call_->GetVideoReceiveStreams()[0]; - EXPECT_EQ(GetEngineCodec("ulpfec").id, - stream->GetConfig().rtp.ulpfec.ulpfec_payload_type) + EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type) << "FEC should be enabled on the receive stream."; } TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("red")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kRedCodec); parameters.codecs[1].id = parameters.codecs[0].id; EXPECT_FALSE(channel_->SetRecvParameters(parameters)); } TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); parameters.codecs[1].id = parameters.codecs[0].id; EXPECT_FALSE(channel_->SetRecvParameters(parameters)); } @@ -2749,8 +2715,8 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) { TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) { cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp8Codec); parameters.codecs[1].id += 1; EXPECT_TRUE(channel_->SetRecvParameters(parameters)); } @@ -2760,16 +2726,16 @@ TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentOrderDoesntRecreateStream) { cricket::VideoRecvParameters parameters1; - parameters1.codecs.push_back(GetEngineCodec("VP8")); - parameters1.codecs.push_back(GetEngineCodec("red")); + parameters1.codecs.push_back(kVp8Codec); + parameters1.codecs.push_back(kRedCodec); EXPECT_TRUE(channel_->SetRecvParameters(parameters1)); AddRecvStream(cricket::StreamParams::CreateLegacy(123)); EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); cricket::VideoRecvParameters parameters2; - parameters2.codecs.push_back(GetEngineCodec("red")); - parameters2.codecs.push_back(GetEngineCodec("VP8")); + parameters2.codecs.push_back(kRedCodec); + parameters2.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters2)); EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams()); } @@ -2889,14 +2855,14 @@ TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) { TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) { cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); + parameters.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); AddSendStream(); cricket::VideoMediaInfo info; ASSERT_TRUE(channel_->GetStats(&info)); - EXPECT_EQ("VP8", info.senders[0].codec_name); + EXPECT_EQ(kVp8Codec.name, info.senders[0].codec_name); } TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) { @@ -3309,7 +3275,7 @@ TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) { EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); // Report VP8 if we're receiving it. - stats.current_payload_type = GetEngineCodec("VP8").id; + stats.current_payload_type = kDefaultVp8PlType; stream->SetStats(stats); ASSERT_TRUE(channel_->GetStats(&info)); EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str()); @@ -3321,15 +3287,12 @@ TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) { EXPECT_STREQ("", info.receivers[0].codec_name.c_str()); } -void WebRtcVideoChannel2Test::TestReceiveUnsignaledSsrcPacket( +void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket( uint8_t payload_type, bool expect_created_receive_stream) { - // kRedRtxPayloadType must currently be unused. - EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType)); - // Add a RED RTX codec. VideoCodec red_rtx_codec = - VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id); + VideoCodec::CreateRtxCodec(kRedRtxPayloadType, kDefaultRedPlType); recv_parameters_.codecs.push_back(red_rtx_codec); EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_)); @@ -3356,30 +3319,23 @@ void WebRtcVideoChannel2Test::TestReceiveUnsignaledSsrcPacket( } TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) { - TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id, - true /* expect_created_receive_stream */); + TestReceiveUnsignalledSsrcPacket(kDefaultVp8PlType, true); } TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) { - TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id, - true /* expect_created_receive_stream */); + TestReceiveUnsignalledSsrcPacket(kDefaultVp9PlType, true); } TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) { - const cricket::VideoCodec vp8 = GetEngineCodec("VP8"); - const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id]; - TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type, - false /* expect_created_receive_stream */); + TestReceiveUnsignalledSsrcPacket(kDefaultRtxVp8PlType, false); } TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) { - TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id, - false /* expect_created_receive_stream */); + TestReceiveUnsignalledSsrcPacket(kDefaultUlpfecType, false); } TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) { - TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType, - false /* expect_created_receive_stream */); + TestReceiveUnsignalledSsrcPacket(kRedRtxPayloadType, false); } TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) { @@ -3474,8 +3430,8 @@ TEST_F(WebRtcVideoChannel2Test, InactiveStreamDoesntStartSendingWhenReconfigured) { // Set an initial codec list, which will be modified later. cricket::VideoSendParameters parameters1; - parameters1.codecs.push_back(GetEngineCodec("VP8")); - parameters1.codecs.push_back(GetEngineCodec("VP9")); + parameters1.codecs.push_back(kVp8Codec); + parameters1.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters1)); FakeVideoSendStream* stream = AddSendStream(); @@ -3494,8 +3450,8 @@ TEST_F(WebRtcVideoChannel2Test, // Reorder the codec list, causing the stream to be reconfigured. cricket::VideoSendParameters parameters2; - parameters2.codecs.push_back(GetEngineCodec("VP9")); - parameters2.codecs.push_back(GetEngineCodec("VP8")); + parameters2.codecs.push_back(kVp9Codec); + parameters2.codecs.push_back(kVp8Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters2)); auto new_streams = GetFakeSendStreams(); // Assert that a new underlying stream was created due to the codec change. @@ -3512,25 +3468,23 @@ TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) { AddSendStream(); cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_); ASSERT_EQ(2u, rtp_parameters.codecs.size()); - EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(), - rtp_parameters.codecs[0]); - EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(), - rtp_parameters.codecs[1]); + EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]); } // Test that if we set/get parameters multiple times, we get the same results. TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) { AddSendStream(); cricket::VideoSendParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); webrtc::RtpParameters initial_params = @@ -3547,17 +3501,15 @@ TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) { TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) { AddRecvStream(); cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(last_ssrc_); ASSERT_EQ(2u, rtp_parameters.codecs.size()); - EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(), - rtp_parameters.codecs[0]); - EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(), - rtp_parameters.codecs[1]); + EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]); } #if defined(WEBRTC_USE_H264) @@ -3614,8 +3566,8 @@ TEST_F(WebRtcVideoChannel2Test, RtpEncodingParametersSsrcIsSet) { TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) { AddRecvStream(); cricket::VideoRecvParameters parameters; - parameters.codecs.push_back(GetEngineCodec("VP8")); - parameters.codecs.push_back(GetEngineCodec("VP9")); + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetRecvParameters(parameters)); webrtc::RtpParameters initial_params = @@ -3809,15 +3761,16 @@ class WebRtcVideoChannel2SimulcastTest : public testing::Test { }; TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) { - VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2); + VerifySimulcastSettings(kVp8Codec, 640, 360, 2, 2); } TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) { - VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3); + VerifySimulcastSettings(kVp8Codec, 1280, 720, 3, 3); } // Test that we normalize send codec format size in simulcast. TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) { - VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2); + cricket::VideoCodec codec(kVp8Codec); + VerifySimulcastSettings(codec, 541, 271, 2, 2); } } // namespace cricket diff --git a/webrtc/video/BUILD.gn b/webrtc/video/BUILD.gn index 5f9f75c1ef..7b6dd8f8e7 100644 --- a/webrtc/video/BUILD.gn +++ b/webrtc/video/BUILD.gn @@ -37,6 +37,7 @@ rtc_static_library("video") { "transport_adapter.cc", "transport_adapter.h", "video_decoder.cc", + "video_encoder.cc", "video_receive_stream.cc", "video_receive_stream.h", "video_send_stream.cc", diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index d93dd247d1..3ff3bd23f5 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -353,20 +353,23 @@ class CodecObserver : public test::EndToEndTest, }; TEST_F(EndToEndTest, SendsAndReceivesVP8Rotation90) { - CodecObserver test(5, kVideoRotation_90, "VP8", VP8Encoder::Create(), + CodecObserver test(5, kVideoRotation_90, "VP8", + VideoEncoder::Create(VideoEncoder::kVp8), VP8Decoder::Create()); RunBaseTest(&test); } #if !defined(RTC_DISABLE_VP9) TEST_F(EndToEndTest, SendsAndReceivesVP9) { - CodecObserver test(500, kVideoRotation_0, "VP9", VP9Encoder::Create(), + CodecObserver test(500, kVideoRotation_0, "VP9", + VideoEncoder::Create(VideoEncoder::kVp9), VP9Decoder::Create()); RunBaseTest(&test); } TEST_F(EndToEndTest, SendsAndReceivesVP9VideoRotation90) { - CodecObserver test(5, kVideoRotation_90, "VP9", VP9Encoder::Create(), + CodecObserver test(5, kVideoRotation_90, "VP9", + VideoEncoder::Create(VideoEncoder::kVp9), VP9Decoder::Create()); RunBaseTest(&test); } @@ -374,13 +377,15 @@ TEST_F(EndToEndTest, SendsAndReceivesVP9VideoRotation90) { #if defined(WEBRTC_USE_H264) TEST_F(EndToEndTest, SendsAndReceivesH264) { - CodecObserver test(500, kVideoRotation_0, "H264", H264Encoder::Create(), + CodecObserver test(500, kVideoRotation_0, "H264", + VideoEncoder::Create(VideoEncoder::kH264), H264Decoder::Create()); RunBaseTest(&test); } TEST_F(EndToEndTest, SendsAndReceivesH264VideoRotation90) { - CodecObserver test(5, kVideoRotation_90, "H264", H264Encoder::Create(), + CodecObserver test(5, kVideoRotation_90, "H264", + VideoEncoder::Create(VideoEncoder::kH264), H264Decoder::Create()); RunBaseTest(&test); } @@ -760,7 +765,7 @@ TEST_F(EndToEndTest, ReceivedUlpfecPacketsNotNacked) { ulpfec_sequence_number_(0), has_last_sequence_number_(false), last_sequence_number_(0), - encoder_(VP8Encoder::Create()), + encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)), decoder_(VP8Decoder::Create()) {} private: @@ -928,7 +933,7 @@ void EndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, bool enable_red) { retransmission_ssrc_(enable_rtx ? kSendRtxSsrcs[0] : kVideoSendSsrcs[0]), retransmission_payload_type_(GetPayloadType(enable_rtx, enable_red)), - encoder_(VP8Encoder::Create()), + encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)), marker_bits_observed_(0), retransmitted_timestamp_(0) {} @@ -1327,7 +1332,7 @@ class MultiStreamTest { std::unique_ptr encoders[kNumStreams]; for (size_t i = 0; i < kNumStreams; ++i) - encoders[i].reset(VP8Encoder::Create()); + encoders[i].reset(VideoEncoder::Create(VideoEncoder::kVp8)); VideoSendStream* send_streams[kNumStreams]; VideoReceiveStream* receive_streams[kNumStreams]; @@ -2177,7 +2182,9 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, use_red_(use_red), screenshare_(screenshare), // This test uses NACK, so to send FEC we can't use a fake encoder. - vp8_encoder_(use_red ? VP8Encoder::Create() : nullptr), + vp8_encoder_( + use_red ? VideoEncoder::Create(VideoEncoder::EncoderType::kVp8) + : nullptr), sender_call_(nullptr), receiver_call_(nullptr), start_runtime_ms_(-1), @@ -3968,7 +3975,7 @@ TEST_F(EndToEndLogTest, LogsEncodedFramesWhenRequested) { VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { - encoder_.reset(VP8Encoder::Create()); + encoder_.reset(VideoEncoder::Create(VideoEncoder::kVp8)); decoder_.reset(VP8Decoder::Create()); send_config->post_encode_callback = this; diff --git a/webrtc/video/video_encoder.cc b/webrtc/video/video_encoder.cc new file mode 100644 index 0000000000..f4e8156528 --- /dev/null +++ b/webrtc/video/video_encoder.cc @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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/video_encoder.h" + +#include "webrtc/base/checks.h" +#include "webrtc/base/logging.h" +#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" +#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" +#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" + +namespace webrtc { +VideoEncoder* VideoEncoder::Create(VideoEncoder::EncoderType codec_type) { + RTC_DCHECK(IsSupportedSoftware(codec_type)); + switch (codec_type) { + case kH264: + return H264Encoder::Create(); + case kVp8: + return VP8Encoder::Create(); + case kVp9: + return VP9Encoder::Create(); + case kUnsupportedCodec: + RTC_NOTREACHED(); + return nullptr; + } + RTC_NOTREACHED(); + return nullptr; +} + +bool VideoEncoder::IsSupportedSoftware(EncoderType codec_type) { + switch (codec_type) { + case kH264: + return H264Encoder::IsSupported(); + case kVp8: + return true; + case kVp9: + return VP9Encoder::IsSupported(); + case kUnsupportedCodec: + RTC_NOTREACHED(); + return false; + } + RTC_NOTREACHED(); + return false; +} + +VideoEncoder::EncoderType VideoEncoder::CodecToEncoderType( + VideoCodecType codec_type) { + switch (codec_type) { + case kVideoCodecH264: + return VideoEncoder::kH264; + case kVideoCodecVP8: + return VideoEncoder::kVp8; + case kVideoCodecVP9: + return VideoEncoder::kVp9; + default: + return VideoEncoder::kUnsupportedCodec; + } +} + +} // namespace webrtc diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc index 42f24046b2..d0624c0a52 100644 --- a/webrtc/video/video_quality_test.cc +++ b/webrtc/video/video_quality_test.cc @@ -29,9 +29,6 @@ #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" -#include "webrtc/modules/video_coding/codecs/h264/include/h264.h" -#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" -#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" #include "webrtc/system_wrappers/include/cpu_info.h" #include "webrtc/test/gtest.h" #include "webrtc/test/layer_filtering_transport.h" @@ -1009,13 +1006,13 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, int payload_type; if (params_.video.codec == "H264") { - video_encoder_.reset(H264Encoder::Create()); + video_encoder_.reset(VideoEncoder::Create(VideoEncoder::kH264)); payload_type = kPayloadTypeH264; } else if (params_.video.codec == "VP8") { - video_encoder_.reset(VP8Encoder::Create()); + video_encoder_.reset(VideoEncoder::Create(VideoEncoder::kVp8)); payload_type = kPayloadTypeVP8; } else if (params_.video.codec == "VP9") { - video_encoder_.reset(VP9Encoder::Create()); + video_encoder_.reset(VideoEncoder::Create(VideoEncoder::kVp9)); payload_type = kPayloadTypeVP9; } else { RTC_NOTREACHED() << "Codec not supported!"; diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc index cc76b13515..c9d8f76549 100644 --- a/webrtc/video/video_send_stream_tests.cc +++ b/webrtc/video/video_send_stream_tests.cc @@ -24,7 +24,6 @@ #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" -#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" #include "webrtc/system_wrappers/include/sleep.h" #include "webrtc/test/call_test.h" @@ -368,9 +367,9 @@ class UlpfecObserver : public test::EndToEndTest { if (codec == "H264") { encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock())); } else if (codec == "VP8") { - encoder_.reset(VP8Encoder::Create()); + encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)); } else if (codec == "VP9") { - encoder_.reset(VP9Encoder::Create()); + encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp9)); } else { RTC_NOTREACHED(); } @@ -553,9 +552,9 @@ class FlexfecObserver : public test::EndToEndTest { if (codec == "H264") { encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock())); } else if (codec == "VP8") { - encoder_.reset(VP8Encoder::Create()); + encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)); } else if (codec == "VP9") { - encoder_.reset(VP9Encoder::Create()); + encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp9)); } else { RTC_NOTREACHED(); } diff --git a/webrtc/video_encoder.h b/webrtc/video_encoder.h index f8a04f2e74..3a997176a9 100644 --- a/webrtc/video_encoder.h +++ b/webrtc/video_encoder.h @@ -63,6 +63,19 @@ class EncodedImageCallback { class VideoEncoder { public: + enum EncoderType { + kH264, + kVp8, + kVp9, + kUnsupportedCodec, + }; + + static VideoEncoder* Create(EncoderType codec_type); + // Returns true if this type of encoder can be created using + // VideoEncoder::Create. + static bool IsSupportedSoftware(EncoderType codec_type); + static EncoderType CodecToEncoderType(VideoCodecType codec_type); + static VideoCodecVP8 GetDefaultVp8Settings(); static VideoCodecVP9 GetDefaultVp9Settings(); static VideoCodecH264 GetDefaultH264Settings();