Chromium Code Reviews| 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, ¤t_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, |