Revert "Merge the codec types"

This reverts commit 49ace8b6548cda6d4ba74abfca9b616f56dbf9bc.

Reason for revert: Breaks downstream projects

Original change's description:
> Merge the codec types
>
> This allows simplifying code in the codebase to be able to remove a lot
> of templated code and special casing for either AudioCodec and VideoCodec.
> Code simplifications will come in later changes.
>
> Bug: webrtc:15214
> Change-Id: I6e75e6ea725163feb6cc4eb49f37b4722d6c6689
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308501
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Florent Castelli <orphis@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#40276}

Bug: webrtc:15214
Change-Id: I57778cccc3a13eb9f955f6ece054dee0ff5a7e92
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/308720
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Owners-Override: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Florent Castelli <orphis@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40278}
This commit is contained in:
Florent Castelli 2023-06-14 11:22:38 +00:00 committed by WebRTC LUCI CQ
parent 1cb54bee7a
commit b7af6b963b
8 changed files with 453 additions and 224 deletions

View File

@ -323,6 +323,20 @@ bool Codec::ValidateCodecFormat() const {
return true; return true;
} }
AudioCodec::AudioCodec(int id,
const std::string& name,
int clockrate,
int unused_bitrate,
size_t channels)
: Codec(Type::kAudio, id, name, clockrate, channels) {}
AudioCodec::AudioCodec() : Codec(Type::kAudio) {}
AudioCodec::AudioCodec(const AudioCodec& c) = default;
AudioCodec::AudioCodec(AudioCodec&& c) = default;
AudioCodec& AudioCodec::operator=(const AudioCodec& c) = default;
AudioCodec& AudioCodec::operator=(AudioCodec&& c) = default;
std::string Codec::ToString() const { std::string Codec::ToString() const {
char buf[256]; char buf[256];
@ -345,16 +359,66 @@ std::string Codec::ToString() const {
return sb.str(); return sb.str();
} }
Codec CreateAudioRtxCodec(int rtx_payload_type, int associated_payload_type) { VideoCodec::VideoCodec(int id, const std::string& name)
Codec rtx_codec = CreateAudioCodec(rtx_payload_type, kRtxCodecName, 0, 1); : Codec(Type::kVideo, id, name, kVideoCodecClockrate) {
SetDefaultParameters();
}
VideoCodec::VideoCodec(const std::string& name) : VideoCodec(0 /* id */, name) {
SetDefaultParameters();
}
VideoCodec::VideoCodec() : Codec(Type::kVideo) {
clockrate = kVideoCodecClockrate;
}
VideoCodec::VideoCodec(const webrtc::SdpVideoFormat& c) : Codec(c) {}
VideoCodec::VideoCodec(const VideoCodec& c) = default;
VideoCodec::VideoCodec(VideoCodec&& c) = default;
VideoCodec& VideoCodec::operator=(const VideoCodec& c) = default;
VideoCodec& VideoCodec::operator=(VideoCodec&& c) = default;
void VideoCodec::SetDefaultParameters() {
if (absl::EqualsIgnoreCase(kH264CodecName, name)) {
// This default is set for all H.264 codecs created because
// that was the default before packetization mode support was added.
// TODO(hta): Move this to the places that create VideoCodecs from
// SDP or from knowledge of implementation capabilities.
SetParam(kH264FmtpPacketizationMode, "1");
}
}
VideoCodec VideoCodec::CreateRtxCodec(int rtx_payload_type,
int associated_payload_type) {
return CreateVideoRtxCodec(rtx_payload_type, associated_payload_type);
}
VideoCodec CreateVideoRtxCodec(int rtx_payload_type,
int associated_payload_type) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName);
#pragma clang diagnostic pop
rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type); rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type);
return rtx_codec; return rtx_codec;
} }
Codec CreateVideoRtxCodec(int rtx_payload_type, int associated_payload_type) { VideoCodec::CodecType VideoCodec::GetCodecType() const {
Codec rtx_codec = CreateVideoCodec(rtx_payload_type, kRtxCodecName); if (absl::EqualsIgnoreCase(name, kRedCodecName)) {
rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type); return CODEC_RED;
return rtx_codec; }
if (absl::EqualsIgnoreCase(name, kUlpfecCodecName)) {
return CODEC_ULPFEC;
}
if (absl::EqualsIgnoreCase(name, kFlexfecCodecName)) {
return CODEC_FLEXFEC;
}
if (absl::EqualsIgnoreCase(name, kRtxCodecName)) {
return CODEC_RTX;
}
return CODEC_VIDEO;
} }
bool HasLntf(const Codec& codec) { bool HasLntf(const Codec& codec) {
@ -435,31 +499,35 @@ void AddH264ConstrainedBaselineProfileToSupportedFormats(
} }
} }
Codec CreateAudioCodec(int id, AudioCodec CreateAudioCodec(int id,
const std::string& name, const std::string& name,
int clockrate, int clockrate,
size_t channels) { size_t channels) {
return Codec(Codec::Type::kAudio, id, name, clockrate, channels); #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return AudioCodec(id, name, clockrate, 0, channels);
#pragma clang diagnostic pop
} }
Codec CreateVideoCodec(const std::string& name) { VideoCodec CreateVideoCodec(const std::string& name) {
return CreateVideoCodec(0, name); #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return VideoCodec(name);
#pragma clang diagnostic pop
} }
Codec CreateVideoCodec(int id, const std::string& name) { VideoCodec CreateVideoCodec(int id, const std::string& name) {
Codec c(Codec::Type::kVideo, id, name, kVideoCodecClockrate); #pragma clang diagnostic push
if (absl::EqualsIgnoreCase(kH264CodecName, name)) { #pragma clang diagnostic ignored "-Wdeprecated-declarations"
// This default is set for all H.264 codecs created because return VideoCodec(id, name);
// that was the default before packetization mode support was added. #pragma clang diagnostic pop
// TODO(hta): Move this to the places that create VideoCodecs from
// SDP or from knowledge of implementation capabilities.
c.SetParam(kH264FmtpPacketizationMode, "1");
}
return c;
} }
Codec CreateVideoCodec(const webrtc::SdpVideoFormat& c) { VideoCodec CreateVideoCodec(const webrtc::SdpVideoFormat& c) {
return Codec(c); #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return VideoCodec(c);
#pragma clang diagnostic pop
} }
} // namespace cricket } // namespace cricket

View File

@ -38,7 +38,6 @@ class FeedbackParam {
: id_(id), param_(kParamValueEmpty) {} : id_(id), param_(kParamValueEmpty) {}
bool operator==(const FeedbackParam& other) const; bool operator==(const FeedbackParam& other) const;
bool operator!=(const FeedbackParam& c) const { return !(*this == c); }
const std::string& id() const { return id_; } const std::string& id() const { return id_; }
const std::string& param() const { return param_; } const std::string& param() const { return param_; }
@ -53,7 +52,6 @@ class FeedbackParams {
FeedbackParams(); FeedbackParams();
~FeedbackParams(); ~FeedbackParams();
bool operator==(const FeedbackParams& other) const; bool operator==(const FeedbackParams& other) const;
bool operator!=(const FeedbackParams& c) const { return !(*this == c); }
bool Has(const FeedbackParam& param) const; bool Has(const FeedbackParam& param) const;
void Add(const FeedbackParam& param); void Add(const FeedbackParam& param);
@ -165,34 +163,71 @@ struct RTC_EXPORT Codec {
const std::string& name, const std::string& name,
int clockrate, int clockrate,
size_t channels); size_t channels);
explicit Codec(const webrtc::SdpVideoFormat& c); explicit Codec(const webrtc::SdpVideoFormat& c);
friend Codec CreateAudioCodec(int id,
const std::string& name,
int clockrate,
size_t channels);
friend Codec CreateAudioRtxCodec(int rtx_payload_type,
int associated_payload_type);
friend Codec CreateVideoCodec(int id, const std::string& name);
friend Codec CreateVideoCodec(const webrtc::SdpVideoFormat& c);
friend Codec CreateVideoRtxCodec(int rtx_payload_type,
int associated_payload_type);
}; };
// TODO(webrtc:15214): Compatibility names, to be migrated away and removed. struct AudioCodec : public Codec {
using VideoCodec = Codec; // Creates a codec with the given parameters.
using AudioCodec = Codec; [[deprecated("Use cricket::CreateAudioCodec")]] AudioCodec(
int id,
const std::string& name,
int clockrate,
int unused_bitrate,
size_t channels);
// Creates an empty codec.
[[deprecated("Do not create empty AudioCodec")]] AudioCodec();
AudioCodec(const AudioCodec& c);
AudioCodec(AudioCodec&& c);
~AudioCodec() override = default;
Codec CreateAudioCodec(int id, AudioCodec& operator=(const AudioCodec& c);
const std::string& name, AudioCodec& operator=(AudioCodec&& c);
int clockrate, };
size_t channels);
Codec CreateAudioRtxCodec(int rtx_payload_type, int associated_payload_type); struct RTC_EXPORT VideoCodec : public Codec {
Codec CreateVideoCodec(const std::string& name); // Creates a codec with the given parameters.
Codec CreateVideoCodec(int id, const std::string& name); [[deprecated("Use cricket::CreateVideoCodec")]] VideoCodec(
Codec CreateVideoCodec(const webrtc::SdpVideoFormat& c); int id,
Codec CreateVideoRtxCodec(int rtx_payload_type, int associated_payload_type); const std::string& name);
// Creates a codec with the given name and empty id.
[[deprecated("Use cricket::CreateVideoCodec")]] explicit VideoCodec(
const std::string& name);
// Creates an empty codec.
[[deprecated("Do not create empty VideoCodec")]] VideoCodec();
VideoCodec(const VideoCodec& c);
[[deprecated]] explicit VideoCodec(const webrtc::SdpVideoFormat& c);
VideoCodec(VideoCodec&& c);
~VideoCodec() override = default;
VideoCodec& operator=(const VideoCodec& c);
VideoCodec& operator=(VideoCodec&& c);
[[deprecated]] static VideoCodec CreateRtxCodec(int rtx_payload_type,
int associated_payload_type);
enum [[deprecated]] CodecType {
CODEC_VIDEO,
CODEC_RED,
CODEC_ULPFEC,
CODEC_FLEXFEC,
CODEC_RTX,
};
[[deprecated]] CodecType GetCodecType() const;
private:
void SetDefaultParameters();
};
AudioCodec CreateAudioCodec(int id,
const std::string& name,
int clockrate,
size_t channels);
VideoCodec CreateVideoCodec(const std::string& name);
VideoCodec CreateVideoCodec(int id, const std::string& name);
VideoCodec CreateVideoCodec(const webrtc::SdpVideoFormat& c);
VideoCodec CreateVideoRtxCodec(int rtx_payload_type,
int associated_payload_type);
// Get the codec setting associated with `payload_type`. If there // Get the codec setting associated with `payload_type`. If there
// is no codec associated with that payload type it returns nullptr. // is no codec associated with that payload type it returns nullptr.

View File

@ -82,8 +82,14 @@ TEST(CodecTest, TestAudioCodecOperators) {
EXPECT_NE(c0, c4); EXPECT_NE(c0, c4);
EXPECT_NE(c0, c5); EXPECT_NE(c0, c5);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
AudioCodec c7;
#pragma clang diagnostic pop
AudioCodec c8 = cricket::CreateAudioCodec(0, "", 0, 0); AudioCodec c8 = cricket::CreateAudioCodec(0, "", 0, 0);
AudioCodec c9 = c0; AudioCodec c9 = c0;
EXPECT_EQ(c8, c7);
EXPECT_NE(c9, c7);
EXPECT_EQ(c9, c0); EXPECT_EQ(c9, c0);
AudioCodec c10(c0); AudioCodec c10(c0);
@ -156,8 +162,14 @@ TEST(CodecTest, TestVideoCodecOperators) {
EXPECT_TRUE(c0 != c1); EXPECT_TRUE(c0 != c1);
EXPECT_TRUE(c0 != c2); EXPECT_TRUE(c0 != c2);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
VideoCodec c7;
#pragma clang diagnostic pop
VideoCodec c8 = cricket::CreateVideoCodec(0, ""); VideoCodec c8 = cricket::CreateVideoCodec(0, "");
VideoCodec c9 = c0; VideoCodec c9 = c0;
EXPECT_TRUE(c8 == c7);
EXPECT_TRUE(c9 != c7);
EXPECT_TRUE(c9 == c0); EXPECT_TRUE(c9 == c0);
VideoCodec c10(c0); VideoCodec c10(c0);

View File

@ -573,7 +573,8 @@ TEST_P(PeerConnectionMediaTest,
TEST_P(PeerConnectionMediaTest, RawPacketizationNotSetInOffer) { TEST_P(PeerConnectionMediaTest, RawPacketizationNotSetInOffer) {
std::vector<cricket::VideoCodec> fake_codecs; std::vector<cricket::VideoCodec> fake_codecs;
fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111)); fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
fake_codecs.push_back( fake_codecs.push_back(
cricket::CreateVideoCodec(114, cricket::kH264CodecName)); cricket::CreateVideoCodec(114, cricket::kH264CodecName));
@ -595,7 +596,8 @@ TEST_P(PeerConnectionMediaTest, RawPacketizationNotSetInOffer) {
TEST_P(PeerConnectionMediaTest, RawPacketizationSetInOfferAndAnswer) { TEST_P(PeerConnectionMediaTest, RawPacketizationSetInOfferAndAnswer) {
std::vector<cricket::VideoCodec> fake_codecs; std::vector<cricket::VideoCodec> fake_codecs;
fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111)); fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
fake_codecs.push_back( fake_codecs.push_back(
cricket::CreateVideoCodec(114, cricket::kH264CodecName)); cricket::CreateVideoCodec(114, cricket::kH264CodecName));
@ -638,7 +640,8 @@ TEST_P(PeerConnectionMediaTest,
RawPacketizationNotSetInAnswerWhenNotSetInOffer) { RawPacketizationNotSetInAnswerWhenNotSetInOffer) {
std::vector<cricket::VideoCodec> fake_codecs; std::vector<cricket::VideoCodec> fake_codecs;
fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
fake_codecs.push_back(cricket::CreateVideoRtxCodec(112, 111)); fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName)); fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
fake_codecs.push_back( fake_codecs.push_back(
cricket::CreateVideoCodec(114, cricket::kH264CodecName)); cricket::CreateVideoCodec(114, cricket::kH264CodecName));
@ -1703,8 +1706,10 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
SetCodecPreferencesAudioRejectsOnlyRtxRedFec) { SetCodecPreferencesAudioRejectsOnlyRtxRedFec) {
auto fake_engine = std::make_unique<FakeMediaEngine>(); auto fake_engine = std::make_unique<FakeMediaEngine>();
auto audio_codecs = fake_engine->voice().send_codecs(); auto audio_codecs = fake_engine->voice().send_codecs();
audio_codecs.push_back(cricket::CreateAudioRtxCodec( audio_codecs.push_back(cricket::CreateAudioCodec(
audio_codecs.back().id + 1, audio_codecs.back().id)); audio_codecs.back().id + 1, cricket::kRtxCodecName, 0, 1));
audio_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(audio_codecs.back().id - 1);
audio_codecs.push_back(cricket::CreateAudioCodec( audio_codecs.push_back(cricket::CreateAudioCodec(
audio_codecs.back().id + 1, cricket::kRedCodecName, 0, 1)); audio_codecs.back().id + 1, cricket::kRedCodecName, 0, 1));
audio_codecs.push_back(cricket::CreateAudioCodec( audio_codecs.push_back(cricket::CreateAudioCodec(
@ -1798,8 +1803,10 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
SetCodecPreferencesVideoRejectsOnlyRtxRedFec) { SetCodecPreferencesVideoRejectsOnlyRtxRedFec) {
auto fake_engine = std::make_unique<FakeMediaEngine>(); auto fake_engine = std::make_unique<FakeMediaEngine>();
auto video_codecs = fake_engine->video().send_codecs(); auto video_codecs = fake_engine->video().send_codecs();
video_codecs.push_back(cricket::CreateVideoRtxCodec( video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
video_codecs.back().id + 1, video_codecs.back().id)); cricket::kRtxCodecName));
video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(video_codecs.back().id - 1);
video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1, video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
cricket::kRedCodecName)); cricket::kRedCodecName));
video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1, video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
@ -1906,12 +1913,16 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoWithRtx) {
auto caller_video_codecs = caller_fake_engine->video().send_codecs(); auto caller_video_codecs = caller_fake_engine->video().send_codecs();
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp9CodecName)); caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_fake_engine->SetVideoCodecs(caller_video_codecs); caller_fake_engine->SetVideoCodecs(caller_video_codecs);
auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine)); auto caller = CreatePeerConnectionWithVideo(std::move(caller_fake_engine));
@ -1954,12 +1965,16 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
auto caller_video_codecs = caller_fake_engine->video().send_codecs(); auto caller_video_codecs = caller_fake_engine->video().send_codecs();
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp9CodecName)); caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_fake_engine->SetVideoCodecs(caller_video_codecs); caller_fake_engine->SetVideoCodecs(caller_video_codecs);
auto callee_fake_engine = std::make_unique<FakeMediaEngine>(); auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@ -2024,12 +2039,16 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
auto caller_video_codecs = caller_fake_engine->video().send_codecs(); auto caller_video_codecs = caller_fake_engine->video().send_codecs();
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp8CodecName)); caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_video_codecs.push_back(cricket::CreateVideoCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, cricket::kVp9CodecName)); caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
caller_video_codecs.push_back(cricket::CreateVideoRtxCodec( caller_video_codecs.push_back(cricket::CreateVideoCodec(
caller_video_codecs.back().id + 1, caller_video_codecs.back().id)); caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
std::to_string(caller_video_codecs.back().id - 1);
caller_fake_engine->SetVideoCodecs(caller_video_codecs); caller_fake_engine->SetVideoCodecs(caller_video_codecs);
auto callee_fake_engine = std::make_unique<FakeMediaEngine>(); auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@ -2111,13 +2130,15 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
auto fake_engine = std::make_unique<cricket::FakeMediaEngine>(); auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();
std::vector<cricket::AudioCodec> audio_codecs; std::vector<cricket::AudioCodec> audio_codecs;
audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1)); audio_codecs.emplace_back(100, "foo", 0, 0, 1);
audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100)); audio_codecs.emplace_back(101, cricket::kRtxCodecName, 0, 0, 1);
audio_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetAudioCodecs(audio_codecs); fake_engine->SetAudioCodecs(audio_codecs);
std::vector<cricket::VideoCodec> video_codecs; std::vector<cricket::VideoCodec> video_codecs;
video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar")); video_codecs.emplace_back(100, "bar");
video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100)); video_codecs.emplace_back(101, cricket::kRtxCodecName);
video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetVideoCodecs(video_codecs); fake_engine->SetVideoCodecs(video_codecs);
auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine)); auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));
@ -2152,13 +2173,15 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
auto fake_engine = std::make_unique<cricket::FakeMediaEngine>(); auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();
std::vector<cricket::AudioCodec> audio_codecs; std::vector<cricket::AudioCodec> audio_codecs;
audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1)); audio_codecs.emplace_back(100, "foo", 0, 0, 1);
audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100)); audio_codecs.emplace_back(101, cricket::kRtxCodecName, 0, 0, 1);
audio_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetAudioCodecs(audio_codecs); fake_engine->SetAudioCodecs(audio_codecs);
std::vector<cricket::VideoCodec> video_codecs; std::vector<cricket::VideoCodec> video_codecs;
video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar")); video_codecs.emplace_back(100, "bar");
video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100)); video_codecs.emplace_back(101, cricket::kRtxCodecName);
video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetVideoCodecs(video_codecs); fake_engine->SetVideoCodecs(video_codecs);
auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine)); auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));
@ -2197,13 +2220,15 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan,
auto fake_engine = std::make_unique<cricket::FakeMediaEngine>(); auto fake_engine = std::make_unique<cricket::FakeMediaEngine>();
std::vector<cricket::AudioCodec> audio_codecs; std::vector<cricket::AudioCodec> audio_codecs;
audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1)); audio_codecs.emplace_back(100, "foo", 0, 0, 1);
audio_codecs.emplace_back(cricket::CreateAudioRtxCodec(101, 100)); audio_codecs.emplace_back(101, cricket::kRtxCodecName, 0, 0, 1);
audio_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetAudioCodecs(audio_codecs); fake_engine->SetAudioCodecs(audio_codecs);
std::vector<cricket::VideoCodec> video_codecs; std::vector<cricket::VideoCodec> video_codecs;
video_codecs.emplace_back(cricket::CreateVideoCodec(100, "bar")); video_codecs.emplace_back(100, "bar");
video_codecs.emplace_back(cricket::CreateVideoRtxCodec(101, 100)); video_codecs.emplace_back(101, cricket::kRtxCodecName);
video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "100";
fake_engine->SetVideoCodecs(video_codecs); fake_engine->SetVideoCodecs(video_codecs);
auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine)); auto caller = CreatePeerConnectionWithAudioVideo(std::move(fake_engine));

View File

@ -18,7 +18,6 @@
#include "api/array_view.h" #include "api/array_view.h"
#include "api/media_types.h" #include "api/media_types.h"
#include "api/rtc_error.h"
#include "media/base/codec.h" #include "media/base/codec.h"
#include "media/base/media_constants.h" #include "media/base/media_constants.h"
#include "media/base/rtp_utils.h" #include "media/base/rtp_utils.h"
@ -81,71 +80,79 @@ RTCErrorOr<cricket::FeedbackParam> ToCricketFeedbackParam(
RTC_CHECK_NOTREACHED(); RTC_CHECK_NOTREACHED();
} }
RTCErrorOr<cricket::Codec> ToCricketCodec(const RtpCodecParameters& codec) { template <typename C>
switch (codec.kind) { static RTCErrorOr<C> ToCricketCodecTypeSpecific(
case cricket::MEDIA_TYPE_AUDIO: const RtpCodecParameters& codec);
if (codec.kind != cricket::MEDIA_TYPE_AUDIO) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Can't use video codec with audio sender or receiver.");
}
if (!codec.num_channels) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing number of channels for audio codec.");
}
if (*codec.num_channels <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
"Number of channels must be positive.");
}
if (!codec.clock_rate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing codec clock rate.");
}
if (*codec.clock_rate <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
"Clock rate must be positive.");
}
break;
case cricket::MEDIA_TYPE_VIDEO:
if (codec.kind != cricket::MEDIA_TYPE_VIDEO) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Can't use audio codec with video sender or receiver.");
}
if (codec.num_channels) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Video codec shouldn't have num_channels.");
}
if (!codec.clock_rate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing codec clock rate.");
}
if (*codec.clock_rate != cricket::kVideoCodecClockrate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Video clock rate must be 90000.");
}
break;
default:
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Unknown codec type");
}
template <>
RTCErrorOr<cricket::AudioCodec> ToCricketCodecTypeSpecific<cricket::AudioCodec>(
const RtpCodecParameters& codec) {
if (codec.kind != cricket::MEDIA_TYPE_AUDIO) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Can't use video codec with audio sender or receiver.");
}
if (!codec.num_channels) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing number of channels for audio codec.");
}
if (*codec.num_channels <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
"Number of channels must be positive.");
}
if (!codec.clock_rate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing codec clock rate.");
}
if (*codec.clock_rate <= 0) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
"Clock rate must be positive.");
}
return cricket::CreateAudioCodec(0, codec.name, *codec.clock_rate,
*codec.num_channels);
}
// Video codecs don't use num_channels or clock_rate, but they should at least
// be validated to ensure the application isn't trying to do something it
// doesn't intend to.
template <>
RTCErrorOr<cricket::VideoCodec> ToCricketCodecTypeSpecific<cricket::VideoCodec>(
const RtpCodecParameters& codec) {
if (codec.kind != cricket::MEDIA_TYPE_VIDEO) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Can't use audio codec with video sender or receiver.");
}
if (codec.num_channels) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Video codec shouldn't have num_channels.");
}
if (!codec.clock_rate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing codec clock rate.");
}
if (*codec.clock_rate != cricket::kVideoCodecClockrate) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Video clock rate must be 90000.");
}
return cricket::CreateVideoCodec(0, codec.name);
}
template <typename C>
RTCErrorOr<C> ToCricketCodec(const RtpCodecParameters& codec) {
// Start with audio/video specific conversion.
RTCErrorOr<C> result = ToCricketCodecTypeSpecific<C>(codec);
if (!result.ok()) {
return result.MoveError();
}
C cricket_codec = result.MoveValue();
if (!cricket::IsValidRtpPayloadType(codec.payload_type)) { if (!cricket::IsValidRtpPayloadType(codec.payload_type)) {
char buf[40]; char buf[40];
rtc::SimpleStringBuilder sb(buf); rtc::SimpleStringBuilder sb(buf);
sb << "Invalid payload type: " << codec.payload_type; sb << "Invalid payload type: " << codec.payload_type;
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE, sb.str()); LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE, sb.str());
} }
cricket_codec.id = codec.payload_type;
cricket::Codec cricket_codec = [&]() {
if (codec.kind == cricket::MEDIA_TYPE_AUDIO) {
return cricket::CreateAudioCodec(codec.payload_type, codec.name,
*codec.clock_rate, *codec.num_channels);
}
RTC_DCHECK(codec.kind == cricket::MEDIA_TYPE_VIDEO);
return cricket::CreateVideoCodec(codec.payload_type, codec.name);
}();
for (const RtcpFeedback& feedback : codec.rtcp_feedback) { for (const RtcpFeedback& feedback : codec.rtcp_feedback) {
auto result = ToCricketFeedbackParam(feedback); auto result = ToCricketFeedbackParam(feedback);
if (!result.ok()) { if (!result.ok()) {
@ -157,12 +164,18 @@ RTCErrorOr<cricket::Codec> ToCricketCodec(const RtpCodecParameters& codec) {
return std::move(cricket_codec); return std::move(cricket_codec);
} }
RTCErrorOr<std::vector<cricket::Codec>> ToCricketCodecs( template RTCErrorOr<cricket::AudioCodec> ToCricketCodec(
const RtpCodecParameters& codec);
template RTCErrorOr<cricket::VideoCodec> ToCricketCodec(
const RtpCodecParameters& codec);
template <typename C>
RTCErrorOr<std::vector<C>> ToCricketCodecs(
const std::vector<RtpCodecParameters>& codecs) { const std::vector<RtpCodecParameters>& codecs) {
std::vector<cricket::Codec> cricket_codecs; std::vector<C> cricket_codecs;
std::set<int> seen_payload_types; std::set<int> seen_payload_types;
for (const RtpCodecParameters& codec : codecs) { for (const RtpCodecParameters& codec : codecs) {
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<C>(codec);
if (!result.ok()) { if (!result.ok()) {
return result.MoveError(); return result.MoveError();
} }
@ -177,6 +190,12 @@ RTCErrorOr<std::vector<cricket::Codec>> ToCricketCodecs(
return std::move(cricket_codecs); return std::move(cricket_codecs);
} }
template RTCErrorOr<std::vector<cricket::AudioCodec>> ToCricketCodecs<
cricket::AudioCodec>(const std::vector<RtpCodecParameters>& codecs);
template RTCErrorOr<std::vector<cricket::VideoCodec>> ToCricketCodecs<
cricket::VideoCodec>(const std::vector<RtpCodecParameters>& codecs);
RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec( RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec(
const std::vector<RtpEncodingParameters>& encodings) { const std::vector<RtpEncodingParameters>& encodings) {
if (encodings.size() > 1u) { if (encodings.size() > 1u) {
@ -259,12 +278,51 @@ std::vector<RtpEncodingParameters> ToRtpEncodings(
return rtp_encodings; return rtp_encodings;
} }
RtpCodecCapability ToRtpCodecCapability(const cricket::Codec& cricket_codec) { template <typename C>
cricket::MediaType KindOfCodec();
template <>
cricket::MediaType KindOfCodec<cricket::AudioCodec>() {
return cricket::MEDIA_TYPE_AUDIO;
}
template <>
cricket::MediaType KindOfCodec<cricket::VideoCodec>() {
return cricket::MEDIA_TYPE_VIDEO;
}
template <typename C>
static void ToRtpCodecCapabilityTypeSpecific(const C& cricket_codec,
RtpCodecCapability* codec);
template <>
void ToRtpCodecCapabilityTypeSpecific<cricket::AudioCodec>(
const cricket::AudioCodec& cricket_codec,
RtpCodecCapability* codec) {
codec->num_channels = static_cast<int>(cricket_codec.channels);
}
template <>
void ToRtpCodecCapabilityTypeSpecific<cricket::VideoCodec>(
const cricket::VideoCodec& cricket_codec,
RtpCodecCapability* codec) {
if (cricket_codec.scalability_modes.empty() ||
(cricket_codec.scalability_modes.size() == 1 &&
cricket_codec.scalability_modes[0] == ScalabilityMode::kL1T1)) {
// https://w3c.github.io/webrtc-svc/#dom-rtcrtpcodeccapability-scalabilitymodes
// If a codec does not support encoding of scalability modes other than
// "L1T1", then the scalabilityModes member is not provided.
return;
}
codec->scalability_modes = cricket_codec.scalability_modes;
}
template <typename C>
RtpCodecCapability ToRtpCodecCapability(const C& cricket_codec) {
RtpCodecCapability codec; RtpCodecCapability codec;
codec.name = cricket_codec.name; codec.name = cricket_codec.name;
codec.kind = cricket_codec.type == cricket::Codec::Type::kAudio codec.kind = KindOfCodec<C>();
? cricket::MEDIA_TYPE_AUDIO
: cricket::MEDIA_TYPE_VIDEO;
codec.clock_rate.emplace(cricket_codec.clockrate); codec.clock_rate.emplace(cricket_codec.clockrate);
codec.preferred_payload_type.emplace(cricket_codec.id); codec.preferred_payload_type.emplace(cricket_codec.id);
for (const cricket::FeedbackParam& cricket_feedback : for (const cricket::FeedbackParam& cricket_feedback :
@ -274,25 +332,37 @@ RtpCodecCapability ToRtpCodecCapability(const cricket::Codec& cricket_codec) {
codec.rtcp_feedback.push_back(feedback.value()); codec.rtcp_feedback.push_back(feedback.value());
} }
} }
switch (cricket_codec.type) { ToRtpCodecCapabilityTypeSpecific(cricket_codec, &codec);
case cricket::Codec::Type::kAudio:
codec.num_channels = static_cast<int>(cricket_codec.channels);
break;
case cricket::Codec::Type::kVideo:
codec.scalability_modes = cricket_codec.scalability_modes;
break;
}
codec.parameters.insert(cricket_codec.params.begin(), codec.parameters.insert(cricket_codec.params.begin(),
cricket_codec.params.end()); cricket_codec.params.end());
return codec; return codec;
} }
RtpCodecParameters ToRtpCodecParameters(const cricket::Codec& cricket_codec) { template RtpCodecCapability ToRtpCodecCapability<cricket::AudioCodec>(
const cricket::AudioCodec& cricket_codec);
template RtpCodecCapability ToRtpCodecCapability<cricket::VideoCodec>(
const cricket::VideoCodec& cricket_codec);
template <typename C>
static void ToRtpCodecParametersTypeSpecific(const C& cricket_codec,
RtpCodecParameters* codec);
template <>
void ToRtpCodecParametersTypeSpecific<cricket::AudioCodec>(
const cricket::AudioCodec& cricket_codec,
RtpCodecParameters* codec) {
codec->num_channels = static_cast<int>(cricket_codec.channels);
}
template <>
void ToRtpCodecParametersTypeSpecific<cricket::VideoCodec>(
const cricket::VideoCodec& cricket_codec,
RtpCodecParameters* codec) {}
template <typename C>
RtpCodecParameters ToRtpCodecParameters(const C& cricket_codec) {
RtpCodecParameters codec_param; RtpCodecParameters codec_param;
codec_param.name = cricket_codec.name; codec_param.name = cricket_codec.name;
codec_param.kind = cricket_codec.type == cricket::Codec::Type::kAudio codec_param.kind = KindOfCodec<C>();
? cricket::MEDIA_TYPE_AUDIO
: cricket::MEDIA_TYPE_VIDEO;
codec_param.clock_rate.emplace(cricket_codec.clockrate); codec_param.clock_rate.emplace(cricket_codec.clockrate);
codec_param.payload_type = cricket_codec.id; codec_param.payload_type = cricket_codec.id;
for (const cricket::FeedbackParam& cricket_feedback : for (const cricket::FeedbackParam& cricket_feedback :
@ -302,27 +372,26 @@ RtpCodecParameters ToRtpCodecParameters(const cricket::Codec& cricket_codec) {
codec_param.rtcp_feedback.push_back(feedback.value()); codec_param.rtcp_feedback.push_back(feedback.value());
} }
} }
switch (cricket_codec.type) { ToRtpCodecParametersTypeSpecific(cricket_codec, &codec_param);
case cricket::Codec::Type::kAudio:
codec_param.num_channels = static_cast<int>(cricket_codec.channels);
break;
case cricket::Codec::Type::kVideo:
// Nothing to do.
break;
}
codec_param.parameters = cricket_codec.params; codec_param.parameters = cricket_codec.params;
return codec_param; return codec_param;
} }
template RtpCodecParameters ToRtpCodecParameters<cricket::AudioCodec>(
const cricket::AudioCodec& cricket_codec);
template RtpCodecParameters ToRtpCodecParameters<cricket::VideoCodec>(
const cricket::VideoCodec& cricket_codec);
template <class C>
RtpCapabilities ToRtpCapabilities( RtpCapabilities ToRtpCapabilities(
const std::vector<cricket::Codec>& cricket_codecs, const std::vector<C>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions) { const cricket::RtpHeaderExtensions& cricket_extensions) {
RtpCapabilities capabilities; RtpCapabilities capabilities;
bool have_red = false; bool have_red = false;
bool have_ulpfec = false; bool have_ulpfec = false;
bool have_flexfec = false; bool have_flexfec = false;
bool have_rtx = false; bool have_rtx = false;
for (const cricket::Codec& cricket_codec : cricket_codecs) { for (const C& cricket_codec : cricket_codecs) {
if (cricket_codec.name == cricket::kRedCodecName) { if (cricket_codec.name == cricket::kRedCodecName) {
have_red = true; have_red = true;
} else if (cricket_codec.name == cricket::kUlpfecCodecName) { } else if (cricket_codec.name == cricket::kUlpfecCodecName) {
@ -359,12 +428,20 @@ RtpCapabilities ToRtpCapabilities(
return capabilities; return capabilities;
} }
template RtpCapabilities ToRtpCapabilities<cricket::AudioCodec>(
const std::vector<cricket::AudioCodec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions);
template RtpCapabilities ToRtpCapabilities<cricket::VideoCodec>(
const std::vector<cricket::VideoCodec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions);
template <class C>
RtpParameters ToRtpParameters( RtpParameters ToRtpParameters(
const std::vector<cricket::Codec>& cricket_codecs, const std::vector<C>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions, const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params) { const cricket::StreamParamsVec& stream_params) {
RtpParameters rtp_parameters; RtpParameters rtp_parameters;
for (const cricket::Codec& cricket_codec : cricket_codecs) { for (const C& cricket_codec : cricket_codecs) {
rtp_parameters.codecs.push_back(ToRtpCodecParameters(cricket_codec)); rtp_parameters.codecs.push_back(ToRtpCodecParameters(cricket_codec));
} }
for (const RtpExtension& cricket_extension : cricket_extensions) { for (const RtpExtension& cricket_extension : cricket_extensions) {
@ -375,4 +452,13 @@ RtpParameters ToRtpParameters(
return rtp_parameters; return rtp_parameters;
} }
template RtpParameters ToRtpParameters<cricket::AudioCodec>(
const std::vector<cricket::AudioCodec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params);
template RtpParameters ToRtpParameters<cricket::VideoCodec>(
const std::vector<cricket::VideoCodec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params);
} // namespace webrtc } // namespace webrtc

View File

@ -48,11 +48,13 @@ RTCErrorOr<cricket::FeedbackParam> ToCricketFeedbackParam(
// Verifies that the codec kind is correct, and it has mandatory parameters // Verifies that the codec kind is correct, and it has mandatory parameters
// filled, with values in valid ranges. // filled, with values in valid ranges.
RTCErrorOr<cricket::Codec> ToCricketCodec(const RtpCodecParameters& codec); template <typename C>
RTCErrorOr<C> ToCricketCodec(const RtpCodecParameters& codec);
// Verifies that payload types aren't duplicated, in addition to normal // Verifies that payload types aren't duplicated, in addition to normal
// validation. // validation.
RTCErrorOr<std::vector<cricket::Codec>> ToCricketCodecs( template <typename C>
RTCErrorOr<std::vector<C>> ToCricketCodecs(
const std::vector<RtpCodecParameters>& codecs); const std::vector<RtpCodecParameters>& codecs);
// SSRCs are allowed to be ommitted. This may be used for receive parameters // SSRCs are allowed to be ommitted. This may be used for receive parameters
@ -80,15 +82,20 @@ absl::optional<RtcpFeedback> ToRtcpFeedback(
std::vector<RtpEncodingParameters> ToRtpEncodings( std::vector<RtpEncodingParameters> ToRtpEncodings(
const cricket::StreamParamsVec& stream_params); const cricket::StreamParamsVec& stream_params);
RtpCodecParameters ToRtpCodecParameters(const cricket::Codec& cricket_codec); template <typename C>
RtpCodecCapability ToRtpCodecCapability(const cricket::Codec& cricket_codec); RtpCodecParameters ToRtpCodecParameters(const C& cricket_codec);
template <typename C>
RtpCodecCapability ToRtpCodecCapability(const C& cricket_codec);
template <class C>
RtpCapabilities ToRtpCapabilities( RtpCapabilities ToRtpCapabilities(
const std::vector<cricket::Codec>& cricket_codecs, const std::vector<C>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions); const cricket::RtpHeaderExtensions& cricket_extensions);
template <class C>
RtpParameters ToRtpParameters( RtpParameters ToRtpParameters(
const std::vector<cricket::Codec>& cricket_codecs, const std::vector<C>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions, const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params); const cricket::StreamParamsVec& stream_params);

View File

@ -88,7 +88,7 @@ TEST(RtpParametersConversionTest, ToAudioCodec) {
codec.num_channels.emplace(6); codec.num_channels.emplace(6);
codec.parameters["foo"] = "bar"; codec.parameters["foo"] = "bar";
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC); codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::AudioCodec>(codec);
ASSERT_TRUE(result.ok()); ASSERT_TRUE(result.ok());
EXPECT_EQ("AuDiO", result.value().name); EXPECT_EQ("AuDiO", result.value().name);
@ -114,7 +114,7 @@ TEST(RtpParametersConversionTest, ToVideoCodec) {
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC); codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK, codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
RtcpFeedbackMessageType::PLI); RtcpFeedbackMessageType::PLI);
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::VideoCodec>(codec);
ASSERT_TRUE(result.ok()); ASSERT_TRUE(result.ok());
EXPECT_EQ("coolcodec", result.value().name); EXPECT_EQ("coolcodec", result.value().name);
@ -147,18 +147,18 @@ TEST(RtpParametersConversionTest, ToCricketCodecInvalidKind) {
video_codec.payload_type = 102; video_codec.payload_type = 102;
video_codec.clock_rate.emplace(90000); video_codec.clock_rate.emplace(90000);
auto audio_result = ToCricketCodec(audio_codec); auto audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type());
auto video_result = ToCricketCodec(video_codec); auto video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type());
// Sanity check that if the kind is correct, the conversion succeeds. // Sanity check that if the kind is correct, the conversion succeeds.
audio_codec.kind = cricket::MEDIA_TYPE_AUDIO; audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
video_codec.kind = cricket::MEDIA_TYPE_VIDEO; video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
audio_result = ToCricketCodec(audio_codec); audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
EXPECT_TRUE(audio_result.ok()); EXPECT_TRUE(audio_result.ok());
video_result = ToCricketCodec(video_codec); video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
EXPECT_TRUE(video_result.ok()); EXPECT_TRUE(video_result.ok());
} }
@ -169,28 +169,28 @@ TEST(RtpParametersConversionTest, ToAudioCodecInvalidParameters) {
codec.kind = cricket::MEDIA_TYPE_AUDIO; codec.kind = cricket::MEDIA_TYPE_AUDIO;
codec.payload_type = 111; codec.payload_type = 111;
codec.clock_rate.emplace(48000); codec.clock_rate.emplace(48000);
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::AudioCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Negative number of channels. // Negative number of channels.
codec.num_channels.emplace(-1); codec.num_channels.emplace(-1);
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::AudioCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Missing clock rate. // Missing clock rate.
codec.num_channels.emplace(2); codec.num_channels.emplace(2);
codec.clock_rate.reset(); codec.clock_rate.reset();
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::AudioCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Negative clock rate. // Negative clock rate.
codec.clock_rate.emplace(-48000); codec.clock_rate.emplace(-48000);
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::AudioCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Sanity check that conversion succeeds if these errors are fixed. // Sanity check that conversion succeeds if these errors are fixed.
codec.clock_rate.emplace(48000); codec.clock_rate.emplace(48000);
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::AudioCodec>(codec);
EXPECT_TRUE(result.ok()); EXPECT_TRUE(result.ok());
} }
@ -200,23 +200,23 @@ TEST(RtpParametersConversionTest, ToVideoCodecInvalidParameters) {
codec.name = "VP8"; codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO; codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.payload_type = 102; codec.payload_type = 102;
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Invalid clock rate. // Invalid clock rate.
codec.clock_rate.emplace(48000); codec.clock_rate.emplace(48000);
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Channels set (should be unset). // Channels set (should be unset).
codec.clock_rate.emplace(90000); codec.clock_rate.emplace(90000);
codec.num_channels.emplace(2); codec.num_channels.emplace(2);
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that conversion succeeds if these errors are fixed. // Sanity check that conversion succeeds if these errors are fixed.
codec.num_channels.reset(); codec.num_channels.reset();
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_TRUE(result.ok()); EXPECT_TRUE(result.ok());
} }
@ -227,17 +227,17 @@ TEST(RtpParametersConversionTest, ToCricketCodecInvalidPayloadType) {
codec.clock_rate.emplace(90000); codec.clock_rate.emplace(90000);
codec.payload_type = -1000; codec.payload_type = -1000;
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Max payload type is 127. // Max payload type is 127.
codec.payload_type = 128; codec.payload_type = 128;
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Sanity check that conversion succeeds with a valid payload type. // Sanity check that conversion succeeds with a valid payload type.
codec.payload_type = 127; codec.payload_type = 127;
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_TRUE(result.ok()); EXPECT_TRUE(result.ok());
} }
@ -252,12 +252,12 @@ TEST(RtpParametersConversionTest, ToCricketCodecInvalidRtcpFeedback) {
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM, codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
RtcpFeedbackMessageType::PLI); RtcpFeedbackMessageType::PLI);
auto result = ToCricketCodec(codec); auto result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that conversion succeeds without invalid feedback. // Sanity check that conversion succeeds without invalid feedback.
codec.rtcp_feedback.clear(); codec.rtcp_feedback.clear();
result = ToCricketCodec(codec); result = ToCricketCodec<cricket::VideoCodec>(codec);
EXPECT_TRUE(result.ok()); EXPECT_TRUE(result.ok());
} }
@ -274,7 +274,7 @@ TEST(RtpParametersConversionTest, ToCricketCodecs) {
codec.payload_type = 100; codec.payload_type = 100;
codecs.push_back(codec); codecs.push_back(codec);
auto result = ToCricketCodecs(codecs); auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
ASSERT_TRUE(result.ok()); ASSERT_TRUE(result.ok());
ASSERT_EQ(2u, result.value().size()); ASSERT_EQ(2u, result.value().size());
EXPECT_EQ("VP8", result.value()[0].name); EXPECT_EQ("VP8", result.value()[0].name);
@ -296,12 +296,12 @@ TEST(RtpParametersConversionTest, ToCricketCodecsDuplicatePayloadType) {
codec.payload_type = 99; codec.payload_type = 99;
codecs.push_back(codec); codecs.push_back(codec);
auto result = ToCricketCodecs(codecs); auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type()); EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that this succeeds without the duplicate payload type. // Sanity check that this succeeds without the duplicate payload type.
codecs[1].payload_type = 120; codecs[1].payload_type = 120;
result = ToCricketCodecs(codecs); result = ToCricketCodecs<cricket::VideoCodec>(codecs);
EXPECT_TRUE(result.ok()); EXPECT_TRUE(result.ok());
} }
@ -541,8 +541,8 @@ TEST(RtpParametersConversionTest, ToRtpCapabilities) {
cricket::VideoCodec rtx2 = cricket::CreateVideoRtxCodec(105, 109); cricket::VideoCodec rtx2 = cricket::CreateVideoRtxCodec(105, 109);
RtpCapabilities capabilities = RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
ToRtpCapabilities({vp8, ulpfec, rtx, rtx2}, {{"uri", 1}, {"uri2", 3}}); {vp8, ulpfec, rtx, rtx2}, {{"uri", 1}, {"uri2", 3}});
ASSERT_EQ(3u, capabilities.codecs.size()); ASSERT_EQ(3u, capabilities.codecs.size());
EXPECT_EQ("VP8", capabilities.codecs[0].name); EXPECT_EQ("VP8", capabilities.codecs[0].name);
EXPECT_EQ("ulpfec", capabilities.codecs[1].name); EXPECT_EQ("ulpfec", capabilities.codecs[1].name);
@ -555,15 +555,15 @@ TEST(RtpParametersConversionTest, ToRtpCapabilities) {
EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id); EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id);
EXPECT_EQ(0u, capabilities.fec.size()); EXPECT_EQ(0u, capabilities.fec.size());
capabilities = ToRtpCapabilities({vp8, red, ulpfec, rtx}, capabilities = ToRtpCapabilities<cricket::VideoCodec>(
cricket::RtpHeaderExtensions()); {vp8, red, ulpfec, rtx}, cricket::RtpHeaderExtensions());
EXPECT_EQ(4u, capabilities.codecs.size()); EXPECT_EQ(4u, capabilities.codecs.size());
EXPECT_THAT( EXPECT_THAT(
capabilities.fec, capabilities.fec,
UnorderedElementsAre(FecMechanism::RED, FecMechanism::RED_AND_ULPFEC)); UnorderedElementsAre(FecMechanism::RED, FecMechanism::RED_AND_ULPFEC));
capabilities = capabilities = ToRtpCapabilities<cricket::VideoCodec>(
ToRtpCapabilities({vp8, red, flexfec}, cricket::RtpHeaderExtensions()); {vp8, red, flexfec}, cricket::RtpHeaderExtensions());
EXPECT_EQ(3u, capabilities.codecs.size()); EXPECT_EQ(3u, capabilities.codecs.size());
EXPECT_THAT(capabilities.fec, EXPECT_THAT(capabilities.fec,
UnorderedElementsAre(FecMechanism::RED, FecMechanism::FLEXFEC)); UnorderedElementsAre(FecMechanism::RED, FecMechanism::FLEXFEC));
@ -584,8 +584,8 @@ TEST(RtpParametersConversionTest, ToRtpParameters) {
stream.ssrcs.push_back(1234u); stream.ssrcs.push_back(1234u);
streams.push_back(stream); streams.push_back(stream);
RtpParameters rtp_parameters = RtpParameters rtp_parameters = ToRtpParameters<cricket::VideoCodec>(
ToRtpParameters({vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams); {vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
ASSERT_EQ(3u, rtp_parameters.codecs.size()); ASSERT_EQ(3u, rtp_parameters.codecs.size());
EXPECT_EQ("VP8", rtp_parameters.codecs[0].name); EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
EXPECT_EQ("red", rtp_parameters.codecs[1].name); EXPECT_EQ("red", rtp_parameters.codecs[1].name);

View File

@ -2897,16 +2897,14 @@ void AddFeedbackParameters(const cricket::FeedbackParams& feedback_params,
// is no Codec associated with that payload type it returns an empty codec // is no Codec associated with that payload type it returns an empty codec
// with that payload type. // with that payload type.
template <class T> template <class T>
T GetCodecWithPayloadType(cricket::MediaType type, T GetCodecWithPayloadType(const std::vector<T>& codecs, int payload_type) {
const std::vector<T>& codecs,
int payload_type) {
const T* codec = FindCodecById(codecs, payload_type); const T* codec = FindCodecById(codecs, payload_type);
if (codec) if (codec)
return *codec; return *codec;
// Return empty codec with `payload_type`. // Return empty codec with `payload_type`.
if (type == cricket::MEDIA_TYPE_AUDIO) { if constexpr (std::is_same<T, cricket::AudioCodec>::value) {
return cricket::CreateAudioCodec(payload_type, "", 0, 0); return cricket::CreateAudioCodec(payload_type, "", 0, 0);
} else { } else if constexpr (std::is_same<T, cricket::VideoCodec>::value) {
return cricket::CreateVideoCodec(payload_type, ""); return cricket::CreateVideoCodec(payload_type, "");
} }
} }
@ -2939,8 +2937,7 @@ void UpdateCodec(MediaContentDescription* content_desc,
int payload_type, int payload_type,
const cricket::CodecParameterMap& parameters) { const cricket::CodecParameterMap& parameters) {
// Codec might already have been populated (from rtpmap). // Codec might already have been populated (from rtpmap).
U new_codec = GetCodecWithPayloadType(content_desc->type(), U new_codec = GetCodecWithPayloadType(static_cast<T*>(content_desc)->codecs(),
static_cast<T*>(content_desc)->codecs(),
payload_type); payload_type);
AddParameters(parameters, &new_codec); AddParameters(parameters, &new_codec);
AddOrReplaceCodec<T, U>(content_desc, new_codec); AddOrReplaceCodec<T, U>(content_desc, new_codec);
@ -2953,8 +2950,7 @@ void UpdateCodec(MediaContentDescription* content_desc,
int payload_type, int payload_type,
const cricket::FeedbackParam& feedback_param) { const cricket::FeedbackParam& feedback_param) {
// Codec might already have been populated (from rtpmap). // Codec might already have been populated (from rtpmap).
U new_codec = GetCodecWithPayloadType(content_desc->type(), U new_codec = GetCodecWithPayloadType(static_cast<T*>(content_desc)->codecs(),
static_cast<T*>(content_desc)->codecs(),
payload_type); payload_type);
AddFeedbackParameter(feedback_param, &new_codec); AddFeedbackParameter(feedback_param, &new_codec);
AddOrReplaceCodec<T, U>(content_desc, new_codec); AddOrReplaceCodec<T, U>(content_desc, new_codec);
@ -2971,8 +2967,8 @@ void UpdateVideoCodecPacketization(VideoContentDescription* video_desc,
} }
// Codec might already have been populated (from rtpmap). // Codec might already have been populated (from rtpmap).
cricket::VideoCodec codec = GetCodecWithPayloadType( cricket::VideoCodec codec =
video_desc->type(), video_desc->codecs(), payload_type); GetCodecWithPayloadType(video_desc->codecs(), payload_type);
codec.packetization = std::string(packetization); codec.packetization = std::string(packetization);
AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc, AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
codec); codec);
@ -3596,8 +3592,8 @@ void UpdateCodec(int payload_type,
AudioContentDescription* audio_desc) { AudioContentDescription* audio_desc) {
// Codec may already be populated with (only) optional parameters // Codec may already be populated with (only) optional parameters
// (from an fmtp). // (from an fmtp).
cricket::AudioCodec codec = GetCodecWithPayloadType( cricket::AudioCodec codec =
audio_desc->type(), audio_desc->codecs(), payload_type); GetCodecWithPayloadType(audio_desc->codecs(), payload_type);
codec.name = std::string(name); codec.name = std::string(name);
codec.clockrate = clockrate; codec.clockrate = clockrate;
codec.bitrate = bitrate; codec.bitrate = bitrate;
@ -3613,8 +3609,8 @@ void UpdateCodec(int payload_type,
VideoContentDescription* video_desc) { VideoContentDescription* video_desc) {
// Codec may already be populated with (only) optional parameters // Codec may already be populated with (only) optional parameters
// (from an fmtp). // (from an fmtp).
cricket::VideoCodec codec = GetCodecWithPayloadType( cricket::VideoCodec codec =
video_desc->type(), video_desc->codecs(), payload_type); GetCodecWithPayloadType(video_desc->codecs(), payload_type);
codec.name = std::string(name); codec.name = std::string(name);
AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc, AddOrReplaceCodec<VideoContentDescription, cricket::VideoCodec>(video_desc,
codec); codec);