| 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 <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/trace_event.h" | 20 #include "webrtc/base/trace_event.h" |
| 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
| 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" | 23 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" |
| 24 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" | 24 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" |
| 25 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" | 25 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" |
| 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" | 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" |
| 27 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
| 28 | 27 |
| 29 namespace webrtc { | 28 namespace webrtc { |
| 30 enum { REDForFECHeaderLength = 1 }; | 29 enum { REDForFECHeaderLength = 1 }; |
| 31 | 30 |
| 32 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) | 31 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) |
| 33 : _rtpSender(*rtpSender), | 32 : _rtpSender(*rtpSender), |
| 34 crit_(CriticalSectionWrapper::CreateCriticalSection()), | |
| 35 _videoType(kRtpVideoGeneric), | 33 _videoType(kRtpVideoGeneric), |
| 36 _retransmissionSettings(kRetransmitBaseLayer), | 34 _retransmissionSettings(kRetransmitBaseLayer), |
| 37 // Generic FEC | 35 // Generic FEC |
| 38 fec_(), | 36 fec_(), |
| 39 fec_enabled_(false), | 37 fec_enabled_(false), |
| 40 red_payload_type_(-1), | 38 red_payload_type_(-1), |
| 41 fec_payload_type_(-1), | 39 fec_payload_type_(-1), |
| 42 delta_fec_params_(), | 40 delta_fec_params_(), |
| 43 key_fec_params_(), | 41 key_fec_params_(), |
| 44 producer_fec_(&fec_), | 42 producer_fec_(&fec_), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 const uint32_t capture_timestamp, | 110 const uint32_t capture_timestamp, |
| 113 int64_t capture_time_ms, | 111 int64_t capture_time_ms, |
| 114 StorageType media_packet_storage, | 112 StorageType media_packet_storage, |
| 115 bool protect) { | 113 bool protect) { |
| 116 rtc::scoped_ptr<RedPacket> red_packet; | 114 rtc::scoped_ptr<RedPacket> red_packet; |
| 117 std::vector<RedPacket*> fec_packets; | 115 std::vector<RedPacket*> fec_packets; |
| 118 StorageType fec_storage = kDontRetransmit; | 116 StorageType fec_storage = kDontRetransmit; |
| 119 uint16_t next_fec_sequence_number = 0; | 117 uint16_t next_fec_sequence_number = 0; |
| 120 { | 118 { |
| 121 // Only protect while creating RED and FEC packets, not when sending. | 119 // Only protect while creating RED and FEC packets, not when sending. |
| 122 CriticalSectionScoped cs(crit_.get()); | 120 rtc::CritScope cs(&crit_); |
| 123 red_packet.reset(producer_fec_.BuildRedPacket( | 121 red_packet.reset(producer_fec_.BuildRedPacket( |
| 124 data_buffer, payload_length, rtp_header_length, red_payload_type_)); | 122 data_buffer, payload_length, rtp_header_length, red_payload_type_)); |
| 125 if (protect) { | 123 if (protect) { |
| 126 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, | 124 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, |
| 127 rtp_header_length); | 125 rtp_header_length); |
| 128 } | 126 } |
| 129 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 127 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); |
| 130 if (num_fec_packets > 0) { | 128 if (num_fec_packets > 0) { |
| 131 next_fec_sequence_number = | 129 next_fec_sequence_number = |
| 132 _rtpSender.AllocateSequenceNumber(num_fec_packets); | 130 _rtpSender.AllocateSequenceNumber(num_fec_packets); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 163 << next_fec_sequence_number; | 161 << next_fec_sequence_number; |
| 164 } | 162 } |
| 165 delete fec_packet; | 163 delete fec_packet; |
| 166 ++next_fec_sequence_number; | 164 ++next_fec_sequence_number; |
| 167 } | 165 } |
| 168 } | 166 } |
| 169 | 167 |
| 170 void RTPSenderVideo::SetGenericFECStatus(const bool enable, | 168 void RTPSenderVideo::SetGenericFECStatus(const bool enable, |
| 171 const uint8_t payloadTypeRED, | 169 const uint8_t payloadTypeRED, |
| 172 const uint8_t payloadTypeFEC) { | 170 const uint8_t payloadTypeFEC) { |
| 173 CriticalSectionScoped cs(crit_.get()); | 171 rtc::CritScope cs(&crit_); |
| 174 fec_enabled_ = enable; | 172 fec_enabled_ = enable; |
| 175 red_payload_type_ = payloadTypeRED; | 173 red_payload_type_ = payloadTypeRED; |
| 176 fec_payload_type_ = payloadTypeFEC; | 174 fec_payload_type_ = payloadTypeFEC; |
| 177 memset(&delta_fec_params_, 0, sizeof(delta_fec_params_)); | 175 memset(&delta_fec_params_, 0, sizeof(delta_fec_params_)); |
| 178 memset(&key_fec_params_, 0, sizeof(key_fec_params_)); | 176 memset(&key_fec_params_, 0, sizeof(key_fec_params_)); |
| 179 delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1; | 177 delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1; |
| 180 delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type = | 178 delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type = |
| 181 kFecMaskRandom; | 179 kFecMaskRandom; |
| 182 } | 180 } |
| 183 | 181 |
| 184 void RTPSenderVideo::GenericFECStatus(bool* enable, | 182 void RTPSenderVideo::GenericFECStatus(bool* enable, |
| 185 uint8_t* payloadTypeRED, | 183 uint8_t* payloadTypeRED, |
| 186 uint8_t* payloadTypeFEC) const { | 184 uint8_t* payloadTypeFEC) const { |
| 187 CriticalSectionScoped cs(crit_.get()); | 185 rtc::CritScope cs(&crit_); |
| 188 *enable = fec_enabled_; | 186 *enable = fec_enabled_; |
| 189 *payloadTypeRED = red_payload_type_; | 187 *payloadTypeRED = red_payload_type_; |
| 190 *payloadTypeFEC = fec_payload_type_; | 188 *payloadTypeFEC = fec_payload_type_; |
| 191 } | 189 } |
| 192 | 190 |
| 193 size_t RTPSenderVideo::FECPacketOverhead() const { | 191 size_t RTPSenderVideo::FECPacketOverhead() const { |
| 194 CriticalSectionScoped cs(crit_.get()); | 192 rtc::CritScope cs(&crit_); |
| 195 if (fec_enabled_) { | 193 if (fec_enabled_) { |
| 196 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 194 // Overhead is FEC headers plus RED for FEC header plus anything in RTP |
| 197 // header beyond the 12 bytes base header (CSRC list, extensions...) | 195 // header beyond the 12 bytes base header (CSRC list, extensions...) |
| 198 // This reason for the header extensions to be included here is that | 196 // This reason for the header extensions to be included here is that |
| 199 // from an FEC viewpoint, they are part of the payload to be protected. | 197 // from an FEC viewpoint, they are part of the payload to be protected. |
| 200 // (The base RTP header is already protected by the FEC header.) | 198 // (The base RTP header is already protected by the FEC header.) |
| 201 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + | 199 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + |
| 202 (_rtpSender.RTPHeaderLength() - kRtpHeaderSize); | 200 (_rtpSender.RTPHeaderLength() - kRtpHeaderSize); |
| 203 } | 201 } |
| 204 return 0; | 202 return 0; |
| 205 } | 203 } |
| 206 | 204 |
| 207 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, | 205 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, |
| 208 const FecProtectionParams* key_params) { | 206 const FecProtectionParams* key_params) { |
| 209 CriticalSectionScoped cs(crit_.get()); | 207 rtc::CritScope cs(&crit_); |
| 210 RTC_DCHECK(delta_params); | 208 RTC_DCHECK(delta_params); |
| 211 RTC_DCHECK(key_params); | 209 RTC_DCHECK(key_params); |
| 212 delta_fec_params_ = *delta_params; | 210 delta_fec_params_ = *delta_params; |
| 213 key_fec_params_ = *key_params; | 211 key_fec_params_ = *key_params; |
| 214 } | 212 } |
| 215 | 213 |
| 216 int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, | 214 int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, |
| 217 const FrameType frameType, | 215 const FrameType frameType, |
| 218 const int8_t payloadType, | 216 const int8_t payloadType, |
| 219 const uint32_t captureTimeStamp, | 217 const uint32_t captureTimeStamp, |
| 220 int64_t capture_time_ms, | 218 int64_t capture_time_ms, |
| 221 const uint8_t* payloadData, | 219 const uint8_t* payloadData, |
| 222 const size_t payloadSize, | 220 const size_t payloadSize, |
| 223 const RTPFragmentationHeader* fragmentation, | 221 const RTPFragmentationHeader* fragmentation, |
| 224 const RTPVideoHeader* video_header) { | 222 const RTPVideoHeader* video_header) { |
| 225 if (payloadSize == 0) { | 223 if (payloadSize == 0) { |
| 226 return -1; | 224 return -1; |
| 227 } | 225 } |
| 228 | 226 |
| 229 rtc::scoped_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 227 rtc::scoped_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 230 videoType, _rtpSender.MaxDataPayloadLength(), | 228 videoType, _rtpSender.MaxDataPayloadLength(), |
| 231 video_header ? &(video_header->codecHeader) : nullptr, frameType)); | 229 video_header ? &(video_header->codecHeader) : nullptr, frameType)); |
| 232 | 230 |
| 233 StorageType storage; | 231 StorageType storage; |
| 234 bool fec_enabled; | 232 bool fec_enabled; |
| 235 bool first_frame = first_frame_sent_(); | 233 bool first_frame = first_frame_sent_(); |
| 236 { | 234 { |
| 237 CriticalSectionScoped cs(crit_.get()); | 235 rtc::CritScope cs(&crit_); |
| 238 FecProtectionParams* fec_params = | 236 FecProtectionParams* fec_params = |
| 239 frameType == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 237 frameType == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; |
| 240 producer_fec_.SetFecParameters(fec_params, 0); | 238 producer_fec_.SetFecParameters(fec_params, 0); |
| 241 storage = packetizer->GetStorageType(_retransmissionSettings); | 239 storage = packetizer->GetStorageType(_retransmissionSettings); |
| 242 fec_enabled = fec_enabled_; | 240 fec_enabled = fec_enabled_; |
| 243 } | 241 } |
| 244 | 242 |
| 245 // Register CVO rtp header extension at the first time when we receive a frame | 243 // Register CVO rtp header extension at the first time when we receive a frame |
| 246 // with pending rotation. | 244 // with pending rotation. |
| 247 RTPSenderInterface::CVOMode cvo_mode = RTPSenderInterface::kCVONone; | 245 RTPSenderInterface::CVOMode cvo_mode = RTPSenderInterface::kCVONone; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 | 336 |
| 339 uint32_t RTPSenderVideo::VideoBitrateSent() const { | 337 uint32_t RTPSenderVideo::VideoBitrateSent() const { |
| 340 return _videoBitrate.BitrateLast(); | 338 return _videoBitrate.BitrateLast(); |
| 341 } | 339 } |
| 342 | 340 |
| 343 uint32_t RTPSenderVideo::FecOverheadRate() const { | 341 uint32_t RTPSenderVideo::FecOverheadRate() const { |
| 344 return _fecOverheadRate.BitrateLast(); | 342 return _fecOverheadRate.BitrateLast(); |
| 345 } | 343 } |
| 346 | 344 |
| 347 int RTPSenderVideo::SelectiveRetransmissions() const { | 345 int RTPSenderVideo::SelectiveRetransmissions() const { |
| 348 CriticalSectionScoped cs(crit_.get()); | 346 rtc::CritScope cs(&crit_); |
| 349 return _retransmissionSettings; | 347 return _retransmissionSettings; |
| 350 } | 348 } |
| 351 | 349 |
| 352 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 350 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
| 353 CriticalSectionScoped cs(crit_.get()); | 351 rtc::CritScope cs(&crit_); |
| 354 _retransmissionSettings = settings; | 352 _retransmissionSettings = settings; |
| 355 } | 353 } |
| 356 | 354 |
| 357 } // namespace webrtc | 355 } // namespace webrtc |
| OLD | NEW |