(Auto)update libjingle 66388864-> 66406192
git-svn-id: http://webrtc.googlecode.com/svn/trunk@6072 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
ed97bb0eb4
commit
dd4742a9ef
@ -271,6 +271,7 @@ class FakeWebRtcVideoEngine
|
||||
can_transmit_(true),
|
||||
remote_rtx_ssrc_(-1),
|
||||
rtx_send_payload_type(-1),
|
||||
rtx_recv_payload_type(-1),
|
||||
rtcp_status_(webrtc::kRtcpNone),
|
||||
key_frame_request_method_(webrtc::kViEKeyFrameRequestNone),
|
||||
tmmbr_(false),
|
||||
@ -292,7 +293,8 @@ class FakeWebRtcVideoEngine
|
||||
receive_bandwidth_(0),
|
||||
reserved_transmit_bitrate_bps_(0),
|
||||
suspend_below_min_bitrate_(false),
|
||||
overuse_observer_(NULL) {
|
||||
overuse_observer_(NULL),
|
||||
last_recvd_payload_type_(-1) {
|
||||
ssrcs_[0] = 0; // default ssrc.
|
||||
memset(&send_codec, 0, sizeof(send_codec));
|
||||
memset(&overuse_options_, 0, sizeof(overuse_options_));
|
||||
@ -308,6 +310,7 @@ class FakeWebRtcVideoEngine
|
||||
std::map<int, int> rtx_ssrcs_;
|
||||
int remote_rtx_ssrc_;
|
||||
int rtx_send_payload_type;
|
||||
int rtx_recv_payload_type;
|
||||
std::string cname_;
|
||||
webrtc::ViERTCPMode rtcp_status_;
|
||||
webrtc::ViEKeyFrameRequestMethod key_frame_request_method_;
|
||||
@ -336,6 +339,7 @@ class FakeWebRtcVideoEngine
|
||||
bool suspend_below_min_bitrate_;
|
||||
webrtc::CpuOveruseObserver* overuse_observer_;
|
||||
webrtc::CpuOveruseOptions overuse_options_;
|
||||
int last_recvd_payload_type_;
|
||||
};
|
||||
class Capturer : public webrtc::ViEExternalCapture {
|
||||
public:
|
||||
@ -555,7 +559,9 @@ class FakeWebRtcVideoEngine
|
||||
bool ReceiveCodecRegistered(int channel,
|
||||
const webrtc::VideoCodec& codec) const {
|
||||
WEBRTC_ASSERT_CHANNEL(channel);
|
||||
return true;
|
||||
const std::vector<webrtc::VideoCodec>& codecs =
|
||||
channels_.find(channel)->second->recv_codecs;
|
||||
return std::find(codecs.begin(), codecs.end(), codec) != codecs.end();
|
||||
};
|
||||
bool ExternalDecoderRegistered(int channel,
|
||||
unsigned int pl_type) const {
|
||||
@ -608,6 +614,10 @@ class FakeWebRtcVideoEngine
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
return channels_[channel]->rtx_send_payload_type;
|
||||
}
|
||||
int GetRtxRecvPayloadType(int channel) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
return channels_[channel]->rtx_recv_payload_type;
|
||||
}
|
||||
int GetRemoteRtxSsrc(int channel) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
return channels_.find(channel)->second->remote_rtx_ssrc_;
|
||||
@ -616,6 +626,10 @@ class FakeWebRtcVideoEngine
|
||||
WEBRTC_ASSERT_CHANNEL(channel);
|
||||
return channels_.find(channel)->second->suspend_below_min_bitrate_;
|
||||
}
|
||||
int GetLastRecvdPayloadType(int channel) const {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
return channels_.find(channel)->second->last_recvd_payload_type_;
|
||||
}
|
||||
unsigned int GetReservedTransmitBitrate(int channel) {
|
||||
WEBRTC_ASSERT_CHANNEL(channel);
|
||||
return channels_.find(channel)->second->reserved_transmit_bitrate_bps_;
|
||||
@ -864,8 +878,18 @@ class FakeWebRtcVideoEngine
|
||||
}
|
||||
WEBRTC_STUB(RegisterSendTransport, (const int, webrtc::Transport&));
|
||||
WEBRTC_STUB(DeregisterSendTransport, (const int));
|
||||
WEBRTC_STUB(ReceivedRTPPacket, (const int, const void*, const int,
|
||||
const webrtc::PacketTime&));
|
||||
|
||||
WEBRTC_FUNC(ReceivedRTPPacket, (const int channel,
|
||||
const void* packet,
|
||||
const int length,
|
||||
const webrtc::PacketTime& packet_time)) {
|
||||
WEBRTC_ASSERT_CHANNEL(channel);
|
||||
ASSERT(length > 1);
|
||||
uint8_t payload_type = static_cast<const uint8_t*>(packet)[1] & 0x7F;
|
||||
channels_[channel]->last_recvd_payload_type_ = payload_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBRTC_STUB(ReceivedRTCPPacket, (const int, const void*, const int));
|
||||
// Not using WEBRTC_STUB due to bool return value
|
||||
virtual bool IsIPv6Enabled(int channel) { return true; }
|
||||
@ -975,7 +999,13 @@ class FakeWebRtcVideoEngine
|
||||
channels_[channel]->rtx_send_payload_type = payload_type;
|
||||
return 0;
|
||||
}
|
||||
WEBRTC_STUB(SetRtxReceivePayloadType, (const int, const uint8));
|
||||
|
||||
WEBRTC_FUNC(SetRtxReceivePayloadType, (const int channel,
|
||||
const uint8 payload_type)) {
|
||||
WEBRTC_CHECK_CHANNEL(channel);
|
||||
channels_[channel]->rtx_recv_payload_type = payload_type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBRTC_STUB(SetStartSequenceNumber, (const int, unsigned short));
|
||||
WEBRTC_FUNC(SetRTCPStatus,
|
||||
|
@ -1299,6 +1299,15 @@ bool WebRtcVideoEngine::ConvertFromCricketVideoCodec(
|
||||
}
|
||||
}
|
||||
|
||||
// Is this an RTX codec? Handled separately here since webrtc doesn't handle
|
||||
// them as webrtc::VideoCodec internally.
|
||||
if (!found && _stricmp(in_codec.name.c_str(), kRtxCodecName) == 0) {
|
||||
talk_base::strcpyn(out_codec->plName, sizeof(out_codec->plName),
|
||||
in_codec.name.c_str(), in_codec.name.length());
|
||||
out_codec->plType = in_codec.id;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
LOG(LS_ERROR) << "invalid codec type";
|
||||
return false;
|
||||
@ -1651,12 +1660,17 @@ WebRtcVideoMediaChannel::~WebRtcVideoMediaChannel() {
|
||||
bool WebRtcVideoMediaChannel::SetRecvCodecs(
|
||||
const std::vector<VideoCodec>& codecs) {
|
||||
receive_codecs_.clear();
|
||||
associated_payload_types_.clear();
|
||||
for (std::vector<VideoCodec>::const_iterator iter = codecs.begin();
|
||||
iter != codecs.end(); ++iter) {
|
||||
if (engine()->FindCodec(*iter)) {
|
||||
webrtc::VideoCodec wcodec;
|
||||
if (engine()->ConvertFromCricketVideoCodec(*iter, &wcodec)) {
|
||||
receive_codecs_.push_back(wcodec);
|
||||
int apt;
|
||||
if (iter->GetParam(cricket::kCodecParamAssociatedPayloadType, &apt)) {
|
||||
associated_payload_types_[wcodec.plType] = apt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG(LS_INFO) << "Unknown codec " << iter->name;
|
||||
@ -2036,15 +2050,21 @@ bool WebRtcVideoMediaChannel::AddRecvStream(const StreamParams& sp) {
|
||||
// Early receive added channel.
|
||||
channel_id = (*channel_iterator).second->channel_id();
|
||||
}
|
||||
channel_iterator = recv_channels_.find(sp.first_ssrc());
|
||||
|
||||
// Set the corresponding RTX SSRC.
|
||||
uint32 rtx_ssrc;
|
||||
bool has_rtx = sp.GetFidSsrc(sp.first_ssrc(), &rtx_ssrc);
|
||||
if (has_rtx && engine()->vie()->rtp()->SetRemoteSSRCType(
|
||||
channel_id, webrtc::kViEStreamTypeRtx, rtx_ssrc) != 0) {
|
||||
LOG_RTCERR3(SetRemoteSSRCType, channel_id, webrtc::kViEStreamTypeRtx,
|
||||
rtx_ssrc);
|
||||
return false;
|
||||
if (has_rtx) {
|
||||
LOG(LS_INFO) << "Setting rtx ssrc " << rtx_ssrc << " for stream "
|
||||
<< sp.first_ssrc();
|
||||
if (engine()->vie()->rtp()->SetRemoteSSRCType(
|
||||
channel_id, webrtc::kViEStreamTypeRtx, rtx_ssrc) != 0) {
|
||||
LOG_RTCERR3(SetRemoteSSRCType, channel_id, webrtc::kViEStreamTypeRtx,
|
||||
rtx_ssrc);
|
||||
return false;
|
||||
}
|
||||
rtx_to_primary_ssrc_[rtx_ssrc] = sp.first_ssrc();
|
||||
}
|
||||
|
||||
// Get the default renderer.
|
||||
@ -2102,6 +2122,17 @@ bool WebRtcVideoMediaChannel::RemoveRecvStreamInternal(uint32 ssrc) {
|
||||
return false;
|
||||
}
|
||||
WebRtcVideoChannelRecvInfo* info = it->second;
|
||||
|
||||
// Remove any RTX SSRC mappings to this stream.
|
||||
SsrcMap::iterator rtx_it = rtx_to_primary_ssrc_.begin();
|
||||
while (rtx_it != rtx_to_primary_ssrc_.end()) {
|
||||
if (rtx_it->second == ssrc) {
|
||||
rtx_to_primary_ssrc_.erase(rtx_it++);
|
||||
} else {
|
||||
++rtx_it;
|
||||
}
|
||||
}
|
||||
|
||||
int channel_id = info->channel_id();
|
||||
if (engine()->vie()->render()->RemoveRenderer(channel_id) != 0) {
|
||||
LOG_RTCERR1(RemoveRenderer, channel_id);
|
||||
@ -2695,10 +2726,10 @@ void WebRtcVideoMediaChannel::OnPacketReceived(
|
||||
if (processing_channel == -1) {
|
||||
// Allocate an unsignalled recv channel for processing in conference mode.
|
||||
if (!InConferenceMode()) {
|
||||
// If we cant find or allocate one, use the default.
|
||||
// If we can't find or allocate one, use the default.
|
||||
processing_channel = video_channel();
|
||||
} else if (!CreateUnsignalledRecvChannel(ssrc, &processing_channel)) {
|
||||
// If we cant create an unsignalled recv channel, drop the packet in
|
||||
// If we can't create an unsignalled recv channel, drop the packet in
|
||||
// conference mode.
|
||||
return;
|
||||
}
|
||||
@ -3806,6 +3837,13 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs(
|
||||
int red_type = -1;
|
||||
int fec_type = -1;
|
||||
int channel_id = info->channel_id();
|
||||
// Build a map from payload types to video codecs so that we easily can find
|
||||
// out if associated payload types are referring to valid codecs.
|
||||
std::map<int, webrtc::VideoCodec*> pt_to_codec;
|
||||
for (std::vector<webrtc::VideoCodec>::iterator it = receive_codecs_.begin();
|
||||
it != receive_codecs_.end(); ++it) {
|
||||
pt_to_codec[it->plType] = &(*it);
|
||||
}
|
||||
for (std::vector<webrtc::VideoCodec>::iterator it = receive_codecs_.begin();
|
||||
it != receive_codecs_.end(); ++it) {
|
||||
if (it->codecType == webrtc::kVideoCodecRED) {
|
||||
@ -3813,6 +3851,32 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs(
|
||||
} else if (it->codecType == webrtc::kVideoCodecULPFEC) {
|
||||
fec_type = it->plType;
|
||||
}
|
||||
// If this is an RTX codec we have to verify that it is associated with
|
||||
// a valid video codec which we have RTX support for.
|
||||
if (_stricmp(it->plName, kRtxCodecName) == 0) {
|
||||
std::map<int, int>::iterator apt_it = associated_payload_types_.find(
|
||||
it->plType);
|
||||
bool valid_apt = false;
|
||||
if (apt_it != associated_payload_types_.end()) {
|
||||
std::map<int, webrtc::VideoCodec*>::iterator codec_it =
|
||||
pt_to_codec.find(apt_it->second);
|
||||
// We currently only support RTX associated with VP8 due to limitations
|
||||
// in webrtc where only one RTX payload type can be registered.
|
||||
valid_apt = codec_it != pt_to_codec.end() &&
|
||||
_stricmp(codec_it->second->plName, kVp8PayloadName) == 0;
|
||||
}
|
||||
if (!valid_apt) {
|
||||
LOG(LS_ERROR) << "The RTX codec isn't associated with a known and "
|
||||
"supported payload type";
|
||||
return false;
|
||||
}
|
||||
if (engine()->vie()->rtp()->SetRtxReceivePayloadType(
|
||||
channel_id, it->plType) != 0) {
|
||||
LOG_RTCERR2(SetRtxReceivePayloadType, channel_id, it->plType);
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (engine()->vie()->codec()->SetReceiveCodec(channel_id, *it) != 0) {
|
||||
LOG_RTCERR2(SetReceiveCodec, channel_id, it->plName);
|
||||
return false;
|
||||
@ -3840,8 +3904,20 @@ int WebRtcVideoMediaChannel::GetRecvChannelNum(uint32 ssrc) {
|
||||
if (ssrc == first_receive_ssrc_) {
|
||||
return vie_channel_;
|
||||
}
|
||||
int recv_channel = -1;
|
||||
RecvChannelMap::iterator it = recv_channels_.find(ssrc);
|
||||
return (it != recv_channels_.end()) ? it->second->channel_id() : -1;
|
||||
if (it == recv_channels_.end()) {
|
||||
// Check if we have an RTX stream registered on this SSRC.
|
||||
SsrcMap::iterator rtx_it = rtx_to_primary_ssrc_.find(ssrc);
|
||||
if (rtx_it != rtx_to_primary_ssrc_.end()) {
|
||||
it = recv_channels_.find(rtx_it->second);
|
||||
assert(it != recv_channels_.end());
|
||||
recv_channel = it->second->channel_id();
|
||||
}
|
||||
} else {
|
||||
recv_channel = it->second->channel_id();
|
||||
}
|
||||
return recv_channel;
|
||||
}
|
||||
|
||||
// If the new frame size is different from the send codec size we set on vie,
|
||||
|
@ -201,6 +201,7 @@ class WebRtcVideoEngine : public sigslot::has_slots<>,
|
||||
void SetTraceFilter(int filter);
|
||||
void SetTraceOptions(const std::string& options);
|
||||
bool InitVideoEngine();
|
||||
bool VerifyApt(const VideoCodec& in, int expected_apt) const;
|
||||
|
||||
// webrtc::TraceCallback implementation.
|
||||
virtual void Print(webrtc::TraceLevel level, const char* trace, int length);
|
||||
@ -313,6 +314,7 @@ class WebRtcVideoMediaChannel : public talk_base::MessageHandler,
|
||||
private:
|
||||
typedef std::map<uint32, WebRtcVideoChannelRecvInfo*> RecvChannelMap;
|
||||
typedef std::map<uint32, WebRtcVideoChannelSendInfo*> SendChannelMap;
|
||||
typedef std::map<uint32, uint32> SsrcMap;
|
||||
typedef int (webrtc::ViERTP_RTCP::* ExtensionSetterFunction)(int, bool, int);
|
||||
|
||||
enum MediaDirection { MD_RECV, MD_SEND, MD_SENDRECV };
|
||||
@ -433,7 +435,16 @@ class WebRtcVideoMediaChannel : public talk_base::MessageHandler,
|
||||
// work properly), resides in both recv_channels_ and send_channels_ with the
|
||||
// ssrc key 0.
|
||||
RecvChannelMap recv_channels_; // Contains all receive channels.
|
||||
// A map from the SSRCs on which RTX packets are received to the media SSRCs
|
||||
// the RTX packets are associated with. RTX packets will be delivered to the
|
||||
// streams matching the primary SSRC.
|
||||
SsrcMap rtx_to_primary_ssrc_;
|
||||
std::vector<webrtc::VideoCodec> receive_codecs_;
|
||||
// A map from codec payload types to their associated payload types, if any.
|
||||
// TODO(holmer): This is a temporary solution until webrtc::VideoCodec has
|
||||
// an associated payload type member, when it does we can rely on
|
||||
// receive_codecs_.
|
||||
std::map<int, int> associated_payload_types_;
|
||||
bool render_started_;
|
||||
uint32 first_receive_ssrc_;
|
||||
std::vector<RtpHeaderExtension> receive_extensions_;
|
||||
|
@ -719,6 +719,76 @@ TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) {
|
||||
EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
|
||||
}
|
||||
|
||||
// Test that we set our inbound RTX codecs properly.
|
||||
TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithRtx) {
|
||||
EXPECT_TRUE(SetupEngine());
|
||||
int channel_num = vie_.GetLastChannel();
|
||||
|
||||
std::vector<cricket::VideoCodec> codecs;
|
||||
cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
|
||||
codecs.push_back(rtx_codec);
|
||||
// Should fail since there's no associated payload type set.
|
||||
EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
|
||||
|
||||
codecs[0].SetParam("apt", 97);
|
||||
// Should still fail since the we don't support RTX on this APT.
|
||||
EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
|
||||
|
||||
codecs[0].SetParam("apt", kVP8Codec.id);
|
||||
// Should still fail since the associated payload type is unknown.
|
||||
EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
|
||||
|
||||
codecs.push_back(kVP8Codec);
|
||||
EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
|
||||
|
||||
webrtc::VideoCodec wcodec;
|
||||
// Should not have been registered as a WebRTC codec.
|
||||
EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(rtx_codec, &wcodec));
|
||||
EXPECT_STREQ("rtx", wcodec.plName);
|
||||
EXPECT_FALSE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
|
||||
|
||||
// The RTX payload type should have been set.
|
||||
EXPECT_EQ(rtx_codec.id, vie_.GetRtxRecvPayloadType(channel_num));
|
||||
}
|
||||
|
||||
// Test that RTX packets are routed to the correct video channel.
|
||||
TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtx) {
|
||||
EXPECT_TRUE(SetupEngine());
|
||||
|
||||
// Setup three channels with associated RTX streams.
|
||||
int channel_num[ARRAY_SIZE(kSsrcs3)];
|
||||
for (size_t i = 0; i < ARRAY_SIZE(kSsrcs3); ++i) {
|
||||
cricket::StreamParams params =
|
||||
cricket::StreamParams::CreateLegacy(kSsrcs3[i]);
|
||||
params.AddFidSsrc(kSsrcs3[i], kRtxSsrcs3[i]);
|
||||
EXPECT_TRUE(channel_->AddRecvStream(params));
|
||||
channel_num[i] = vie_.GetLastChannel();
|
||||
}
|
||||
|
||||
// Register codecs.
|
||||
std::vector<cricket::VideoCodec> codec_list;
|
||||
codec_list.push_back(kVP8Codec720p);
|
||||
cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
|
||||
rtx_codec.SetParam("apt", kVP8Codec.id);
|
||||
codec_list.push_back(rtx_codec);
|
||||
EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
|
||||
|
||||
// Construct a fake RTX packet and verify that it is passed to the
|
||||
// right WebRTC channel.
|
||||
const size_t kDataLength = 12;
|
||||
uint8_t data[kDataLength];
|
||||
memset(data, 0, sizeof(data));
|
||||
data[0] = 0x80;
|
||||
data[1] = rtx_codec.id;
|
||||
talk_base::SetBE32(&data[8], kRtxSsrcs3[1]);
|
||||
talk_base::Buffer packet(data, kDataLength);
|
||||
talk_base::PacketTime packet_time;
|
||||
channel_->OnPacketReceived(&packet, packet_time);
|
||||
EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[0]));
|
||||
EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[1]));
|
||||
EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[2]));
|
||||
}
|
||||
|
||||
// Test that channel connects and disconnects external capturer correctly.
|
||||
TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) {
|
||||
EXPECT_TRUE(SetupEngine());
|
||||
@ -2053,6 +2123,7 @@ TEST_F(WebRtcVideoEngineTest, FindCodec) {
|
||||
EXPECT_TRUE(engine_.FindCodec(fec));
|
||||
|
||||
cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
|
||||
rtx.SetParam("apt", kVP8Codec.id);
|
||||
EXPECT_TRUE(engine_.FindCodec(rtx));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user