Skip to content

Commit

Permalink
introduce an unsupported content description type
Browse files Browse the repository at this point in the history
This carries around unsupported content descriptions
(i.e. things where webrtc does not understand the media type
or protocol) in a special data type so that a rejected content or
mediasection is added to the answer SDP.

BUG=webrtc:3513

Change-Id: Ifc4168eae11e899f2504649de5e1eecb6801a9fb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/179082
Reviewed-by: Kári Helgason <[email protected]>
Reviewed-by: Harald Alvestrand <[email protected]>
Commit-Queue: Philipp Hancke <[email protected]>
Cr-Commit-Position: refs/heads/master@{#32410}
  • Loading branch information
fippo authored and Commit Bot committed Oct 15, 2020
1 parent a2b31c3 commit 239f92e
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 29 deletions.
4 changes: 4 additions & 0 deletions api/media_types.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ std::string MediaTypeToString(MediaType type) {
return kMediaTypeVideo;
case MEDIA_TYPE_DATA:
return kMediaTypeData;
case MEDIA_TYPE_UNSUPPORTED:
// Unsupported media stores the m=<mediatype> differently.
RTC_NOTREACHED();
return "";
}
FATAL();
// Not reachable; avoids compile warning.
Expand Down
7 changes: 6 additions & 1 deletion api/media_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@

namespace cricket {

enum MediaType { MEDIA_TYPE_AUDIO, MEDIA_TYPE_VIDEO, MEDIA_TYPE_DATA };
enum MediaType {
MEDIA_TYPE_AUDIO,
MEDIA_TYPE_VIDEO,
MEDIA_TYPE_DATA,
MEDIA_TYPE_UNSUPPORTED
};

extern const char kMediaTypeAudio[];
extern const char kMediaTypeVideo[];
Expand Down
80 changes: 80 additions & 0 deletions pc/media_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,13 @@ std::unique_ptr<SessionDescription> MediaSessionDescriptionFactory::CreateOffer(
return nullptr;
}
break;
case MEDIA_TYPE_UNSUPPORTED:
if (!AddUnsupportedContentForOffer(
media_description_options, session_options, current_content,
current_description, offer.get(), &ice_credentials)) {
return nullptr;
}
break;
default:
RTC_NOTREACHED();
}
Expand Down Expand Up @@ -1713,6 +1720,14 @@ MediaSessionDescriptionFactory::CreateAnswer(
return nullptr;
}
break;
case MEDIA_TYPE_UNSUPPORTED:
if (!AddUnsupportedContentForAnswer(
media_description_options, session_options, offer_content,
offer, current_content, current_description,
bundle_transport.get(), answer.get(), &ice_credentials)) {
return nullptr;
}
break;
default:
RTC_NOTREACHED();
}
Expand Down Expand Up @@ -2403,6 +2418,31 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer(
}
}

bool MediaSessionDescriptionFactory::AddUnsupportedContentForOffer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
const ContentInfo* current_content,
const SessionDescription* current_description,
SessionDescription* desc,
IceCredentialsIterator* ice_credentials) const {
RTC_CHECK(IsMediaContentOfType(current_content, MEDIA_TYPE_UNSUPPORTED));

const UnsupportedContentDescription* current_unsupported_description =
current_content->media_description()->as_unsupported();
auto unsupported = std::make_unique<UnsupportedContentDescription>(
current_unsupported_description->media_type());
unsupported->set_protocol(current_content->media_description()->protocol());
desc->AddContent(media_description_options.mid, MediaProtocolType::kOther,
/*rejected=*/true, std::move(unsupported));

if (!AddTransportOffer(media_description_options.mid,
media_description_options.transport_options,
current_description, desc, ice_credentials)) {
return false;
}
return true;
}

// |audio_codecs| = set of all possible codecs that can be used, with correct
// payload type mappings
//
Expand Down Expand Up @@ -2745,6 +2785,42 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer(
return true;
}

bool MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
const ContentInfo* offer_content,
const SessionDescription* offer_description,
const ContentInfo* current_content,
const SessionDescription* current_description,
const TransportInfo* bundle_transport,
SessionDescription* answer,
IceCredentialsIterator* ice_credentials) const {
std::unique_ptr<TransportDescription> unsupported_transport =
CreateTransportAnswer(media_description_options.mid, offer_description,
media_description_options.transport_options,
current_description, bundle_transport != nullptr,
ice_credentials);
if (!unsupported_transport) {
return false;
}
RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_UNSUPPORTED));

const UnsupportedContentDescription* offer_unsupported_description =
offer_content->media_description()->as_unsupported();
std::unique_ptr<MediaContentDescription> unsupported_answer =
std::make_unique<UnsupportedContentDescription>(
offer_unsupported_description->media_type());
unsupported_answer->set_protocol(offer_unsupported_description->protocol());

if (!AddTransportAnswer(media_description_options.mid,
*(unsupported_transport.get()), answer)) {
return false;
}
answer->AddContent(media_description_options.mid, offer_content->type,
/*rejected=*/true, std::move(unsupported_answer));
return true;
}

void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() {
audio_sendrecv_codecs_.clear();
all_audio_codecs_.clear();
Expand Down Expand Up @@ -2822,6 +2898,10 @@ bool IsDataContent(const ContentInfo* content) {
return IsMediaContentOfType(content, MEDIA_TYPE_DATA);
}

bool IsUnsupportedContent(const ContentInfo* content) {
return IsMediaContentOfType(content, MEDIA_TYPE_UNSUPPORTED);
}

const ContentInfo* GetFirstMediaContent(const ContentInfos& contents,
MediaType media_type) {
for (const ContentInfo& content : contents) {
Expand Down
20 changes: 20 additions & 0 deletions pc/media_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ class MediaSessionDescriptionFactory {
SessionDescription* desc,
IceCredentialsIterator* ice_credentials) const;

bool AddUnsupportedContentForOffer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
const ContentInfo* current_content,
const SessionDescription* current_description,
SessionDescription* desc,
IceCredentialsIterator* ice_credentials) const;

bool AddAudioContentForAnswer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
Expand Down Expand Up @@ -324,6 +332,17 @@ class MediaSessionDescriptionFactory {
SessionDescription* answer,
IceCredentialsIterator* ice_credentials) const;

bool AddUnsupportedContentForAnswer(
const MediaDescriptionOptions& media_description_options,
const MediaSessionOptions& session_options,
const ContentInfo* offer_content,
const SessionDescription* offer_description,
const ContentInfo* current_content,
const SessionDescription* current_description,
const TransportInfo* bundle_transport,
SessionDescription* answer,
IceCredentialsIterator* ice_credentials) const;

void ComputeAudioCodecsIntersectionAndUnion();

void ComputeVideoCodecsIntersectionAndUnion();
Expand Down Expand Up @@ -356,6 +375,7 @@ bool IsMediaContent(const ContentInfo* content);
bool IsAudioContent(const ContentInfo* content);
bool IsVideoContent(const ContentInfo* content);
bool IsDataContent(const ContentInfo* content);
bool IsUnsupportedContent(const ContentInfo* content);
const ContentInfo* GetFirstMediaContent(const ContentInfos& contents,
MediaType media_type);
const ContentInfo* GetFirstAudioContent(const ContentInfos& contents);
Expand Down
4 changes: 4 additions & 0 deletions pc/peer_connection_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
}
case cricket::MEDIA_TYPE_DATA:
return RtpCapabilities();
case cricket::MEDIA_TYPE_UNSUPPORTED:
return RtpCapabilities();
}
// Not reached; avoids compile warning.
FATAL();
Expand All @@ -215,6 +217,8 @@ RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
}
case cricket::MEDIA_TYPE_DATA:
return RtpCapabilities();
case cricket::MEDIA_TYPE_UNSUPPORTED:
return RtpCapabilities();
}
// Not reached; avoids compile warning.
FATAL();
Expand Down
60 changes: 60 additions & 0 deletions pc/peer_connection_signaling_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/create_peerconnection_factory.h"
#include "api/jsep_session_description.h"
#include "api/peer_connection_proxy.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
#include "pc/peer_connection.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/sdp_utils.h"
#include "pc/webrtc_sdp.h"
#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif
Expand Down Expand Up @@ -841,6 +843,64 @@ TEST_P(PeerConnectionSignalingTest,
observer->error());
}

TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
auto caller = CreatePeerConnection();

// Call setRemoteDescription with a m= line we don't understand.
std::string sdp =
"v=0\r\n"
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
"m=bogus 9 FOO 0 8\r\n"
"c=IN IP4 0.0.0.0\r\n"
"a=mid:bogusmid\r\n";
std::unique_ptr<webrtc::SessionDescriptionInterface> remote_description =
webrtc::CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

// Assert we respond back with something meaningful.
auto answer = caller->CreateAnswer();
ASSERT_EQ(answer->description()->contents().size(), 1u);
EXPECT_NE(answer->description()
->contents()[0]
.media_description()
->as_unsupported(),
nullptr);
EXPECT_EQ(answer->description()
->contents()[0]
.media_description()
->as_unsupported()
->media_type(),
"bogus");
EXPECT_TRUE(answer->description()->contents()[0].rejected);
EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
EXPECT_EQ(
answer->description()->contents()[0].media_description()->protocol(),
"FOO");
EXPECT_FALSE(
answer->description()->contents()[0].media_description()->has_codecs());

EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));

// Assert we keep this in susequent offers.
auto offer = caller->CreateOffer();
EXPECT_EQ(offer->description()
->contents()[0]
.media_description()
->as_unsupported()
->media_type(),
"bogus");
EXPECT_TRUE(offer->description()->contents()[0].rejected);
EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
"FOO");
EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
EXPECT_FALSE(
offer->description()->contents()[0].media_description()->has_codecs());
EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
PeerConnectionSignalingTest,
Values(SdpSemantics::kPlanB,
Expand Down
2 changes: 2 additions & 0 deletions pc/rtc_stats_collector_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2597,6 +2597,7 @@ class RTCStatsCollectorTestWithParamKind
case cricket::MEDIA_TYPE_VIDEO:
return "Video";
case cricket::MEDIA_TYPE_DATA:
case cricket::MEDIA_TYPE_UNSUPPORTED:
RTC_NOTREACHED();
return "";
}
Expand Down Expand Up @@ -2655,6 +2656,7 @@ class RTCStatsCollectorTestWithParamKind
return;
}
case cricket::MEDIA_TYPE_DATA:
case cricket::MEDIA_TYPE_UNSUPPORTED:
RTC_NOTREACHED();
}
}
Expand Down
22 changes: 22 additions & 0 deletions pc/sdp_offer_answer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ static absl::string_view GetDefaultMidForPlanB(cricket::MediaType media_type) {
return cricket::CN_VIDEO;
case cricket::MEDIA_TYPE_DATA:
return cricket::CN_DATA;
case cricket::MEDIA_TYPE_UNSUPPORTED:
return "not supported";
}
RTC_NOTREACHED();
return "";
Expand Down Expand Up @@ -2999,6 +3001,8 @@ RTCError SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels(
if (!error.ok()) {
return error;
}
} else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) {
RTC_LOG(LS_INFO) << "Ignoring unsupported media type";
} else {
LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
"Unknown section type.");
Expand Down Expand Up @@ -3538,6 +3542,12 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer(
transceiver->internal()->set_mline_index(i);
}
}
} else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) {
RTC_DCHECK(local_content->rejected);
session_options->media_description_options.push_back(
cricket::MediaDescriptionOptions(media_type, mid,
RtpTransceiverDirection::kInactive,
/*stopped=*/true));
} else {
RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type);
if (had_been_rejected) {
Expand Down Expand Up @@ -3701,6 +3711,12 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanAnswer(
RtpTransceiverDirection::kInactive,
/*stopped=*/true));
}
} else if (media_type == cricket::MEDIA_TYPE_UNSUPPORTED) {
RTC_DCHECK(content.rejected);
session_options->media_description_options.push_back(
cricket::MediaDescriptionOptions(media_type, content.name,
RtpTransceiverDirection::kInactive,
/*stopped=*/true));
} else {
RTC_CHECK_EQ(cricket::MEDIA_TYPE_DATA, media_type);
// Reject all data sections if data channels are disabled.
Expand Down Expand Up @@ -4642,6 +4658,12 @@ void SdpOfferAnswerHandler::GenerateMediaDescriptionOptions(
}
session_options->media_description_options.back().header_extensions =
channel_manager()->GetSupportedVideoRtpHeaderExtensions();
} else if (IsUnsupportedContent(&content)) {
session_options->media_description_options.push_back(
cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_UNSUPPORTED,
content.name,
RtpTransceiverDirection::kInactive,
/*stopped=*/true));
} else {
RTC_DCHECK(IsDataContent(&content));
// If we already have an data m= section, reject this extra one.
Expand Down
Loading

0 comments on commit 239f92e

Please sign in to comment.