Index: talk/session/media/channel.cc |
diff --git a/talk/session/media/channel.cc b/talk/session/media/channel.cc |
index 5a6b7e198f16cb8380790e82d4eda8bc958e4c2a..9e4cc3ff9f37a22228b6b13c5dfa9cff9adf1958 100644 |
--- a/talk/session/media/channel.cc |
+++ b/talk/session/media/channel.cc |
@@ -191,7 +191,8 @@ BaseChannel::BaseChannel(rtc::Thread* thread, |
has_received_packet_(false), |
dtls_keyed_(false), |
secure_required_(false), |
- rtp_abs_sendtime_extn_id_(-1) { |
+ rtp_abs_sendtime_extn_id_(-1), |
+ rtp_transport_sequence_number_extn_id_(-1) { |
ASSERT(worker_thread_ == rtc::Thread::Current()); |
LOG(LS_INFO) << "Created channel for " << content_name; |
} |
@@ -343,6 +344,7 @@ void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
+ tc->SignalSentPacket.connect(this, &BaseChannel::OnPacketSent); |
tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
} |
@@ -477,6 +479,14 @@ void BaseChannel::OnChannelRead(TransportChannel* channel, |
HandlePacket(rtcp, &packet, packet_time); |
} |
+void BaseChannel::OnPacketSent(TransportChannel* channel, |
+ const rtc::SentPacket& packet_sent) { |
+ ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
+ if (channel == transport_channel_) { |
+ media_channel_->OnPacketSent(packet_sent); |
pthatcher1
2015/09/25 23:24:57
This means that all 3 channels (audio, video, and
stefan-webrtc
2015/09/28 12:10:49
That would be nicer. I'll look into it.
|
+ } |
+} |
+ |
void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
SetReadyToSend(channel == rtcp_transport_channel_, true); |
@@ -561,6 +571,8 @@ bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, |
#else |
options.packet_time_params.rtp_sendtime_extension_id = |
rtp_abs_sendtime_extn_id_; |
+ options.transport_sequence_number = |
+ ParseTransportSequenceNumberHeaderExtension(data, len); |
pthatcher1
2015/09/25 23:24:57
I really think is the wrong place for this. It wo
stefan-webrtc
2015/09/28 12:10:50
Yes, I definitely agree that it would make more se
stefan-webrtc
2015/10/02 13:29:12
Done.
|
res = srtp_filter_.ProtectRtp( |
data, len, static_cast<int>(packet->capacity()), &len, |
&options.packet_time_params.srtp_packet_index); |
@@ -625,6 +637,88 @@ bool BaseChannel::SendPacket(bool rtcp, rtc::Buffer* packet, |
return true; |
} |
+int32_t BaseChannel::ParseTransportSequenceNumberHeaderExtension( |
+ uint8_t* data, |
+ size_t length) const { |
+ // 0 1 2 3 |
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // |V=2|P|X| CC |M| PT | sequence number | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | timestamp | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | synchronization source (SSRC) identifier | |
+ // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
+ // | contributing source (CSRC) identifiers | |
+ // | .... | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ |
+ // Return if extension bit is not set. |
+ if (!(data[0] & 0x10)) { |
+ return -1; |
+ } |
+ |
+ size_t cc_count = data[0] & 0x0F; |
+ const size_t kMinRtpHeaderLength = 12; |
+ size_t header_length_without_extension = kMinRtpHeaderLength + 4 * cc_count; |
+ |
+ data += header_length_without_extension; |
+ |
+ // Getting extension profile ID and length. |
+ uint16 profile_id = rtc::GetBE16(data); |
+ // Length is in 32 bit words. |
+ uint16 extension_length_in_32bits = rtc::GetBE16(data + 2); |
+ size_t extension_length = extension_length_in_32bits * 4; |
+ |
+ const size_t kRtpExtensionHeaderLength = 4; |
+ data += kRtpExtensionHeaderLength; // Moving past extension header. |
+ |
+ int32_t transport_sequence_number = -1; |
+ // The transport sequence number is a one byte header extension. |
+ if (profile_id == 0xBEDE) { // One byte extension header. |
+ // 0 |
+ // 0 1 2 3 4 5 6 7 |
+ // +-+-+-+-+-+-+-+-+ |
+ // | ID |length | |
+ // +-+-+-+-+-+-+-+-+ |
+ |
+ // 0 1 2 3 |
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | 0xBE | 0xDE | length=3 | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | ID | L=0 | data | ID | L=1 | data... |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // ...data | 0 (pad) | 0 (pad) | ID | L=3 | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | data | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ const uint8_t* extension_start = data; |
+ const uint8_t* extension_end = extension_start + extension_length; |
+ |
+ while (data < extension_end) { |
+ const int id = (*data & 0xF0) >> 4; |
+ const size_t length = (*data & 0x0F) + 1; |
+ const size_t kOneByteHeaderLength = 1; |
+ if (data + kOneByteHeaderLength + length > extension_end) { |
+ break; |
+ } |
+ // The 4-bit length is the number minus one of data bytes of this header |
+ // extension element following the one-byte header. |
+ if (id == rtp_transport_sequence_number_extn_id_) { |
+ transport_sequence_number = rtc::GetBE24(data + kOneByteHeaderLength); |
+ break; |
+ } |
+ data += kOneByteHeaderLength + length; |
+ // Counting padding bytes. |
+ while ((data < extension_end) && (*data == 0)) { |
+ ++data; |
+ } |
+ } |
+ } |
+ return transport_sequence_number; |
+} |
+ |
bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { |
// Protect ourselves against crazy data. |
if (!ValidPacket(rtcp, packet)) { |
@@ -1239,12 +1333,17 @@ bool BaseChannel::UpdateRemoteStreams_w( |
return ret; |
} |
-void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( |
+void BaseChannel::MaybeCacheRtpHeaderExtensions( |
const std::vector<RtpHeaderExtension>& extensions) { |
const RtpHeaderExtension* send_time_extension = |
FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); |
rtp_abs_sendtime_extn_id_ = |
send_time_extension ? send_time_extension->id : -1; |
+ |
+ const RtpHeaderExtension* transport_sequence_number = FindHeaderExtension( |
+ extensions, kRtpTransportSequenceNumberHeaderExtension); |
+ rtp_transport_sequence_number_extn_id_ = |
+ transport_sequence_number ? transport_sequence_number->id : -1; |
} |
void BaseChannel::OnMessage(rtc::Message *pmsg) { |
@@ -1538,7 +1637,7 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content, |
} |
if (audio->rtp_header_extensions_set()) { |
- MaybeCacheRtpAbsSendTimeHeaderExtension(audio->rtp_header_extensions()); |
+ MaybeCacheRtpHeaderExtensions(audio->rtp_header_extensions()); |
} |
set_remote_content_direction(content->direction()); |
@@ -1864,7 +1963,7 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content, |
} |
if (video->rtp_header_extensions_set()) { |
- MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); |
+ MaybeCacheRtpHeaderExtensions(video->rtp_header_extensions()); |
} |
set_remote_content_direction(content->direction()); |