OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 const std::vector<webrtc::RtpExtension>& extensions, | 256 const std::vector<webrtc::RtpExtension>& extensions, |
257 const std::string& name) { | 257 const std::string& name) { |
258 for (const auto& kv : extensions) { | 258 for (const auto& kv : extensions) { |
259 if (kv.name == name) { | 259 if (kv.name == name) { |
260 return true; | 260 return true; |
261 } | 261 } |
262 } | 262 } |
263 return false; | 263 return false; |
264 } | 264 } |
265 | 265 |
266 // Merges two fec configs and logs an error if a conflict arises | |
267 // such that merging in different order would trigger a different output. | |
268 static void MergeFecConfig(const webrtc::FecConfig& other, | |
269 webrtc::FecConfig* output) { | |
270 if (other.ulpfec_payload_type != -1) { | |
271 if (output->ulpfec_payload_type != -1 && | |
272 output->ulpfec_payload_type != other.ulpfec_payload_type) { | |
273 LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " | |
274 << output->ulpfec_payload_type << " and " | |
275 << other.ulpfec_payload_type; | |
276 } | |
277 output->ulpfec_payload_type = other.ulpfec_payload_type; | |
278 } | |
279 if (other.red_payload_type != -1) { | |
280 if (output->red_payload_type != -1 && | |
281 output->red_payload_type != other.red_payload_type) { | |
282 LOG(LS_WARNING) << "Conflict merging red_payload_type configs: " | |
283 << output->red_payload_type << " and " | |
284 << other.red_payload_type; | |
285 } | |
286 output->red_payload_type = other.red_payload_type; | |
287 } | |
288 if (other.red_rtx_payload_type != -1) { | |
289 if (output->red_rtx_payload_type != -1 && | |
290 output->red_rtx_payload_type != other.red_rtx_payload_type) { | |
291 LOG(LS_WARNING) << "Conflict merging red_rtx_payload_type configs: " | |
292 << output->red_rtx_payload_type << " and " | |
293 << other.red_rtx_payload_type; | |
294 } | |
295 output->red_rtx_payload_type = other.red_rtx_payload_type; | |
296 } | |
297 } | |
298 | |
299 // Returns true if the given codec is disallowed from doing simulcast. | 266 // Returns true if the given codec is disallowed from doing simulcast. |
300 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { | 267 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { |
301 return CodecNamesEq(codec_name, kH264CodecName) || | 268 return CodecNamesEq(codec_name, kH264CodecName) || |
302 CodecNamesEq(codec_name, kVp9CodecName); | 269 CodecNamesEq(codec_name, kVp9CodecName); |
303 } | 270 } |
304 | 271 |
305 // The selected thresholds for QVGA and VGA corresponded to a QP around 10. | 272 // The selected thresholds for QVGA and VGA corresponded to a QP around 10. |
306 // The change in QP declined above the selected bitrates. | 273 // The change in QP declined above the selected bitrates. |
307 static int GetMaxDefaultVideoBitrateKbps(int width, int height) { | 274 static int GetMaxDefaultVideoBitrateKbps(int width, int height) { |
308 if (width * height <= 320 * 240) { | 275 if (width * height <= 320 * 240) { |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 const VideoOptions& options, | 642 const VideoOptions& options, |
676 const std::vector<VideoCodec>& recv_codecs, | 643 const std::vector<VideoCodec>& recv_codecs, |
677 WebRtcVideoEncoderFactory* external_encoder_factory, | 644 WebRtcVideoEncoderFactory* external_encoder_factory, |
678 WebRtcVideoDecoderFactory* external_decoder_factory) | 645 WebRtcVideoDecoderFactory* external_decoder_factory) |
679 : VideoMediaChannel(config), | 646 : VideoMediaChannel(config), |
680 call_(call), | 647 call_(call), |
681 unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), | 648 unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), |
682 video_config_(config.video), | 649 video_config_(config.video), |
683 external_encoder_factory_(external_encoder_factory), | 650 external_encoder_factory_(external_encoder_factory), |
684 external_decoder_factory_(external_decoder_factory), | 651 external_decoder_factory_(external_decoder_factory), |
685 default_send_options_(options) { | 652 default_send_options_(options), |
| 653 red_disabled_by_remote_side_(false) { |
686 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 654 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
687 | 655 |
688 rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; | 656 rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; |
689 sending_ = false; | 657 sending_ = false; |
690 RTC_DCHECK(ValidateCodecFormats(recv_codecs)); | 658 RTC_DCHECK(ValidateCodecFormats(recv_codecs)); |
691 recv_codecs_ = FilterSupportedCodecs(MapCodecs(recv_codecs)); | 659 recv_codecs_ = FilterSupportedCodecs(MapCodecs(recv_codecs)); |
692 } | 660 } |
693 | 661 |
694 WebRtcVideoChannel2::~WebRtcVideoChannel2() { | 662 WebRtcVideoChannel2::~WebRtcVideoChannel2() { |
695 for (auto& kv : send_streams_) | 663 for (auto& kv : send_streams_) |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 "codec or RTCP mode has changed."; | 833 "codec or RTCP mode has changed."; |
866 for (auto& kv : receive_streams_) { | 834 for (auto& kv : receive_streams_) { |
867 RTC_DCHECK(kv.second != nullptr); | 835 RTC_DCHECK(kv.second != nullptr); |
868 kv.second->SetFeedbackParameters( | 836 kv.second->SetFeedbackParameters( |
869 HasNack(send_codec_->codec), HasRemb(send_codec_->codec), | 837 HasNack(send_codec_->codec), HasRemb(send_codec_->codec), |
870 HasTransportCc(send_codec_->codec), | 838 HasTransportCc(send_codec_->codec), |
871 params.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize | 839 params.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize |
872 : webrtc::RtcpMode::kCompound); | 840 : webrtc::RtcpMode::kCompound); |
873 } | 841 } |
874 } | 842 } |
| 843 if (changed_params.codec) { |
| 844 bool red_was_disabled = red_disabled_by_remote_side_; |
| 845 red_disabled_by_remote_side_ = |
| 846 changed_params.codec->fec.red_payload_type == -1; |
| 847 if (red_was_disabled != red_disabled_by_remote_side_) { |
| 848 for (auto& kv : receive_streams_) { |
| 849 // In practice VideoChannel::SetRemoteContent appears to most of the |
| 850 // time also call UpdateRemoteStreams, which recreates the receive |
| 851 // streams. If that's always true this call isn't needed. |
| 852 kv.second->SetFecDisabledRemotely(red_disabled_by_remote_side_); |
| 853 } |
| 854 } |
| 855 } |
875 } | 856 } |
876 send_params_ = params; | 857 send_params_ = params; |
877 return true; | 858 return true; |
878 } | 859 } |
879 | 860 |
880 webrtc::RtpParameters WebRtcVideoChannel2::GetRtpSendParameters( | 861 webrtc::RtpParameters WebRtcVideoChannel2::GetRtpSendParameters( |
881 uint32_t ssrc) const { | 862 uint32_t ssrc) const { |
882 rtc::CritScope stream_lock(&stream_crit_); | 863 rtc::CritScope stream_lock(&stream_crit_); |
883 auto it = send_streams_.find(ssrc); | 864 auto it = send_streams_.find(ssrc); |
884 if (it == send_streams_.end()) { | 865 if (it == send_streams_.end()) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 config.sync_group = sp.sync_label; | 1211 config.sync_group = sp.sync_label; |
1231 | 1212 |
1232 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; | 1213 config.rtp.remb = send_codec_ ? HasRemb(send_codec_->codec) : false; |
1233 config.rtp.transport_cc = | 1214 config.rtp.transport_cc = |
1234 send_codec_ ? HasTransportCc(send_codec_->codec) : false; | 1215 send_codec_ ? HasTransportCc(send_codec_->codec) : false; |
1235 config.disable_prerenderer_smoothing = | 1216 config.disable_prerenderer_smoothing = |
1236 video_config_.disable_prerenderer_smoothing; | 1217 video_config_.disable_prerenderer_smoothing; |
1237 | 1218 |
1238 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( | 1219 receive_streams_[ssrc] = new WebRtcVideoReceiveStream( |
1239 call_, sp, config, external_decoder_factory_, default_stream, | 1220 call_, sp, config, external_decoder_factory_, default_stream, |
1240 recv_codecs_); | 1221 recv_codecs_, red_disabled_by_remote_side_); |
1241 | 1222 |
1242 return true; | 1223 return true; |
1243 } | 1224 } |
1244 | 1225 |
1245 void WebRtcVideoChannel2::ConfigureReceiverRtp( | 1226 void WebRtcVideoChannel2::ConfigureReceiverRtp( |
1246 webrtc::VideoReceiveStream::Config* config, | 1227 webrtc::VideoReceiveStream::Config* config, |
1247 const StreamParams& sp) const { | 1228 const StreamParams& sp) const { |
1248 uint32_t ssrc = sp.first_ssrc(); | 1229 uint32_t ssrc = sp.first_ssrc(); |
1249 | 1230 |
1250 config->rtp.remote_ssrc = ssrc; | 1231 config->rtp.remote_ssrc = ssrc; |
(...skipping 15 matching lines...) Expand all Loading... |
1266 // (receive-only) or know a good local SSRC. | 1247 // (receive-only) or know a good local SSRC. |
1267 if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { | 1248 if (config->rtp.remote_ssrc == config->rtp.local_ssrc) { |
1268 if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { | 1249 if (config->rtp.local_ssrc != kDefaultRtcpReceiverReportSsrc) { |
1269 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; | 1250 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc; |
1270 } else { | 1251 } else { |
1271 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; | 1252 config->rtp.local_ssrc = kDefaultRtcpReceiverReportSsrc + 1; |
1272 } | 1253 } |
1273 } | 1254 } |
1274 | 1255 |
1275 for (size_t i = 0; i < recv_codecs_.size(); ++i) { | 1256 for (size_t i = 0; i < recv_codecs_.size(); ++i) { |
1276 MergeFecConfig(recv_codecs_[i].fec, &config->rtp.fec); | |
1277 } | |
1278 | |
1279 for (size_t i = 0; i < recv_codecs_.size(); ++i) { | |
1280 uint32_t rtx_ssrc; | 1257 uint32_t rtx_ssrc; |
1281 if (recv_codecs_[i].rtx_payload_type != -1 && | 1258 if (recv_codecs_[i].rtx_payload_type != -1 && |
1282 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { | 1259 sp.GetFidSsrc(ssrc, &rtx_ssrc)) { |
1283 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = | 1260 webrtc::VideoReceiveStream::Config::Rtp::Rtx& rtx = |
1284 config->rtp.rtx[recv_codecs_[i].codec.id]; | 1261 config->rtp.rtx[recv_codecs_[i].codec.id]; |
1285 rtx.ssrc = rtx_ssrc; | 1262 rtx.ssrc = rtx_ssrc; |
1286 rtx.payload_type = recv_codecs_[i].rtx_payload_type; | 1263 rtx.payload_type = recv_codecs_[i].rtx_payload_type; |
1287 } | 1264 } |
1288 } | 1265 } |
1289 } | 1266 } |
(...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 stream_->Start(); | 2209 stream_->Start(); |
2233 } | 2210 } |
2234 } | 2211 } |
2235 | 2212 |
2236 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( | 2213 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( |
2237 webrtc::Call* call, | 2214 webrtc::Call* call, |
2238 const StreamParams& sp, | 2215 const StreamParams& sp, |
2239 const webrtc::VideoReceiveStream::Config& config, | 2216 const webrtc::VideoReceiveStream::Config& config, |
2240 WebRtcVideoDecoderFactory* external_decoder_factory, | 2217 WebRtcVideoDecoderFactory* external_decoder_factory, |
2241 bool default_stream, | 2218 bool default_stream, |
2242 const std::vector<VideoCodecSettings>& recv_codecs) | 2219 const std::vector<VideoCodecSettings>& recv_codecs, |
| 2220 bool red_disabled_by_remote_side) |
2243 : call_(call), | 2221 : call_(call), |
2244 ssrcs_(sp.ssrcs), | 2222 ssrcs_(sp.ssrcs), |
2245 ssrc_groups_(sp.ssrc_groups), | 2223 ssrc_groups_(sp.ssrc_groups), |
2246 stream_(NULL), | 2224 stream_(NULL), |
2247 default_stream_(default_stream), | 2225 default_stream_(default_stream), |
2248 config_(config), | 2226 config_(config), |
| 2227 red_disabled_by_remote_side_(red_disabled_by_remote_side), |
2249 external_decoder_factory_(external_decoder_factory), | 2228 external_decoder_factory_(external_decoder_factory), |
2250 sink_(NULL), | 2229 sink_(NULL), |
2251 last_width_(-1), | 2230 last_width_(-1), |
2252 last_height_(-1), | 2231 last_height_(-1), |
2253 first_frame_timestamp_(-1), | 2232 first_frame_timestamp_(-1), |
2254 estimated_remote_start_ntp_time_ms_(0) { | 2233 estimated_remote_start_ntp_time_ms_(0) { |
2255 config_.renderer = this; | 2234 config_.renderer = this; |
2256 std::vector<AllocatedDecoder> old_decoders; | 2235 std::vector<AllocatedDecoder> old_decoders; |
2257 ConfigureCodecs(recv_codecs, &old_decoders); | 2236 ConfigureCodecs(recv_codecs, &old_decoders); |
2258 RecreateWebRtcStream(); | 2237 RecreateWebRtcStream(); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2414 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; | 2393 LOG(LS_INFO) << "RecreateWebRtcStream (recv) because of SetRecvParameters"; |
2415 RecreateWebRtcStream(); | 2394 RecreateWebRtcStream(); |
2416 ClearDecoders(&old_decoders); | 2395 ClearDecoders(&old_decoders); |
2417 } | 2396 } |
2418 } | 2397 } |
2419 | 2398 |
2420 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { | 2399 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::RecreateWebRtcStream() { |
2421 if (stream_ != NULL) { | 2400 if (stream_ != NULL) { |
2422 call_->DestroyVideoReceiveStream(stream_); | 2401 call_->DestroyVideoReceiveStream(stream_); |
2423 } | 2402 } |
2424 stream_ = call_->CreateVideoReceiveStream(config_); | 2403 webrtc::VideoReceiveStream::Config config = config_; |
| 2404 if (red_disabled_by_remote_side_) { |
| 2405 config.rtp.fec.red_payload_type = -1; |
| 2406 config.rtp.fec.ulpfec_payload_type = -1; |
| 2407 config.rtp.fec.red_rtx_payload_type = -1; |
| 2408 } |
| 2409 stream_ = call_->CreateVideoReceiveStream(config); |
2425 stream_->Start(); | 2410 stream_->Start(); |
2426 } | 2411 } |
2427 | 2412 |
2428 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( | 2413 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ClearDecoders( |
2429 std::vector<AllocatedDecoder>* allocated_decoders) { | 2414 std::vector<AllocatedDecoder>* allocated_decoders) { |
2430 for (size_t i = 0; i < allocated_decoders->size(); ++i) { | 2415 for (size_t i = 0; i < allocated_decoders->size(); ++i) { |
2431 if ((*allocated_decoders)[i].external) { | 2416 if ((*allocated_decoders)[i].external) { |
2432 external_decoder_factory_->DestroyVideoDecoder( | 2417 external_decoder_factory_->DestroyVideoDecoder( |
2433 (*allocated_decoders)[i].external_decoder); | 2418 (*allocated_decoders)[i].external_decoder); |
2434 } | 2419 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2522 | 2507 |
2523 info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); | 2508 info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); |
2524 | 2509 |
2525 info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; | 2510 info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; |
2526 info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; | 2511 info.plis_sent = stats.rtcp_packet_type_counts.pli_packets; |
2527 info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; | 2512 info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets; |
2528 | 2513 |
2529 return info; | 2514 return info; |
2530 } | 2515 } |
2531 | 2516 |
| 2517 void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetFecDisabledRemotely( |
| 2518 bool disable) { |
| 2519 red_disabled_by_remote_side_ = disable; |
| 2520 RecreateWebRtcStream(); |
| 2521 } |
| 2522 |
2532 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() | 2523 WebRtcVideoChannel2::VideoCodecSettings::VideoCodecSettings() |
2533 : rtx_payload_type(-1) {} | 2524 : rtx_payload_type(-1) {} |
2534 | 2525 |
2535 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( | 2526 bool WebRtcVideoChannel2::VideoCodecSettings::operator==( |
2536 const WebRtcVideoChannel2::VideoCodecSettings& other) const { | 2527 const WebRtcVideoChannel2::VideoCodecSettings& other) const { |
2537 return codec == other.codec && | 2528 return codec == other.codec && |
2538 fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && | 2529 fec.ulpfec_payload_type == other.fec.ulpfec_payload_type && |
2539 fec.red_payload_type == other.fec.red_payload_type && | 2530 fec.red_payload_type == other.fec.red_payload_type && |
2540 fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && | 2531 fec.red_rtx_payload_type == other.fec.red_rtx_payload_type && |
2541 rtx_payload_type == other.rtx_payload_type; | 2532 rtx_payload_type == other.rtx_payload_type; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2635 rtx_mapping[video_codecs[i].codec.id] != | 2626 rtx_mapping[video_codecs[i].codec.id] != |
2636 fec_settings.red_payload_type) { | 2627 fec_settings.red_payload_type) { |
2637 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2628 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
2638 } | 2629 } |
2639 } | 2630 } |
2640 | 2631 |
2641 return video_codecs; | 2632 return video_codecs; |
2642 } | 2633 } |
2643 | 2634 |
2644 } // namespace cricket | 2635 } // namespace cricket |
OLD | NEW |