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 |