| Index: webrtc/pc/mediasession.cc
|
| diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc
|
| index 52abfe855f6aef47fa83d7e1ce51321f090a2417..15b5099a7541d2d3d7aebfc606ed7f9d5dac10a0 100644
|
| --- a/webrtc/pc/mediasession.cc
|
| +++ b/webrtc/pc/mediasession.cc
|
| @@ -1173,6 +1173,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 +1250,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 {
|
| + 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 +1318,30 @@ SessionDescription* MediaSessionDescriptionFactory::CreateOffer(
|
| StreamParamsVec current_streams;
|
| GetCurrentStreamParams(current_description, ¤t_streams);
|
|
|
| + const AudioCodecs *supported_audio_codecs;
|
| + 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 +1502,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 +1540,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 +1827,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 +1837,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 +1874,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,
|
|
|