Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: talk/session/media/channel.cc

Issue 1363573002: Wire up transport sequence number / send time callbacks to webrtc via libjingle. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: . Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2004 Google Inc. 3 * Copyright 2004 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 enabled_(false), 184 enabled_(false),
185 writable_(false), 185 writable_(false),
186 rtp_ready_to_send_(false), 186 rtp_ready_to_send_(false),
187 rtcp_ready_to_send_(false), 187 rtcp_ready_to_send_(false),
188 was_ever_writable_(false), 188 was_ever_writable_(false),
189 local_content_direction_(MD_INACTIVE), 189 local_content_direction_(MD_INACTIVE),
190 remote_content_direction_(MD_INACTIVE), 190 remote_content_direction_(MD_INACTIVE),
191 has_received_packet_(false), 191 has_received_packet_(false),
192 dtls_keyed_(false), 192 dtls_keyed_(false),
193 secure_required_(false), 193 secure_required_(false),
194 rtp_abs_sendtime_extn_id_(-1) { 194 rtp_abs_sendtime_extn_id_(-1),
195 rtp_transport_sequence_number_extn_id_(-1) {
195 ASSERT(worker_thread_ == rtc::Thread::Current()); 196 ASSERT(worker_thread_ == rtc::Thread::Current());
196 LOG(LS_INFO) << "Created channel for " << content_name; 197 LOG(LS_INFO) << "Created channel for " << content_name;
197 } 198 }
198 199
199 BaseChannel::~BaseChannel() { 200 BaseChannel::~BaseChannel() {
200 ASSERT(worker_thread_ == rtc::Thread::Current()); 201 ASSERT(worker_thread_ == rtc::Thread::Current());
201 Deinit(); 202 Deinit();
202 StopConnectionMonitor(); 203 StopConnectionMonitor();
203 FlushRtcpMessages(); // Send any outstanding RTCP packets. 204 FlushRtcpMessages(); // Send any outstanding RTCP packets.
204 worker_thread_->Clear(this); // eats any outstanding messages or packets 205 worker_thread_->Clear(this); // eats any outstanding messages or packets
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 // setting new channel 337 // setting new channel
337 UpdateWritableState_w(); 338 UpdateWritableState_w();
338 SetReadyToSend(true, new_tc && new_tc->writable()); 339 SetReadyToSend(true, new_tc && new_tc->writable());
339 } 340 }
340 341
341 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { 342 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) {
342 ASSERT(worker_thread_ == rtc::Thread::Current()); 343 ASSERT(worker_thread_ == rtc::Thread::Current());
343 344
344 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); 345 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState);
345 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); 346 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead);
347 tc->SignalSentPacket.connect(this, &BaseChannel::OnPacketSent);
346 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); 348 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend);
347 } 349 }
348 350
349 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { 351 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) {
350 ASSERT(worker_thread_ == rtc::Thread::Current()); 352 ASSERT(worker_thread_ == rtc::Thread::Current());
351 353
352 tc->SignalWritableState.disconnect(this); 354 tc->SignalWritableState.disconnect(this);
353 tc->SignalReadPacket.disconnect(this); 355 tc->SignalReadPacket.disconnect(this);
354 tc->SignalReadyToSend.disconnect(this); 356 tc->SignalReadyToSend.disconnect(this);
355 } 357 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine 472 // OnChannelRead gets called from P2PSocket; now pass data to MediaEngine
471 ASSERT(worker_thread_ == rtc::Thread::Current()); 473 ASSERT(worker_thread_ == rtc::Thread::Current());
472 474
473 // When using RTCP multiplexing we might get RTCP packets on the RTP 475 // When using RTCP multiplexing we might get RTCP packets on the RTP
474 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. 476 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP.
475 bool rtcp = PacketIsRtcp(channel, data, len); 477 bool rtcp = PacketIsRtcp(channel, data, len);
476 rtc::Buffer packet(data, len); 478 rtc::Buffer packet(data, len);
477 HandlePacket(rtcp, &packet, packet_time); 479 HandlePacket(rtcp, &packet, packet_time);
478 } 480 }
479 481
482 void BaseChannel::OnPacketSent(TransportChannel* channel,
483 const rtc::SentPacket& packet_sent) {
484 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
485 if (channel == transport_channel_) {
486 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.
487 }
488 }
489
480 void BaseChannel::OnReadyToSend(TransportChannel* channel) { 490 void BaseChannel::OnReadyToSend(TransportChannel* channel) {
481 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); 491 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_);
482 SetReadyToSend(channel == rtcp_transport_channel_, true); 492 SetReadyToSend(channel == rtcp_transport_channel_, true);
483 } 493 }
484 494
485 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { 495 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) {
486 if (rtcp) { 496 if (rtcp) {
487 rtcp_ready_to_send_ = ready; 497 rtcp_ready_to_send_ = ready;
488 } else { 498 } else {
489 rtp_ready_to_send_ = ready; 499 rtp_ready_to_send_ = ready;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 // inside libsrtp for a RTP packet. A external HMAC module will be writing 564 // inside libsrtp for a RTP packet. A external HMAC module will be writing
555 // a fake HMAC value. This is ONLY done for a RTP packet. 565 // a fake HMAC value. This is ONLY done for a RTP packet.
556 // Socket layer will update rtp sendtime extension header if present in 566 // Socket layer will update rtp sendtime extension header if present in
557 // packet with current time before updating the HMAC. 567 // packet with current time before updating the HMAC.
558 #if !defined(ENABLE_EXTERNAL_AUTH) 568 #if !defined(ENABLE_EXTERNAL_AUTH)
559 res = srtp_filter_.ProtectRtp( 569 res = srtp_filter_.ProtectRtp(
560 data, len, static_cast<int>(packet->capacity()), &len); 570 data, len, static_cast<int>(packet->capacity()), &len);
561 #else 571 #else
562 options.packet_time_params.rtp_sendtime_extension_id = 572 options.packet_time_params.rtp_sendtime_extension_id =
563 rtp_abs_sendtime_extn_id_; 573 rtp_abs_sendtime_extn_id_;
574 options.transport_sequence_number =
575 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.
564 res = srtp_filter_.ProtectRtp( 576 res = srtp_filter_.ProtectRtp(
565 data, len, static_cast<int>(packet->capacity()), &len, 577 data, len, static_cast<int>(packet->capacity()), &len,
566 &options.packet_time_params.srtp_packet_index); 578 &options.packet_time_params.srtp_packet_index);
567 // If protection succeeds, let's get auth params from srtp. 579 // If protection succeeds, let's get auth params from srtp.
568 if (res) { 580 if (res) {
569 uint8* auth_key = NULL; 581 uint8* auth_key = NULL;
570 int key_len; 582 int key_len;
571 res = srtp_filter_.GetRtpAuthParams( 583 res = srtp_filter_.GetRtpAuthParams(
572 &auth_key, &key_len, &options.packet_time_params.srtp_auth_tag_len); 584 &auth_key, &key_len, &options.packet_time_params.srtp_auth_tag_len);
573 if (res) { 585 if (res) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (ret != static_cast<int>(packet->size())) { 630 if (ret != static_cast<int>(packet->size())) {
619 if (channel->GetError() == EWOULDBLOCK) { 631 if (channel->GetError() == EWOULDBLOCK) {
620 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket."; 632 LOG(LS_WARNING) << "Got EWOULDBLOCK from socket.";
621 SetReadyToSend(rtcp, false); 633 SetReadyToSend(rtcp, false);
622 } 634 }
623 return false; 635 return false;
624 } 636 }
625 return true; 637 return true;
626 } 638 }
627 639
640 int32_t BaseChannel::ParseTransportSequenceNumberHeaderExtension(
641 uint8_t* data,
642 size_t length) const {
643 // 0 1 2 3
644 // 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
645 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
646 // |V=2|P|X| CC |M| PT | sequence number |
647 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
648 // | timestamp |
649 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
650 // | synchronization source (SSRC) identifier |
651 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
652 // | contributing source (CSRC) identifiers |
653 // | .... |
654 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
655
656 // Return if extension bit is not set.
657 if (!(data[0] & 0x10)) {
658 return -1;
659 }
660
661 size_t cc_count = data[0] & 0x0F;
662 const size_t kMinRtpHeaderLength = 12;
663 size_t header_length_without_extension = kMinRtpHeaderLength + 4 * cc_count;
664
665 data += header_length_without_extension;
666
667 // Getting extension profile ID and length.
668 uint16 profile_id = rtc::GetBE16(data);
669 // Length is in 32 bit words.
670 uint16 extension_length_in_32bits = rtc::GetBE16(data + 2);
671 size_t extension_length = extension_length_in_32bits * 4;
672
673 const size_t kRtpExtensionHeaderLength = 4;
674 data += kRtpExtensionHeaderLength; // Moving past extension header.
675
676 int32_t transport_sequence_number = -1;
677 // The transport sequence number is a one byte header extension.
678 if (profile_id == 0xBEDE) { // One byte extension header.
679 // 0
680 // 0 1 2 3 4 5 6 7
681 // +-+-+-+-+-+-+-+-+
682 // | ID |length |
683 // +-+-+-+-+-+-+-+-+
684
685 // 0 1 2 3
686 // 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
687 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
688 // | 0xBE | 0xDE | length=3 |
689 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
690 // | ID | L=0 | data | ID | L=1 | data...
691 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
692 // ...data | 0 (pad) | 0 (pad) | ID | L=3 |
693 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
694 // | data |
695 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
696 const uint8_t* extension_start = data;
697 const uint8_t* extension_end = extension_start + extension_length;
698
699 while (data < extension_end) {
700 const int id = (*data & 0xF0) >> 4;
701 const size_t length = (*data & 0x0F) + 1;
702 const size_t kOneByteHeaderLength = 1;
703 if (data + kOneByteHeaderLength + length > extension_end) {
704 break;
705 }
706 // The 4-bit length is the number minus one of data bytes of this header
707 // extension element following the one-byte header.
708 if (id == rtp_transport_sequence_number_extn_id_) {
709 transport_sequence_number = rtc::GetBE24(data + kOneByteHeaderLength);
710 break;
711 }
712 data += kOneByteHeaderLength + length;
713 // Counting padding bytes.
714 while ((data < extension_end) && (*data == 0)) {
715 ++data;
716 }
717 }
718 }
719 return transport_sequence_number;
720 }
721
628 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) { 722 bool BaseChannel::WantsPacket(bool rtcp, rtc::Buffer* packet) {
629 // Protect ourselves against crazy data. 723 // Protect ourselves against crazy data.
630 if (!ValidPacket(rtcp, packet)) { 724 if (!ValidPacket(rtcp, packet)) {
631 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " 725 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " "
632 << PacketType(rtcp) 726 << PacketType(rtcp)
633 << " packet: wrong size=" << packet->size(); 727 << " packet: wrong size=" << packet->size();
634 return false; 728 return false;
635 } 729 }
636 730
637 // Bundle filter handles both rtp and rtcp packets. 731 // Bundle filter handles both rtp and rtcp packets.
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 desc << "Failed to add remote stream ssrc: " << it->first_ssrc(); 1326 desc << "Failed to add remote stream ssrc: " << it->first_ssrc();
1233 SafeSetError(desc.str(), error_desc); 1327 SafeSetError(desc.str(), error_desc);
1234 ret = false; 1328 ret = false;
1235 } 1329 }
1236 } 1330 }
1237 } 1331 }
1238 remote_streams_ = streams; 1332 remote_streams_ = streams;
1239 return ret; 1333 return ret;
1240 } 1334 }
1241 1335
1242 void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( 1336 void BaseChannel::MaybeCacheRtpHeaderExtensions(
1243 const std::vector<RtpHeaderExtension>& extensions) { 1337 const std::vector<RtpHeaderExtension>& extensions) {
1244 const RtpHeaderExtension* send_time_extension = 1338 const RtpHeaderExtension* send_time_extension =
1245 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); 1339 FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
1246 rtp_abs_sendtime_extn_id_ = 1340 rtp_abs_sendtime_extn_id_ =
1247 send_time_extension ? send_time_extension->id : -1; 1341 send_time_extension ? send_time_extension->id : -1;
1342
1343 const RtpHeaderExtension* transport_sequence_number = FindHeaderExtension(
1344 extensions, kRtpTransportSequenceNumberHeaderExtension);
1345 rtp_transport_sequence_number_extn_id_ =
1346 transport_sequence_number ? transport_sequence_number->id : -1;
1248 } 1347 }
1249 1348
1250 void BaseChannel::OnMessage(rtc::Message *pmsg) { 1349 void BaseChannel::OnMessage(rtc::Message *pmsg) {
1251 switch (pmsg->message_id) { 1350 switch (pmsg->message_id) {
1252 case MSG_RTPPACKET: 1351 case MSG_RTPPACKET:
1253 case MSG_RTCPPACKET: { 1352 case MSG_RTCPPACKET: {
1254 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata); 1353 PacketMessageData* data = static_cast<PacketMessageData*>(pmsg->pdata);
1255 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet, data->dscp); 1354 SendPacket(pmsg->message_id == MSG_RTCPPACKET, &data->packet, data->dscp);
1256 delete data; // because it is Posted 1355 delete data; // because it is Posted
1257 break; 1356 break;
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 // TODO(pthatcher): Move remote streams into AudioRecvParameters, 1630 // TODO(pthatcher): Move remote streams into AudioRecvParameters,
1532 // and only give it to the media channel once we have a local 1631 // and only give it to the media channel once we have a local
1533 // description too (without a local description, we won't be able to 1632 // description too (without a local description, we won't be able to
1534 // recv them anyway). 1633 // recv them anyway).
1535 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) { 1634 if (!UpdateRemoteStreams_w(audio->streams(), action, error_desc)) {
1536 SafeSetError("Failed to set remote audio description streams.", error_desc); 1635 SafeSetError("Failed to set remote audio description streams.", error_desc);
1537 return false; 1636 return false;
1538 } 1637 }
1539 1638
1540 if (audio->rtp_header_extensions_set()) { 1639 if (audio->rtp_header_extensions_set()) {
1541 MaybeCacheRtpAbsSendTimeHeaderExtension(audio->rtp_header_extensions()); 1640 MaybeCacheRtpHeaderExtensions(audio->rtp_header_extensions());
1542 } 1641 }
1543 1642
1544 set_remote_content_direction(content->direction()); 1643 set_remote_content_direction(content->direction());
1545 ChangeState(); 1644 ChangeState();
1546 return true; 1645 return true;
1547 } 1646 }
1548 1647
1549 void VoiceChannel::HandleEarlyMediaTimeout() { 1648 void VoiceChannel::HandleEarlyMediaTimeout() {
1550 // This occurs on the main thread, not the worker thread. 1649 // This occurs on the main thread, not the worker thread.
1551 if (!received_media_) { 1650 if (!received_media_) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 // TODO(pthatcher): Move remote streams into VideoRecvParameters, 1956 // TODO(pthatcher): Move remote streams into VideoRecvParameters,
1858 // and only give it to the media channel once we have a local 1957 // and only give it to the media channel once we have a local
1859 // description too (without a local description, we won't be able to 1958 // description too (without a local description, we won't be able to
1860 // recv them anyway). 1959 // recv them anyway).
1861 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) { 1960 if (!UpdateRemoteStreams_w(video->streams(), action, error_desc)) {
1862 SafeSetError("Failed to set remote video description streams.", error_desc); 1961 SafeSetError("Failed to set remote video description streams.", error_desc);
1863 return false; 1962 return false;
1864 } 1963 }
1865 1964
1866 if (video->rtp_header_extensions_set()) { 1965 if (video->rtp_header_extensions_set()) {
1867 MaybeCacheRtpAbsSendTimeHeaderExtension(video->rtp_header_extensions()); 1966 MaybeCacheRtpHeaderExtensions(video->rtp_header_extensions());
1868 } 1967 }
1869 1968
1870 set_remote_content_direction(content->direction()); 1969 set_remote_content_direction(content->direction());
1871 ChangeState(); 1970 ChangeState();
1872 return true; 1971 return true;
1873 } 1972 }
1874 1973
1875 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) { 1974 bool VideoChannel::ApplyViewRequest_w(const ViewRequest& request) {
1876 bool ret = true; 1975 bool ret = true;
1877 // Set the send format for each of the local streams. If the view request 1976 // Set the send format for each of the local streams. If the view request
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 return (data_channel_type_ == DCT_RTP); 2502 return (data_channel_type_ == DCT_RTP);
2404 } 2503 }
2405 2504
2406 void DataChannel::OnStreamClosedRemotely(uint32 sid) { 2505 void DataChannel::OnStreamClosedRemotely(uint32 sid) {
2407 rtc::TypedMessageData<uint32>* message = 2506 rtc::TypedMessageData<uint32>* message =
2408 new rtc::TypedMessageData<uint32>(sid); 2507 new rtc::TypedMessageData<uint32>(sid);
2409 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); 2508 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message);
2410 } 2509 }
2411 2510
2412 } // namespace cricket 2511 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698