Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Unified Diff: webrtc/pc/mediasession.cc

Issue 1956343002: Initial asymmetric codec support in MediaSessionDescription (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Check stream type to decide on whether or not to receive. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/pc/mediasession.cc
diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc
index 52abfe855f6aef47fa83d7e1ce51321f090a2417..328f67593bd434cb214abc74781b9994bbb942bc 100644
--- a/webrtc/pc/mediasession.cc
+++ b/webrtc/pc/mediasession.cc
@@ -1030,24 +1030,26 @@ static bool CreateMediaContentAnswer(
// Make sure the answer media content direction is per default set as
// described in RFC3264 section 6.1.
+ const bool should_send =
+ !IsRtpProtocol(answer->protocol()) || !answer->streams().empty();
pthatcher1 2016/05/31 21:52:36 This would be more clear as: const bool is_data =
ossu 2016/06/02 13:28:02 Acknowledged.
+ const bool should_receive =
+ answer->type() == cricket::MEDIA_TYPE_VIDEO ? options.recv_video :
+ (answer->type() == cricket::MEDIA_TYPE_AUDIO ? options.recv_audio : true);
ossu 2016/05/25 11:26:14 I expect that since there's no flag for data, we'l
+
switch (offer->direction()) {
case MD_INACTIVE:
answer->set_direction(MD_INACTIVE);
break;
case MD_SENDONLY:
- answer->set_direction(MD_RECVONLY);
+ answer->set_direction(should_receive ? MD_RECVONLY : MD_INACTIVE);
break;
case MD_RECVONLY:
- answer->set_direction(IsRtpProtocol(answer->protocol()) &&
- answer->streams().empty()
- ? MD_INACTIVE
- : MD_SENDONLY);
+ answer->set_direction(should_send ? MD_SENDONLY : MD_INACTIVE);
break;
case MD_SENDRECV:
- answer->set_direction(IsRtpProtocol(answer->protocol()) &&
- answer->streams().empty()
- ? MD_RECVONLY
- : MD_SENDRECV);
+ answer->set_direction(should_send
+ ? (should_receive ? MD_SENDRECV : MD_SENDONLY)
+ : (should_receive ? MD_RECVONLY : MD_INACTIVE));
break;
pthatcher1 2016/05/31 21:52:36 I think this would be more clear if we made an Rtp
ossu 2016/06/02 13:28:02 I've put an RtpTranscieverDirection in and changed
default:
RTC_DCHECK(false && "MediaContentDescription has unexpected direction.");
@@ -1173,6 +1175,22 @@ std::string MediaTypeToString(MediaType type) {
return type_str;
}
+std::string MediaContentDirectionToString(MediaContentDirection direction) {
+ switch (direction) {
+ case MD_INACTIVE:
+ return "inactive";
+ case MD_SENDONLY:
+ return "sendonly";
+ case MD_RECVONLY:
+ return "recvonly";
+ case MD_SENDRECV:
+ return "sendrecv";
+ default:
+ ASSERT(false);
+ break;
+ }
+}
+
void MediaSessionOptions::AddSendStream(MediaType type,
const std::string& id,
const std::string& sync_label) {
@@ -1234,11 +1252,64 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
: secure_(SEC_DISABLED),
add_legacy_(true),
transport_desc_factory_(transport_desc_factory) {
- channel_manager->GetSupportedAudioCodecs(&audio_codecs_);
+ channel_manager->GetSupportedAudioCodecs(&audio_sendrecv_codecs_);
channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_);
channel_manager->GetSupportedVideoCodecs(&video_codecs_);
channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_);
channel_manager->GetSupportedDataCodecs(&data_codecs_);
+ audio_send_codecs_ = audio_sendrecv_codecs_;
+ audio_recv_codecs_ = audio_sendrecv_codecs_;
+}
+
+const AudioCodecs& MediaSessionDescriptionFactory::audio_codecs() const {
pthatcher1 2016/05/31 21:52:35 This could be renamed to audio_sendrecv_codecs().
+ return audio_sendrecv_codecs_;
+}
+
+const AudioCodecs& MediaSessionDescriptionFactory::audio_send_codecs() const {
+ return audio_send_codecs_;
+}
+
+const AudioCodecs& MediaSessionDescriptionFactory::audio_recv_codecs() const {
+ return audio_recv_codecs_;
+}
+
+void MediaSessionDescriptionFactory::set_audio_codecs(
+ const AudioCodecs& send_and_recv_codecs) {
+ audio_send_codecs_ = send_and_recv_codecs;
+ audio_recv_codecs_ = send_and_recv_codecs;
+ audio_sendrecv_codecs_ = send_and_recv_codecs;
+}
+
+void MediaSessionDescriptionFactory::set_audio_codecs(
+ const AudioCodecs& send_codecs, const AudioCodecs& recv_codecs) {
+ audio_send_codecs_ = send_codecs;
+ audio_recv_codecs_ = recv_codecs;
+ audio_sendrecv_codecs_.clear();
+
+ // Intersect the two lists of codecs, preserving the order of the send codecs.
+ // If there's any difference in priorities, chances are encoding is more
+ // expensive than decoding, and high-priority send codecs are likely handled
+ // better (e.g. through hardware encoder support) than low-priority ones.
+ // TODO(ossu): This is O(n^2). However, each list should generally be small
+ // enough for this to not be a problem. They are also nicely local in memory
+ // like this.
+ for (const auto& sc : audio_send_codecs_) {
+ for (const auto& rc : audio_recv_codecs_) {
+ const size_t send_channels = (sc.channels == 0) ? 1 : sc.channels;
+ const size_t recv_channels = (rc.channels == 0) ? 1 : rc.channels;
+ if (sc.clockrate == rc.clockrate &&
+ sc.bitrate == rc.bitrate &&
+ send_channels == recv_channels &&
+ (_stricmp(sc.name.c_str(), rc.name.c_str()) == 0) &&
+ sc.params == rc.params &&
+ sc.feedback_params == rc.feedback_params) {
+ AudioCodec out_codec = sc;
+ out_codec.channels = send_channels;
+ audio_sendrecv_codecs_.push_back(out_codec);
+ break;
+ }
+ }
+ }
}
SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
@@ -1249,11 +1320,30 @@ SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
StreamParamsVec current_streams;
GetCurrentStreamParams(current_description, &current_streams);
+ const AudioCodecs *supported_audio_codecs;
+ if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_) {
+ if (options.recv_audio) {
+ // sendrecv
+ supported_audio_codecs = &audio_sendrecv_codecs_;
+ } else {
+ // sendonly
+ supported_audio_codecs = &audio_send_codecs_;
+ }
+ } else if (options.recv_audio) {
+ // recvonly
+ supported_audio_codecs = &audio_recv_codecs_;
+ } else {
+ // Stream is inactive - generate list as if sendrecv.
+ // See RFC 3264 Section 6.1.
+ supported_audio_codecs = &audio_sendrecv_codecs_;
+ }
pthatcher1 2016/05/31 21:52:36 Would it make sense to make a method like this? c
ossu 2016/06/02 13:28:02 Why not have it take an RtpTranscieverDirection di
pthatcher1 2016/06/02 22:29:17 Sounds like a great idea.
+
AudioCodecs audio_codecs;
VideoCodecs video_codecs;
DataCodecs data_codecs;
- GetCodecsToOffer(current_description, &audio_codecs, &video_codecs,
- &data_codecs);
+ GetCodecsToOffer(current_description, *supported_audio_codecs,
+ video_codecs_, data_codecs_,
+ &audio_codecs, &video_codecs, &data_codecs);
if (!options.vad_enabled) {
// If application doesn't want CN codecs in offer.
@@ -1414,6 +1504,9 @@ SessionDescription* MediaSessionDescriptionFactory::CreateAnswer(
void MediaSessionDescriptionFactory::GetCodecsToOffer(
const SessionDescription* current_description,
+ const AudioCodecs& supported_audio_codecs,
+ const VideoCodecs& supported_video_codecs,
+ const DataCodecs& supported_data_codecs,
AudioCodecs* audio_codecs,
VideoCodecs* video_codecs,
DataCodecs* data_codecs) const {
@@ -1449,9 +1542,12 @@ void MediaSessionDescriptionFactory::GetCodecsToOffer(
}
// Add our codecs that are not in |current_description|.
- FindCodecsToOffer<AudioCodec>(audio_codecs_, audio_codecs, &used_pltypes);
- FindCodecsToOffer<VideoCodec>(video_codecs_, video_codecs, &used_pltypes);
- FindCodecsToOffer<DataCodec>(data_codecs_, data_codecs, &used_pltypes);
+ FindCodecsToOffer<AudioCodec>(supported_audio_codecs, audio_codecs,
+ &used_pltypes);
+ FindCodecsToOffer<VideoCodec>(supported_video_codecs, video_codecs,
+ &used_pltypes);
+ FindCodecsToOffer<DataCodec>(supported_data_codecs, data_codecs,
+ &used_pltypes);
}
void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
@@ -1733,6 +1829,8 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
StreamParamsVec* current_streams,
SessionDescription* answer) const {
const ContentInfo* audio_content = GetFirstAudioContent(offer);
+ const AudioContentDescription* audio_content_description =
pthatcher1 2016/05/31 21:52:36 A better name would be offer_audio.
+ static_cast<const AudioContentDescription*>(audio_content->description);
std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer(
audio_content->name, offer,
@@ -1741,7 +1839,39 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
return false;
}
- AudioCodecs audio_codecs = audio_codecs_;
+ // Pick codecs based on the requested communications direction in the offer.
+ // According to RFC 3264 Section 6.1, inactive is to be treated as sendrecv
+ // when constructing the list of supported formats.
+ AudioCodecs audio_codecs;
+ switch (audio_content_description->direction()) {
+ case MD_INACTIVE:
+ audio_codecs = audio_sendrecv_codecs_;
+ break;
+ case MD_SENDRECV:
+ if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_) {
+ audio_codecs = options.recv_audio
+ ? audio_sendrecv_codecs_
+ : audio_send_codecs_;
+ } else {
+ audio_codecs = options.recv_audio
+ ? audio_recv_codecs_
+ : audio_sendrecv_codecs_; // inactive
+ }
+ break;
+ case MD_RECVONLY:
+ if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO) || add_legacy_)
+ audio_codecs = audio_send_codecs_;
+ else
+ audio_codecs = audio_sendrecv_codecs_; // inactive
+ break;
+ case MD_SENDONLY:
+ if (options.recv_audio)
+ audio_codecs = audio_recv_codecs_;
+ else
+ audio_codecs = audio_sendrecv_codecs_; // inactive
+ break;
+ }
pthatcher1 2016/05/31 21:52:36 This could be more simple also: auto offer_rtd =
+
if (!options.vad_enabled) {
StripCNCodecs(&audio_codecs);
}
@@ -1754,8 +1884,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer(
cricket::SecurePolicy sdes_policy =
audio_transport->secure() ? cricket::SEC_DISABLED : secure();
if (!CreateMediaContentAnswer(
- static_cast<const AudioContentDescription*>(
- audio_content->description),
+ audio_content_description,
options,
audio_codecs,
sdes_policy,

Powered by Google App Engine
This is Rietveld 408576698