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