Reland "WebRtcVoiceMediaChannel::AddRecvStream: Don't call SetRecPayloadType"
BUG=webrtc:5805 Review-Url: https://codereview.webrtc.org/2774833003 Cr-Commit-Position: refs/heads/master@{#17391}
This commit is contained in:
@ -94,10 +94,7 @@ AudioReceiveStream::AudioReceiveStream(
|
|||||||
channel_proxy_->GetAudioDecoderFactory());
|
channel_proxy_->GetAudioDecoderFactory());
|
||||||
|
|
||||||
channel_proxy_->RegisterExternalTransport(config.rtcp_send_transport);
|
channel_proxy_->RegisterExternalTransport(config.rtcp_send_transport);
|
||||||
|
channel_proxy_->SetReceiveCodecs(config.decoder_map);
|
||||||
for (const auto& kv : config.decoder_map) {
|
|
||||||
channel_proxy_->SetRecPayloadType(kv.first, kv.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& extension : config.rtp.extensions) {
|
for (const auto& extension : config.rtp.extensions) {
|
||||||
if (extension.uri == RtpExtension::kAudioLevelUri) {
|
if (extension.uri == RtpExtension::kAudioLevelUri) {
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -111,6 +112,11 @@ struct ConfigHelper {
|
|||||||
.Times(1)
|
.Times(1)
|
||||||
.After(expect_set);
|
.After(expect_set);
|
||||||
EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
|
EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
|
||||||
|
EXPECT_CALL(*channel_proxy_, SetReceiveCodecs(_))
|
||||||
|
.WillRepeatedly(
|
||||||
|
Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
EXPECT_THAT(codecs, testing::IsEmpty());
|
||||||
|
}));
|
||||||
return channel_proxy_;
|
return channel_proxy_;
|
||||||
}));
|
}));
|
||||||
stream_config_.voe_channel_id = kChannelId;
|
stream_config_.voe_channel_id = kChannelId;
|
||||||
|
|||||||
@ -241,6 +241,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec,
|
|||||||
audio_recv_config.voe_channel_id = recv_channel_id;
|
audio_recv_config.voe_channel_id = recv_channel_id;
|
||||||
audio_recv_config.sync_group = kSyncGroup;
|
audio_recv_config.sync_group = kSyncGroup;
|
||||||
audio_recv_config.decoder_factory = decoder_factory_;
|
audio_recv_config.decoder_factory = decoder_factory_;
|
||||||
|
audio_recv_config.decoder_map = {{103, {"ISAC", 16000, 1}}};
|
||||||
|
|
||||||
AudioReceiveStream* audio_receive_stream;
|
AudioReceiveStream* audio_receive_stream;
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "webrtc/call/audio_state.h"
|
#include "webrtc/call/audio_state.h"
|
||||||
@ -141,6 +142,11 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
|
|||||||
new testing::NiceMock<test::MockVoEChannelProxy>();
|
new testing::NiceMock<test::MockVoEChannelProxy>();
|
||||||
EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
|
EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
|
||||||
.WillRepeatedly(testing::ReturnRef(decoder_factory));
|
.WillRepeatedly(testing::ReturnRef(decoder_factory));
|
||||||
|
EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
|
||||||
|
.WillRepeatedly(testing::Invoke(
|
||||||
|
[](const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
EXPECT_THAT(codecs, testing::IsEmpty());
|
||||||
|
}));
|
||||||
// If being called for the send channel, save a pointer to the channel
|
// If being called for the send channel, save a pointer to the channel
|
||||||
// proxy for later.
|
// proxy for later.
|
||||||
if (channel_id == kRecvChannelId) {
|
if (channel_id == kRecvChannelId) {
|
||||||
@ -188,6 +194,11 @@ TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
|
|||||||
new testing::NiceMock<test::MockVoEChannelProxy>();
|
new testing::NiceMock<test::MockVoEChannelProxy>();
|
||||||
EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
|
EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
|
||||||
.WillRepeatedly(testing::ReturnRef(decoder_factory));
|
.WillRepeatedly(testing::ReturnRef(decoder_factory));
|
||||||
|
EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
|
||||||
|
.WillRepeatedly(testing::Invoke(
|
||||||
|
[](const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
EXPECT_THAT(codecs, testing::IsEmpty());
|
||||||
|
}));
|
||||||
// If being called for the send channel, save a pointer to the channel
|
// If being called for the send channel, save a pointer to the channel
|
||||||
// proxy for later.
|
// proxy for later.
|
||||||
if (channel_id == kRecvChannelId) {
|
if (channel_id == kRecvChannelId) {
|
||||||
|
|||||||
@ -117,8 +117,6 @@ class FakeWebRtcVoiceEngine
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Channel* ch = new Channel();
|
Channel* ch = new Channel();
|
||||||
auto db = webrtc::acm2::RentACodec::Database();
|
|
||||||
ch->recv_codecs.assign(db.begin(), db.end());
|
|
||||||
ch->neteq_capacity = config.acm_config.neteq_config.max_packets_in_buffer;
|
ch->neteq_capacity = config.acm_config.neteq_config.max_packets_in_buffer;
|
||||||
ch->neteq_fast_accelerate =
|
ch->neteq_fast_accelerate =
|
||||||
config.acm_config.neteq_config.enable_fast_accelerate;
|
config.acm_config.neteq_config.enable_fast_accelerate;
|
||||||
|
|||||||
@ -132,13 +132,6 @@ std::string ToString(const AudioCodec& codec) {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString(const webrtc::CodecInst& codec) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
|
|
||||||
<< " (" << codec.pltype << ")";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCodec(const AudioCodec& codec, const char* ref_name) {
|
bool IsCodec(const AudioCodec& codec, const char* ref_name) {
|
||||||
return (_stricmp(codec.name.c_str(), ref_name) == 0);
|
return (_stricmp(codec.name.c_str(), ref_name) == 0);
|
||||||
}
|
}
|
||||||
@ -1466,7 +1459,8 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
|
|||||||
const std::vector<webrtc::RtpExtension>& extensions,
|
const std::vector<webrtc::RtpExtension>& extensions,
|
||||||
webrtc::Call* call,
|
webrtc::Call* call,
|
||||||
webrtc::Transport* rtcp_send_transport,
|
webrtc::Transport* rtcp_send_transport,
|
||||||
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory)
|
const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
|
||||||
|
const std::map<int, webrtc::SdpAudioFormat>& decoder_map)
|
||||||
: call_(call), config_() {
|
: call_(call), config_() {
|
||||||
RTC_DCHECK_GE(ch, 0);
|
RTC_DCHECK_GE(ch, 0);
|
||||||
RTC_DCHECK(call);
|
RTC_DCHECK(call);
|
||||||
@ -1479,6 +1473,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
|
|||||||
config_.voe_channel_id = ch;
|
config_.voe_channel_id = ch;
|
||||||
config_.sync_group = sync_group;
|
config_.sync_group = sync_group;
|
||||||
config_.decoder_factory = decoder_factory;
|
config_.decoder_factory = decoder_factory;
|
||||||
|
config_.decoder_map = decoder_map;
|
||||||
RecreateAudioReceiveStream();
|
RecreateAudioReceiveStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1859,8 +1854,9 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs(
|
|||||||
ChangePlayout(false);
|
ChangePlayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decoder_map_ = std::move(decoder_map);
|
||||||
for (auto& kv : recv_streams_) {
|
for (auto& kv : recv_streams_) {
|
||||||
kv.second->RecreateAudioReceiveStream(decoder_map);
|
kv.second->RecreateAudioReceiveStream(decoder_map_);
|
||||||
}
|
}
|
||||||
recv_codecs_ = codecs;
|
recv_codecs_ = codecs;
|
||||||
|
|
||||||
@ -2219,38 +2215,12 @@ bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn off all supported codecs.
|
|
||||||
// TODO(solenberg): Remove once "no codecs" is the default state of a stream.
|
|
||||||
for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
|
|
||||||
voe_codec.pltype = -1;
|
|
||||||
if (engine()->voe()->codec()->SetRecPayloadType(channel, voe_codec) == -1) {
|
|
||||||
LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
|
|
||||||
DeleteVoEChannel(channel);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only enable those configured for this channel.
|
|
||||||
for (const auto& codec : recv_codecs_) {
|
|
||||||
webrtc::CodecInst voe_codec = {0};
|
|
||||||
if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
|
|
||||||
voe_codec.pltype = codec.id;
|
|
||||||
if (engine()->voe()->codec()->SetRecPayloadType(
|
|
||||||
channel, voe_codec) == -1) {
|
|
||||||
LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
|
|
||||||
DeleteVoEChannel(channel);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
recv_streams_.insert(std::make_pair(
|
recv_streams_.insert(std::make_pair(
|
||||||
ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_,
|
ssrc,
|
||||||
recv_transport_cc_enabled_,
|
new WebRtcAudioReceiveStream(
|
||||||
recv_nack_enabled_,
|
channel, ssrc, receiver_reports_ssrc_, recv_transport_cc_enabled_,
|
||||||
sp.sync_label, recv_rtp_extensions_,
|
recv_nack_enabled_, sp.sync_label, recv_rtp_extensions_, call_, this,
|
||||||
call_, this,
|
engine()->decoder_factory_, decoder_map_)));
|
||||||
engine()->decoder_factory_)));
|
|
||||||
recv_streams_[ssrc]->SetPlayout(playout_);
|
recv_streams_[ssrc]->SetPlayout(playout_);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -251,7 +251,12 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
|
|||||||
|
|
||||||
WebRtcVoiceEngine* const engine_ = nullptr;
|
WebRtcVoiceEngine* const engine_ = nullptr;
|
||||||
std::vector<AudioCodec> send_codecs_;
|
std::vector<AudioCodec> send_codecs_;
|
||||||
|
|
||||||
|
// TODO(kwiberg): decoder_map_ and recv_codecs_ store the exact same
|
||||||
|
// information, in slightly different formats. Eliminate recv_codecs_.
|
||||||
|
std::map<int, webrtc::SdpAudioFormat> decoder_map_;
|
||||||
std::vector<AudioCodec> recv_codecs_;
|
std::vector<AudioCodec> recv_codecs_;
|
||||||
|
|
||||||
int max_send_bitrate_bps_ = 0;
|
int max_send_bitrate_bps_ = 0;
|
||||||
AudioOptions options_;
|
AudioOptions options_;
|
||||||
rtc::Optional<int> dtmf_payload_type_;
|
rtc::Optional<int> dtmf_payload_type_;
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#include "webrtc/test/gtest.h"
|
#include "webrtc/test/gtest.h"
|
||||||
#include "webrtc/voice_engine/transmit_mixer.h"
|
#include "webrtc/voice_engine/transmit_mixer.h"
|
||||||
|
|
||||||
|
using testing::ContainerEq;
|
||||||
using testing::Return;
|
using testing::Return;
|
||||||
using testing::StrictMock;
|
using testing::StrictMock;
|
||||||
|
|
||||||
@ -795,26 +796,12 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
|
|||||||
parameters.codecs[2].id = 126;
|
parameters.codecs[2].id = 126;
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
||||||
int channel_num = voe_.GetLastChannel();
|
EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
|
||||||
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
webrtc::CodecInst gcodec;
|
{{0, {"PCMU", 8000, 1}},
|
||||||
rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
|
{106, {"ISAC", 16000, 1}},
|
||||||
gcodec.plfreq = 16000;
|
{126, {"telephone-event", 8000, 1}},
|
||||||
gcodec.channels = 1;
|
{107, {"telephone-event", 32000, 1}}})));
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
|
|
||||||
EXPECT_EQ(106, gcodec.pltype);
|
|
||||||
EXPECT_STREQ("ISAC", gcodec.plname);
|
|
||||||
|
|
||||||
rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
|
|
||||||
gcodec.plfreq = 8000;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
|
|
||||||
EXPECT_EQ(126, gcodec.pltype);
|
|
||||||
EXPECT_STREQ("telephone-event", gcodec.plname);
|
|
||||||
|
|
||||||
gcodec.plfreq = 32000;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
|
|
||||||
EXPECT_EQ(107, gcodec.pltype);
|
|
||||||
EXPECT_STREQ("telephone-event", gcodec.plname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we fail to set an unknown inbound codec.
|
// Test that we fail to set an unknown inbound codec.
|
||||||
@ -845,16 +832,11 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
|
|||||||
parameters.codecs.push_back(kOpusCodec);
|
parameters.codecs.push_back(kOpusCodec);
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
||||||
int channel_num = voe_.GetLastChannel();
|
EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
|
||||||
webrtc::CodecInst opus;
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
|
{{0, {"PCMU", 8000, 1}},
|
||||||
// Even without stereo parameters, recv codecs still specify channels = 2.
|
{103, {"ISAC", 16000, 1}},
|
||||||
EXPECT_EQ(2, opus.channels);
|
{111, {"opus", 48000, 2}}})));
|
||||||
EXPECT_EQ(111, opus.pltype);
|
|
||||||
EXPECT_STREQ("opus", opus.plname);
|
|
||||||
opus.pltype = 0;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
|
|
||||||
EXPECT_EQ(111, opus.pltype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we can decode OPUS with stereo = 0.
|
// Test that we can decode OPUS with stereo = 0.
|
||||||
@ -867,16 +849,11 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
|
|||||||
parameters.codecs[2].params["stereo"] = "0";
|
parameters.codecs[2].params["stereo"] = "0";
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
||||||
int channel_num2 = voe_.GetLastChannel();
|
EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
|
||||||
webrtc::CodecInst opus;
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
|
{{0, {"PCMU", 8000, 1}},
|
||||||
// Even when stereo is off, recv codecs still specify channels = 2.
|
{103, {"ISAC", 16000, 1}},
|
||||||
EXPECT_EQ(2, opus.channels);
|
{111, {"opus", 48000, 2, {{"stereo", "0"}}}}})));
|
||||||
EXPECT_EQ(111, opus.pltype);
|
|
||||||
EXPECT_STREQ("opus", opus.plname);
|
|
||||||
opus.pltype = 0;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
|
|
||||||
EXPECT_EQ(111, opus.pltype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we can decode OPUS with stereo = 1.
|
// Test that we can decode OPUS with stereo = 1.
|
||||||
@ -889,15 +866,11 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
|
|||||||
parameters.codecs[2].params["stereo"] = "1";
|
parameters.codecs[2].params["stereo"] = "1";
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
||||||
int channel_num2 = voe_.GetLastChannel();
|
EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
|
||||||
webrtc::CodecInst opus;
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
|
{{0, {"PCMU", 8000, 1}},
|
||||||
EXPECT_EQ(2, opus.channels);
|
{103, {"ISAC", 16000, 1}},
|
||||||
EXPECT_EQ(111, opus.pltype);
|
{111, {"opus", 48000, 2, {{"stereo", "1"}}}}})));
|
||||||
EXPECT_STREQ("opus", opus.plname);
|
|
||||||
opus.pltype = 0;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
|
|
||||||
EXPECT_EQ(111, opus.pltype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that changes to recv codecs are applied to all streams.
|
// Test that changes to recv codecs are applied to all streams.
|
||||||
@ -911,28 +884,15 @@ TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
|
|||||||
parameters.codecs[0].id = 106; // collide with existing CN 32k
|
parameters.codecs[0].id = 106; // collide with existing CN 32k
|
||||||
parameters.codecs[2].id = 126;
|
parameters.codecs[2].id = 126;
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
for (const auto& ssrc : {kSsrcX, kSsrcY}) {
|
||||||
int channel_num2 = voe_.GetLastChannel();
|
EXPECT_TRUE(AddRecvStream(ssrc));
|
||||||
|
EXPECT_THAT(GetRecvStreamConfig(ssrc).decoder_map,
|
||||||
webrtc::CodecInst gcodec;
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
|
{{0, {"PCMU", 8000, 1}},
|
||||||
gcodec.plfreq = 16000;
|
{106, {"ISAC", 16000, 1}},
|
||||||
gcodec.channels = 1;
|
{126, {"telephone-event", 8000, 1}},
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
|
{107, {"telephone-event", 32000, 1}}})));
|
||||||
EXPECT_EQ(106, gcodec.pltype);
|
}
|
||||||
EXPECT_STREQ("ISAC", gcodec.plname);
|
|
||||||
|
|
||||||
rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
|
|
||||||
gcodec.plfreq = 8000;
|
|
||||||
gcodec.channels = 1;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
|
|
||||||
EXPECT_EQ(126, gcodec.pltype);
|
|
||||||
EXPECT_STREQ("telephone-event", gcodec.plname);
|
|
||||||
|
|
||||||
gcodec.plfreq = 32000;
|
|
||||||
EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
|
|
||||||
EXPECT_EQ(107, gcodec.pltype);
|
|
||||||
EXPECT_STREQ("telephone-event", gcodec.plname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
|
TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
|
||||||
@ -2961,12 +2921,9 @@ TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
|
|||||||
parameters.codecs.push_back(kPcmuCodec);
|
parameters.codecs.push_back(kPcmuCodec);
|
||||||
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
EXPECT_TRUE(channel_->SetRecvParameters(parameters));
|
||||||
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
EXPECT_TRUE(AddRecvStream(kSsrcX));
|
||||||
int channel_num2 = voe_.GetLastChannel();
|
EXPECT_THAT(GetRecvStreamConfig(kSsrcX).decoder_map,
|
||||||
webrtc::CodecInst gcodec;
|
(ContainerEq<std::map<int, webrtc::SdpAudioFormat>>(
|
||||||
rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
|
{{0, {"PCMU", 8000, 1}}, {103, {"ISAC", 16000, 1}}})));
|
||||||
gcodec.plfreq = 48000;
|
|
||||||
gcodec.channels = 2;
|
|
||||||
EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we properly clean up any streams that were added, even if
|
// Test that we properly clean up any streams that were added, even if
|
||||||
|
|||||||
@ -179,6 +179,10 @@ int AcmReceiver::GetAudio(int desired_freq_hz,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AcmReceiver::SetCodecs(const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
neteq_->SetCodecs(codecs);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t AcmReceiver::AddCodec(int acm_codec_id,
|
int32_t AcmReceiver::AddCodec(int acm_codec_id,
|
||||||
uint8_t payload_type,
|
uint8_t payload_type,
|
||||||
size_t channels,
|
size_t channels,
|
||||||
|
|||||||
@ -79,6 +79,9 @@ class AcmReceiver {
|
|||||||
//
|
//
|
||||||
int GetAudio(int desired_freq_hz, AudioFrame* audio_frame, bool* muted);
|
int GetAudio(int desired_freq_hz, AudioFrame* audio_frame, bool* muted);
|
||||||
|
|
||||||
|
// Replace the current set of decoders with the specified set.
|
||||||
|
void SetCodecs(const std::map<int, SdpAudioFormat>& codecs);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Adds a new codec to the NetEq codec database.
|
// Adds a new codec to the NetEq codec database.
|
||||||
//
|
//
|
||||||
|
|||||||
@ -121,6 +121,8 @@ class AudioCodingModuleImpl final : public AudioCodingModule {
|
|||||||
// Get current playout frequency.
|
// Get current playout frequency.
|
||||||
int PlayoutFrequency() const override;
|
int PlayoutFrequency() const override;
|
||||||
|
|
||||||
|
void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
|
||||||
|
|
||||||
bool RegisterReceiveCodec(int rtp_payload_type,
|
bool RegisterReceiveCodec(int rtp_payload_type,
|
||||||
const SdpAudioFormat& audio_format) override;
|
const SdpAudioFormat& audio_format) override;
|
||||||
|
|
||||||
@ -318,16 +320,6 @@ void UpdateCodecTypeHistogram(size_t codec_type) {
|
|||||||
webrtc::AudioEncoder::CodecType::kMaxLoggedAudioCodecTypes));
|
webrtc::AudioEncoder::CodecType::kMaxLoggedAudioCodecTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(turajs): the same functionality is used in NetEq. If both classes
|
|
||||||
// need them, make it a static function in ACMCodecDB.
|
|
||||||
bool IsCodecRED(const CodecInst& codec) {
|
|
||||||
return (STR_CASE_CMP(codec.plname, "RED") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCodecCN(const CodecInst& codec) {
|
|
||||||
return (STR_CASE_CMP(codec.plname, "CN") == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stereo-to-mono can be used as in-place.
|
// Stereo-to-mono can be used as in-place.
|
||||||
int DownMix(const AudioFrame& frame,
|
int DownMix(const AudioFrame& frame,
|
||||||
size_t length_out_buff,
|
size_t length_out_buff,
|
||||||
@ -956,19 +948,6 @@ int AudioCodingModuleImpl::InitializeReceiverSafe() {
|
|||||||
receiver_.SetMaximumDelay(0);
|
receiver_.SetMaximumDelay(0);
|
||||||
receiver_.FlushBuffers();
|
receiver_.FlushBuffers();
|
||||||
|
|
||||||
// Register RED and CN.
|
|
||||||
auto db = acm2::RentACodec::Database();
|
|
||||||
for (size_t i = 0; i < db.size(); i++) {
|
|
||||||
if (IsCodecRED(db[i]) || IsCodecCN(db[i])) {
|
|
||||||
if (receiver_.AddCodec(static_cast<int>(i),
|
|
||||||
static_cast<uint8_t>(db[i].pltype), 1,
|
|
||||||
db[i].plfreq, nullptr, db[i].plname) < 0) {
|
|
||||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
|
|
||||||
"Cannot register master codec.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
receiver_initialized_ = true;
|
receiver_initialized_ = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -987,6 +966,12 @@ int AudioCodingModuleImpl::PlayoutFrequency() const {
|
|||||||
return receiver_.last_output_sample_rate_hz();
|
return receiver_.last_output_sample_rate_hz();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioCodingModuleImpl::SetReceiveCodecs(
|
||||||
|
const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
rtc::CritScope lock(&acm_crit_sect_);
|
||||||
|
receiver_.SetCodecs(codecs);
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioCodingModuleImpl::RegisterReceiveCodec(
|
bool AudioCodingModuleImpl::RegisterReceiveCodec(
|
||||||
int rtp_payload_type,
|
int rtp_payload_type,
|
||||||
const SdpAudioFormat& audio_format) {
|
const SdpAudioFormat& audio_format) {
|
||||||
|
|||||||
@ -485,6 +485,10 @@ class AudioCodingModule {
|
|||||||
//
|
//
|
||||||
virtual int32_t PlayoutFrequency() const = 0;
|
virtual int32_t PlayoutFrequency() const = 0;
|
||||||
|
|
||||||
|
// Replace any existing decoders with the given payload type -> decoder map.
|
||||||
|
virtual void SetReceiveCodecs(
|
||||||
|
const std::map<int, SdpAudioFormat>& codecs) = 0;
|
||||||
|
|
||||||
// Registers a decoder for the given payload type. Returns true iff
|
// Registers a decoder for the given payload type. Returns true iff
|
||||||
// successful.
|
// successful.
|
||||||
virtual bool RegisterReceiveCodec(int rtp_payload_type,
|
virtual bool RegisterReceiveCodec(int rtp_payload_type,
|
||||||
|
|||||||
@ -123,6 +123,38 @@ void DecoderDatabase::Reset() {
|
|||||||
active_cng_decoder_type_ = -1;
|
active_cng_decoder_type_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<int> DecoderDatabase::SetCodecs(
|
||||||
|
const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
// First collect all payload types that we'll remove or reassign, then remove
|
||||||
|
// them from the database.
|
||||||
|
std::vector<int> changed_payload_types;
|
||||||
|
for (const std::pair<uint8_t, const DecoderInfo&> kv : decoders_) {
|
||||||
|
auto i = codecs.find(kv.first);
|
||||||
|
if (i == codecs.end() || i->second != kv.second.GetFormat()) {
|
||||||
|
changed_payload_types.push_back(kv.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int pl_type : changed_payload_types) {
|
||||||
|
Remove(pl_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enter the new and changed payload type mappings into the database.
|
||||||
|
for (const auto& kv : codecs) {
|
||||||
|
const int& rtp_payload_type = kv.first;
|
||||||
|
const SdpAudioFormat& audio_format = kv.second;
|
||||||
|
RTC_DCHECK_GE(rtp_payload_type, 0);
|
||||||
|
RTC_DCHECK_LE(rtp_payload_type, 0x7f);
|
||||||
|
if (decoders_.count(rtp_payload_type) == 0) {
|
||||||
|
decoders_.insert(std::make_pair(
|
||||||
|
rtp_payload_type, DecoderInfo(audio_format, decoder_factory_.get())));
|
||||||
|
} else {
|
||||||
|
// The mapping for this payload type hasn't changed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed_payload_types;
|
||||||
|
}
|
||||||
|
|
||||||
int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type,
|
int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type,
|
||||||
NetEqDecoder codec_type,
|
NetEqDecoder codec_type,
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
|
|||||||
@ -149,6 +149,11 @@ class DecoderDatabase {
|
|||||||
// using InsertExternal().
|
// using InsertExternal().
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
|
|
||||||
|
// Replaces the existing set of decoders with the given set. Returns the
|
||||||
|
// payload types that were reassigned or removed while doing so.
|
||||||
|
virtual std::vector<int> SetCodecs(
|
||||||
|
const std::map<int, SdpAudioFormat>& codecs);
|
||||||
|
|
||||||
// Registers |rtp_payload_type| as a decoder of type |codec_type|. The |name|
|
// Registers |rtp_payload_type| as a decoder of type |codec_type|. The |name|
|
||||||
// is only used to populate the name field in the DecoderInfo struct in the
|
// is only used to populate the name field in the DecoderInfo struct in the
|
||||||
// database, and can be arbitrary (including empty). Returns kOK on success;
|
// database, and can be arbitrary (including empty). Returns kOK on success;
|
||||||
|
|||||||
@ -157,6 +157,9 @@ class NetEq {
|
|||||||
// Returns kOK on success, or kFail in case of an error.
|
// Returns kOK on success, or kFail in case of an error.
|
||||||
virtual int GetAudio(AudioFrame* audio_frame, bool* muted) = 0;
|
virtual int GetAudio(AudioFrame* audio_frame, bool* muted) = 0;
|
||||||
|
|
||||||
|
// Replaces the current set of decoders with the given one.
|
||||||
|
virtual void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) = 0;
|
||||||
|
|
||||||
// Associates |rtp_payload_type| with |codec| and |codec_name|, and stores the
|
// Associates |rtp_payload_type| with |codec| and |codec_name|, and stores the
|
||||||
// information in the codec database. Returns 0 on success, -1 on failure.
|
// information in the codec database. Returns 0 on success, -1 on failure.
|
||||||
// The name is only used to provide information back to the caller about the
|
// The name is only used to provide information back to the caller about the
|
||||||
|
|||||||
@ -212,6 +212,15 @@ int NetEqImpl::GetAudio(AudioFrame* audio_frame, bool* muted) {
|
|||||||
return kOK;
|
return kOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetEqImpl::SetCodecs(const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
rtc::CritScope lock(&crit_sect_);
|
||||||
|
const std::vector<int> changed_payload_types =
|
||||||
|
decoder_database_->SetCodecs(codecs);
|
||||||
|
for (const int pt : changed_payload_types) {
|
||||||
|
packet_buffer_->DiscardPacketsWithPayloadType(pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NetEqImpl::RegisterPayloadType(NetEqDecoder codec,
|
int NetEqImpl::RegisterPayloadType(NetEqDecoder codec,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
uint8_t rtp_payload_type) {
|
uint8_t rtp_payload_type) {
|
||||||
|
|||||||
@ -111,6 +111,8 @@ class NetEqImpl : public webrtc::NetEq {
|
|||||||
|
|
||||||
int GetAudio(AudioFrame* audio_frame, bool* muted) override;
|
int GetAudio(AudioFrame* audio_frame, bool* muted) override;
|
||||||
|
|
||||||
|
void SetCodecs(const std::map<int, SdpAudioFormat>& codecs) override;
|
||||||
|
|
||||||
int RegisterPayloadType(NetEqDecoder codec,
|
int RegisterPayloadType(NetEqDecoder codec,
|
||||||
const std::string& codec_name,
|
const std::string& codec_name,
|
||||||
uint8_t rtp_payload_type) override;
|
uint8_t rtp_payload_type) override;
|
||||||
|
|||||||
@ -168,6 +168,7 @@ rtc_static_library("rtp_rtcp") {
|
|||||||
deps = [
|
deps = [
|
||||||
"../..:webrtc_common",
|
"../..:webrtc_common",
|
||||||
"../../api:transport_api",
|
"../../api:transport_api",
|
||||||
|
"../../api/audio_codecs:audio_codecs_api",
|
||||||
"../../base:gtest_prod",
|
"../../base:gtest_prod",
|
||||||
"../../base:rtc_base_approved",
|
"../../base:rtc_base_approved",
|
||||||
"../../base:rtc_task_queue",
|
"../../base:rtc_task_queue",
|
||||||
@ -175,6 +176,7 @@ rtc_static_library("rtp_rtcp") {
|
|||||||
"../../common_video",
|
"../../common_video",
|
||||||
"../../logging:rtc_event_log_api",
|
"../../logging:rtc_event_log_api",
|
||||||
"../../system_wrappers",
|
"../../system_wrappers",
|
||||||
|
"../audio_coding:audio_format_conversion",
|
||||||
"../remote_bitrate_estimator",
|
"../remote_bitrate_estimator",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "webrtc/api/audio_codecs/audio_format.h"
|
||||||
#include "webrtc/base/criticalsection.h"
|
#include "webrtc/base/criticalsection.h"
|
||||||
#include "webrtc/base/deprecation.h"
|
#include "webrtc/base/deprecation.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
|
||||||
@ -43,6 +44,10 @@ class RTPPayloadRegistry {
|
|||||||
|
|
||||||
// TODO(magjed): Split RTPPayloadRegistry into separate Audio and Video class
|
// TODO(magjed): Split RTPPayloadRegistry into separate Audio and Video class
|
||||||
// and simplify the code. http://crbug/webrtc/6743.
|
// and simplify the code. http://crbug/webrtc/6743.
|
||||||
|
|
||||||
|
// Replace all audio receive payload types with the given map.
|
||||||
|
void SetAudioReceivePayloads(std::map<int, SdpAudioFormat> codecs);
|
||||||
|
|
||||||
int32_t RegisterReceivePayload(const CodecInst& audio_codec,
|
int32_t RegisterReceivePayload(const CodecInst& audio_codec,
|
||||||
bool* created_new_payload_type);
|
bool* created_new_payload_type);
|
||||||
int32_t RegisterReceivePayload(const VideoCodec& video_codec);
|
int32_t RegisterReceivePayload(const VideoCodec& video_codec);
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/base/stringutils.h"
|
#include "webrtc/base/stringutils.h"
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
|
#include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -119,6 +120,31 @@ RTPPayloadRegistry::RTPPayloadRegistry()
|
|||||||
|
|
||||||
RTPPayloadRegistry::~RTPPayloadRegistry() = default;
|
RTPPayloadRegistry::~RTPPayloadRegistry() = default;
|
||||||
|
|
||||||
|
void RTPPayloadRegistry::SetAudioReceivePayloads(
|
||||||
|
std::map<int, SdpAudioFormat> codecs) {
|
||||||
|
rtc::CritScope cs(&crit_sect_);
|
||||||
|
|
||||||
|
#if RTC_DCHECK_IS_ON
|
||||||
|
RTC_DCHECK(!used_for_video_);
|
||||||
|
used_for_audio_ = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
payload_type_map_.clear();
|
||||||
|
for (const auto& kv : codecs) {
|
||||||
|
const int& rtp_payload_type = kv.first;
|
||||||
|
const SdpAudioFormat& audio_format = kv.second;
|
||||||
|
const CodecInst ci = SdpToCodecInst(rtp_payload_type, audio_format);
|
||||||
|
RTC_DCHECK(IsPayloadTypeValid(rtp_payload_type));
|
||||||
|
payload_type_map_.insert(
|
||||||
|
std::make_pair(rtp_payload_type, CreatePayloadType(ci)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the value of last received payload type since it might mean
|
||||||
|
// something else now.
|
||||||
|
last_received_payload_type_ = -1;
|
||||||
|
last_received_media_payload_type_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
|
int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
|
||||||
bool* created_new_payload) {
|
bool* created_new_payload) {
|
||||||
rtc::CritScope cs(&crit_sect_);
|
rtc::CritScope cs(&crit_sect_);
|
||||||
|
|||||||
@ -85,6 +85,8 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
|
|||||||
MOCK_METHOD1(SetSendCodec, bool(const CodecInst& codec_inst));
|
MOCK_METHOD1(SetSendCodec, bool(const CodecInst& codec_inst));
|
||||||
MOCK_METHOD2(SetSendCNPayloadType,
|
MOCK_METHOD2(SetSendCNPayloadType,
|
||||||
bool(int type, PayloadFrequencies frequency));
|
bool(int type, PayloadFrequencies frequency));
|
||||||
|
MOCK_METHOD1(SetReceiveCodecs,
|
||||||
|
void(const std::map<int, SdpAudioFormat>& codecs));
|
||||||
MOCK_METHOD1(OnTwccBasedUplinkPacketLossRate, void(float packet_loss_rate));
|
MOCK_METHOD1(OnTwccBasedUplinkPacketLossRate, void(float packet_loss_rate));
|
||||||
MOCK_METHOD1(OnRecoverableUplinkPacketLossRate,
|
MOCK_METHOD1(OnRecoverableUplinkPacketLossRate,
|
||||||
void(float recoverable_packet_loss_rate));
|
void(float recoverable_packet_loss_rate));
|
||||||
|
|||||||
@ -52,6 +52,11 @@ class MockVoiceEngine : public VoiceEngineImpl {
|
|||||||
new testing::NiceMock<webrtc::test::MockVoEChannelProxy>();
|
new testing::NiceMock<webrtc::test::MockVoEChannelProxy>();
|
||||||
EXPECT_CALL(*proxy, GetAudioDecoderFactory())
|
EXPECT_CALL(*proxy, GetAudioDecoderFactory())
|
||||||
.WillRepeatedly(testing::ReturnRef(decoder_factory_));
|
.WillRepeatedly(testing::ReturnRef(decoder_factory_));
|
||||||
|
EXPECT_CALL(*proxy, SetReceiveCodecs(testing::_))
|
||||||
|
.WillRepeatedly(testing::Invoke(
|
||||||
|
[](const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
EXPECT_THAT(codecs, testing::IsEmpty());
|
||||||
|
}));
|
||||||
return proxy;
|
return proxy;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@ -988,16 +988,50 @@ int32_t Channel::Init() {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Register all supported codecs to the receiving side of the
|
// Register a default set of send codecs.
|
||||||
// RTP/RTCP module
|
const int nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
|
||||||
|
|
||||||
CodecInst codec;
|
|
||||||
const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
|
|
||||||
|
|
||||||
for (int idx = 0; idx < nSupportedCodecs; idx++) {
|
for (int idx = 0; idx < nSupportedCodecs; idx++) {
|
||||||
|
CodecInst codec;
|
||||||
|
RTC_CHECK_EQ(0, audio_coding_->Codec(idx, &codec));
|
||||||
|
|
||||||
|
// Ensure that PCMU is used as default send codec.
|
||||||
|
if (STR_CASE_CMP(codec.plname, "PCMU") == 0 && codec.channels == 1) {
|
||||||
|
SetSendCodec(codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register default PT for 'telephone-event'
|
||||||
|
if (STR_CASE_CMP(codec.plname, "telephone-event") == 0) {
|
||||||
|
if (_rtpRtcpModule->RegisterSendPayload(codec) == -1) {
|
||||||
|
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||||
|
"Channel::Init() failed to register outband "
|
||||||
|
"'telephone-event' (%d/%d) correctly",
|
||||||
|
codec.pltype, codec.plfreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STR_CASE_CMP(codec.plname, "CN") == 0) {
|
||||||
|
if (!codec_manager_.RegisterEncoder(codec) ||
|
||||||
|
!codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get()) ||
|
||||||
|
_rtpRtcpModule->RegisterSendPayload(codec) == -1) {
|
||||||
|
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||||
|
"Channel::Init() failed to register CN (%d/%d) "
|
||||||
|
"correctly - 1",
|
||||||
|
codec.pltype, codec.plfreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Channel::RegisterLegacyReceiveCodecs() {
|
||||||
|
const int nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
|
||||||
|
for (int idx = 0; idx < nSupportedCodecs; idx++) {
|
||||||
|
CodecInst codec;
|
||||||
|
RTC_CHECK_EQ(0, audio_coding_->Codec(idx, &codec));
|
||||||
|
|
||||||
// Open up the RTP/RTCP receiver for all supported codecs
|
// Open up the RTP/RTCP receiver for all supported codecs
|
||||||
if ((audio_coding_->Codec(idx, &codec) == -1) ||
|
if (rtp_receiver_->RegisterReceivePayload(codec) == -1) {
|
||||||
(rtp_receiver_->RegisterReceivePayload(codec) == -1)) {
|
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||||
"Channel::Init() unable to register %s "
|
"Channel::Init() unable to register %s "
|
||||||
"(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver",
|
"(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver",
|
||||||
@ -1012,29 +1046,20 @@ int32_t Channel::Init() {
|
|||||||
codec.rate);
|
codec.rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that PCMU is used as default codec on the sending side
|
// Register default PT for 'telephone-event'
|
||||||
if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) {
|
if (STR_CASE_CMP(codec.plname, "telephone-event") == 0) {
|
||||||
SetSendCodec(codec);
|
if (!audio_coding_->RegisterReceiveCodec(codec.pltype,
|
||||||
}
|
|
||||||
|
|
||||||
// Register default PT for outband 'telephone-event'
|
|
||||||
if (!STR_CASE_CMP(codec.plname, "telephone-event")) {
|
|
||||||
if (_rtpRtcpModule->RegisterSendPayload(codec) == -1 ||
|
|
||||||
!audio_coding_->RegisterReceiveCodec(codec.pltype,
|
|
||||||
CodecInstToSdp(codec))) {
|
CodecInstToSdp(codec))) {
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||||
"Channel::Init() failed to register outband "
|
"Channel::Init() failed to register inband "
|
||||||
"'telephone-event' (%d/%d) correctly",
|
"'telephone-event' (%d/%d) correctly",
|
||||||
codec.pltype, codec.plfreq);
|
codec.pltype, codec.plfreq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!STR_CASE_CMP(codec.plname, "CN")) {
|
if (STR_CASE_CMP(codec.plname, "CN") == 0) {
|
||||||
if (!codec_manager_.RegisterEncoder(codec) ||
|
if (!audio_coding_->RegisterReceiveCodec(codec.pltype,
|
||||||
!codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get()) ||
|
CodecInstToSdp(codec))) {
|
||||||
!audio_coding_->RegisterReceiveCodec(codec.pltype,
|
|
||||||
CodecInstToSdp(codec)) ||
|
|
||||||
_rtpRtcpModule->RegisterSendPayload(codec) == -1) {
|
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||||
"Channel::Init() failed to register CN (%d/%d) "
|
"Channel::Init() failed to register CN (%d/%d) "
|
||||||
"correctly - 1",
|
"correctly - 1",
|
||||||
@ -1042,8 +1067,6 @@ int32_t Channel::Init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::Terminate() {
|
void Channel::Terminate() {
|
||||||
@ -1361,6 +1384,11 @@ int32_t Channel::GetVADStatus(bool& enabledVAD,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Channel::SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
rtp_payload_registry_->SetAudioReceivePayloads(codecs);
|
||||||
|
audio_coding_->SetReceiveCodecs(codecs);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t Channel::SetRecPayloadType(const CodecInst& codec) {
|
int32_t Channel::SetRecPayloadType(const CodecInst& codec) {
|
||||||
return SetRecPayloadType(codec.pltype, CodecInstToSdp(codec));
|
return SetRecPayloadType(codec.pltype, CodecInstToSdp(codec));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -152,6 +152,7 @@ class Channel
|
|||||||
uint32_t instanceId,
|
uint32_t instanceId,
|
||||||
const VoEBase::ChannelConfig& config);
|
const VoEBase::ChannelConfig& config);
|
||||||
int32_t Init();
|
int32_t Init();
|
||||||
|
void RegisterLegacyReceiveCodecs();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
int32_t SetEngineInformation(Statistics& engineStatistics,
|
int32_t SetEngineInformation(Statistics& engineStatistics,
|
||||||
OutputMixer& outputMixer,
|
OutputMixer& outputMixer,
|
||||||
@ -169,6 +170,8 @@ class Channel
|
|||||||
// go.
|
// go.
|
||||||
const rtc::scoped_refptr<AudioDecoderFactory>& GetAudioDecoderFactory() const;
|
const rtc::scoped_refptr<AudioDecoderFactory>& GetAudioDecoderFactory() const;
|
||||||
|
|
||||||
|
void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs);
|
||||||
|
|
||||||
// API methods
|
// API methods
|
||||||
|
|
||||||
// VoEBase
|
// VoEBase
|
||||||
|
|||||||
@ -171,6 +171,12 @@ void ChannelProxy::SetRecPayloadType(int payload_type,
|
|||||||
RTC_DCHECK_EQ(0, result);
|
RTC_DCHECK_EQ(0, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelProxy::SetReceiveCodecs(
|
||||||
|
const std::map<int, SdpAudioFormat>& codecs) {
|
||||||
|
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||||
|
channel()->SetReceiveCodecs(codecs);
|
||||||
|
}
|
||||||
|
|
||||||
void ChannelProxy::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
|
void ChannelProxy::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
|
||||||
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||||
channel()->SetSink(std::move(sink));
|
channel()->SetSink(std::move(sink));
|
||||||
@ -377,6 +383,11 @@ void ChannelProxy::OnRecoverableUplinkPacketLossRate(
|
|||||||
channel()->OnRecoverableUplinkPacketLossRate(recoverable_packet_loss_rate);
|
channel()->OnRecoverableUplinkPacketLossRate(recoverable_packet_loss_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelProxy::RegisterLegacyReceiveCodecs() {
|
||||||
|
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
||||||
|
channel()->RegisterLegacyReceiveCodecs();
|
||||||
|
}
|
||||||
|
|
||||||
Channel* ChannelProxy::channel() const {
|
Channel* ChannelProxy::channel() const {
|
||||||
RTC_DCHECK(channel_owner_.channel());
|
RTC_DCHECK(channel_owner_.channel());
|
||||||
return channel_owner_.channel();
|
return channel_owner_.channel();
|
||||||
|
|||||||
@ -81,6 +81,7 @@ class ChannelProxy {
|
|||||||
virtual void SetBitrate(int bitrate_bps, int64_t probing_interval_ms);
|
virtual void SetBitrate(int bitrate_bps, int64_t probing_interval_ms);
|
||||||
virtual void SetRecPayloadType(int payload_type,
|
virtual void SetRecPayloadType(int payload_type,
|
||||||
const SdpAudioFormat& format);
|
const SdpAudioFormat& format);
|
||||||
|
virtual void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs);
|
||||||
virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink);
|
virtual void SetSink(std::unique_ptr<AudioSinkInterface> sink);
|
||||||
virtual void SetInputMute(bool muted);
|
virtual void SetInputMute(bool muted);
|
||||||
virtual void RegisterExternalTransport(Transport* transport);
|
virtual void RegisterExternalTransport(Transport* transport);
|
||||||
@ -118,6 +119,7 @@ class ChannelProxy {
|
|||||||
virtual void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate);
|
virtual void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate);
|
||||||
virtual void OnRecoverableUplinkPacketLossRate(
|
virtual void OnRecoverableUplinkPacketLossRate(
|
||||||
float recoverable_packet_loss_rate);
|
float recoverable_packet_loss_rate);
|
||||||
|
virtual void RegisterLegacyReceiveCodecs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Channel* channel() const;
|
Channel* channel() const;
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
#include "webrtc/base/byteorder.h"
|
#include "webrtc/base/byteorder.h"
|
||||||
#include "webrtc/base/timeutils.h"
|
#include "webrtc/base/timeutils.h"
|
||||||
#include "webrtc/system_wrappers/include/sleep.h"
|
#include "webrtc/system_wrappers/include/sleep.h"
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const unsigned int kReflectorSsrc = 0x0000;
|
static const unsigned int kReflectorSsrc = 0x0000;
|
||||||
@ -62,6 +64,9 @@ ConferenceTransport::ConferenceTransport()
|
|||||||
|
|
||||||
EXPECT_EQ(0, local_base_->Init());
|
EXPECT_EQ(0, local_base_->Init());
|
||||||
local_sender_ = local_base_->CreateChannel();
|
local_sender_ = local_base_->CreateChannel();
|
||||||
|
static_cast<webrtc::VoiceEngineImpl*>(local_voe_)
|
||||||
|
->GetChannelProxy(local_sender_)
|
||||||
|
->RegisterLegacyReceiveCodecs();
|
||||||
EXPECT_EQ(0, local_network_->RegisterExternalTransport(local_sender_, *this));
|
EXPECT_EQ(0, local_network_->RegisterExternalTransport(local_sender_, *this));
|
||||||
EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(local_sender_, kLocalSsrc));
|
EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(local_sender_, kLocalSsrc));
|
||||||
EXPECT_EQ(0, local_rtp_rtcp_->
|
EXPECT_EQ(0, local_rtp_rtcp_->
|
||||||
@ -72,6 +77,9 @@ ConferenceTransport::ConferenceTransport()
|
|||||||
|
|
||||||
EXPECT_EQ(0, remote_base_->Init());
|
EXPECT_EQ(0, remote_base_->Init());
|
||||||
reflector_ = remote_base_->CreateChannel();
|
reflector_ = remote_base_->CreateChannel();
|
||||||
|
static_cast<webrtc::VoiceEngineImpl*>(remote_voe_)
|
||||||
|
->GetChannelProxy(reflector_)
|
||||||
|
->RegisterLegacyReceiveCodecs();
|
||||||
EXPECT_EQ(0, remote_network_->RegisterExternalTransport(reflector_, *this));
|
EXPECT_EQ(0, remote_network_->RegisterExternalTransport(reflector_, *this));
|
||||||
EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(reflector_, kReflectorSsrc));
|
EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(reflector_, kReflectorSsrc));
|
||||||
|
|
||||||
@ -222,6 +230,9 @@ void ConferenceTransport::SetRtt(unsigned int rtt_ms) {
|
|||||||
unsigned int ConferenceTransport::AddStream(std::string file_name,
|
unsigned int ConferenceTransport::AddStream(std::string file_name,
|
||||||
webrtc::FileFormats format) {
|
webrtc::FileFormats format) {
|
||||||
const int new_sender = remote_base_->CreateChannel();
|
const int new_sender = remote_base_->CreateChannel();
|
||||||
|
static_cast<webrtc::VoiceEngineImpl*>(remote_voe_)
|
||||||
|
->GetChannelProxy(new_sender)
|
||||||
|
->RegisterLegacyReceiveCodecs();
|
||||||
EXPECT_EQ(0, remote_network_->RegisterExternalTransport(new_sender, *this));
|
EXPECT_EQ(0, remote_network_->RegisterExternalTransport(new_sender, *this));
|
||||||
|
|
||||||
const unsigned int remote_ssrc = kFirstRemoteSsrc + stream_count_++;
|
const unsigned int remote_ssrc = kFirstRemoteSsrc + stream_count_++;
|
||||||
@ -235,6 +246,9 @@ unsigned int ConferenceTransport::AddStream(std::string file_name,
|
|||||||
new_sender, file_name.c_str(), true, false, format, 1.0));
|
new_sender, file_name.c_str(), true, false, format, 1.0));
|
||||||
|
|
||||||
const int new_receiver = local_base_->CreateChannel();
|
const int new_receiver = local_base_->CreateChannel();
|
||||||
|
static_cast<webrtc::VoiceEngineImpl*>(local_voe_)
|
||||||
|
->GetChannelProxy(new_receiver)
|
||||||
|
->RegisterLegacyReceiveCodecs();
|
||||||
EXPECT_EQ(0, local_base_->AssociateSendChannel(new_receiver, local_sender_));
|
EXPECT_EQ(0, local_base_->AssociateSendChannel(new_receiver, local_sender_));
|
||||||
|
|
||||||
EXPECT_EQ(0, local_network_->RegisterExternalTransport(new_receiver, *this));
|
EXPECT_EQ(0, local_network_->RegisterExternalTransport(new_receiver, *this));
|
||||||
|
|||||||
@ -16,5 +16,6 @@ AfterStreamingFixture::AfterStreamingFixture()
|
|||||||
webrtc::VoiceEngineImpl* voe_impl =
|
webrtc::VoiceEngineImpl* voe_impl =
|
||||||
static_cast<webrtc::VoiceEngineImpl*>(voice_engine_);
|
static_cast<webrtc::VoiceEngineImpl*>(voice_engine_);
|
||||||
channel_proxy_ = voe_impl->GetChannelProxy(channel_);
|
channel_proxy_ = voe_impl->GetChannelProxy(channel_);
|
||||||
|
channel_proxy_->RegisterLegacyReceiveCodecs();
|
||||||
ResumePlaying();
|
ResumePlaying();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,9 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
#include "webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h"
|
#include "webrtc/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h"
|
||||||
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
class CodecBeforeStreamingTest : public AfterInitializationFixture {
|
class CodecBeforeStreamingTest : public AfterInitializationFixture {
|
||||||
protected:
|
protected:
|
||||||
@ -19,6 +21,9 @@ class CodecBeforeStreamingTest : public AfterInitializationFixture {
|
|||||||
codec_instance_.pacsize = 480;
|
codec_instance_.pacsize = 480;
|
||||||
|
|
||||||
channel_ = voe_base_->CreateChannel();
|
channel_ = voe_base_->CreateChannel();
|
||||||
|
static_cast<webrtc::VoiceEngineImpl*>(voice_engine_)
|
||||||
|
->GetChannelProxy(channel_)
|
||||||
|
->RegisterLegacyReceiveCodecs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDown() {
|
void TearDown() {
|
||||||
|
|||||||
Reference in New Issue
Block a user