OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 bool RTPSender::ActivateCVORtpHeaderExtension() { | 441 bool RTPSender::ActivateCVORtpHeaderExtension() { |
442 if (!video_rotation_active_) { | 442 if (!video_rotation_active_) { |
443 rtc::CritScope lock(&send_critsect_); | 443 rtc::CritScope lock(&send_critsect_); |
444 if (rtp_header_extension_map_.SetActive(kRtpExtensionVideoRotation, true)) { | 444 if (rtp_header_extension_map_.SetActive(kRtpExtensionVideoRotation, true)) { |
445 video_rotation_active_ = true; | 445 video_rotation_active_ = true; |
446 } | 446 } |
447 } | 447 } |
448 return video_rotation_active_; | 448 return video_rotation_active_; |
449 } | 449 } |
450 | 450 |
451 int32_t RTPSender::SendOutgoingData(FrameType frame_type, | 451 bool RTPSender::SendOutgoingData(FrameType frame_type, |
452 int8_t payload_type, | 452 int8_t payload_type, |
453 uint32_t capture_timestamp, | 453 uint32_t capture_timestamp, |
454 int64_t capture_time_ms, | 454 int64_t capture_time_ms, |
455 const uint8_t* payload_data, | 455 const uint8_t* payload_data, |
456 size_t payload_size, | 456 size_t payload_size, |
457 const RTPFragmentationHeader* fragmentation, | 457 const RTPFragmentationHeader* fragmentation, |
458 const RTPVideoHeader* rtp_hdr) { | 458 const RTPVideoHeader* rtp_header, |
| 459 uint32_t* transport_frame_id_out) { |
459 uint32_t ssrc; | 460 uint32_t ssrc; |
460 uint16_t sequence_number; | 461 uint16_t sequence_number; |
461 { | 462 { |
462 // Drop this packet if we're not sending media packets. | 463 // Drop this packet if we're not sending media packets. |
463 rtc::CritScope lock(&send_critsect_); | 464 rtc::CritScope lock(&send_critsect_); |
464 ssrc = ssrc_; | 465 ssrc = ssrc_; |
465 sequence_number = sequence_number_; | 466 sequence_number = sequence_number_; |
466 if (!sending_media_) { | 467 if (!sending_media_) |
467 return 0; | 468 return true; |
468 } | |
469 } | 469 } |
470 RtpVideoCodecTypes video_type = kRtpVideoGeneric; | 470 RtpVideoCodecTypes video_type = kRtpVideoGeneric; |
471 if (CheckPayloadType(payload_type, &video_type) != 0) { | 471 if (CheckPayloadType(payload_type, &video_type) != 0) { |
472 LOG(LS_ERROR) << "Don't send data with unknown payload type: " | 472 LOG(LS_ERROR) << "Don't send data with unknown payload type: " |
473 << static_cast<int>(payload_type) << "."; | 473 << static_cast<int>(payload_type) << "."; |
474 return -1; | 474 return false; |
475 } | 475 } |
476 | 476 |
477 int32_t ret_val; | 477 bool result; |
478 if (audio_configured_) { | 478 if (audio_configured_) { |
479 TRACE_EVENT_ASYNC_STEP1("webrtc", "Audio", capture_timestamp, | 479 TRACE_EVENT_ASYNC_STEP1("webrtc", "Audio", capture_timestamp, |
480 "Send", "type", FrameTypeToString(frame_type)); | 480 "Send", "type", FrameTypeToString(frame_type)); |
481 assert(frame_type == kAudioFrameSpeech || frame_type == kAudioFrameCN || | 481 assert(frame_type == kAudioFrameSpeech || frame_type == kAudioFrameCN || |
482 frame_type == kEmptyFrame); | 482 frame_type == kEmptyFrame); |
483 | 483 |
484 ret_val = audio_->SendAudio(frame_type, payload_type, capture_timestamp, | 484 result = audio_->SendAudio(frame_type, payload_type, capture_timestamp, |
485 payload_data, payload_size, fragmentation); | 485 payload_data, payload_size, fragmentation); |
486 } else { | 486 } else { |
487 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, | 487 TRACE_EVENT_ASYNC_STEP1("webrtc", "Video", capture_time_ms, |
488 "Send", "type", FrameTypeToString(frame_type)); | 488 "Send", "type", FrameTypeToString(frame_type)); |
489 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN); | 489 assert(frame_type != kAudioFrameSpeech && frame_type != kAudioFrameCN); |
490 | 490 |
491 if (frame_type == kEmptyFrame) | 491 if (frame_type == kEmptyFrame) |
492 return 0; | 492 return true; |
493 | 493 |
494 if (rtp_hdr) { | 494 if (rtp_header) { |
495 playout_delay_oracle_.UpdateRequest(ssrc, rtp_hdr->playout_delay, | 495 playout_delay_oracle_.UpdateRequest(ssrc, rtp_header->playout_delay, |
496 sequence_number); | 496 sequence_number); |
497 } | 497 } |
498 | 498 |
499 // Update the active/inactive status of playout delay extension based | 499 // Update the active/inactive status of playout delay extension based |
500 // on what the oracle indicates. | 500 // on what the oracle indicates. |
501 { | 501 { |
502 rtc::CritScope lock(&send_critsect_); | 502 rtc::CritScope lock(&send_critsect_); |
503 if (playout_delay_active_ != playout_delay_oracle_.send_playout_delay()) { | 503 if (playout_delay_active_ != playout_delay_oracle_.send_playout_delay()) { |
504 playout_delay_active_ = playout_delay_oracle_.send_playout_delay(); | 504 playout_delay_active_ = playout_delay_oracle_.send_playout_delay(); |
505 rtp_header_extension_map_.SetActive(kRtpExtensionPlayoutDelay, | 505 rtp_header_extension_map_.SetActive(kRtpExtensionPlayoutDelay, |
506 playout_delay_active_); | 506 playout_delay_active_); |
507 } | 507 } |
508 } | 508 } |
509 | 509 |
510 ret_val = video_->SendVideo( | 510 result = video_->SendVideo(video_type, frame_type, payload_type, |
511 video_type, frame_type, payload_type, capture_timestamp, | 511 capture_timestamp, capture_time_ms, payload_data, |
512 capture_time_ms, payload_data, payload_size, fragmentation, rtp_hdr); | 512 payload_size, fragmentation, rtp_header); |
| 513 } |
| 514 |
| 515 if (transport_frame_id_out) { |
| 516 rtc::CritScope lock(&send_critsect_); |
| 517 // TODO(sergeyu): Move RTP timestamp calculation from BuildRTPheader() to |
| 518 // SendOutgoingData() and pass it to SendVideo()/SendAudio() calls. |
| 519 *transport_frame_id_out = timestamp_; |
513 } | 520 } |
514 | 521 |
515 rtc::CritScope cs(&statistics_crit_); | 522 rtc::CritScope cs(&statistics_crit_); |
516 // Note: This is currently only counting for video. | 523 // Note: This is currently only counting for video. |
517 if (frame_type == kVideoFrameKey) { | 524 if (frame_type == kVideoFrameKey) { |
518 ++frame_counts_.key_frames; | 525 ++frame_counts_.key_frames; |
519 } else if (frame_type == kVideoFrameDelta) { | 526 } else if (frame_type == kVideoFrameDelta) { |
520 ++frame_counts_.delta_frames; | 527 ++frame_counts_.delta_frames; |
521 } | 528 } |
522 if (frame_count_observer_) { | 529 if (frame_count_observer_) { |
523 frame_count_observer_->FrameCountUpdated(frame_counts_, ssrc); | 530 frame_count_observer_->FrameCountUpdated(frame_counts_, ssrc); |
524 } | 531 } |
525 | 532 |
526 return ret_val; | 533 return result; |
527 } | 534 } |
528 | 535 |
529 size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send, | 536 size_t RTPSender::TrySendRedundantPayloads(size_t bytes_to_send, |
530 int probe_cluster_id) { | 537 int probe_cluster_id) { |
531 { | 538 { |
532 rtc::CritScope lock(&send_critsect_); | 539 rtc::CritScope lock(&send_critsect_); |
533 if (!sending_media_) | 540 if (!sending_media_) |
534 return 0; | 541 return 0; |
535 if ((rtx_ & kRtxRedundantPayloads) == 0) | 542 if ((rtx_ & kRtxRedundantPayloads) == 0) |
536 return 0; | 543 return 0; |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 if (audio_configured_ || bytes == 0) | 945 if (audio_configured_ || bytes == 0) |
939 return 0; | 946 return 0; |
940 size_t bytes_sent = TrySendRedundantPayloads(bytes, probe_cluster_id); | 947 size_t bytes_sent = TrySendRedundantPayloads(bytes, probe_cluster_id); |
941 if (bytes_sent < bytes) | 948 if (bytes_sent < bytes) |
942 bytes_sent += | 949 bytes_sent += |
943 SendPadData(bytes - bytes_sent, false, 0, 0, probe_cluster_id); | 950 SendPadData(bytes - bytes_sent, false, 0, 0, probe_cluster_id); |
944 return bytes_sent; | 951 return bytes_sent; |
945 } | 952 } |
946 | 953 |
947 // TODO(pwestin): send in the RtpHeaderParser to avoid parsing it again. | 954 // TODO(pwestin): send in the RtpHeaderParser to avoid parsing it again. |
948 int32_t RTPSender::SendToNetwork(uint8_t* buffer, | 955 bool RTPSender::SendToNetwork(uint8_t* buffer, |
949 size_t payload_length, | 956 size_t payload_length, |
950 size_t rtp_header_length, | 957 size_t rtp_header_length, |
951 int64_t capture_time_ms, | 958 int64_t capture_time_ms, |
952 StorageType storage, | 959 StorageType storage, |
953 RtpPacketSender::Priority priority) { | 960 RtpPacketSender::Priority priority) { |
954 size_t length = payload_length + rtp_header_length; | 961 size_t length = payload_length + rtp_header_length; |
955 RtpUtility::RtpHeaderParser rtp_parser(buffer, length); | 962 RtpUtility::RtpHeaderParser rtp_parser(buffer, length); |
956 | 963 |
957 RTPHeader rtp_header; | 964 RTPHeader rtp_header; |
958 rtp_parser.Parse(&rtp_header); | 965 rtp_parser.Parse(&rtp_header); |
959 | 966 |
960 int64_t now_ms = clock_->TimeInMilliseconds(); | 967 int64_t now_ms = clock_->TimeInMilliseconds(); |
961 | 968 |
962 // |capture_time_ms| <= 0 is considered invalid. | 969 // |capture_time_ms| <= 0 is considered invalid. |
963 // TODO(holmer): This should be changed all over Video Engine so that negative | 970 // TODO(holmer): This should be changed all over Video Engine so that negative |
964 // time is consider invalid, while 0 is considered a valid time. | 971 // time is consider invalid, while 0 is considered a valid time. |
965 if (capture_time_ms > 0) { | 972 if (capture_time_ms > 0) { |
966 UpdateTransmissionTimeOffset(buffer, length, rtp_header, | 973 UpdateTransmissionTimeOffset(buffer, length, rtp_header, |
967 now_ms - capture_time_ms); | 974 now_ms - capture_time_ms); |
968 } | 975 } |
969 | 976 |
970 UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms); | 977 UpdateAbsoluteSendTime(buffer, length, rtp_header, now_ms); |
971 | 978 |
972 // Used for NACK and to spread out the transmission of packets. | 979 // Used for NACK and to spread out the transmission of packets. |
973 if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) != | 980 if (packet_history_.PutRTPPacket(buffer, length, capture_time_ms, storage) != |
974 0) { | 981 0) { |
975 return -1; | 982 return false; |
976 } | 983 } |
977 | 984 |
978 if (paced_sender_) { | 985 if (paced_sender_) { |
979 // Correct offset between implementations of millisecond time stamps in | 986 // Correct offset between implementations of millisecond time stamps in |
980 // TickTime and Clock. | 987 // TickTime and Clock. |
981 int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_; | 988 int64_t corrected_time_ms = capture_time_ms + clock_delta_ms_; |
982 paced_sender_->InsertPacket(priority, rtp_header.ssrc, | 989 paced_sender_->InsertPacket(priority, rtp_header.ssrc, |
983 rtp_header.sequenceNumber, corrected_time_ms, | 990 rtp_header.sequenceNumber, corrected_time_ms, |
984 payload_length, false); | 991 payload_length, false); |
985 if (last_capture_time_ms_sent_ == 0 || | 992 if (last_capture_time_ms_sent_ == 0 || |
986 corrected_time_ms > last_capture_time_ms_sent_) { | 993 corrected_time_ms > last_capture_time_ms_sent_) { |
987 last_capture_time_ms_sent_ = corrected_time_ms; | 994 last_capture_time_ms_sent_ = corrected_time_ms; |
988 TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 995 TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
989 "PacedSend", corrected_time_ms, | 996 "PacedSend", corrected_time_ms, |
990 "capture_time_ms", corrected_time_ms); | 997 "capture_time_ms", corrected_time_ms); |
991 } | 998 } |
992 return 0; | 999 return true; |
993 } | 1000 } |
994 | 1001 |
995 PacketOptions options; | 1002 PacketOptions options; |
996 if (UpdateTransportSequenceNumber(buffer, length, rtp_header, | 1003 if (UpdateTransportSequenceNumber(buffer, length, rtp_header, |
997 &options.packet_id)) { | 1004 &options.packet_id)) { |
998 if (transport_feedback_observer_) | 1005 if (transport_feedback_observer_) |
999 transport_feedback_observer_->AddPacket(options.packet_id, length, | 1006 transport_feedback_observer_->AddPacket(options.packet_id, length, |
1000 PacketInfo::kNotAProbe); | 1007 PacketInfo::kNotAProbe); |
1001 } | 1008 } |
1002 UpdateDelayStatistics(capture_time_ms, now_ms); | 1009 UpdateDelayStatistics(capture_time_ms, now_ms); |
1003 UpdateOnSendPacket(options.packet_id, capture_time_ms, rtp_header.ssrc); | 1010 UpdateOnSendPacket(options.packet_id, capture_time_ms, rtp_header.ssrc); |
1004 | 1011 |
1005 bool sent = SendPacketToNetwork(buffer, length, options); | 1012 bool sent = SendPacketToNetwork(buffer, length, options); |
1006 | 1013 |
1007 // Mark the packet as sent in the history even if send failed. Dropping a | 1014 // Mark the packet as sent in the history even if send failed. Dropping a |
1008 // packet here should be treated as any other packet drop so we should be | 1015 // packet here should be treated as any other packet drop so we should be |
1009 // ready for a retransmission. | 1016 // ready for a retransmission. |
1010 packet_history_.SetSent(rtp_header.sequenceNumber); | 1017 packet_history_.SetSent(rtp_header.sequenceNumber); |
1011 | 1018 |
1012 if (!sent) | 1019 if (!sent) |
1013 return -1; | 1020 return false; |
1014 | 1021 |
1015 { | 1022 { |
1016 rtc::CritScope lock(&send_critsect_); | 1023 rtc::CritScope lock(&send_critsect_); |
1017 media_has_been_sent_ = true; | 1024 media_has_been_sent_ = true; |
1018 } | 1025 } |
1019 UpdateRtpStats(buffer, length, rtp_header, false, false); | 1026 UpdateRtpStats(buffer, length, rtp_header, false, false); |
1020 return 0; | 1027 return true; |
1021 } | 1028 } |
1022 | 1029 |
1023 void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { | 1030 void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { |
1024 if (!send_side_delay_observer_ || capture_time_ms <= 0) | 1031 if (!send_side_delay_observer_ || capture_time_ms <= 0) |
1025 return; | 1032 return; |
1026 | 1033 |
1027 uint32_t ssrc; | 1034 uint32_t ssrc; |
1028 int avg_delay_ms = 0; | 1035 int avg_delay_ms = 0; |
1029 int max_delay_ms = 0; | 1036 int max_delay_ms = 0; |
1030 { | 1037 { |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 rtc::CritScope lock(&send_critsect_); | 1901 rtc::CritScope lock(&send_critsect_); |
1895 | 1902 |
1896 RtpState state; | 1903 RtpState state; |
1897 state.sequence_number = sequence_number_rtx_; | 1904 state.sequence_number = sequence_number_rtx_; |
1898 state.start_timestamp = start_timestamp_; | 1905 state.start_timestamp = start_timestamp_; |
1899 | 1906 |
1900 return state; | 1907 return state; |
1901 } | 1908 } |
1902 | 1909 |
1903 } // namespace webrtc | 1910 } // namespace webrtc |
OLD | NEW |