| 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 |
| 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h" |
| 12 | 12 |
| 13 #include <stdlib.h> | 13 #include <stdlib.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 | 15 |
| 16 #include <memory> | 16 #include <memory> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/base/trace_event.h" | 21 #include "webrtc/base/trace_event.h" |
| 22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 23 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 24 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" | 24 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" |
| 25 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" | 25 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" |
| 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" | 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" |
| 27 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" | 27 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" |
| 28 | 28 |
| 29 namespace webrtc { | 29 namespace webrtc { |
| 30 |
| 30 enum { REDForFECHeaderLength = 1 }; | 31 enum { REDForFECHeaderLength = 1 }; |
| 31 | 32 |
| 32 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) | 33 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtp_sender) |
| 33 : _rtpSender(*rtpSender), | 34 : rtp_sender_(rtp_sender), |
| 34 clock_(clock), | 35 clock_(clock), |
| 35 _videoType(kRtpVideoGeneric), | |
| 36 _retransmissionSettings(kRetransmitBaseLayer), | |
| 37 // Generic FEC | 36 // Generic FEC |
| 38 fec_(), | |
| 39 fec_enabled_(false), | |
| 40 red_payload_type_(0), | |
| 41 fec_payload_type_(0), | |
| 42 delta_fec_params_(), | |
| 43 key_fec_params_(), | |
| 44 producer_fec_(&fec_), | 37 producer_fec_(&fec_), |
| 45 fec_bitrate_(1000, RateStatistics::kBpsScale), | 38 fec_bitrate_(1000, RateStatistics::kBpsScale), |
| 46 video_bitrate_(1000, RateStatistics::kBpsScale) { | 39 video_bitrate_(1000, RateStatistics::kBpsScale) {} |
| 47 memset(&delta_fec_params_, 0, sizeof(delta_fec_params_)); | |
| 48 memset(&key_fec_params_, 0, sizeof(key_fec_params_)); | |
| 49 delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1; | |
| 50 delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type = | |
| 51 kFecMaskRandom; | |
| 52 } | |
| 53 | 40 |
| 54 RTPSenderVideo::~RTPSenderVideo() { | 41 RTPSenderVideo::~RTPSenderVideo() {} |
| 55 } | |
| 56 | 42 |
| 57 void RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes videoType) { | 43 void RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes video_type) { |
| 58 _videoType = videoType; | 44 video_type_ = video_type; |
| 59 } | 45 } |
| 60 | 46 |
| 61 RtpVideoCodecTypes RTPSenderVideo::VideoCodecType() const { | 47 RtpVideoCodecTypes RTPSenderVideo::VideoCodecType() const { |
| 62 return _videoType; | 48 return video_type_; |
| 63 } | 49 } |
| 64 | 50 |
| 65 // Static. | 51 // Static. |
| 66 RtpUtility::Payload* RTPSenderVideo::CreateVideoPayload( | 52 RtpUtility::Payload* RTPSenderVideo::CreateVideoPayload( |
| 67 const char payloadName[RTP_PAYLOAD_NAME_SIZE], | 53 const char payload_name[RTP_PAYLOAD_NAME_SIZE], |
| 68 const int8_t payloadType) { | 54 int8_t payload_type) { |
| 69 RtpVideoCodecTypes videoType = kRtpVideoGeneric; | 55 RtpVideoCodecTypes video_type = kRtpVideoGeneric; |
| 70 if (RtpUtility::StringCompare(payloadName, "VP8", 3)) { | 56 if (RtpUtility::StringCompare(payload_name, "VP8", 3)) { |
| 71 videoType = kRtpVideoVp8; | 57 video_type = kRtpVideoVp8; |
| 72 } else if (RtpUtility::StringCompare(payloadName, "VP9", 3)) { | 58 } else if (RtpUtility::StringCompare(payload_name, "VP9", 3)) { |
| 73 videoType = kRtpVideoVp9; | 59 video_type = kRtpVideoVp9; |
| 74 } else if (RtpUtility::StringCompare(payloadName, "H264", 4)) { | 60 } else if (RtpUtility::StringCompare(payload_name, "H264", 4)) { |
| 75 videoType = kRtpVideoH264; | 61 video_type = kRtpVideoH264; |
| 76 } else if (RtpUtility::StringCompare(payloadName, "I420", 4)) { | 62 } else if (RtpUtility::StringCompare(payload_name, "I420", 4)) { |
| 77 videoType = kRtpVideoGeneric; | 63 video_type = kRtpVideoGeneric; |
| 78 } else { | 64 } else { |
| 79 videoType = kRtpVideoGeneric; | 65 video_type = kRtpVideoGeneric; |
| 80 } | 66 } |
| 81 RtpUtility::Payload* payload = new RtpUtility::Payload(); | 67 RtpUtility::Payload* payload = new RtpUtility::Payload(); |
| 82 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; | 68 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; |
| 83 strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); | 69 strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1); |
| 84 payload->typeSpecific.Video.videoCodecType = videoType; | 70 payload->typeSpecific.Video.videoCodecType = video_type; |
| 85 payload->audio = false; | 71 payload->audio = false; |
| 86 return payload; | 72 return payload; |
| 87 } | 73 } |
| 88 | 74 |
| 89 void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, | 75 void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, |
| 90 const size_t payload_length, | 76 size_t payload_length, |
| 91 const size_t rtp_header_length, | 77 size_t rtp_header_length, |
| 92 uint16_t seq_num, | 78 uint16_t seq_num, |
| 93 const uint32_t capture_timestamp, | 79 uint32_t capture_timestamp, |
| 94 int64_t capture_time_ms, | 80 int64_t capture_time_ms, |
| 95 StorageType storage) { | 81 StorageType storage) { |
| 96 if (_rtpSender.SendToNetwork(data_buffer, payload_length, rtp_header_length, | 82 if (rtp_sender_->SendToNetwork(data_buffer, payload_length, rtp_header_length, |
| 97 capture_time_ms, storage, | 83 capture_time_ms, storage, |
| 98 RtpPacketSender::kLowPriority) == 0) { | 84 RtpPacketSender::kLowPriority) == 0) { |
| 99 rtc::CritScope cs(&stats_crit_); | 85 rtc::CritScope cs(&stats_crit_); |
| 100 video_bitrate_.Update(payload_length + rtp_header_length, | 86 video_bitrate_.Update(payload_length + rtp_header_length, |
| 101 clock_->TimeInMilliseconds()); | 87 clock_->TimeInMilliseconds()); |
| 102 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 88 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 103 "Video::PacketNormal", "timestamp", capture_timestamp, | 89 "Video::PacketNormal", "timestamp", capture_timestamp, |
| 104 "seqnum", seq_num); | 90 "seqnum", seq_num); |
| 105 } else { | 91 } else { |
| 106 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; | 92 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; |
| 107 } | 93 } |
| 108 } | 94 } |
| 109 | 95 |
| 110 void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer, | 96 void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer, |
| 111 const size_t payload_length, | 97 size_t payload_length, |
| 112 const size_t rtp_header_length, | 98 size_t rtp_header_length, |
| 113 uint16_t media_seq_num, | 99 uint16_t media_seq_num, |
| 114 const uint32_t capture_timestamp, | 100 uint32_t capture_timestamp, |
| 115 int64_t capture_time_ms, | 101 int64_t capture_time_ms, |
| 116 StorageType media_packet_storage, | 102 StorageType media_packet_storage, |
| 117 bool protect) { | 103 bool protect) { |
| 118 std::unique_ptr<RedPacket> red_packet; | 104 std::unique_ptr<RedPacket> red_packet; |
| 119 std::vector<RedPacket*> fec_packets; | 105 std::vector<RedPacket*> fec_packets; |
| 120 StorageType fec_storage = kDontRetransmit; | 106 StorageType fec_storage = kDontRetransmit; |
| 121 uint16_t next_fec_sequence_number = 0; | 107 uint16_t next_fec_sequence_number = 0; |
| 122 { | 108 { |
| 123 // Only protect while creating RED and FEC packets, not when sending. | 109 // Only protect while creating RED and FEC packets, not when sending. |
| 124 rtc::CritScope cs(&crit_); | 110 rtc::CritScope cs(&crit_); |
| 125 red_packet.reset(producer_fec_.BuildRedPacket( | 111 red_packet.reset(producer_fec_.BuildRedPacket( |
| 126 data_buffer, payload_length, rtp_header_length, red_payload_type_)); | 112 data_buffer, payload_length, rtp_header_length, red_payload_type_)); |
| 127 if (protect) { | 113 if (protect) { |
| 128 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, | 114 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, |
| 129 rtp_header_length); | 115 rtp_header_length); |
| 130 } | 116 } |
| 131 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 117 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); |
| 132 if (num_fec_packets > 0) { | 118 if (num_fec_packets > 0) { |
| 133 next_fec_sequence_number = | 119 next_fec_sequence_number = |
| 134 _rtpSender.AllocateSequenceNumber(num_fec_packets); | 120 rtp_sender_->AllocateSequenceNumber(num_fec_packets); |
| 135 fec_packets = producer_fec_.GetFecPackets( | 121 fec_packets = producer_fec_.GetFecPackets( |
| 136 red_payload_type_, fec_payload_type_, next_fec_sequence_number, | 122 red_payload_type_, fec_payload_type_, next_fec_sequence_number, |
| 137 rtp_header_length); | 123 rtp_header_length); |
| 138 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 124 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); |
| 139 if (_retransmissionSettings & kRetransmitFECPackets) | 125 if (retransmission_settings_ & kRetransmitFECPackets) |
| 140 fec_storage = kAllowRetransmission; | 126 fec_storage = kAllowRetransmission; |
| 141 } | 127 } |
| 142 } | 128 } |
| 143 if (_rtpSender.SendToNetwork( | 129 if (rtp_sender_->SendToNetwork( |
| 144 red_packet->data(), red_packet->length() - rtp_header_length, | 130 red_packet->data(), red_packet->length() - rtp_header_length, |
| 145 rtp_header_length, capture_time_ms, media_packet_storage, | 131 rtp_header_length, capture_time_ms, media_packet_storage, |
| 146 RtpPacketSender::kLowPriority) == 0) { | 132 RtpPacketSender::kLowPriority) == 0) { |
| 147 rtc::CritScope cs(&stats_crit_); | 133 rtc::CritScope cs(&stats_crit_); |
| 148 video_bitrate_.Update(red_packet->length(), clock_->TimeInMilliseconds()); | 134 video_bitrate_.Update(red_packet->length(), clock_->TimeInMilliseconds()); |
| 149 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 135 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 150 "Video::PacketRed", "timestamp", capture_timestamp, | 136 "Video::PacketRed", "timestamp", capture_timestamp, |
| 151 "seqnum", media_seq_num); | 137 "seqnum", media_seq_num); |
| 152 } else { | 138 } else { |
| 153 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; | 139 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; |
| 154 } | 140 } |
| 155 for (RedPacket* fec_packet : fec_packets) { | 141 for (RedPacket* fec_packet : fec_packets) { |
| 156 if (_rtpSender.SendToNetwork( | 142 if (rtp_sender_->SendToNetwork( |
| 157 fec_packet->data(), fec_packet->length() - rtp_header_length, | 143 fec_packet->data(), fec_packet->length() - rtp_header_length, |
| 158 rtp_header_length, capture_time_ms, fec_storage, | 144 rtp_header_length, capture_time_ms, fec_storage, |
| 159 RtpPacketSender::kLowPriority) == 0) { | 145 RtpPacketSender::kLowPriority) == 0) { |
| 160 rtc::CritScope cs(&stats_crit_); | 146 rtc::CritScope cs(&stats_crit_); |
| 161 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 147 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); |
| 162 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 148 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 163 "Video::PacketFec", "timestamp", capture_timestamp, | 149 "Video::PacketFec", "timestamp", capture_timestamp, |
| 164 "seqnum", next_fec_sequence_number); | 150 "seqnum", next_fec_sequence_number); |
| 165 } else { | 151 } else { |
| 166 LOG(LS_WARNING) << "Failed to send FEC packet " | 152 LOG(LS_WARNING) << "Failed to send FEC packet " |
| 167 << next_fec_sequence_number; | 153 << next_fec_sequence_number; |
| 168 } | 154 } |
| 169 delete fec_packet; | 155 delete fec_packet; |
| 170 ++next_fec_sequence_number; | 156 ++next_fec_sequence_number; |
| 171 } | 157 } |
| 172 } | 158 } |
| 173 | 159 |
| 174 void RTPSenderVideo::SetGenericFECStatus(const bool enable, | 160 void RTPSenderVideo::SetGenericFECStatus(bool enable, |
| 175 const uint8_t payloadTypeRED, | 161 uint8_t payload_type_red, |
| 176 const uint8_t payloadTypeFEC) { | 162 uint8_t payload_type_fec) { |
| 177 RTC_DCHECK(!enable || payloadTypeRED > 0); | 163 RTC_DCHECK(!enable || payload_type_red > 0); |
| 178 rtc::CritScope cs(&crit_); | 164 rtc::CritScope cs(&crit_); |
| 179 fec_enabled_ = enable; | 165 fec_enabled_ = enable; |
| 180 red_payload_type_ = payloadTypeRED; | 166 red_payload_type_ = payload_type_red; |
| 181 fec_payload_type_ = payloadTypeFEC; | 167 fec_payload_type_ = payload_type_fec; |
| 182 memset(&delta_fec_params_, 0, sizeof(delta_fec_params_)); | 168 delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
| 183 memset(&key_fec_params_, 0, sizeof(key_fec_params_)); | 169 key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
| 184 delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1; | |
| 185 delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type = | |
| 186 kFecMaskRandom; | |
| 187 } | 170 } |
| 188 | 171 |
| 189 void RTPSenderVideo::GenericFECStatus(bool* enable, | 172 void RTPSenderVideo::GenericFECStatus(bool* enable, |
| 190 uint8_t* payloadTypeRED, | 173 uint8_t* payload_type_red, |
| 191 uint8_t* payloadTypeFEC) const { | 174 uint8_t* payload_type_fec) const { |
| 192 rtc::CritScope cs(&crit_); | 175 rtc::CritScope cs(&crit_); |
| 193 *enable = fec_enabled_; | 176 *enable = fec_enabled_; |
| 194 *payloadTypeRED = red_payload_type_; | 177 *payload_type_red = red_payload_type_; |
| 195 *payloadTypeFEC = fec_payload_type_; | 178 *payload_type_fec = fec_payload_type_; |
| 196 } | 179 } |
| 197 | 180 |
| 198 size_t RTPSenderVideo::FECPacketOverhead() const { | 181 size_t RTPSenderVideo::FECPacketOverhead() const { |
| 199 rtc::CritScope cs(&crit_); | 182 rtc::CritScope cs(&crit_); |
| 200 size_t overhead = 0; | 183 size_t overhead = 0; |
| 201 if (red_payload_type_ != 0) { | 184 if (red_payload_type_ != 0) { |
| 202 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 185 // Overhead is FEC headers plus RED for FEC header plus anything in RTP |
| 203 // header beyond the 12 bytes base header (CSRC list, extensions...) | 186 // header beyond the 12 bytes base header (CSRC list, extensions...) |
| 204 // This reason for the header extensions to be included here is that | 187 // This reason for the header extensions to be included here is that |
| 205 // from an FEC viewpoint, they are part of the payload to be protected. | 188 // from an FEC viewpoint, they are part of the payload to be protected. |
| 206 // (The base RTP header is already protected by the FEC header.) | 189 // (The base RTP header is already protected by the FEC header.) |
| 207 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + | 190 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + |
| 208 (_rtpSender.RtpHeaderLength() - kRtpHeaderSize); | 191 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); |
| 209 } | 192 } |
| 210 if (fec_enabled_) | 193 if (fec_enabled_) |
| 211 overhead += ForwardErrorCorrection::PacketOverhead(); | 194 overhead += ForwardErrorCorrection::PacketOverhead(); |
| 212 return overhead; | 195 return overhead; |
| 213 } | 196 } |
| 214 | 197 |
| 215 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, | 198 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, |
| 216 const FecProtectionParams* key_params) { | 199 const FecProtectionParams* key_params) { |
| 217 rtc::CritScope cs(&crit_); | 200 rtc::CritScope cs(&crit_); |
| 218 RTC_DCHECK(delta_params); | 201 RTC_DCHECK(delta_params); |
| 219 RTC_DCHECK(key_params); | 202 RTC_DCHECK(key_params); |
| 220 if (fec_enabled_) { | 203 if (fec_enabled_) { |
| 221 delta_fec_params_ = *delta_params; | 204 delta_fec_params_ = *delta_params; |
| 222 key_fec_params_ = *key_params; | 205 key_fec_params_ = *key_params; |
| 223 } | 206 } |
| 224 } | 207 } |
| 225 | 208 |
| 226 int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, | 209 int32_t RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
| 227 const FrameType frameType, | 210 FrameType frame_type, |
| 228 const int8_t payloadType, | 211 int8_t payload_type, |
| 229 const uint32_t captureTimeStamp, | 212 uint32_t capture_timestamp, |
| 230 int64_t capture_time_ms, | 213 int64_t capture_time_ms, |
| 231 const uint8_t* payloadData, | 214 const uint8_t* payload_data, |
| 232 const size_t payloadSize, | 215 size_t payload_size, |
| 233 const RTPFragmentationHeader* fragmentation, | 216 const RTPFragmentationHeader* fragmentation, |
| 234 const RTPVideoHeader* video_header) { | 217 const RTPVideoHeader* video_header) { |
| 235 if (payloadSize == 0) { | 218 if (payload_size == 0) { |
| 236 return -1; | 219 return -1; |
| 237 } | 220 } |
| 238 | 221 |
| 239 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 222 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 240 videoType, _rtpSender.MaxDataPayloadLength(), | 223 video_type, rtp_sender_->MaxDataPayloadLength(), |
| 241 video_header ? &(video_header->codecHeader) : nullptr, frameType)); | 224 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); |
| 242 | 225 |
| 243 StorageType storage; | 226 StorageType storage; |
| 244 int red_payload_type; | 227 int red_payload_type; |
| 245 bool first_frame = first_frame_sent_(); | 228 bool first_frame = first_frame_sent_(); |
| 246 { | 229 { |
| 247 rtc::CritScope cs(&crit_); | 230 rtc::CritScope cs(&crit_); |
| 248 FecProtectionParams* fec_params = | 231 FecProtectionParams* fec_params = |
| 249 frameType == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 232 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; |
| 250 producer_fec_.SetFecParameters(fec_params, 0); | 233 producer_fec_.SetFecParameters(fec_params, 0); |
| 251 storage = packetizer->GetStorageType(_retransmissionSettings); | 234 storage = packetizer->GetStorageType(retransmission_settings_); |
| 252 red_payload_type = red_payload_type_; | 235 red_payload_type = red_payload_type_; |
| 253 } | 236 } |
| 254 | 237 |
| 255 // Register CVO rtp header extension at the first time when we receive a frame | 238 // Register CVO rtp header extension at the first time when we receive a frame |
| 256 // with pending rotation. | 239 // with pending rotation. |
| 257 bool video_rotation_active = false; | 240 bool video_rotation_active = false; |
| 258 if (video_header && video_header->rotation != kVideoRotation_0) { | 241 if (video_header && video_header->rotation != kVideoRotation_0) { |
| 259 video_rotation_active = _rtpSender.ActivateCVORtpHeaderExtension(); | 242 video_rotation_active = rtp_sender_->ActivateCVORtpHeaderExtension(); |
| 260 } | 243 } |
| 261 | 244 |
| 262 int rtp_header_length = _rtpSender.RtpHeaderLength(); | 245 int rtp_header_length = rtp_sender_->RtpHeaderLength(); |
| 263 size_t payload_bytes_to_send = payloadSize; | 246 size_t payload_bytes_to_send = payload_size; |
| 264 const uint8_t* data = payloadData; | 247 const uint8_t* data = payload_data; |
| 265 | 248 |
| 266 // TODO(changbin): we currently don't support to configure the codec to | 249 // TODO(changbin): we currently don't support to configure the codec to |
| 267 // output multiple partitions for VP8. Should remove below check after the | 250 // output multiple partitions for VP8. Should remove below check after the |
| 268 // issue is fixed. | 251 // issue is fixed. |
| 269 const RTPFragmentationHeader* frag = | 252 const RTPFragmentationHeader* frag = |
| 270 (videoType == kRtpVideoVp8) ? NULL : fragmentation; | 253 (video_type == kRtpVideoVp8) ? NULL : fragmentation; |
| 271 | 254 |
| 272 packetizer->SetPayloadData(data, payload_bytes_to_send, frag); | 255 packetizer->SetPayloadData(data, payload_bytes_to_send, frag); |
| 273 | 256 |
| 274 bool first = true; | 257 bool first = true; |
| 275 bool last = false; | 258 bool last = false; |
| 276 while (!last) { | 259 while (!last) { |
| 277 uint8_t dataBuffer[IP_PACKET_SIZE] = {0}; | 260 uint8_t dataBuffer[IP_PACKET_SIZE] = {0}; |
| 278 size_t payload_bytes_in_packet = 0; | 261 size_t payload_bytes_in_packet = 0; |
| 279 | 262 |
| 280 if (!packetizer->NextPacket(&dataBuffer[rtp_header_length], | 263 if (!packetizer->NextPacket(&dataBuffer[rtp_header_length], |
| 281 &payload_bytes_in_packet, &last)) { | 264 &payload_bytes_in_packet, &last)) { |
| 282 return -1; | 265 return -1; |
| 283 } | 266 } |
| 284 | 267 |
| 285 // Write RTP header. | 268 // Write RTP header. |
| 286 _rtpSender.BuildRTPheader( | 269 rtp_sender_->BuildRtpHeader(dataBuffer, payload_type, last, |
| 287 dataBuffer, payloadType, last, captureTimeStamp, capture_time_ms); | 270 capture_timestamp, capture_time_ms); |
| 288 | 271 |
| 289 // According to | 272 // According to |
| 290 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ | 273 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ |
| 291 // ts_126114v120700p.pdf Section 7.4.5: | 274 // ts_126114v120700p.pdf Section 7.4.5: |
| 292 // The MTSI client shall add the payload bytes as defined in this clause | 275 // The MTSI client shall add the payload bytes as defined in this clause |
| 293 // onto the last RTP packet in each group of packets which make up a key | 276 // onto the last RTP packet in each group of packets which make up a key |
| 294 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 | 277 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 |
| 295 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP | 278 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP |
| 296 // packet in each group of packets which make up another type of frame | 279 // packet in each group of packets which make up another type of frame |
| 297 // (e.g. a P-Frame) only if the current value is different from the previous | 280 // (e.g. a P-Frame) only if the current value is different from the previous |
| 298 // value sent. | 281 // value sent. |
| 299 // Here we are adding it to every packet of every frame at this point. | 282 // Here we are adding it to every packet of every frame at this point. |
| 300 if (!video_header) { | 283 if (!video_header) { |
| 301 RTC_DCHECK(!_rtpSender.IsRtpHeaderExtensionRegistered( | 284 RTC_DCHECK(!rtp_sender_->IsRtpHeaderExtensionRegistered( |
| 302 kRtpExtensionVideoRotation)); | 285 kRtpExtensionVideoRotation)); |
| 303 } else if (video_rotation_active) { | 286 } else if (video_rotation_active) { |
| 304 // Checking whether CVO header extension is registered will require taking | 287 // Checking whether CVO header extension is registered will require taking |
| 305 // a lock. It'll be a no-op if it's not registered. | 288 // a lock. It'll be a no-op if it's not registered. |
| 306 // TODO(guoweis): For now, all packets sent will carry the CVO such that | 289 // TODO(guoweis): For now, all packets sent will carry the CVO such that |
| 307 // the RTP header length is consistent, although the receiver side will | 290 // the RTP header length is consistent, although the receiver side will |
| 308 // only exam the packets with marker bit set. | 291 // only exam the packets with marker bit set. |
| 309 size_t packetSize = payloadSize + rtp_header_length; | 292 size_t packetSize = payload_size + rtp_header_length; |
| 310 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); | 293 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); |
| 311 RTPHeader rtp_header; | 294 RTPHeader rtp_header; |
| 312 rtp_parser.Parse(&rtp_header); | 295 rtp_parser.Parse(&rtp_header); |
| 313 _rtpSender.UpdateVideoRotation(dataBuffer, packetSize, rtp_header, | 296 rtp_sender_->UpdateVideoRotation(dataBuffer, packetSize, rtp_header, |
| 314 video_header->rotation); | 297 video_header->rotation); |
| 315 } | 298 } |
| 316 if (red_payload_type != 0) { | 299 if (red_payload_type != 0) { |
| 317 SendVideoPacketAsRed(dataBuffer, payload_bytes_in_packet, | 300 SendVideoPacketAsRed(dataBuffer, payload_bytes_in_packet, |
| 318 rtp_header_length, _rtpSender.SequenceNumber(), | 301 rtp_header_length, rtp_sender_->SequenceNumber(), |
| 319 captureTimeStamp, capture_time_ms, storage, | 302 capture_timestamp, capture_time_ms, storage, |
| 320 packetizer->GetProtectionType() == kProtectedPacket); | 303 packetizer->GetProtectionType() == kProtectedPacket); |
| 321 } else { | 304 } else { |
| 322 SendVideoPacket(dataBuffer, payload_bytes_in_packet, rtp_header_length, | 305 SendVideoPacket(dataBuffer, payload_bytes_in_packet, rtp_header_length, |
| 323 _rtpSender.SequenceNumber(), captureTimeStamp, | 306 rtp_sender_->SequenceNumber(), capture_timestamp, |
| 324 capture_time_ms, storage); | 307 capture_time_ms, storage); |
| 325 } | 308 } |
| 326 | 309 |
| 327 if (first_frame) { | 310 if (first_frame) { |
| 328 if (first) { | 311 if (first) { |
| 329 LOG(LS_INFO) | 312 LOG(LS_INFO) |
| 330 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 313 << "Sent first RTP packet of the first video frame (pre-pacer)"; |
| 331 } | 314 } |
| 332 if (last) { | 315 if (last) { |
| 333 LOG(LS_INFO) | 316 LOG(LS_INFO) |
| 334 << "Sent last RTP packet of the first video frame (pre-pacer)"; | 317 << "Sent last RTP packet of the first video frame (pre-pacer)"; |
| 335 } | 318 } |
| 336 } | 319 } |
| 337 first = false; | 320 first = false; |
| 338 } | 321 } |
| 339 | 322 |
| 340 TRACE_EVENT_ASYNC_END1( | 323 TRACE_EVENT_ASYNC_END1("webrtc", "Video", capture_time_ms, "timestamp", |
| 341 "webrtc", "Video", capture_time_ms, "timestamp", _rtpSender.Timestamp()); | 324 rtp_sender_->Timestamp()); |
| 342 return 0; | 325 return 0; |
| 343 } | 326 } |
| 344 | 327 |
| 345 uint32_t RTPSenderVideo::VideoBitrateSent() const { | 328 uint32_t RTPSenderVideo::VideoBitrateSent() const { |
| 346 rtc::CritScope cs(&stats_crit_); | 329 rtc::CritScope cs(&stats_crit_); |
| 347 return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); | 330 return video_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); |
| 348 } | 331 } |
| 349 | 332 |
| 350 uint32_t RTPSenderVideo::FecOverheadRate() const { | 333 uint32_t RTPSenderVideo::FecOverheadRate() const { |
| 351 rtc::CritScope cs(&stats_crit_); | 334 rtc::CritScope cs(&stats_crit_); |
| 352 return fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); | 335 return fec_bitrate_.Rate(clock_->TimeInMilliseconds()).value_or(0); |
| 353 } | 336 } |
| 354 | 337 |
| 355 int RTPSenderVideo::SelectiveRetransmissions() const { | 338 int RTPSenderVideo::SelectiveRetransmissions() const { |
| 356 rtc::CritScope cs(&crit_); | 339 rtc::CritScope cs(&crit_); |
| 357 return _retransmissionSettings; | 340 return retransmission_settings_; |
| 358 } | 341 } |
| 359 | 342 |
| 360 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 343 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
| 361 rtc::CritScope cs(&crit_); | 344 rtc::CritScope cs(&crit_); |
| 362 _retransmissionSettings = settings; | 345 retransmission_settings_ = settings; |
| 363 } | 346 } |
| 364 | 347 |
| 365 } // namespace webrtc | 348 } // namespace webrtc |
| OLD | NEW |