 Chromium Code Reviews
 Chromium Code Reviews Issue 2217383002:
  Use RtpPacketToSend in RtpSenderVideo  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 2217383002:
  Use RtpPacketToSend in RtpSenderVideo  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| 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 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | |
| 29 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" | |
| 28 | 30 | 
| 29 namespace webrtc { | 31 namespace webrtc { | 
| 30 | 32 | 
| 31 enum { REDForFECHeaderLength = 1 }; | 33 enum { REDForFECHeaderLength = 1 }; | 
| 32 | 34 | 
| 33 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) | 35 RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSender* rtp_sender) | 
| 34 : rtp_sender_(rtp_sender), | 36 : rtp_sender_(rtp_sender), | 
| 35 clock_(clock), | 37 clock_(clock), | 
| 36 // Generic FEC | 38 // Generic FEC | 
| 37 producer_fec_(&fec_), | 39 producer_fec_(&fec_), | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 65 video_type = kRtpVideoGeneric; | 67 video_type = kRtpVideoGeneric; | 
| 66 } | 68 } | 
| 67 RtpUtility::Payload* payload = new RtpUtility::Payload(); | 69 RtpUtility::Payload* payload = new RtpUtility::Payload(); | 
| 68 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; | 70 payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; | 
| 69 strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1); | 71 strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1); | 
| 70 payload->typeSpecific.Video.videoCodecType = video_type; | 72 payload->typeSpecific.Video.videoCodecType = video_type; | 
| 71 payload->audio = false; | 73 payload->audio = false; | 
| 72 return payload; | 74 return payload; | 
| 73 } | 75 } | 
| 74 | 76 | 
| 75 void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, | 77 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 capture_timestamp, | |
| 80 int64_t capture_time_ms, | |
| 81 StorageType storage) { | 78 StorageType storage) { | 
| 82 if (!rtp_sender_->SendToNetwork(data_buffer, payload_length, | 79 size_t packet_size = packet->size(); | 
| 83 rtp_header_length, capture_time_ms, storage, | 80 uint32_t capture_timestamp = packet->Timestamp(); | 
| 81 if (!rtp_sender_->PrepareToSend(packet.get())) { | |
| 82 return; | |
| 83 } | |
| 84 uint16_t seq_num = packet->SequenceNumber(); | |
| 85 if (!rtp_sender_->SendToNetwork(std::move(packet), storage, | |
| 84 RtpPacketSender::kLowPriority)) { | 86 RtpPacketSender::kLowPriority)) { | 
| 85 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; | 87 LOG(LS_WARNING) << "Failed to send video packet " << seq_num; | 
| 86 return; | 88 return; | 
| 87 } | 89 } | 
| 88 rtc::CritScope cs(&stats_crit_); | 90 rtc::CritScope cs(&stats_crit_); | 
| 89 video_bitrate_.Update(payload_length + rtp_header_length, | 91 video_bitrate_.Update(packet_size, clock_->TimeInMilliseconds()); | 
| 90 clock_->TimeInMilliseconds()); | |
| 91 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 92 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 
| 92 "Video::PacketNormal", "timestamp", capture_timestamp, | 93 "Video::PacketNormal", "timestamp", capture_timestamp, | 
| 93 "seqnum", seq_num); | 94 "seqnum", seq_num); | 
| 94 } | 95 } | 
| 95 | 96 | 
| 96 void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer, | 97 void RTPSenderVideo::SendVideoPacketAsRed( | 
| 97 size_t payload_length, | 98 std::unique_ptr<RtpPacketToSend> packet, | 
| 98 size_t rtp_header_length, | 99 StorageType media_packet_storage, | 
| 99 uint16_t media_seq_num, | 100 bool protect) { | 
| 100 uint32_t capture_timestamp, | 101 // Do it old, slow way for now. | 
| 
brandtr
2016/08/15 08:31:31
Not sure what this comment means?
 
danilchap
2016/08/15 08:55:16
Mean this function is too drafty.
Not relevant any
 | |
| 101 int64_t capture_time_ms, | 102 uint32_t capture_timestamp = packet->Timestamp(); | 
| 102 StorageType media_packet_storage, | 103 rtp_sender_->PrepareToSend(packet.get()); | 
| 103 bool protect) { | 104 uint16_t media_seq_num = packet->SequenceNumber(); | 
| 104 std::unique_ptr<RedPacket> red_packet; | 105 | 
| 106 std::unique_ptr<RtpPacketToSend> red_packet; | |
| 105 std::vector<std::unique_ptr<RedPacket>> fec_packets; | 107 std::vector<std::unique_ptr<RedPacket>> fec_packets; | 
| 106 StorageType fec_storage = kDontRetransmit; | 108 StorageType fec_storage = kDontRetransmit; | 
| 107 uint16_t next_fec_sequence_number = 0; | 109 uint16_t next_fec_sequence_number = 0; | 
| 108 { | 110 { | 
| 109 // Only protect while creating RED and FEC packets, not when sending. | 111 // Only protect while creating RED and FEC packets, not when sending. | 
| 112 red_packet = rtp_sender_->AllocatePacket(false); | |
| 110 rtc::CritScope cs(&crit_); | 113 rtc::CritScope cs(&crit_); | 
| 111 red_packet = ProducerFec::BuildRedPacket( | 114 producer_fec_.BuildRedPacket(red_payload_type_, *packet, red_packet.get()); | 
| 112 data_buffer, payload_length, rtp_header_length, red_payload_type_); | 115 red_packet->set_capture_time_ms(packet->capture_time_ms()); | 
| 113 if (protect) { | 116 if (protect) { | 
| 114 producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, | 117 producer_fec_.AddRtpPacketAndGenerateFec( | 
| 115 rtp_header_length); | 118 packet->data(), packet->payload_size(), packet->headers_size()); | 
| 116 } | 119 } | 
| 117 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 120 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 
| 118 if (num_fec_packets > 0) { | 121 if (num_fec_packets > 0) { | 
| 119 next_fec_sequence_number = | 122 next_fec_sequence_number = | 
| 120 rtp_sender_->AllocateSequenceNumber(num_fec_packets); | 123 rtp_sender_->AllocateSequenceNumber(num_fec_packets); | 
| 121 fec_packets = producer_fec_.GetFecPacketsAsRed( | 124 fec_packets = producer_fec_.GetFecPacketsAsRed( | 
| 122 red_payload_type_, fec_payload_type_, next_fec_sequence_number, | 125 red_payload_type_, fec_payload_type_, next_fec_sequence_number, | 
| 123 rtp_header_length); | 126 packet->headers_size()); | 
| 124 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 127 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 
| 125 if (retransmission_settings_ & kRetransmitFECPackets) | 128 if (retransmission_settings_ & kRetransmitFECPackets) | 
| 126 fec_storage = kAllowRetransmission; | 129 fec_storage = kAllowRetransmission; | 
| 127 } | 130 } | 
| 128 } | 131 } | 
| 129 if (rtp_sender_->SendToNetwork( | 132 size_t red_packet_size = red_packet->size(); | 
| 130 red_packet->data(), red_packet->length() - rtp_header_length, | 133 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, | 
| 131 rtp_header_length, capture_time_ms, media_packet_storage, | 134 RtpPacketSender::kLowPriority)) { | 
| 132 RtpPacketSender::kLowPriority)) { | |
| 133 rtc::CritScope cs(&stats_crit_); | 135 rtc::CritScope cs(&stats_crit_); | 
| 134 video_bitrate_.Update(red_packet->length(), clock_->TimeInMilliseconds()); | 136 video_bitrate_.Update(red_packet_size, clock_->TimeInMilliseconds()); | 
| 135 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 137 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 
| 136 "Video::PacketRed", "timestamp", capture_timestamp, | 138 "Video::PacketRed", "timestamp", capture_timestamp, | 
| 137 "seqnum", media_seq_num); | 139 "seqnum", media_seq_num); | 
| 138 } else { | 140 } else { | 
| 139 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; | 141 LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; | 
| 140 } | 142 } | 
| 141 for (const auto& fec_packet : fec_packets) { | 143 for (const auto& fec_packet : fec_packets) { | 
| 142 if (rtp_sender_->SendToNetwork( | 144 // TODO(danilchap): Make producer_fec_ generate rtp::Packets to avoid | 
| 143 fec_packet->data(), fec_packet->length() - rtp_header_length, | 145 // reparsing them. | 
| 144 rtp_header_length, capture_time_ms, fec_storage, | 146 std::unique_ptr<RtpPacketToSend> rtp_packet = | 
| 145 RtpPacketSender::kLowPriority)) { | 147 rtp_sender_->AllocatePacket(false); | 
| 148 RTC_CHECK(rtp_packet->Parse(fec_packet->data(), fec_packet->length())); | |
| 149 rtp_packet->set_capture_time_ms(packet->capture_time_ms()); | |
| 150 if (rtp_sender_->SendToNetwork(std::move(rtp_packet), fec_storage, | |
| 151 RtpPacketSender::kLowPriority)) { | |
| 146 rtc::CritScope cs(&stats_crit_); | 152 rtc::CritScope cs(&stats_crit_); | 
| 147 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 153 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 
| 148 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 154 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 
| 149 "Video::PacketFec", "timestamp", capture_timestamp, | 155 "Video::PacketFec", "timestamp", capture_timestamp, | 
| 150 "seqnum", next_fec_sequence_number); | 156 "seqnum", next_fec_sequence_number); | 
| 151 } else { | 157 } else { | 
| 152 LOG(LS_WARNING) << "Failed to send FEC packet " | 158 LOG(LS_WARNING) << "Failed to send FEC packet " | 
| 153 << next_fec_sequence_number; | 159 << next_fec_sequence_number; | 
| 154 } | 160 } | 
| 155 ++next_fec_sequence_number; | 161 ++next_fec_sequence_number; | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 172 uint8_t* payload_type_red, | 178 uint8_t* payload_type_red, | 
| 173 uint8_t* payload_type_fec) const { | 179 uint8_t* payload_type_fec) const { | 
| 174 rtc::CritScope cs(&crit_); | 180 rtc::CritScope cs(&crit_); | 
| 175 *enable = fec_enabled_; | 181 *enable = fec_enabled_; | 
| 176 *payload_type_red = red_payload_type_; | 182 *payload_type_red = red_payload_type_; | 
| 177 *payload_type_fec = fec_payload_type_; | 183 *payload_type_fec = fec_payload_type_; | 
| 178 } | 184 } | 
| 179 | 185 | 
| 180 size_t RTPSenderVideo::FECPacketOverhead() const { | 186 size_t RTPSenderVideo::FECPacketOverhead() const { | 
| 181 rtc::CritScope cs(&crit_); | 187 rtc::CritScope cs(&crit_); | 
| 182 size_t overhead = 0; | |
| 183 if (red_payload_type_ != 0) { | 188 if (red_payload_type_ != 0) { | 
| 184 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 189 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 
| 185 // header beyond the 12 bytes base header (CSRC list, extensions...) | 190 // header beyond the 12 bytes base header (CSRC list, extensions...) | 
| 186 // This reason for the header extensions to be included here is that | 191 // This reason for the header extensions to be included here is that | 
| 187 // from an FEC viewpoint, they are part of the payload to be protected. | 192 // from an FEC viewpoint, they are part of the payload to be protected. | 
| 188 // (The base RTP header is already protected by the FEC header.) | 193 // (The base RTP header is already protected by the FEC header.) | 
| 189 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + | 194 return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength + | 
| 190 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); | 195 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); | 
| 191 } | 196 } | 
| 192 if (fec_enabled_) | 197 if (fec_enabled_) | 
| 193 overhead += ForwardErrorCorrection::PacketOverhead(); | 198 return ForwardErrorCorrection::PacketOverhead(); | 
| 194 return overhead; | 199 return 0; | 
| 195 } | 200 } | 
| 196 | 201 | 
| 197 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, | 202 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, | 
| 198 const FecProtectionParams* key_params) { | 203 const FecProtectionParams* key_params) { | 
| 199 rtc::CritScope cs(&crit_); | 204 rtc::CritScope cs(&crit_); | 
| 200 RTC_DCHECK(delta_params); | 205 RTC_DCHECK(delta_params); | 
| 201 RTC_DCHECK(key_params); | 206 RTC_DCHECK(key_params); | 
| 202 if (fec_enabled_) { | 207 if (fec_enabled_) { | 
| 203 delta_fec_params_ = *delta_params; | 208 delta_fec_params_ = *delta_params; | 
| 204 key_fec_params_ = *key_params; | 209 key_fec_params_ = *key_params; | 
| 205 } | 210 } | 
| 206 } | 211 } | 
| 207 | 212 | 
| 208 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, | 213 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, | 
| 209 FrameType frame_type, | 214 FrameType frame_type, | 
| 210 int8_t payload_type, | 215 int8_t payload_type, | 
| 211 uint32_t capture_timestamp, | 216 uint32_t capture_timestamp, | 
| 212 int64_t capture_time_ms, | 217 int64_t capture_time_ms, | 
| 213 const uint8_t* payload_data, | 218 const uint8_t* payload_data, | 
| 214 size_t payload_size, | 219 size_t payload_size, | 
| 215 const RTPFragmentationHeader* fragmentation, | 220 const RTPFragmentationHeader* fragmentation, | 
| 216 const RTPVideoHeader* video_header) { | 221 const RTPVideoHeader* video_header) { | 
| 217 if (payload_size == 0) | 222 if (payload_size == 0) | 
| 218 return false; | 223 return false; | 
| 219 | 224 | 
| 225 size_t packet_capacity = rtp_sender_->MaxPayloadLength() - | |
| 226 FECPacketOverhead() - | |
| 227 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); | |
| 228 std::unique_ptr<RtpPacketToSend> packet = rtp_sender_->AllocatePacket(false); | |
| 229 if (!packet) | |
| 230 return false; | |
| 231 | |
| 232 RTC_DCHECK_LE(packet_capacity, packet->capacity()); | |
| 233 packet->SetPayloadType(payload_type); | |
| 234 packet->SetTimestamp(capture_timestamp); | |
| 235 packet->set_capture_time_ms(capture_time_ms); | |
| 236 if (video_header && video_header->rotation != kVideoRotation_0) | |
| 237 packet->SetExtension<VideoOrientation>(video_header->rotation); | |
| 238 // TODO(danilchap): Optionally set playout delay extension. | |
| 239 | |
| 240 size_t max_data_payload_length = packet_capacity - packet->headers_size(); | |
| 241 | |
| 220 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 242 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 
| 221 video_type, rtp_sender_->MaxDataPayloadLength(), | 243 video_type, max_data_payload_length, | 
| 222 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 244 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 
| 223 | 245 | 
| 224 StorageType storage; | 246 StorageType storage; | 
| 225 int red_payload_type; | 247 int red_payload_type; | 
| 226 bool first_frame = first_frame_sent_(); | 248 bool first_frame = first_frame_sent_(); | 
| 227 { | 249 { | 
| 228 rtc::CritScope cs(&crit_); | 250 rtc::CritScope cs(&crit_); | 
| 229 FecProtectionParams* fec_params = | 251 FecProtectionParams* fec_params = | 
| 230 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 252 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 
| 231 // We currently do not use unequal protection in the FEC. | 253 // We currently do not use unequal protection in the FEC. | 
| 232 // This is signalled both here (by setting the number of important | 254 // This is signalled both here (by setting the number of important | 
| 233 // packets to zero), as well as in ProducerFec::AddRtpPacketAndGenerateFec. | 255 // packets to zero), as well as in ProducerFec::AddRtpPacketAndGenerateFec. | 
| 234 constexpr int kNumImportantPackets = 0; | 256 constexpr int kNumImportantPackets = 0; | 
| 235 producer_fec_.SetFecParameters(fec_params, kNumImportantPackets); | 257 producer_fec_.SetFecParameters(fec_params, kNumImportantPackets); | 
| 236 storage = packetizer->GetStorageType(retransmission_settings_); | 258 storage = packetizer->GetStorageType(retransmission_settings_); | 
| 237 red_payload_type = red_payload_type_; | 259 red_payload_type = red_payload_type_; | 
| 238 } | 260 } | 
| 239 | 261 | 
| 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 | 262 // TODO(changbin): we currently don't support to configure the codec to | 
| 252 // output multiple partitions for VP8. Should remove below check after the | 263 // output multiple partitions for VP8. Should remove below check after the | 
| 253 // issue is fixed. | 264 // issue is fixed. | 
| 254 const RTPFragmentationHeader* frag = | 265 const RTPFragmentationHeader* frag = | 
| 255 (video_type == kRtpVideoVp8) ? NULL : fragmentation; | 266 (video_type == kRtpVideoVp8) ? NULL : fragmentation; | 
| 256 | 267 | 
| 257 packetizer->SetPayloadData(data, payload_bytes_to_send, frag); | 268 packetizer->SetPayloadData(payload_data, payload_size, frag); | 
| 258 | 269 | 
| 259 bool first = true; | 270 bool first = true; | 
| 260 bool last = false; | 271 bool last = false; | 
| 261 while (!last) { | 272 while (!last) { | 
| 262 uint8_t dataBuffer[IP_PACKET_SIZE] = {0}; | |
| 263 size_t payload_bytes_in_packet = 0; | 273 size_t payload_bytes_in_packet = 0; | 
| 264 | 274 if (!packetizer->NextPacket( | 
| 265 if (!packetizer->NextPacket(&dataBuffer[rtp_header_length], | 275 packet->AllocatePayload(max_data_payload_length), | 
| 266 &payload_bytes_in_packet, &last)) { | 276 &payload_bytes_in_packet, &last)) { | 
| 267 return false; | 277 return false; | 
| 268 } | 278 } | 
| 279 packet->SetPayloadSize(payload_bytes_in_packet); | |
| 280 packet->SetMarker(last); | |
| 269 | 281 | 
| 270 // Write RTP header. | 282 std::unique_ptr<RtpPacketToSend> packet_to_send = std::move(packet); | 
| 271 int32_t header_length = rtp_sender_->BuildRtpHeader( | 283 if (!last) { | 
| 272 dataBuffer, payload_type, last, capture_timestamp, capture_time_ms); | 284 // Allocate next packet and copy all headers. | 
| 273 if (header_length <= 0) | 285 packet = rtp_sender_->AllocatePacket(false); | 
| 274 return false; | 286 packet->CopyHeaderFrom(*packet_to_send); | 
| 287 packet->set_capture_time_ms(packet_to_send->capture_time_ms()); | |
| 288 } | |
| 275 | 289 | 
| 276 // According to | |
| 277 // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ | |
| 278 // ts_126114v120700p.pdf Section 7.4.5: | |
| 279 // The MTSI client shall add the payload bytes as defined in this clause | |
| 280 // onto the last RTP packet in each group of packets which make up a key | |
| 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) { | 290 if (red_payload_type != 0) { | 
| 304 SendVideoPacketAsRed(dataBuffer, payload_bytes_in_packet, | 291 SendVideoPacketAsRed(std::move(packet_to_send), storage, | 
| 305 rtp_header_length, rtp_sender_->SequenceNumber(), | |
| 306 capture_timestamp, capture_time_ms, storage, | |
| 307 packetizer->GetProtectionType() == kProtectedPacket); | 292 packetizer->GetProtectionType() == kProtectedPacket); | 
| 308 } else { | 293 } else { | 
| 309 SendVideoPacket(dataBuffer, payload_bytes_in_packet, rtp_header_length, | 294 SendVideoPacket(std::move(packet_to_send), storage); | 
| 310 rtp_sender_->SequenceNumber(), capture_timestamp, | |
| 311 capture_time_ms, storage); | |
| 312 } | 295 } | 
| 313 | 296 | 
| 314 if (first_frame) { | 297 if (first_frame) { | 
| 315 if (first) { | 298 if (first) { | 
| 316 LOG(LS_INFO) | 299 LOG(LS_INFO) | 
| 317 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 300 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 
| 318 } | 301 } | 
| 319 if (last) { | 302 if (last) { | 
| 320 LOG(LS_INFO) | 303 LOG(LS_INFO) | 
| 321 << "Sent last RTP packet of the first video frame (pre-pacer)"; | 304 << "Sent last RTP packet of the first video frame (pre-pacer)"; | 
| (...skipping 21 matching lines...) Expand all Loading... | |
| 343 rtc::CritScope cs(&crit_); | 326 rtc::CritScope cs(&crit_); | 
| 344 return retransmission_settings_; | 327 return retransmission_settings_; | 
| 345 } | 328 } | 
| 346 | 329 | 
| 347 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 330 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 
| 348 rtc::CritScope cs(&crit_); | 331 rtc::CritScope cs(&crit_); | 
| 349 retransmission_settings_ = settings; | 332 retransmission_settings_ = settings; | 
| 350 } | 333 } | 
| 351 | 334 | 
| 352 } // namespace webrtc | 335 } // namespace webrtc | 
| OLD | NEW |