Remove functions from rtp_parameters_conversion.

These functions seem to have been unused except for tests.
It seems to have been added in 2017.

Bug: None
Change-Id: I01983f4b72456b1df27ec2d346014e0de1b5cae7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366943
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43332}
This commit is contained in:
Harald Alvestrand 2024-10-30 03:53:59 +00:00 committed by WebRTC LUCI CQ
parent 461e828d57
commit dd493e56a4
3 changed files with 3 additions and 663 deletions

View File

@ -28,174 +28,6 @@
namespace webrtc {
RTCErrorOr<cricket::FeedbackParam> ToCricketFeedbackParam(
const RtcpFeedback& feedback) {
switch (feedback.type) {
case RtcpFeedbackType::CCM:
if (!feedback.message_type) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing message type in CCM RtcpFeedback.");
} else if (*feedback.message_type != RtcpFeedbackMessageType::FIR) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Invalid message type in CCM RtcpFeedback.");
}
return cricket::FeedbackParam(cricket::kRtcpFbParamCcm,
cricket::kRtcpFbCcmParamFir);
case RtcpFeedbackType::LNTF:
if (feedback.message_type) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Didn't expect message type in LNTF RtcpFeedback.");
}
return cricket::FeedbackParam(cricket::kRtcpFbParamLntf);
case RtcpFeedbackType::NACK:
if (!feedback.message_type) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Missing message type in NACK RtcpFeedback.");
}
switch (*feedback.message_type) {
case RtcpFeedbackMessageType::GENERIC_NACK:
return cricket::FeedbackParam(cricket::kRtcpFbParamNack);
case RtcpFeedbackMessageType::PLI:
return cricket::FeedbackParam(cricket::kRtcpFbParamNack,
cricket::kRtcpFbNackParamPli);
default:
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Invalid message type in NACK RtcpFeedback.");
}
case RtcpFeedbackType::REMB:
if (feedback.message_type) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Didn't expect message type in REMB RtcpFeedback.");
}
return cricket::FeedbackParam(cricket::kRtcpFbParamRemb);
case RtcpFeedbackType::TRANSPORT_CC:
if (feedback.message_type) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Didn't expect message type in transport-cc RtcpFeedback.");
}
return cricket::FeedbackParam(cricket::kRtcpFbParamTransportCc);
}
RTC_CHECK_NOTREACHED();
}
RTCErrorOr<cricket::Codec> ToCricketCodec(const RtpCodecParameters& codec) {
switch (codec.kind) {
case cricket::MEDIA_TYPE_AUDIO:
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");
}
if (!cricket::IsValidRtpPayloadType(codec.payload_type)) {
char buf[40];
rtc::SimpleStringBuilder sb(buf);
sb << "Invalid payload type: " << codec.payload_type;
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE, sb.str());
}
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) {
auto result = ToCricketFeedbackParam(feedback);
if (!result.ok()) {
return result.MoveError();
}
cricket_codec.AddFeedbackParam(result.MoveValue());
}
cricket_codec.params = codec.parameters;
return std::move(cricket_codec);
}
RTCErrorOr<std::vector<cricket::Codec>> ToCricketCodecs(
const std::vector<RtpCodecParameters>& codecs) {
std::vector<cricket::Codec> cricket_codecs;
std::set<int> seen_payload_types;
for (const RtpCodecParameters& codec : codecs) {
auto result = ToCricketCodec(codec);
if (!result.ok()) {
return result.MoveError();
}
if (!seen_payload_types.insert(codec.payload_type).second) {
char buf[40];
rtc::SimpleStringBuilder sb(buf);
sb << "Duplicate payload type: " << codec.payload_type;
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, sb.str());
}
cricket_codecs.push_back(result.MoveValue());
}
return std::move(cricket_codecs);
}
RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec(
const std::vector<RtpEncodingParameters>& encodings) {
if (encodings.size() > 1u) {
LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER,
"ORTC API implementation doesn't currently "
"support simulcast or layered encodings.");
} else if (encodings.empty()) {
return cricket::StreamParamsVec();
}
cricket::StreamParamsVec cricket_streams;
const RtpEncodingParameters& encoding = encodings[0];
if (encoding.ssrc) {
cricket::StreamParams stream_params;
stream_params.add_ssrc(*encoding.ssrc);
cricket_streams.push_back(std::move(stream_params));
}
return std::move(cricket_streams);
}
std::optional<RtcpFeedback> ToRtcpFeedback(
const cricket::FeedbackParam& cricket_feedback) {
if (cricket_feedback.id() == cricket::kRtcpFbParamCcm) {
@ -248,17 +80,6 @@ std::optional<RtcpFeedback> ToRtcpFeedback(
return std::nullopt;
}
std::vector<RtpEncodingParameters> ToRtpEncodings(
const cricket::StreamParamsVec& stream_params) {
std::vector<RtpEncodingParameters> rtp_encodings;
for (const cricket::StreamParams& stream_param : stream_params) {
RtpEncodingParameters rtp_encoding;
rtp_encoding.ssrc.emplace(stream_param.first_ssrc());
rtp_encodings.push_back(std::move(rtp_encoding));
}
return rtp_encodings;
}
RtpCodecCapability ToRtpCodecCapability(const cricket::Codec& cricket_codec) {
RtpCodecCapability codec;
codec.name = cricket_codec.name;
@ -359,20 +180,4 @@ RtpCapabilities ToRtpCapabilities(
return capabilities;
}
RtpParameters ToRtpParameters(
const std::vector<cricket::Codec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params) {
RtpParameters rtp_parameters;
for (const cricket::Codec& cricket_codec : cricket_codecs) {
rtp_parameters.codecs.push_back(ToRtpCodecParameters(cricket_codec));
}
for (const RtpExtension& cricket_extension : cricket_extensions) {
rtp_parameters.header_extensions.emplace_back(cricket_extension.uri,
cricket_extension.id);
}
rtp_parameters.encodings = ToRtpEncodings(stream_params);
return rtp_parameters;
}
} // namespace webrtc

View File

@ -22,54 +22,14 @@
namespace webrtc {
// NOTE: Some functions are templated for convenience, such that template-based
// code dealing with AudioContentDescription and VideoContentDescription can
// use this easily. Such methods are usable with cricket::AudioCodec and
// cricket::VideoCodec.
//***************************************************************************
// Functions for converting from new webrtc:: structures to old cricket::
// structures.
//
// As the return values imply, all of these functions do validation of the
// parameters and return an error if they're invalid. It's expected that any
// default values (such as video clock rate of 90000) have been filled by the
// time the webrtc:: structure is being converted to the cricket:: one.
//
// These are expected to be used when parameters are passed into an RtpSender
// or RtpReceiver, and need to be validated and converted so they can be
// applied to the media engine level.
//***************************************************************************
// Returns error on invalid input. Certain message types are only valid for
// certain feedback types.
RTCErrorOr<cricket::FeedbackParam> ToCricketFeedbackParam(
const RtcpFeedback& feedback);
// Verifies that the codec kind is correct, and it has mandatory parameters
// filled, with values in valid ranges.
RTCErrorOr<cricket::Codec> ToCricketCodec(const RtpCodecParameters& codec);
// Verifies that payload types aren't duplicated, in addition to normal
// validation.
RTCErrorOr<std::vector<cricket::Codec>> ToCricketCodecs(
const std::vector<RtpCodecParameters>& codecs);
// SSRCs are allowed to be ommitted. This may be used for receive parameters
// where SSRCs are unsignaled.
RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec(
const std::vector<RtpEncodingParameters>& encodings);
//*****************************************************************************
// Functions for converting from old cricket:: structures to new webrtc::
// structures. Unlike the above functions, these are permissive with regards to
// structures. These are permissive with regards to
// input validation; it's assumed that any necessary validation already
// occurred.
//
// These are expected to be used either to convert from audio/video engine
// capabilities to RtpCapabilities, or to convert from already-parsed SDP
// (in the form of cricket:: structures) to webrtc:: structures. The latter
// functionality is not yet implemented.
// These are expected to be used to convert from audio/video engine
// capabilities to RtpCapabilities.
//*****************************************************************************
// Returns empty value if `cricket_feedback` is a feedback type not
@ -77,21 +37,12 @@ RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec(
std::optional<RtcpFeedback> ToRtcpFeedback(
const cricket::FeedbackParam& cricket_feedback);
std::vector<RtpEncodingParameters> ToRtpEncodings(
const cricket::StreamParamsVec& stream_params);
RtpCodecParameters ToRtpCodecParameters(const cricket::Codec& cricket_codec);
RtpCodecCapability ToRtpCodecCapability(const cricket::Codec& cricket_codec);
RtpCapabilities ToRtpCapabilities(
const std::vector<cricket::Codec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions);
RtpParameters ToRtpParameters(
const std::vector<cricket::Codec>& cricket_codecs,
const cricket::RtpHeaderExtensions& cricket_extensions,
const cricket::StreamParamsVec& stream_params);
} // namespace webrtc
#endif // PC_RTP_PARAMETERS_CONVERSION_H_

View File

@ -23,326 +23,6 @@ using ::testing::UnorderedElementsAre;
namespace webrtc {
TEST(RtpParametersConversionTest, ToCricketFeedbackParam) {
auto result = ToCricketFeedbackParam(
{RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR});
EXPECT_EQ(cricket::FeedbackParam("ccm", "fir"), result.value());
result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::LNTF));
EXPECT_EQ(cricket::FeedbackParam("goog-lntf"), result.value());
result = ToCricketFeedbackParam(
{RtcpFeedbackType::NACK, RtcpFeedbackMessageType::GENERIC_NACK});
EXPECT_EQ(cricket::FeedbackParam("nack"), result.value());
result = ToCricketFeedbackParam(
{RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI});
EXPECT_EQ(cricket::FeedbackParam("nack", "pli"), result.value());
result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::REMB));
EXPECT_EQ(cricket::FeedbackParam("goog-remb"), result.value());
result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC));
EXPECT_EQ(cricket::FeedbackParam("transport-cc"), result.value());
}
TEST(RtpParametersConversionTest, ToCricketFeedbackParamErrors) {
// CCM with missing or invalid message type.
auto result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::CCM));
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
result = ToCricketFeedbackParam(
{RtcpFeedbackType::CCM, RtcpFeedbackMessageType::PLI});
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// LNTF with message type (should be left empty).
result = ToCricketFeedbackParam(
{RtcpFeedbackType::LNTF, RtcpFeedbackMessageType::GENERIC_NACK});
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// NACK with missing or invalid message type.
result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::NACK));
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
result = ToCricketFeedbackParam(
{RtcpFeedbackType::NACK, RtcpFeedbackMessageType::FIR});
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// REMB with message type (should be left empty).
result = ToCricketFeedbackParam(
{RtcpFeedbackType::REMB, RtcpFeedbackMessageType::GENERIC_NACK});
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// TRANSPORT_CC with message type (should be left empty).
result = ToCricketFeedbackParam(
{RtcpFeedbackType::TRANSPORT_CC, RtcpFeedbackMessageType::FIR});
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
}
TEST(RtpParametersConversionTest, ToAudioCodec) {
RtpCodecParameters codec;
codec.name = "AuDiO";
codec.kind = cricket::MEDIA_TYPE_AUDIO;
codec.payload_type = 120;
codec.clock_rate.emplace(36000);
codec.num_channels.emplace(6);
codec.parameters["foo"] = "bar";
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
auto result = ToCricketCodec(codec);
ASSERT_TRUE(result.ok());
EXPECT_EQ("AuDiO", result.value().name);
EXPECT_EQ(120, result.value().id);
EXPECT_EQ(36000, result.value().clockrate);
EXPECT_EQ(6u, result.value().channels);
ASSERT_EQ(1u, result.value().params.size());
EXPECT_EQ("bar", result.value().params["foo"]);
EXPECT_EQ(1u, result.value().feedback_params.params().size());
EXPECT_TRUE(result.value().feedback_params.Has(
cricket::FeedbackParam("transport-cc")));
}
TEST(RtpParametersConversionTest, ToVideoCodec) {
RtpCodecParameters codec;
codec.name = "coolcodec";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.payload_type = 101;
codec.clock_rate.emplace(90000);
codec.parameters["foo"] = "bar";
codec.parameters["PING"] = "PONG";
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::LNTF);
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
RtcpFeedbackMessageType::PLI);
auto result = ToCricketCodec(codec);
ASSERT_TRUE(result.ok());
EXPECT_EQ("coolcodec", result.value().name);
EXPECT_EQ(101, result.value().id);
EXPECT_EQ(90000, result.value().clockrate);
ASSERT_EQ(2u, result.value().params.size());
EXPECT_EQ("bar", result.value().params["foo"]);
EXPECT_EQ("PONG", result.value().params["PING"]);
EXPECT_EQ(3u, result.value().feedback_params.params().size());
EXPECT_TRUE(
result.value().feedback_params.Has(cricket::FeedbackParam("goog-lntf")));
EXPECT_TRUE(result.value().feedback_params.Has(
cricket::FeedbackParam("transport-cc")));
EXPECT_TRUE(result.value().feedback_params.Has(
cricket::FeedbackParam("nack", "pli")));
}
// Trying to convert to an AudioCodec if the kind is "video" should fail.
TEST(RtpParametersConversionTest, ToCricketCodecInvalidKind) {
RtpCodecParameters audio_codec;
audio_codec.name = "opus";
audio_codec.kind = cricket::MEDIA_TYPE_VIDEO;
audio_codec.payload_type = 111;
audio_codec.clock_rate.emplace(48000);
audio_codec.num_channels.emplace(2);
RtpCodecParameters video_codec;
video_codec.name = "VP8";
video_codec.kind = cricket::MEDIA_TYPE_AUDIO;
video_codec.payload_type = 102;
video_codec.clock_rate.emplace(90000);
auto audio_result = ToCricketCodec(audio_codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type());
auto video_result = ToCricketCodec(video_codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type());
// Sanity check that if the kind is correct, the conversion succeeds.
audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
audio_result = ToCricketCodec(audio_codec);
EXPECT_TRUE(audio_result.ok());
video_result = ToCricketCodec(video_codec);
EXPECT_TRUE(video_result.ok());
}
TEST(RtpParametersConversionTest, ToAudioCodecInvalidParameters) {
// Missing channels.
RtpCodecParameters codec;
codec.name = "opus";
codec.kind = cricket::MEDIA_TYPE_AUDIO;
codec.payload_type = 111;
codec.clock_rate.emplace(48000);
auto result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Negative number of channels.
codec.num_channels.emplace(-1);
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Missing clock rate.
codec.num_channels.emplace(2);
codec.clock_rate.reset();
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Negative clock rate.
codec.clock_rate.emplace(-48000);
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Sanity check that conversion succeeds if these errors are fixed.
codec.clock_rate.emplace(48000);
result = ToCricketCodec(codec);
EXPECT_TRUE(result.ok());
}
TEST(RtpParametersConversionTest, ToVideoCodecInvalidParameters) {
// Missing clock rate.
RtpCodecParameters codec;
codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.payload_type = 102;
auto result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Invalid clock rate.
codec.clock_rate.emplace(48000);
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Channels set (should be unset).
codec.clock_rate.emplace(90000);
codec.num_channels.emplace(2);
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that conversion succeeds if these errors are fixed.
codec.num_channels.reset();
result = ToCricketCodec(codec);
EXPECT_TRUE(result.ok());
}
TEST(RtpParametersConversionTest, ToCricketCodecInvalidPayloadType) {
RtpCodecParameters codec;
codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.clock_rate.emplace(90000);
codec.payload_type = -1000;
auto result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Max payload type is 127.
codec.payload_type = 128;
result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
// Sanity check that conversion succeeds with a valid payload type.
codec.payload_type = 127;
result = ToCricketCodec(codec);
EXPECT_TRUE(result.ok());
}
// There are already tests for ToCricketFeedbackParam, but ensure that those
// errors are propagated from ToCricketCodec.
TEST(RtpParametersConversionTest, ToCricketCodecInvalidRtcpFeedback) {
RtpCodecParameters codec;
codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.clock_rate.emplace(90000);
codec.payload_type = 99;
codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
RtcpFeedbackMessageType::PLI);
auto result = ToCricketCodec(codec);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that conversion succeeds without invalid feedback.
codec.rtcp_feedback.clear();
result = ToCricketCodec(codec);
EXPECT_TRUE(result.ok());
}
TEST(RtpParametersConversionTest, ToCricketCodecs) {
std::vector<RtpCodecParameters> codecs;
RtpCodecParameters codec;
codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.clock_rate.emplace(90000);
codec.payload_type = 99;
codecs.push_back(codec);
codec.name = "VP9";
codec.payload_type = 100;
codecs.push_back(codec);
auto result = ToCricketCodecs(codecs);
ASSERT_TRUE(result.ok());
ASSERT_EQ(2u, result.value().size());
EXPECT_EQ("VP8", result.value()[0].name);
EXPECT_EQ(99, result.value()[0].id);
EXPECT_EQ("VP9", result.value()[1].name);
EXPECT_EQ(100, result.value()[1].id);
}
TEST(RtpParametersConversionTest, ToCricketCodecsDuplicatePayloadType) {
std::vector<RtpCodecParameters> codecs;
RtpCodecParameters codec;
codec.name = "VP8";
codec.kind = cricket::MEDIA_TYPE_VIDEO;
codec.clock_rate.emplace(90000);
codec.payload_type = 99;
codecs.push_back(codec);
codec.name = "VP9";
codec.payload_type = 99;
codecs.push_back(codec);
auto result = ToCricketCodecs(codecs);
EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
// Sanity check that this succeeds without the duplicate payload type.
codecs[1].payload_type = 120;
result = ToCricketCodecs(codecs);
EXPECT_TRUE(result.ok());
}
TEST(RtpParametersConversionTest, ToCricketStreamParamsVecSimple) {
std::vector<RtpEncodingParameters> encodings;
RtpEncodingParameters encoding;
encoding.ssrc.emplace(0xbaadf00d);
encodings.push_back(encoding);
auto result = ToCricketStreamParamsVec(encodings);
ASSERT_TRUE(result.ok());
ASSERT_EQ(1u, result.value().size());
EXPECT_EQ(1u, result.value()[0].ssrcs.size());
EXPECT_EQ(0xbaadf00d, result.value()[0].first_ssrc());
}
// No encodings should be accepted; an endpoint may want to prepare a
// decoder/encoder without having something to receive/send yet.
TEST(RtpParametersConversionTest, ToCricketStreamParamsVecNoEncodings) {
std::vector<RtpEncodingParameters> encodings;
auto result = ToCricketStreamParamsVec(encodings);
ASSERT_TRUE(result.ok());
EXPECT_EQ(0u, result.value().size());
}
// An encoding without SSRCs should be accepted. This could be the case when
// SSRCs aren't signaled and payload-type based demuxing is used.
TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMissingSsrcs) {
std::vector<RtpEncodingParameters> encodings = {{}};
// Creates RtxParameters with empty SSRC.
auto result = ToCricketStreamParamsVec(encodings);
ASSERT_TRUE(result.ok());
EXPECT_EQ(0u, result.value().size());
}
// TODO(deadbeef): Update this test when we support multiple encodings.
TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMultipleEncodings) {
std::vector<RtpEncodingParameters> encodings = {{}, {}};
auto result = ToCricketStreamParamsVec(encodings);
EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, result.error().type());
}
TEST(RtpParametersConversionTest, ToRtcpFeedback) {
std::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
@ -439,72 +119,6 @@ TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
codec.rtcp_feedback[2]);
}
TEST(RtpParametersConversionTest, ToRtpEncodingsWithEmptyStreamParamsVec) {
cricket::StreamParamsVec streams;
auto rtp_encodings = ToRtpEncodings(streams);
ASSERT_EQ(0u, rtp_encodings.size());
}
TEST(RtpParametersConversionTest, ToRtpEncodingsWithMultipleStreamParams) {
cricket::StreamParamsVec streams;
cricket::StreamParams stream1;
stream1.ssrcs.push_back(1111u);
cricket::StreamParams stream2;
stream2.ssrcs.push_back(2222u);
streams.push_back(stream1);
streams.push_back(stream2);
auto rtp_encodings = ToRtpEncodings(streams);
ASSERT_EQ(2u, rtp_encodings.size());
EXPECT_EQ(1111u, rtp_encodings[0].ssrc);
EXPECT_EQ(2222u, rtp_encodings[1].ssrc);
}
TEST(RtpParametersConversionTest, ToAudioRtpCodecParameters) {
cricket::Codec cricket_codec = cricket::CreateAudioCodec(50, "foo", 22222, 4);
cricket_codec.params["foo"] = "bar";
cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
EXPECT_EQ("foo", codec.name);
EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
EXPECT_EQ(50, codec.payload_type);
EXPECT_EQ(22222, codec.clock_rate);
EXPECT_EQ(4, codec.num_channels);
ASSERT_EQ(1u, codec.parameters.size());
EXPECT_EQ("bar", codec.parameters["foo"]);
EXPECT_EQ(1u, codec.rtcp_feedback.size());
EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
codec.rtcp_feedback[0]);
}
TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
cricket::Codec cricket_codec = cricket::CreateVideoCodec(101, "VID");
cricket_codec.clockrate = 80000;
cricket_codec.params["foo"] = "bar";
cricket_codec.params["ANOTHER"] = "param";
cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
cricket_codec.feedback_params.Add(cricket::FeedbackParam("goog-lntf"));
cricket_codec.feedback_params.Add({"nack", "pli"});
RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
EXPECT_EQ("VID", codec.name);
EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
EXPECT_EQ(101, codec.payload_type);
EXPECT_EQ(80000, codec.clock_rate);
ASSERT_EQ(2u, codec.parameters.size());
EXPECT_EQ("bar", codec.parameters["foo"]);
EXPECT_EQ("param", codec.parameters["ANOTHER"]);
EXPECT_EQ(3u, codec.rtcp_feedback.size());
EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
codec.rtcp_feedback[0]);
EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), codec.rtcp_feedback[1]);
EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
codec.rtcp_feedback[2]);
}
// An unknown feedback param should just be ignored.
TEST(RtpParametersConversionTest, ToRtpCodecCapabilityUnknownFeedbackParam) {
cricket::Codec cricket_codec = cricket::CreateAudioCodec(50, "foo", 22222, 4);
@ -566,34 +180,4 @@ TEST(RtpParametersConversionTest, ToRtpCapabilities) {
UnorderedElementsAre(FecMechanism::RED, FecMechanism::FLEXFEC));
}
TEST(RtpParametersConversionTest, ToRtpParameters) {
cricket::Codec vp8 = cricket::CreateVideoCodec(101, "VP8");
vp8.clockrate = 90000;
cricket::Codec red = cricket::CreateVideoCodec(102, "red");
red.clockrate = 90000;
cricket::Codec ulpfec = cricket::CreateVideoCodec(103, "ulpfec");
ulpfec.clockrate = 90000;
cricket::StreamParamsVec streams;
cricket::StreamParams stream;
stream.ssrcs.push_back(1234u);
streams.push_back(stream);
RtpParameters rtp_parameters =
ToRtpParameters({vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
ASSERT_EQ(3u, rtp_parameters.codecs.size());
EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
EXPECT_EQ("red", rtp_parameters.codecs[1].name);
EXPECT_EQ("ulpfec", rtp_parameters.codecs[2].name);
ASSERT_EQ(2u, rtp_parameters.header_extensions.size());
EXPECT_EQ("uri", rtp_parameters.header_extensions[0].uri);
EXPECT_EQ(1, rtp_parameters.header_extensions[0].id);
EXPECT_EQ("uri2", rtp_parameters.header_extensions[1].uri);
EXPECT_EQ(3, rtp_parameters.header_extensions[1].id);
ASSERT_EQ(1u, rtp_parameters.encodings.size());
EXPECT_EQ(1234u, rtp_parameters.encodings[0].ssrc);
}
} // namespace webrtc