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<VideoCodec> 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}
This commit is contained in:
parent
0d0d7531b5
commit
eacbaea920
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 <utility>
|
||||
|
||||
#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<cricket::VideoCodec>&
|
||||
InternalEncoderFactory::supported_codecs() const {
|
||||
return supported_codecs_;
|
||||
}
|
||||
|
||||
void InternalEncoderFactory::DestroyVideoEncoder(
|
||||
webrtc::VideoEncoder* encoder) {
|
||||
delete encoder;
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
@ -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 <vector>
|
||||
|
||||
#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<cricket::VideoCodec>& 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<cricket::VideoCodec> supported_codecs_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_MEDIA_ENGINE_INTERNALENCODERFACTORY_H_
|
||||
@ -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},
|
||||
|
||||
@ -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});
|
||||
};
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<webrtc::VideoEncoder> fallback_encoder_;
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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<VideoCodec>& 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<VideoCodec>* 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<webrtc::H264::ProfileLevelId> 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<VideoCodec> DefaultVideoCodecList() {
|
||||
std::vector<VideoCodec> 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<VideoCodec> 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<int> NextFreePayloadType(
|
||||
const std::vector<VideoCodec>& 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<int>(i);
|
||||
}
|
||||
// No free payload type.
|
||||
return rtc::Optional<int>();
|
||||
}
|
||||
|
||||
// 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<VideoCodec>& input_codecs,
|
||||
std::vector<VideoCodec>* unified_codecs) {
|
||||
for (VideoCodec codec : input_codecs) {
|
||||
const rtc::Optional<int> 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<int> 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<VideoCodec> GetSupportedCodecs(
|
||||
const WebRtcVideoEncoderFactory* external_encoder_factory) {
|
||||
const std::vector<VideoCodec>& internal_codecs =
|
||||
InternalEncoderFactory::GetInstance().supported_codecs();
|
||||
LOG(LS_INFO) << "Internally supported codecs: "
|
||||
<< CodecVectorToString(internal_codecs);
|
||||
std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList();
|
||||
|
||||
std::vector<VideoCodec> unified_codecs;
|
||||
AppendVideoCodecs(internal_codecs, &unified_codecs);
|
||||
|
||||
if (external_encoder_factory != nullptr) {
|
||||
const std::vector<VideoCodec>& 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<VideoCodec>& 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(
|
||||
|
||||
@ -61,6 +61,9 @@ class WebRtcVoiceMediaChannel;
|
||||
|
||||
struct Device;
|
||||
|
||||
// Exposed here for unittests.
|
||||
std::vector<VideoCodec> 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;
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
||||
@ -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<VideoEncoder> 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<VideoReceiveStream::Config>* 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;
|
||||
|
||||
67
webrtc/video/video_encoder.cc
Normal file
67
webrtc/video/video_encoder.cc
Normal file
@ -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
|
||||
@ -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!";
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user