Bug 1231507 - Part 1: selectSsrc chrome-only API for SSRC-based filtering of receive tracks. r=drno, r=smaug

This commit is contained in:
Byron Campen [:bwc] 2015-12-09 15:37:38 -05:00
parent c5916ac016
commit 805ab6b140
11 changed files with 77 additions and 23 deletions

View File

@ -1108,6 +1108,10 @@ RTCPeerConnection.prototype = {
return this._receivers;
},
mozSelectSsrc: function(receiver, ssrcIndex) {
this._impl.selectSsrc(receiver.track, ssrcIndex);
},
get localDescription() {
this._checkClosed();
let sdp = this._impl.localDescription;

View File

@ -57,6 +57,8 @@ interface PeerConnectionImpl {
sequence<MediaStream> getLocalStreams();
sequence<MediaStream> getRemoteStreams();
void selectSsrc(MediaStreamTrack recvTrack, unsigned short ssrcIndex);
/* As the ICE candidates roll in this one should be called each time
* in order to keep the candidate list up-to-date for the next SDP-related
* call PeerConnectionImpl does not parse ICE candidates, just sticks them

View File

@ -137,6 +137,9 @@ interface RTCPeerConnection : EventTarget {
sequence<RTCRtpSender> getSenders();
sequence<RTCRtpReceiver> getReceivers();
[ChromeOnly]
void mozSelectSsrc(RTCRtpReceiver receiver, unsigned short ssrcIndex);
void close ();
attribute EventHandler onnegotiationneeded;
attribute EventHandler onicecandidate;

View File

@ -189,6 +189,30 @@ MediaPipeline::UpdateTransport_s(int level,
}
}
void
MediaPipeline::SelectSsrc_m(size_t ssrc_index)
{
RUN_ON_THREAD(sts_thread_,
WrapRunnable(
this,
&MediaPipeline::SelectSsrc_s,
ssrc_index),
NS_DISPATCH_NORMAL);
}
void
MediaPipeline::SelectSsrc_s(size_t ssrc_index)
{
filter_ = new MediaPipelineFilter;
if (ssrc_index < ssrcs_received_.size()) {
filter_->AddRemoteSSRC(ssrcs_received_[ssrc_index]);
} else {
MOZ_MTLOG(ML_WARNING, "SelectSsrc called with " << ssrc_index << " but we "
<< "have only seen " << ssrcs_received_.size()
<< " ssrcs");
}
}
void MediaPipeline::StateChange(TransportFlow *flow, TransportLayer::State state) {
TransportInfo* info = GetTransportInfo_s(flow);
MOZ_ASSERT(info);
@ -474,12 +498,18 @@ void MediaPipeline::RtpPacketReceived(TransportLayer *layer,
return;
}
if (filter_) {
webrtc::RTPHeader header;
if (!rtp_parser_->Parse(data, len, &header) ||
!filter_->Filter(header)) {
return;
}
webrtc::RTPHeader header;
if (!rtp_parser_->Parse(data, len, &header)) {
return;
}
if (std::find(ssrcs_received_.begin(), ssrcs_received_.end(), header.ssrc) ==
ssrcs_received_.end()) {
ssrcs_received_.push_back(header.ssrc);
}
if (filter_ && !filter_->Filter(header)) {
return;
}
// Make a copy rather than cast away constness

View File

@ -143,6 +143,11 @@ class MediaPipeline : public sigslot::has_slots<> {
RefPtr<TransportFlow> rtcp_transport,
nsAutoPtr<MediaPipelineFilter> filter);
// Used only for testing; installs a MediaPipelineFilter that filters
// everything but the nth ssrc
void SelectSsrc_m(size_t ssrc_index);
void SelectSsrc_s(size_t ssrc_index);
virtual Direction direction() const { return direction_; }
virtual const std::string& trackid() const { return track_id_; }
virtual int level() const { return level_; }
@ -288,6 +293,8 @@ class MediaPipeline : public sigslot::has_slots<> {
int64_t rtp_bytes_sent_;
int64_t rtp_bytes_received_;
std::vector<uint32_t> ssrcs_received_;
// Written on Init. Read on STS thread.
std::string pc_;
std::string description_;

View File

@ -47,10 +47,6 @@ bool MediaPipelineFilter::Filter(const webrtc::RTPHeader& header,
return false;
}
void MediaPipelineFilter::AddLocalSSRC(uint32_t ssrc) {
local_ssrc_set_.insert(ssrc);
}
void MediaPipelineFilter::AddRemoteSSRC(uint32_t ssrc) {
remote_ssrc_set_.insert(ssrc);
}
@ -71,7 +67,6 @@ void MediaPipelineFilter::Update(const MediaPipelineFilter& filter_update) {
remote_ssrc_set_ = filter_update.remote_ssrc_set_;
}
local_ssrc_set_ = filter_update.local_ssrc_set_;
payload_type_set_ = filter_update.payload_type_set_;
correlator_ = filter_update.correlator_;
}

View File

@ -56,7 +56,6 @@ class MediaPipelineFilter {
// payload types too.
bool FilterSenderReport(const unsigned char* data, size_t len) const;
void AddLocalSSRC(uint32_t ssrc);
void AddRemoteSSRC(uint32_t ssrc);
// When a payload type id is unique to our media section, add it here.
@ -78,7 +77,6 @@ class MediaPipelineFilter {
// The number of filters we manage here is quite small, so I am optimizing
// for readability.
std::set<uint32_t> remote_ssrc_set_;
std::set<uint32_t> local_ssrc_set_;
std::set<uint8_t> payload_type_set_;
};

View File

@ -347,13 +347,6 @@ MediaPipelineFactory::GetTransportParameters(
for (auto i = uniquePts.begin(); i != uniquePts.end(); ++i) {
(*aFilterOut)->AddUniquePT(*i);
}
} else {
// Add local SSRCs so we can distinguish which RTCP packets actually
// belong to this pipeline.
for (auto i = aTrack.GetSsrcs().begin();
i != aTrack.GetSsrcs().end(); ++i) {
(*aFilterOut)->AddLocalSSRC(*i);
}
}
}

View File

@ -2214,6 +2214,24 @@ PeerConnectionImpl::AddTrack(MediaStreamTrack& aTrack,
return NS_OK;
}
nsresult
PeerConnectionImpl::SelectSsrc(MediaStreamTrack& aRecvTrack,
unsigned short aSsrcIndex)
{
for (size_t i = 0; i < mMedia->RemoteStreamsLength(); ++i) {
if (mMedia->GetRemoteStreamByIndex(i)->GetMediaStream()->
HasTrack(aRecvTrack)) {
auto& pipelines = mMedia->GetRemoteStreamByIndex(i)->GetPipelines();
std::string trackId = PeerConnectionImpl::GetTrackId(aRecvTrack);
auto it = pipelines.find(trackId);
if (it != pipelines.end()) {
it->second->SelectSsrc_m(aSsrcIndex);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::RemoveTrack(MediaStreamTrack& aTrack) {
PC_AUTO_ENTER_API_CALL(true);

View File

@ -468,6 +468,13 @@ public:
GetParameters(dom::MediaStreamTrack& aTrack,
std::vector<JsepTrack::JsConstraints>* aOutConstraints);
NS_IMETHODIMP_TO_ERRORRESULT(SelectSsrc, ErrorResult &rv,
dom::MediaStreamTrack& aRecvTrack,
unsigned short aSsrcIndex)
{
rv = SelectSsrc(aRecvTrack, aSsrcIndex);
}
nsresult GetPeerIdentity(nsAString& peerIdentity)
{
#if !defined(MOZILLA_EXTERNAL_LINKAGE)

View File

@ -561,7 +561,6 @@ TEST_F(MediaPipelineFilterTest, TestFilterReport0CountTruncated) {
TEST_F(MediaPipelineFilterTest, TestFilterReport1SSRCTruncated) {
MediaPipelineFilter filter;
filter.AddRemoteSSRC(16);
filter.AddLocalSSRC(17);
const unsigned char sr[] = {
RTCP_TYPEINFO(1, MediaPipelineFilter::SENDER_REPORT_T, 12),
REPORT_FRAGMENT(16),
@ -573,7 +572,6 @@ TEST_F(MediaPipelineFilterTest, TestFilterReport1SSRCTruncated) {
TEST_F(MediaPipelineFilterTest, TestFilterReport1BigSSRC) {
MediaPipelineFilter filter;
filter.AddRemoteSSRC(0x01020304);
filter.AddLocalSSRC(0x11121314);
const unsigned char sr[] = {
RTCP_TYPEINFO(1, MediaPipelineFilter::SENDER_REPORT_T, 12),
SSRC(0x01020304),
@ -598,7 +596,6 @@ TEST_F(MediaPipelineFilterTest, TestFilterReportNoMatch) {
TEST_F(MediaPipelineFilterTest, TestFilterUnknownRTCPType) {
MediaPipelineFilter filter;
filter.AddLocalSSRC(18);
ASSERT_FALSE(filter.FilterSenderReport(unknown_type, sizeof(unknown_type)));
}