Index: webrtc/pc/mediasession.cc |
diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc |
index 52abfe855f6aef47fa83d7e1ce51321f090a2417..b010b69cd3d81b3d9ea8f896d31550bcf827bc6d 100644 |
--- a/webrtc/pc/mediasession.cc |
+++ b/webrtc/pc/mediasession.cc |
@@ -1234,11 +1234,52 @@ 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 { |
+ return audio_sendrecv_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): Deal with channels == 0 also meaning channels = 1. |
+ // TODO(ossu): This is O(n^2). Normalizing and putting in a set could handle |
+ // both issues. |
+ for (const auto& sc : audio_send_codecs_) { |
ossu
2016/05/09 10:57:06
This clearly needs testing and should probably be
|
+ for (const auto& rc : audio_recv_codecs_) { |
+ if (sc.clockrate == rc.clockrate && |
+ sc.bitrate == rc.bitrate && |
+ sc.channels == rc.channels && |
+ sc.name == rc.name && |
+ sc.params == rc.params && |
+ sc.feedback_params == rc.feedback_params) { |
+ audio_sendrecv_codecs_.push_back(sc); |
+ break; |
+ } |
+ } |
+ } |
} |
SessionDescription* MediaSessionDescriptionFactory::CreateOffer( |
@@ -1249,11 +1290,30 @@ SessionDescription* MediaSessionDescriptionFactory::CreateOffer( |
StreamParamsVec current_streams; |
GetCurrentStreamParams(current_description, ¤t_streams); |
+ const AudioCodecs *supported_audio_codecs = nullptr; |
kwiberg-webrtc
2016/05/17 12:22:36
You set this in all branches below, so the default
ossu
2016/05/23 14:18:04
Acknowledged.
|
+ if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO)) { |
+ 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_; |
+ } |
+ |
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 +1474,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 +1512,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 +1799,8 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( |
StreamParamsVec* current_streams, |
SessionDescription* answer) const { |
const ContentInfo* audio_content = GetFirstAudioContent(offer); |
+ const AudioContentDescription* audio_content_description = |
+ static_cast<const AudioContentDescription*>(audio_content->description); |
std::unique_ptr<TransportDescription> audio_transport(CreateTransportAnswer( |
audio_content->name, offer, |
@@ -1741,7 +1809,31 @@ 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)) |
+ audio_codecs = audio_sendrecv_codecs_; |
+ else |
+ audio_codecs = audio_recv_codecs_; |
+ break; |
+ case MD_RECVONLY: |
+ if (options.HasSendMediaStream(MEDIA_TYPE_AUDIO)) |
+ audio_codecs = audio_send_codecs_; |
+ else |
+ audio_codecs = audio_sendrecv_codecs_; // inactive |
+ break; |
+ case MD_SENDONLY: |
+ audio_codecs = audio_recv_codecs_; |
+ break; |
+ } |
+ |
if (!options.vad_enabled) { |
StripCNCodecs(&audio_codecs); |
} |
@@ -1754,8 +1846,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, |