Chromium Code Reviews| 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 #include <utility> | |
| 18 | 19 |
| 19 #include "webrtc/base/checks.h" | 20 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/logging.h" | 21 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/base/trace_event.h" | 22 #include "webrtc/base/trace_event.h" |
| 22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 24 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 24 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" | 25 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" |
| 25 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" | 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h" |
| 26 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" | 27 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h" |
| 27 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" | 28 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h" |
| 29 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | |
| 30 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" | |
| 28 | 31 |
| 29 namespace webrtc { | 32 namespace webrtc { |
| 30 | 33 |
| 31 namespace { | 34 namespace { |
| 32 constexpr size_t kRedForFecHeaderLength = 1; | 35 constexpr size_t kRedForFecHeaderLength = 1; |
| 36 | |
| 37 void BuildRedPayload(const RtpPacketToSend& media_packet, | |
| 38 RtpPacketToSend* red_packet) { | |
| 39 uint8_t* red_payload = red_packet->AllocatePayload( | |
| 40 kRedForFecHeaderLength + media_packet.payload_size()); | |
| 41 RTC_DCHECK(red_payload); | |
| 42 red_payload[0] = media_packet.PayloadType(); | |
| 43 memcpy(&red_payload[kRedForFecHeaderLength], media_packet.payload(), | |
| 44 media_packet.payload_size()); | |
| 45 } | |
| 33 } // namespace | 46 } // namespace |
| 34 | 47 |
| 35 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) | 48 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) |
| 36 : rtp_sender_(rtp_sender), | 49 : rtp_sender_(rtp_sender), |
| 37 clock_(clock), | 50 clock_(clock), |
| 38 fec_bitrate_(1000, RateStatistics::kBpsScale), | 51 fec_bitrate_(1000, RateStatistics::kBpsScale), |
| 39 video_bitrate_(1000, RateStatistics::kBpsScale) {} | 52 video_bitrate_(1000, RateStatistics::kBpsScale) {} |
| 40 | 53 |
| 41 RTPSenderVideo::~RTPSenderVideo() {} | 54 RTPSenderVideo::~RTPSenderVideo() {} |
| 42 | 55 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 65 video_type = kRtpVideoGeneric; | 78 video_type = kRtpVideoGeneric; |
| 66 } | 79 } |
| 67 RtpUtility::Payload* payload = new RtpUtility::Payload(); | 80 RtpUtility::Payload* payload = new RtpUtility::Payload(); |
| 68 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; | 81 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; |
| 69 strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1); | 82 strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1); |
| 70 payload->typeSpecific.Video.videoCodecType = video_type; | 83 payload->typeSpecific.Video.videoCodecType = video_type; |
| 71 payload->audio = false; | 84 payload->audio = false; |
| 72 return payload; | 85 return payload; |
| 73 } | 86 } |
| 74 | 87 |
| 75 void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, | 88 void RTPSenderVideo::SendVideoPacket(std::unique_ptr<RtpPacketToSend> packet, |
| 76 size_t payload_length, | |
| 77 size_t rtp_header_length, | |
| 78 uint16_t seq_num, | |
| 79 uint32_t rtp_timestamp, | |
| 80 int64_t capture_time_ms, | |
| 81 StorageType storage) { | 89 StorageType storage) { |
| 82 if (!rtp_sender_->SendToNetwork(data_buffer, payload_length, | 90 // Remember some values about the packet before sending it away. |
| 83 rtp_header_length, capture_time_ms, storage, | 91 size_t packet_size = packet->size(); |
| 92 uint16_t seq_num = packet->SequenceNumber(); | |
| 93 uint32_t rtp_timestamp = packet->Timestamp(); | |
| 94 if (!rtp_sender_->SendToNetwork(std::move(packet), storage, | |
| 84 RtpPacketSender::kLowPriority)) { | 95 RtpPacketSender::kLowPriority)) { |
| 85 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; | 96 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; |
| 86 return; | 97 return; |
| 87 } | 98 } |
| 88 rtc::CritScope cs(&stats_crit_); | 99 rtc::CritScope cs(&stats_crit_); |
| 89 video_bitrate_.Update(payload_length + rtp_header_length, | 100 video_bitrate_.Update(packet_size, clock_->TimeInMilliseconds()); |
| 90 clock_->TimeInMilliseconds()); | |
| 91 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 101 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 92 "Video::PacketNormal", "timestamp", rtp_timestamp, | 102 "Video::PacketNormal", "timestamp", rtp_timestamp, |
| 93 "seqnum", seq_num); | 103 "seqnum", seq_num); |
| 94 } | 104 } |
| 95 | 105 |
| 96 void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer, | 106 void RTPSenderVideo::SendVideoPacketAsRed( |
| 97 size_t payload_length, | 107 std::unique_ptr<RtpPacketToSend> media_packet, |
| 98 size_t rtp_header_length, | 108 StorageType media_packet_storage, |
| 99 uint16_t media_seq_num, | 109 bool protect) { |
| 100 uint32_t rtp_timestamp, | 110 uint32_t rtp_timestamp = media_packet->Timestamp(); |
| 101 int64_t capture_time_ms, | 111 uint16_t media_seq_num = media_packet->SequenceNumber(); |
| 102 StorageType media_packet_storage, | 112 |
| 103 bool protect) { | 113 std::unique_ptr<RtpPacketToSend> red_packet( |
| 104 std::unique_ptr<RedPacket> red_packet; | 114 new RtpPacketToSend(*media_packet)); |
| 115 BuildRedPayload(*media_packet, red_packet.get()); | |
| 116 | |
| 105 std::vector<std::unique_ptr<RedPacket>> fec_packets; | 117 std::vector<std::unique_ptr<RedPacket>> fec_packets; |
| 106 StorageType fec_storage = kDontRetransmit; | 118 StorageType fec_storage = kDontRetransmit; |
| 107 uint16_t next_fec_sequence_number = 0; | |
| 108 { | 119 { |
| 109 // Only protect while creating RED and FEC packets, not when sending. | 120 // Only protect while creating RED and FEC packets, not when sending. |
| 110 rtc::CritScope cs(&crit_); | 121 rtc::CritScope cs(&crit_); |
| 111 red_packet = ProducerFec::BuildRedPacket( | 122 red_packet->SetPayloadType(red_payload_type_); |
| 112 data_buffer, payload_length, rtp_header_length, red_payload_type_); | |
| 113 if (protect) { | 123 if (protect) { |
| 114 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, | 124 producer_fec_.AddRtpPacketAndGenerateFec(media_packet->data(), |
| 115 rtp_header_length); | 125 media_packet->payload_size(), |
| 126 media_packet->headers_size()); | |
| 116 } | 127 } |
| 117 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 128 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); |
| 118 if (num_fec_packets > 0) { | 129 if (num_fec_packets > 0) { |
| 119 next_fec_sequence_number = | 130 uint16_t first_fec_sequence_number = |
| 120 rtp_sender_->AllocateSequenceNumber(num_fec_packets); | 131 rtp_sender_->AllocateSequenceNumber(num_fec_packets); |
| 121 fec_packets = producer_fec_.GetFecPacketsAsRed( | 132 fec_packets = producer_fec_.GetFecPacketsAsRed( |
| 122 red_payload_type_, fec_payload_type_, next_fec_sequence_number, | 133 red_payload_type_, fec_payload_type_, first_fec_sequence_number, |
| 123 rtp_header_length); | 134 media_packet->headers_size()); |
| 124 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 135 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); |
| 125 if (retransmission_settings_ & kRetransmitFECPackets) | 136 if (retransmission_settings_ & kRetransmitFECPackets) |
| 126 fec_storage = kAllowRetransmission; | 137 fec_storage = kAllowRetransmission; |
| 127 } | 138 } |
| 128 } | 139 } |
| 129 if (rtp_sender_->SendToNetwork( | 140 // Send |red_packet| instead of |packet| for allocated sequence number. |
| 130 red_packet->data(), red_packet->length() - rtp_header_length, | 141 size_t red_packet_size = red_packet->size(); |
| 131 rtp_header_length, capture_time_ms, media_packet_storage, | 142 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, |
| 132 RtpPacketSender::kLowPriority)) { | 143 RtpPacketSender::kLowPriority)) { |
| 133 rtc::CritScope cs(&stats_crit_); | 144 rtc::CritScope cs(&stats_crit_); |
| 134 video_bitrate_.Update(red_packet->length(), clock_->TimeInMilliseconds()); | 145 video_bitrate_.Update(red_packet_size, clock_->TimeInMilliseconds()); |
| 135 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 146 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 136 "Video::PacketRed", "timestamp", rtp_timestamp, | 147 "Video::PacketRed", "timestamp", rtp_timestamp, |
| 137 "seqnum", media_seq_num); | 148 "seqnum", media_seq_num); |
| 138 } else { | 149 } else { |
| 139 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; | 150 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; |
| 140 } | 151 } |
| 141 for (const auto& fec_packet : fec_packets) { | 152 for (const auto& fec_packet : fec_packets) { |
| 142 if (rtp_sender_->SendToNetwork( | 153 // TODO(danilchap): Make producer_fec_ generate RtpPacketToSend to avoid |
| 143 fec_packet->data(), fec_packet->length() - rtp_header_length, | 154 // reparsing them. |
| 144 rtp_header_length, capture_time_ms, fec_storage, | 155 std::unique_ptr<RtpPacketToSend> rtp_packet( |
| 145 RtpPacketSender::kLowPriority)) { | 156 new RtpPacketToSend(*media_packet)); |
| 157 RTC_CHECK(rtp_packet->Parse(fec_packet->data(), fec_packet->length())); | |
| 158 rtp_packet->set_capture_time_ms(media_packet->capture_time_ms()); | |
| 159 uint16_t fec_sequence_number = rtp_packet->SequenceNumber(); | |
| 160 if (rtp_sender_->SendToNetwork(std::move(rtp_packet), fec_storage, | |
| 161 RtpPacketSender::kLowPriority)) { | |
| 146 rtc::CritScope cs(&stats_crit_); | 162 rtc::CritScope cs(&stats_crit_); |
| 147 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 163 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); |
| 148 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 164 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| 149 "Video::PacketFec", "timestamp", rtp_timestamp, | 165 "Video::PacketFec", "timestamp", rtp_timestamp, |
| 150 "seqnum", next_fec_sequence_number); | 166 "seqnum", fec_sequence_number); |
| 151 } else { | 167 } else { |
| 152 LOG(LS_WARNING) << "Failed to send FEC packet " | 168 LOG(LS_WARNING) << "Failed to send FEC packet " << fec_sequence_number; |
| 153 << next_fec_sequence_number; | |
| 154 } | 169 } |
| 155 ++next_fec_sequence_number; | |
| 156 } | 170 } |
| 157 } | 171 } |
| 158 | 172 |
| 159 void RTPSenderVideo::SetGenericFECStatus(bool enable, | 173 void RTPSenderVideo::SetGenericFECStatus(bool enable, |
| 160 uint8_t payload_type_red, | 174 uint8_t payload_type_red, |
| 161 uint8_t payload_type_fec) { | 175 uint8_t payload_type_fec) { |
| 162 RTC_DCHECK(!enable || payload_type_red > 0); | 176 RTC_DCHECK(!enable || payload_type_red > 0); |
| 163 rtc::CritScope cs(&crit_); | 177 rtc::CritScope cs(&crit_); |
| 164 fec_enabled_ = enable; | 178 fec_enabled_ = enable; |
| 165 red_payload_type_ = payload_type_red; | 179 red_payload_type_ = payload_type_red; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 int8_t payload_type, | 224 int8_t payload_type, |
| 211 uint32_t rtp_timestamp, | 225 uint32_t rtp_timestamp, |
| 212 int64_t capture_time_ms, | 226 int64_t capture_time_ms, |
| 213 const uint8_t* payload_data, | 227 const uint8_t* payload_data, |
| 214 size_t payload_size, | 228 size_t payload_size, |
| 215 const RTPFragmentationHeader* fragmentation, | 229 const RTPFragmentationHeader* fragmentation, |
| 216 const RTPVideoHeader* video_header) { | 230 const RTPVideoHeader* video_header) { |
| 217 if (payload_size == 0) | 231 if (payload_size == 0) |
| 218 return false; | 232 return false; |
| 219 | 233 |
| 234 // Create header that will be reused in all packets. | |
| 235 std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket(); | |
| 236 rtp_header->SetPayloadType(payload_type); | |
| 237 rtp_header->SetTimestamp(rtp_timestamp); | |
| 238 rtp_header->set_capture_time_ms(capture_time_ms); | |
| 239 // According to | |
| 240 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ | |
| 241 // ts_126114v120700p.pdf Section 7.4.5: | |
| 242 // The MTSI client shall add the payload bytes as defined in this clause | |
| 243 // onto the last RTP packet in each group of packets which make up a key | |
| 244 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 | |
| 245 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP | |
| 246 // packet in each group of packets which make up another type of frame | |
| 247 // (e.g. a P-Frame) only if the current value is different from the previous | |
| 248 // value sent. | |
| 249 // Here we are adding it to every packet of every frame at this point. | |
| 250 if (video_header && video_header->rotation != kVideoRotation_0) { | |
| 251 // TODO(danilchap): Remove next call together with concept | |
| 252 // of inactive extension. Now it helps to calulate total maximum size | |
| 253 // or rtp header extensions that is used in FECPacketOverhead() function. | |
| 254 rtp_sender_->ActivateCVORtpHeaderExtension(); | |
| 255 rtp_header->SetExtension<VideoOrientation>(video_header->rotation); | |
| 256 } | |
| 257 | |
| 258 size_t packet_capacity = rtp_sender_->MaxPayloadLength() - | |
| 259 FecPacketOverhead() - | |
| 260 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); | |
| 261 RTC_DCHECK_LE(packet_capacity, rtp_header->capacity()); | |
| 262 RTC_DCHECK_GT(packet_capacity, rtp_header->headers_size()); | |
| 263 size_t max_data_payload_length = packet_capacity - rtp_header->headers_size(); | |
| 264 | |
| 220 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 265 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 221 video_type, rtp_sender_->MaxDataPayloadLength(), | 266 video_type, max_data_payload_length, |
| 222 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 267 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); |
| 223 | 268 |
| 224 StorageType storage; | 269 StorageType storage; |
| 225 int red_payload_type; | 270 int red_payload_type; |
| 226 bool first_frame = first_frame_sent_(); | 271 bool first_frame = first_frame_sent_(); |
| 227 { | 272 { |
| 228 rtc::CritScope cs(&crit_); | 273 rtc::CritScope cs(&crit_); |
| 229 FecProtectionParams* fec_params = | 274 FecProtectionParams* fec_params = |
| 230 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 275 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; |
| 231 // We currently do not use unequal protection in the FEC. | 276 // We currently do not use unequal protection in the FEC. |
| 232 // This is signalled both here (by setting the number of important | 277 // This is signalled both here (by setting the number of important |
| 233 // packets to zero), as well as in ProducerFec::AddRtpPacketAndGenerateFec. | 278 // packets to zero), as well as in ProducerFec::AddRtpPacketAndGenerateFec. |
| 234 constexpr int kNumImportantPackets = 0; | 279 constexpr int kNumImportantPackets = 0; |
| 235 producer_fec_.SetFecParameters(fec_params, kNumImportantPackets); | 280 producer_fec_.SetFecParameters(fec_params, kNumImportantPackets); |
| 236 storage = packetizer->GetStorageType(retransmission_settings_); | 281 storage = packetizer->GetStorageType(retransmission_settings_); |
| 237 red_payload_type = red_payload_type_; | 282 red_payload_type = red_payload_type_; |
| 238 } | 283 } |
| 239 | 284 |
| 240 // Register CVO rtp header extension at the first time when we receive a frame | |
| 241 // with pending rotation. | |
| 242 bool video_rotation_active = false; | |
| 243 if (video_header && video_header->rotation != kVideoRotation_0) { | |
| 244 video_rotation_active = rtp_sender_->ActivateCVORtpHeaderExtension(); | |
| 245 } | |
| 246 | |
| 247 int rtp_header_length = rtp_sender_->RtpHeaderLength(); | |
| 248 size_t payload_bytes_to_send = payload_size; | |
| 249 const uint8_t* data = payload_data; | |
| 250 | |
| 251 // TODO(changbin): we currently don't support to configure the codec to | 285 // TODO(changbin): we currently don't support to configure the codec to |
| 252 // output multiple partitions for VP8. Should remove below check after the | 286 // output multiple partitions for VP8. Should remove below check after the |
| 253 // issue is fixed. | 287 // issue is fixed. |
| 254 const RTPFragmentationHeader* frag = | 288 const RTPFragmentationHeader* frag = |
| 255 (video_type == kRtpVideoVp8) ? NULL : fragmentation; | 289 (video_type == kRtpVideoVp8) ? NULL : fragmentation; |
| 256 | 290 |
| 257 packetizer->SetPayloadData(data, payload_bytes_to_send, frag); | 291 packetizer->SetPayloadData(payload_data, payload_size, frag); |
| 258 | 292 |
| 259 bool first = true; | 293 bool first = true; |
| 260 bool last = false; | 294 bool last = false; |
| 261 while (!last) { | 295 while (!last) { |
| 262 uint8_t dataBuffer[IP_PACKET_SIZE] = {0}; | 296 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); |
|
sprang_webrtc
2016/09/27 10:45:00
Have there been any discussion re going from stack
danilchap
2016/09/27 11:47:05
Acknowledged.
No, there was no discussion about po
sprang_webrtc
2016/09/27 12:16:37
Fair enough. Might be worth keeping an eye on the
| |
| 297 uint8_t* payload = packet->AllocatePayload(max_data_payload_length); | |
| 298 RTC_DCHECK(payload); | |
| 299 | |
| 263 size_t payload_bytes_in_packet = 0; | 300 size_t payload_bytes_in_packet = 0; |
| 264 | 301 if (!packetizer->NextPacket(payload, &payload_bytes_in_packet, &last)) |
| 265 if (!packetizer->NextPacket(&dataBuffer[rtp_header_length], | |
| 266 &payload_bytes_in_packet, &last)) { | |
| 267 return false; | |
| 268 } | |
| 269 | |
| 270 // Write RTP header. | |
| 271 int32_t header_length = rtp_sender_->BuildRtpHeader( | |
| 272 dataBuffer, payload_type, last, rtp_timestamp, capture_time_ms); | |
| 273 if (header_length <= 0) | |
| 274 return false; | 302 return false; |
| 275 | 303 |
| 276 // According to | 304 packet->SetPayloadSize(payload_bytes_in_packet); |
| 277 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ | 305 packet->SetMarker(last); |
| 278 // ts_126114v120700p.pdf Section 7.4.5: | 306 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
| 279 // The MTSI client shall add the payload bytes as defined in this clause | 307 return false; |
| 280 // onto the last RTP packet in each group of packets which make up a key | 308 |
| 281 // frame (I-frame or IDR frame in H.264 (AVC), or an IRAP picture in H.265 | |
| 282 // (HEVC)). The MTSI client may also add the payload bytes onto the last RTP | |
| 283 // packet in each group of packets which make up another type of frame | |
| 284 // (e.g. a P-Frame) only if the current value is different from the previous | |
| 285 // value sent. | |
| 286 // Here we are adding it to every packet of every frame at this point. | |
| 287 if (!video_header) { | |
| 288 RTC_DCHECK(!rtp_sender_->IsRtpHeaderExtensionRegistered( | |
| 289 kRtpExtensionVideoRotation)); | |
| 290 } else if (video_rotation_active) { | |
| 291 // Checking whether CVO header extension is registered will require taking | |
| 292 // a lock. It'll be a no-op if it's not registered. | |
| 293 // TODO(guoweis): For now, all packets sent will carry the CVO such that | |
| 294 // the RTP header length is consistent, although the receiver side will | |
| 295 // only exam the packets with marker bit set. | |
| 296 size_t packetSize = payload_size + rtp_header_length; | |
| 297 RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize); | |
| 298 RTPHeader rtp_header; | |
| 299 rtp_parser.Parse(&rtp_header); | |
| 300 rtp_sender_->UpdateVideoRotation(dataBuffer, packetSize, rtp_header, | |
| 301 video_header->rotation); | |
| 302 } | |
| 303 if (red_payload_type != 0) { | 309 if (red_payload_type != 0) { |
| 304 SendVideoPacketAsRed(dataBuffer, payload_bytes_in_packet, | 310 SendVideoPacketAsRed(std::move(packet), storage, |
| 305 rtp_header_length, rtp_sender_->SequenceNumber(), | |
| 306 rtp_timestamp, capture_time_ms, storage, | |
| 307 packetizer->GetProtectionType() == kProtectedPacket); | 311 packetizer->GetProtectionType() == kProtectedPacket); |
| 308 } else { | 312 } else { |
| 309 SendVideoPacket(dataBuffer, payload_bytes_in_packet, rtp_header_length, | 313 SendVideoPacket(std::move(packet), storage); |
| 310 rtp_sender_->SequenceNumber(), rtp_timestamp, | |
| 311 capture_time_ms, storage); | |
| 312 } | 314 } |
| 313 | 315 |
| 314 if (first_frame) { | 316 if (first_frame) { |
| 315 if (first) { | 317 if (first) { |
| 316 LOG(LS_INFO) | 318 LOG(LS_INFO) |
| 317 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 319 << "Sent first RTP packet of the first video frame (pre-pacer)"; |
| 318 } | 320 } |
| 319 if (last) { | 321 if (last) { |
| 320 LOG(LS_INFO) | 322 LOG(LS_INFO) |
| 321 << "Sent last RTP packet of the first video frame (pre-pacer)"; | 323 << "Sent last RTP packet of the first video frame (pre-pacer)"; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 343 rtc::CritScope cs(&crit_); | 345 rtc::CritScope cs(&crit_); |
| 344 return retransmission_settings_; | 346 return retransmission_settings_; |
| 345 } | 347 } |
| 346 | 348 |
| 347 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 349 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
| 348 rtc::CritScope cs(&crit_); | 350 rtc::CritScope cs(&crit_); |
| 349 retransmission_settings_ = settings; | 351 retransmission_settings_ = settings; |
| 350 } | 352 } |
| 351 | 353 |
| 352 } // namespace webrtc | 354 } // namespace webrtc |
| OLD | NEW |