Chromium Code Reviews| 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()); |