Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 } | 70 } |
| 71 | 71 |
| 72 void Destroy(webrtc::VideoEncoder* encoder) override { | 72 void Destroy(webrtc::VideoEncoder* encoder) override { |
| 73 return factory_->DestroyVideoEncoder(encoder); | 73 return factory_->DestroyVideoEncoder(encoder); |
| 74 } | 74 } |
| 75 | 75 |
| 76 private: | 76 private: |
| 77 cricket::WebRtcVideoEncoderFactory* const factory_; | 77 cricket::WebRtcVideoEncoderFactory* const factory_; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 webrtc::Call::Config::BitrateConfig GetBitrateConfigForCodec( | |
| 81 const VideoCodec& codec) { | |
| 82 webrtc::Call::Config::BitrateConfig config; | |
| 83 int bitrate_kbps; | |
| 84 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && | |
| 85 bitrate_kbps > 0) { | |
| 86 config.min_bitrate_bps = bitrate_kbps * 1000; | |
| 87 } else { | |
| 88 config.min_bitrate_bps = 0; | |
| 89 } | |
| 90 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && | |
| 91 bitrate_kbps > 0) { | |
| 92 config.start_bitrate_bps = bitrate_kbps * 1000; | |
| 93 } else { | |
| 94 // Do not reconfigure start bitrate unless it's specified and positive. | |
| 95 config.start_bitrate_bps = -1; | |
| 96 } | |
| 97 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && | |
| 98 bitrate_kbps > 0) { | |
| 99 config.max_bitrate_bps = bitrate_kbps * 1000; | |
| 100 } else { | |
| 101 config.max_bitrate_bps = -1; | |
| 102 } | |
| 103 return config; | |
| 104 } | |
| 105 | |
| 80 // An encoder factory that wraps Create requests for simulcastable codec types | 106 // An encoder factory that wraps Create requests for simulcastable codec types |
| 81 // with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type | 107 // with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type |
| 82 // requests are just passed through to the contained encoder factory. | 108 // requests are just passed through to the contained encoder factory. |
| 83 class WebRtcSimulcastEncoderFactory | 109 class WebRtcSimulcastEncoderFactory |
| 84 : public cricket::WebRtcVideoEncoderFactory { | 110 : public cricket::WebRtcVideoEncoderFactory { |
| 85 public: | 111 public: |
| 86 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is | 112 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is |
| 87 // owned by e.g. PeerConnectionFactory. | 113 // owned by e.g. PeerConnectionFactory. |
| 88 explicit WebRtcSimulcastEncoderFactory( | 114 explicit WebRtcSimulcastEncoderFactory( |
| 89 cricket::WebRtcVideoEncoderFactory* factory) | 115 cricket::WebRtcVideoEncoderFactory* factory) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { | 262 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { |
| 237 LOG(LS_ERROR) | 263 LOG(LS_ERROR) |
| 238 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " | 264 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " |
| 239 << sp.ToString(); | 265 << sp.ToString(); |
| 240 return false; | 266 return false; |
| 241 } | 267 } |
| 242 | 268 |
| 243 return true; | 269 return true; |
| 244 } | 270 } |
| 245 | 271 |
| 246 inline const webrtc::RtpExtension* FindHeaderExtension( | 272 inline bool ContainsHeaderExtension( |
| 247 const std::vector<webrtc::RtpExtension>& extensions, | 273 const std::vector<webrtc::RtpExtension>& extensions, |
| 248 const std::string& name) { | 274 const std::string& name) { |
| 249 for (const auto& kv : extensions) { | 275 for (const auto& kv : extensions) { |
| 250 if (kv.name == name) { | 276 if (kv.name == name) { |
| 251 return &kv; | 277 return true; |
| 252 } | 278 } |
| 253 } | 279 } |
| 254 return NULL; | 280 return false; |
| 255 } | 281 } |
| 256 | 282 |
| 257 // Merges two fec configs and logs an error if a conflict arises | 283 // Merges two fec configs and logs an error if a conflict arises |
| 258 // such that merging in different order would trigger a different output. | 284 // such that merging in different order would trigger a different output. |
| 259 static void MergeFecConfig(const webrtc::FecConfig& other, | 285 static void MergeFecConfig(const webrtc::FecConfig& other, |
| 260 webrtc::FecConfig* output) { | 286 webrtc::FecConfig* output) { |
| 261 if (other.ulpfec_payload_type != -1) { | 287 if (other.ulpfec_payload_type != -1) { |
| 262 if (output->ulpfec_payload_type != -1 && | 288 if (output->ulpfec_payload_type != -1 && |
| 263 output->ulpfec_payload_type != other.ulpfec_payload_type) { | 289 output->ulpfec_payload_type != other.ulpfec_payload_type) { |
| 264 LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " | 290 LOG(LS_WARNING) << "Conflict merging ulpfec_payload_type configs: " |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 encoder_factory->codecs())) { | 566 encoder_factory->codecs())) { |
| 541 simulcast_encoder_factory_.reset( | 567 simulcast_encoder_factory_.reset( |
| 542 new WebRtcSimulcastEncoderFactory(encoder_factory)); | 568 new WebRtcSimulcastEncoderFactory(encoder_factory)); |
| 543 encoder_factory = simulcast_encoder_factory_.get(); | 569 encoder_factory = simulcast_encoder_factory_.get(); |
| 544 } | 570 } |
| 545 external_encoder_factory_ = encoder_factory; | 571 external_encoder_factory_ = encoder_factory; |
| 546 | 572 |
| 547 video_codecs_ = GetSupportedCodecs(); | 573 video_codecs_ = GetSupportedCodecs(); |
| 548 } | 574 } |
| 549 | 575 |
| 550 bool WebRtcVideoEngine2::EnableTimedRender() { | |
| 551 // TODO(pbos): Figure out whether this can be removed. | |
| 552 return true; | |
| 553 } | |
| 554 | |
| 555 // Checks to see whether we comprehend and could receive a particular codec | 576 // Checks to see whether we comprehend and could receive a particular codec |
| 556 bool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { | 577 bool WebRtcVideoEngine2::FindCodec(const VideoCodec& in) { |
| 557 // TODO(pbos): Probe encoder factory to figure out that the codec is supported | 578 // TODO(pbos): Probe encoder factory to figure out that the codec is supported |
| 558 // if supported by the encoder factory. Add a corresponding test that fails | 579 // if supported by the encoder factory. Add a corresponding test that fails |
| 559 // with this code (that doesn't ask the factory). | 580 // with this code (that doesn't ask the factory). |
| 560 for (size_t j = 0; j < video_codecs_.size(); ++j) { | 581 for (size_t j = 0; j < video_codecs_.size(); ++j) { |
| 561 VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); | 582 VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0); |
| 562 if (codec.Matches(in)) { | 583 if (codec.Matches(in)) { |
| 563 return true; | 584 return true; |
| 564 } | 585 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 703 // side to cause recreation of the stream. | 724 // side to cause recreation of the stream. |
| 704 before[i].codec.preference = 0; | 725 before[i].codec.preference = 0; |
| 705 after[i].codec.preference = 0; | 726 after[i].codec.preference = 0; |
| 706 if (before[i] != after[i]) { | 727 if (before[i] != after[i]) { |
| 707 return true; | 728 return true; |
| 708 } | 729 } |
| 709 } | 730 } |
| 710 return false; | 731 return false; |
| 711 } | 732 } |
| 712 | 733 |
| 734 bool WebRtcVideoChannel2::GetChangedSendParameters( | |
| 735 const VideoSendParameters& params, | |
| 736 ChangedSendParameters* changed_params) const { | |
| 737 if (!ValidateCodecFormats(params.codecs) || | |
| 738 !ValidateRtpExtensions(params.extensions)) { | |
| 739 return false; | |
| 740 } | |
| 741 | |
| 742 // ==== SEND CODEC ==== | |
| 743 const std::vector<VideoCodecSettings> supported_codecs = | |
| 744 FilterSupportedCodecs(MapCodecs(params.codecs)); | |
| 745 | |
| 746 if (supported_codecs.empty()) { | |
| 747 LOG(LS_ERROR) << "No video codecs supported."; | |
| 748 return false; | |
| 749 } | |
| 750 | |
| 751 if (!send_codec_ || supported_codecs.front() != *send_codec_) { | |
| 752 // Send codec has changed. | |
| 753 changed_params->codec = | |
| 754 rtc::Optional<VideoCodecSettings>(supported_codecs.front()); | |
| 755 } | |
| 756 | |
| 757 // ==== RTP HEADER EXTENSIONS ==== | |
| 758 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( | |
| 759 params.extensions, webrtc::RtpExtension::IsSupportedForVideo, true); | |
| 760 if (send_rtp_extensions_ != filtered_extensions) { | |
| 761 changed_params->rtp_header_extensions = | |
| 762 rtc::Optional<std::vector<webrtc::RtpExtension>>(filtered_extensions); | |
| 763 } | |
| 764 | |
| 765 // ==== MAX BITRATE ==== | |
| 766 if (params.max_bandwidth_bps != bitrate_config_.max_bitrate_bps && | |
| 767 params.max_bandwidth_bps >= 0) { | |
| 768 // 0 uncaps max bitrate (-1). | |
| 769 changed_params->max_bandwidth_bps = rtc::Optional<int>( | |
| 770 params.max_bandwidth_bps == 0 ? -1 : params.max_bandwidth_bps); | |
| 771 } | |
| 772 | |
| 773 // ==== OPTIONS ==== | |
| 774 // TODO(pbos): Require VideoSendParameters to contain a full set of options | |
| 775 // and check if params.options != options_ instead of applying a delta. | |
| 776 VideoOptions new_options = options_; | |
| 777 new_options.SetAll(params.options); | |
| 778 if (!(new_options == options_)) { | |
| 779 changed_params->options = rtc::Optional<VideoOptions>(new_options); | |
| 780 } | |
| 781 | |
| 782 changed_params->rtcp_mode = params.rtcp.reduced_size | |
| 783 ? webrtc::RtcpMode::kReducedSize | |
| 784 : webrtc::RtcpMode::kCompound; | |
|
pthatcher1
2016/01/26 23:00:41
Would it make sense to check send_params_.rtcp.red
pbos-webrtc
2016/01/27 15:43:42
Done for consistency.
| |
| 785 | |
| 786 return true; | |
| 787 } | |
| 788 | |
| 713 bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { | 789 bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { |
| 714 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendParameters"); | 790 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendParameters"); |
| 715 LOG(LS_INFO) << "SetSendParameters: " << params.ToString(); | 791 LOG(LS_INFO) << "SetSendParameters: " << params.ToString(); |
| 716 // TODO(pbos): Refactor this to only recreate the send streams once | 792 ChangedSendParameters changed_params; |
| 717 // instead of 4 times. | 793 if (!GetChangedSendParameters(params, &changed_params)) { |
| 718 if (!SetSendCodecs(params.codecs) || | |
| 719 !SetSendRtpHeaderExtensions(params.extensions) || | |
| 720 !SetMaxSendBandwidth(params.max_bandwidth_bps) || | |
| 721 !SetOptions(params.options)) { | |
| 722 return false; | 794 return false; |
| 723 } | 795 } |
| 724 if (send_params_.rtcp.reduced_size != params.rtcp.reduced_size) { | 796 |
| 797 bool bitrate_config_changed = false; | |
| 798 | |
| 799 if (changed_params.codec) { | |
| 800 const VideoCodecSettings& codec_settings = *changed_params.codec; | |
| 801 send_codec_ = rtc::Optional<VideoCodecSettings>(codec_settings); | |
| 802 | |
| 803 LOG(LS_INFO) << "Using codec: " << codec_settings.codec.ToString(); | |
| 804 // TODO(holmer): Changing the codec parameters shouldn't necessarily mean | |
| 805 // that we change the min/max of bandwidth estimation. Reevaluate this. | |
| 806 bitrate_config_ = GetBitrateConfigForCodec(codec_settings.codec); | |
| 807 bitrate_config_changed = true; | |
| 808 } | |
| 809 | |
| 810 if (changed_params.rtp_header_extensions) { | |
| 811 send_rtp_extensions_ = *changed_params.rtp_header_extensions; | |
| 812 } | |
| 813 | |
| 814 if (changed_params.max_bandwidth_bps) { | |
| 815 // TODO(pbos): Figure out whether b=AS means max bitrate for this | |
| 816 // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in | |
| 817 // which case this should not set a Call::BitrateConfig but rather | |
| 818 // reconfigure all senders. | |
| 819 int max_bitrate_bps = *changed_params.max_bandwidth_bps; | |
| 820 bitrate_config_.start_bitrate_bps = -1; | |
| 821 bitrate_config_.max_bitrate_bps = max_bitrate_bps; | |
| 822 if (max_bitrate_bps > 0 && | |
| 823 bitrate_config_.min_bitrate_bps > max_bitrate_bps) { | |
| 824 bitrate_config_.min_bitrate_bps = max_bitrate_bps; | |
| 825 } | |
|
pthatcher1
2016/01/26 23:00:42
Would it make sense to move this logic into GetCha
pbos-webrtc
2016/01/27 15:43:42
I think this unfortunately makes it more complex,
| |
| 826 bitrate_config_changed = true; | |
| 827 } | |
| 828 | |
| 829 if (bitrate_config_changed) { | |
| 830 call_->SetBitrateConfig(bitrate_config_); | |
| 831 } | |
| 832 | |
| 833 if (changed_params.options) { | |
| 834 options_.SetAll(*changed_params.options); | |
| 835 { | |
| 836 rtc::CritScope lock(&capturer_crit_); | |
| 837 if (options_.cpu_overuse_detection) { | |
| 838 signal_cpu_adaptation_ = *options_.cpu_overuse_detection; | |
| 839 } | |
| 840 } | |
| 841 rtc::DiffServCodePoint dscp = | |
| 842 options_.dscp.value_or(false) ? rtc::DSCP_AF41 : rtc::DSCP_DEFAULT; | |
| 843 MediaChannel::SetDscp(dscp); | |
| 844 } | |
| 845 | |
| 846 { | |
| 725 rtc::CritScope stream_lock(&stream_crit_); | 847 rtc::CritScope stream_lock(&stream_crit_); |
| 726 for (auto& kv : send_streams_) { | 848 for (auto& kv : send_streams_) { |
| 727 kv.second->SetSendParameters(params); | 849 kv.second->SetSendParameters(changed_params); |
| 850 } | |
| 851 if (changed_params.codec) { | |
| 852 // Update receive feedback parameters from new codec. | |
| 853 LOG(LS_INFO) | |
| 854 << "SetFeedbackOptions on all the receive streams because the send " | |
| 855 "codec has changed."; | |
| 856 for (auto& kv : receive_streams_) { | |
| 857 RTC_DCHECK(kv.second != nullptr); | |
| 858 kv.second->SetFeedbackParameters(HasNack(send_codec_->codec), | |
| 859 HasRemb(send_codec_->codec), | |
| 860 HasTransportCc(send_codec_->codec)); | |
| 861 } | |
| 728 } | 862 } |
| 729 } | 863 } |
| 730 send_params_ = params; | 864 send_params_ = params; |
| 731 return true; | 865 return true; |
| 732 } | 866 } |
| 733 | 867 |
| 734 bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { | 868 bool WebRtcVideoChannel2::SetRecvParameters(const VideoRecvParameters& params) { |
| 735 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvParameters"); | 869 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRecvParameters"); |
| 736 LOG(LS_INFO) << "SetRecvParameters: " << params.ToString(); | 870 LOG(LS_INFO) << "SetRecvParameters: " << params.ToString(); |
| 737 // TODO(pbos): Refactor this to only recreate the recv streams once | 871 // TODO(pbos): Refactor this to only recreate the recv streams once |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 rtc::CritScope stream_lock(&stream_crit_); | 934 rtc::CritScope stream_lock(&stream_crit_); |
| 801 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = | 935 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = |
| 802 receive_streams_.begin(); | 936 receive_streams_.begin(); |
| 803 it != receive_streams_.end(); ++it) { | 937 it != receive_streams_.end(); ++it) { |
| 804 it->second->SetRecvCodecs(recv_codecs_); | 938 it->second->SetRecvCodecs(recv_codecs_); |
| 805 } | 939 } |
| 806 | 940 |
| 807 return true; | 941 return true; |
| 808 } | 942 } |
| 809 | 943 |
| 810 bool WebRtcVideoChannel2::SetSendCodecs(const std::vector<VideoCodec>& codecs) { | |
| 811 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendCodecs"); | |
| 812 LOG(LS_INFO) << "SetSendCodecs: " << CodecVectorToString(codecs); | |
| 813 if (!ValidateCodecFormats(codecs)) { | |
| 814 return false; | |
| 815 } | |
| 816 | |
| 817 const std::vector<VideoCodecSettings> supported_codecs = | |
| 818 FilterSupportedCodecs(MapCodecs(codecs)); | |
| 819 | |
| 820 if (supported_codecs.empty()) { | |
| 821 LOG(LS_ERROR) << "No video codecs supported."; | |
| 822 return false; | |
| 823 } | |
| 824 | |
| 825 LOG(LS_INFO) << "Using codec: " << supported_codecs.front().codec.ToString(); | |
| 826 | |
| 827 if (send_codec_ && supported_codecs.front() == *send_codec_) { | |
| 828 LOG(LS_INFO) << "Ignore call to SetSendCodecs because first supported " | |
| 829 "codec hasn't changed."; | |
| 830 // Using same codec, avoid reconfiguring. | |
| 831 return true; | |
| 832 } | |
| 833 | |
| 834 send_codec_ = rtc::Optional<WebRtcVideoChannel2::VideoCodecSettings>( | |
| 835 supported_codecs.front()); | |
| 836 | |
| 837 rtc::CritScope stream_lock(&stream_crit_); | |
| 838 LOG(LS_INFO) << "Change the send codec because SetSendCodecs has a different " | |
| 839 "first supported codec."; | |
| 840 for (auto& kv : send_streams_) { | |
| 841 RTC_DCHECK(kv.second != nullptr); | |
| 842 kv.second->SetCodec(supported_codecs.front()); | |
| 843 } | |
| 844 LOG(LS_INFO) | |
| 845 << "SetFeedbackOptions on all the receive streams because the send " | |
| 846 "codec has changed."; | |
| 847 for (auto& kv : receive_streams_) { | |
| 848 RTC_DCHECK(kv.second != nullptr); | |
| 849 kv.second->SetFeedbackParameters( | |
| 850 HasNack(supported_codecs.front().codec), | |
| 851 HasRemb(supported_codecs.front().codec), | |
| 852 HasTransportCc(supported_codecs.front().codec)); | |
| 853 } | |
| 854 | |
| 855 // TODO(holmer): Changing the codec parameters shouldn't necessarily mean that | |
| 856 // we change the min/max of bandwidth estimation. Reevaluate this. | |
| 857 VideoCodec codec = supported_codecs.front().codec; | |
| 858 int bitrate_kbps; | |
| 859 if (codec.GetParam(kCodecParamMinBitrate, &bitrate_kbps) && | |
| 860 bitrate_kbps > 0) { | |
| 861 bitrate_config_.min_bitrate_bps = bitrate_kbps * 1000; | |
| 862 } else { | |
| 863 bitrate_config_.min_bitrate_bps = 0; | |
| 864 } | |
| 865 if (codec.GetParam(kCodecParamStartBitrate, &bitrate_kbps) && | |
| 866 bitrate_kbps > 0) { | |
| 867 bitrate_config_.start_bitrate_bps = bitrate_kbps * 1000; | |
| 868 } else { | |
| 869 // Do not reconfigure start bitrate unless it's specified and positive. | |
| 870 bitrate_config_.start_bitrate_bps = -1; | |
| 871 } | |
| 872 if (codec.GetParam(kCodecParamMaxBitrate, &bitrate_kbps) && | |
| 873 bitrate_kbps > 0) { | |
| 874 bitrate_config_.max_bitrate_bps = bitrate_kbps * 1000; | |
| 875 } else { | |
| 876 bitrate_config_.max_bitrate_bps = -1; | |
| 877 } | |
| 878 call_->SetBitrateConfig(bitrate_config_); | |
| 879 | |
| 880 return true; | |
| 881 } | |
| 882 | |
| 883 bool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { | 944 bool WebRtcVideoChannel2::GetSendCodec(VideoCodec* codec) { |
| 884 if (!send_codec_) { | 945 if (!send_codec_) { |
| 885 LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; | 946 LOG(LS_VERBOSE) << "GetSendCodec: No send codec set."; |
| 886 return false; | 947 return false; |
| 887 } | 948 } |
| 888 *codec = send_codec_->codec; | 949 *codec = send_codec_->codec; |
| 889 return true; | 950 return true; |
| 890 } | 951 } |
| 891 | 952 |
| 892 bool WebRtcVideoChannel2::SetSendStreamFormat(uint32_t ssrc, | 953 bool WebRtcVideoChannel2::SetSendStreamFormat(uint32_t ssrc, |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 910 StartAllSendStreams(); | 971 StartAllSendStreams(); |
| 911 } else { | 972 } else { |
| 912 StopAllSendStreams(); | 973 StopAllSendStreams(); |
| 913 } | 974 } |
| 914 sending_ = send; | 975 sending_ = send; |
| 915 return true; | 976 return true; |
| 916 } | 977 } |
| 917 | 978 |
| 918 bool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, | 979 bool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, |
| 919 const VideoOptions* options) { | 980 const VideoOptions* options) { |
| 981 TRACE_EVENT0("webrtc", "SetVideoSend"); | |
| 982 LOG(LS_INFO) << "SetVideoSend (ssrc= " << ssrc << ", enable = " << enable | |
| 983 << "options: " << (options ? options->ToString() : "nullptr") | |
| 984 << ")."; | |
| 985 | |
| 920 // TODO(solenberg): The state change should be fully rolled back if any one of | 986 // TODO(solenberg): The state change should be fully rolled back if any one of |
| 921 // these calls fail. | 987 // these calls fail. |
| 922 if (!MuteStream(ssrc, !enable)) { | 988 if (!MuteStream(ssrc, !enable)) { |
| 923 return false; | 989 return false; |
| 924 } | 990 } |
| 925 if (enable && options) { | 991 if (enable && options) { |
| 926 return SetOptions(*options); | 992 VideoSendParameters new_params = send_params_; |
| 927 } else { | 993 new_params.options.SetAll(*options); |
| 928 return true; | 994 SetSendParameters(send_params_); |
| 929 } | 995 } |
| 996 return true; | |
| 930 } | 997 } |
| 931 | 998 |
| 932 bool WebRtcVideoChannel2::ValidateSendSsrcAvailability( | 999 bool WebRtcVideoChannel2::ValidateSendSsrcAvailability( |
| 933 const StreamParams& sp) const { | 1000 const StreamParams& sp) const { |
| 934 for (uint32_t ssrc: sp.ssrcs) { | 1001 for (uint32_t ssrc: sp.ssrcs) { |
| 935 if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { | 1002 if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { |
| 936 LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; | 1003 LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists."; |
| 937 return false; | 1004 return false; |
| 938 } | 1005 } |
| 939 } | 1006 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1243 if (send_streams_.find(ssrc) == send_streams_.end()) { | 1310 if (send_streams_.find(ssrc) == send_streams_.end()) { |
| 1244 LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; | 1311 LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; |
| 1245 return false; | 1312 return false; |
| 1246 } | 1313 } |
| 1247 if (!send_streams_[ssrc]->SetCapturer(capturer)) { | 1314 if (!send_streams_[ssrc]->SetCapturer(capturer)) { |
| 1248 return false; | 1315 return false; |
| 1249 } | 1316 } |
| 1250 } | 1317 } |
| 1251 | 1318 |
| 1252 if (capturer) { | 1319 if (capturer) { |
| 1253 capturer->SetApplyRotation( | 1320 capturer->SetApplyRotation(!ContainsHeaderExtension( |
| 1254 !FindHeaderExtension(send_rtp_extensions_, | 1321 send_rtp_extensions_, kRtpVideoRotationHeaderExtension)); |
| 1255 kRtpVideoRotationHeaderExtension)); | |
| 1256 } | 1322 } |
| 1257 { | 1323 { |
| 1258 rtc::CritScope lock(&capturer_crit_); | 1324 rtc::CritScope lock(&capturer_crit_); |
| 1259 capturers_[ssrc] = capturer; | 1325 capturers_[ssrc] = capturer; |
| 1260 } | 1326 } |
| 1261 return true; | 1327 return true; |
| 1262 } | 1328 } |
| 1263 | 1329 |
| 1264 bool WebRtcVideoChannel2::SendIntraFrame() { | 1330 bool WebRtcVideoChannel2::SendIntraFrame() { |
| 1265 // TODO(pbos): Implement. | 1331 // TODO(pbos): Implement. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1382 | 1448 |
| 1383 rtc::CritScope stream_lock(&stream_crit_); | 1449 rtc::CritScope stream_lock(&stream_crit_); |
| 1384 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = | 1450 for (std::map<uint32_t, WebRtcVideoReceiveStream*>::iterator it = |
| 1385 receive_streams_.begin(); | 1451 receive_streams_.begin(); |
| 1386 it != receive_streams_.end(); ++it) { | 1452 it != receive_streams_.end(); ++it) { |
| 1387 it->second->SetRtpExtensions(recv_rtp_extensions_); | 1453 it->second->SetRtpExtensions(recv_rtp_extensions_); |
| 1388 } | 1454 } |
| 1389 return true; | 1455 return true; |
| 1390 } | 1456 } |
| 1391 | 1457 |
| 1392 bool WebRtcVideoChannel2::SetSendRtpHeaderExtensions( | 1458 // TODO(pbos): Remove SetOptions in favor of SetSendParameters. |
| 1393 const std::vector<RtpHeaderExtension>& extensions) { | 1459 void WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { |
| 1394 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetSendRtpHeaderExtensions"); | 1460 VideoSendParameters new_params = send_params_; |
| 1395 if (!ValidateRtpExtensions(extensions)) { | 1461 new_params.options.SetAll(options); |
| 1396 return false; | 1462 SetSendParameters(send_params_); |
| 1397 } | |
| 1398 std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions( | |
| 1399 extensions, webrtc::RtpExtension::IsSupportedForVideo, true); | |
| 1400 if (send_rtp_extensions_ == filtered_extensions) { | |
| 1401 LOG(LS_INFO) << "Ignoring call to SetRecvRtpHeaderExtensions because " | |
| 1402 "header extensions haven't changed."; | |
| 1403 return true; | |
| 1404 } | |
| 1405 send_rtp_extensions_.swap(filtered_extensions); | |
| 1406 | |
| 1407 const webrtc::RtpExtension* cvo_extension = FindHeaderExtension( | |
| 1408 send_rtp_extensions_, kRtpVideoRotationHeaderExtension); | |
| 1409 | |
| 1410 rtc::CritScope stream_lock(&stream_crit_); | |
| 1411 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = | |
| 1412 send_streams_.begin(); | |
| 1413 it != send_streams_.end(); ++it) { | |
| 1414 it->second->SetRtpExtensions(send_rtp_extensions_); | |
| 1415 it->second->SetApplyRotation(!cvo_extension); | |
| 1416 } | |
| 1417 return true; | |
| 1418 } | |
| 1419 | |
| 1420 // Counter-intuitively this method doesn't only set global bitrate caps but also | |
| 1421 // per-stream codec max bitrates. This is to permit SetMaxSendBitrate (b=AS) to | |
| 1422 // raise bitrates above the 2000k default bitrate cap. | |
| 1423 bool WebRtcVideoChannel2::SetMaxSendBandwidth(int max_bitrate_bps) { | |
| 1424 // TODO(pbos): Figure out whether b=AS means max bitrate for this | |
| 1425 // WebRtcVideoChannel2 (in which case we're good), or per sender (SSRC), in | |
| 1426 // which case this should not set a Call::BitrateConfig but rather reconfigure | |
| 1427 // all senders. | |
| 1428 LOG(LS_INFO) << "SetMaxSendBandwidth: " << max_bitrate_bps << "bps."; | |
| 1429 if (max_bitrate_bps == bitrate_config_.max_bitrate_bps) | |
| 1430 return true; | |
| 1431 | |
| 1432 if (max_bitrate_bps < 0) { | |
| 1433 // Option not set. | |
| 1434 return true; | |
| 1435 } | |
| 1436 if (max_bitrate_bps == 0) { | |
| 1437 // Unsetting max bitrate. | |
| 1438 max_bitrate_bps = -1; | |
| 1439 } | |
| 1440 bitrate_config_.start_bitrate_bps = -1; | |
| 1441 bitrate_config_.max_bitrate_bps = max_bitrate_bps; | |
| 1442 if (max_bitrate_bps > 0 && | |
| 1443 bitrate_config_.min_bitrate_bps > max_bitrate_bps) { | |
| 1444 bitrate_config_.min_bitrate_bps = max_bitrate_bps; | |
| 1445 } | |
| 1446 call_->SetBitrateConfig(bitrate_config_); | |
| 1447 rtc::CritScope stream_lock(&stream_crit_); | |
| 1448 for (auto& kv : send_streams_) | |
| 1449 kv.second->SetMaxBitrateBps(max_bitrate_bps); | |
| 1450 return true; | |
| 1451 } | |
| 1452 | |
| 1453 bool WebRtcVideoChannel2::SetOptions(const VideoOptions& options) { | |
| 1454 TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetOptions"); | |
| 1455 LOG(LS_INFO) << "SetOptions: " << options.ToString(); | |
| 1456 VideoOptions old_options = options_; | |
| 1457 options_.SetAll(options); | |
| 1458 if (options_ == old_options) { | |
| 1459 // No new options to set. | |
| 1460 return true; | |
| 1461 } | |
| 1462 { | |
| 1463 rtc::CritScope lock(&capturer_crit_); | |
| 1464 if (options_.cpu_overuse_detection) | |
| 1465 signal_cpu_adaptation_ = *options_.cpu_overuse_detection; | |
| 1466 } | |
| 1467 rtc::DiffServCodePoint dscp = | |
| 1468 options_.dscp.value_or(false) ? rtc::DSCP_AF41 : rtc::DSCP_DEFAULT; | |
| 1469 MediaChannel::SetDscp(dscp); | |
| 1470 rtc::CritScope stream_lock(&stream_crit_); | |
| 1471 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator it = | |
| 1472 send_streams_.begin(); | |
| 1473 it != send_streams_.end(); ++it) { | |
| 1474 it->second->SetOptions(options_); | |
| 1475 } | |
| 1476 return true; | |
| 1477 } | 1463 } |
| 1478 | 1464 |
| 1479 void WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { | 1465 void WebRtcVideoChannel2::SetInterface(NetworkInterface* iface) { |
| 1480 MediaChannel::SetInterface(iface); | 1466 MediaChannel::SetInterface(iface); |
| 1481 // Set the RTP recv/send buffer to a bigger size | 1467 // Set the RTP recv/send buffer to a bigger size |
| 1482 MediaChannel::SetOption(NetworkInterface::ST_RTP, | 1468 MediaChannel::SetOption(NetworkInterface::ST_RTP, |
| 1483 rtc::Socket::OPT_RCVBUF, | 1469 rtc::Socket::OPT_RCVBUF, |
| 1484 kVideoRtpBufferSize); | 1470 kVideoRtpBufferSize); |
| 1485 | 1471 |
| 1486 // Speculative change to increase the outbound socket buffer size. | 1472 // Speculative change to increase the outbound socket buffer size. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1589 const std::vector<webrtc::RtpExtension>& rtp_extensions, | 1575 const std::vector<webrtc::RtpExtension>& rtp_extensions, |
| 1590 // TODO(deadbeef): Don't duplicate information between send_params, | 1576 // TODO(deadbeef): Don't duplicate information between send_params, |
| 1591 // rtp_extensions, options, etc. | 1577 // rtp_extensions, options, etc. |
| 1592 const VideoSendParameters& send_params) | 1578 const VideoSendParameters& send_params) |
| 1593 : ssrcs_(sp.ssrcs), | 1579 : ssrcs_(sp.ssrcs), |
| 1594 ssrc_groups_(sp.ssrc_groups), | 1580 ssrc_groups_(sp.ssrc_groups), |
| 1595 call_(call), | 1581 call_(call), |
| 1596 external_encoder_factory_(external_encoder_factory), | 1582 external_encoder_factory_(external_encoder_factory), |
| 1597 stream_(NULL), | 1583 stream_(NULL), |
| 1598 parameters_(config, options, max_bitrate_bps, codec_settings), | 1584 parameters_(config, options, max_bitrate_bps, codec_settings), |
| 1585 pending_encoder_reconfiguration_(false), | |
| 1599 allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), | 1586 allocated_encoder_(NULL, webrtc::kVideoCodecUnknown, false), |
| 1600 capturer_(NULL), | 1587 capturer_(NULL), |
| 1601 sending_(false), | 1588 sending_(false), |
| 1602 muted_(false), | 1589 muted_(false), |
| 1603 old_adapt_changes_(0), | 1590 old_adapt_changes_(0), |
| 1604 first_frame_timestamp_ms_(0), | 1591 first_frame_timestamp_ms_(0), |
| 1605 last_frame_timestamp_ms_(0) { | 1592 last_frame_timestamp_ms_(0) { |
| 1606 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1593 parameters_.config.rtp.max_packet_size = kVideoMtu; |
| 1607 | 1594 |
| 1608 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1595 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1609 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1596 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
| 1610 ¶meters_.config.rtp.rtx.ssrcs); | 1597 ¶meters_.config.rtp.rtx.ssrcs); |
| 1611 parameters_.config.rtp.c_name = sp.cname; | 1598 parameters_.config.rtp.c_name = sp.cname; |
| 1612 parameters_.config.rtp.extensions = rtp_extensions; | 1599 parameters_.config.rtp.extensions = rtp_extensions; |
| 1613 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size | 1600 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size |
| 1614 ? webrtc::RtcpMode::kReducedSize | 1601 ? webrtc::RtcpMode::kReducedSize |
| 1615 : webrtc::RtcpMode::kCompound; | 1602 : webrtc::RtcpMode::kCompound; |
| 1616 | 1603 |
| 1617 if (codec_settings) { | 1604 if (codec_settings) { |
| 1618 SetCodec(*codec_settings); | 1605 SetCodecAndOptions(*codec_settings, parameters_.options); |
| 1619 } | 1606 } |
| 1620 } | 1607 } |
| 1621 | 1608 |
| 1622 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { | 1609 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { |
| 1623 DisconnectCapturer(); | 1610 DisconnectCapturer(); |
| 1624 if (stream_ != NULL) { | 1611 if (stream_ != NULL) { |
| 1625 call_->DestroyVideoSendStream(stream_); | 1612 call_->DestroyVideoSendStream(stream_); |
| 1626 } | 1613 } |
| 1627 DestroyVideoEncoder(&allocated_encoder_); | 1614 DestroyVideoEncoder(&allocated_encoder_); |
| 1628 } | 1615 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1722 } | 1709 } |
| 1723 | 1710 |
| 1724 capturer_ = capturer; | 1711 capturer_ = capturer; |
| 1725 } | 1712 } |
| 1726 // Lock cannot be held while connecting the capturer to prevent lock-order | 1713 // Lock cannot be held while connecting the capturer to prevent lock-order |
| 1727 // violations. | 1714 // violations. |
| 1728 capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); | 1715 capturer->SignalVideoFrame.connect(this, &WebRtcVideoSendStream::InputFrame); |
| 1729 return true; | 1716 return true; |
| 1730 } | 1717 } |
| 1731 | 1718 |
| 1719 // TODO(pbos): Apply this on the VideoAdapter instead! | |
|
pthatcher1
2016/01/26 23:00:42
Actually, nothing calls VideoChannel::ApplyViewRe
pbos-webrtc
2016/01/27 15:43:42
Will do here: https://codereview.webrtc.org/161343
| |
| 1732 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( | 1720 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoFormat( |
| 1733 const VideoFormat& format) { | 1721 const VideoFormat& format) { |
| 1734 if ((format.width == 0 || format.height == 0) && | 1722 if ((format.width == 0 || format.height == 0) && |
| 1735 format.width != format.height) { | 1723 format.width != format.height) { |
| 1736 LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " | 1724 LOG(LS_ERROR) << "Can't set VideoFormat, width or height is zero (but not " |
| 1737 "both, 0x0 drops frames)."; | 1725 "both, 0x0 drops frames)."; |
| 1738 return false; | 1726 return false; |
| 1739 } | 1727 } |
| 1740 | 1728 |
| 1741 rtc::CritScope cs(&lock_); | 1729 rtc::CritScope cs(&lock_); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1774 } | 1762 } |
| 1775 capturer->SignalVideoFrame.disconnect(this); | 1763 capturer->SignalVideoFrame.disconnect(this); |
| 1776 return true; | 1764 return true; |
| 1777 } | 1765 } |
| 1778 | 1766 |
| 1779 const std::vector<uint32_t>& | 1767 const std::vector<uint32_t>& |
| 1780 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { | 1768 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { |
| 1781 return ssrcs_; | 1769 return ssrcs_; |
| 1782 } | 1770 } |
| 1783 | 1771 |
| 1784 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetApplyRotation( | |
| 1785 bool apply_rotation) { | |
| 1786 rtc::CritScope cs(&lock_); | |
| 1787 if (capturer_ == NULL) | |
| 1788 return; | |
| 1789 | |
| 1790 capturer_->SetApplyRotation(apply_rotation); | |
| 1791 } | |
| 1792 | |
| 1793 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( | 1772 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( |
| 1794 const VideoOptions& options) { | 1773 const VideoOptions& options) { |
| 1795 rtc::CritScope cs(&lock_); | 1774 rtc::CritScope cs(&lock_); |
| 1796 if (parameters_.codec_settings) { | 1775 if (parameters_.codec_settings) { |
| 1797 LOG(LS_INFO) << "SetCodecAndOptions because of SetOptions; options=" | 1776 LOG(LS_INFO) << "SetCodecAndOptions because of SetOptions; options=" |
| 1798 << options.ToString(); | 1777 << options.ToString(); |
| 1799 SetCodecAndOptions(*parameters_.codec_settings, options); | 1778 SetCodecAndOptions(*parameters_.codec_settings, options); |
| 1800 } else { | 1779 } else { |
| 1801 parameters_.options = options; | 1780 parameters_.options = options; |
| 1802 } | 1781 } |
| 1803 } | 1782 } |
| 1804 | 1783 |
| 1805 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( | |
| 1806 const VideoCodecSettings& codec_settings) { | |
| 1807 rtc::CritScope cs(&lock_); | |
| 1808 LOG(LS_INFO) << "SetCodecAndOptions because of SetCodec."; | |
| 1809 SetCodecAndOptions(codec_settings, parameters_.options); | |
| 1810 } | |
| 1811 | |
| 1812 webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { | 1784 webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { |
| 1813 if (CodecNamesEq(name, kVp8CodecName)) { | 1785 if (CodecNamesEq(name, kVp8CodecName)) { |
| 1814 return webrtc::kVideoCodecVP8; | 1786 return webrtc::kVideoCodecVP8; |
| 1815 } else if (CodecNamesEq(name, kVp9CodecName)) { | 1787 } else if (CodecNamesEq(name, kVp9CodecName)) { |
| 1816 return webrtc::kVideoCodecVP9; | 1788 return webrtc::kVideoCodecVP9; |
| 1817 } else if (CodecNamesEq(name, kH264CodecName)) { | 1789 } else if (CodecNamesEq(name, kH264CodecName)) { |
| 1818 return webrtc::kVideoCodecH264; | 1790 return webrtc::kVideoCodecH264; |
| 1819 } | 1791 } |
| 1820 return webrtc::kVideoCodecUnknown; | 1792 return webrtc::kVideoCodecUnknown; |
| 1821 } | 1793 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1861 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); | 1833 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); |
| 1862 } | 1834 } |
| 1863 delete encoder->encoder; | 1835 delete encoder->encoder; |
| 1864 } | 1836 } |
| 1865 | 1837 |
| 1866 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( | 1838 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodecAndOptions( |
| 1867 const VideoCodecSettings& codec_settings, | 1839 const VideoCodecSettings& codec_settings, |
| 1868 const VideoOptions& options) { | 1840 const VideoOptions& options) { |
| 1869 parameters_.encoder_config = | 1841 parameters_.encoder_config = |
| 1870 CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); | 1842 CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); |
| 1871 if (parameters_.encoder_config.streams.empty()) | 1843 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
| 1872 return; | |
| 1873 | 1844 |
| 1874 format_ = VideoFormat(codec_settings.codec.width, | 1845 format_ = VideoFormat(codec_settings.codec.width, |
| 1875 codec_settings.codec.height, | 1846 codec_settings.codec.height, |
| 1876 VideoFormat::FpsToInterval(30), | 1847 VideoFormat::FpsToInterval(30), |
| 1877 FOURCC_I420); | 1848 FOURCC_I420); |
| 1878 | 1849 |
| 1879 AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); | 1850 AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); |
| 1880 parameters_.config.encoder_settings.encoder = new_encoder.encoder; | 1851 parameters_.config.encoder_settings.encoder = new_encoder.encoder; |
| 1881 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; | 1852 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; |
| 1882 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; | 1853 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1912 LOG(LS_INFO) | 1883 LOG(LS_INFO) |
| 1913 << "RecreateWebRtcStream (send) because of SetCodecAndOptions; options=" | 1884 << "RecreateWebRtcStream (send) because of SetCodecAndOptions; options=" |
| 1914 << options.ToString(); | 1885 << options.ToString(); |
| 1915 RecreateWebRtcStream(); | 1886 RecreateWebRtcStream(); |
| 1916 if (allocated_encoder_.encoder != new_encoder.encoder) { | 1887 if (allocated_encoder_.encoder != new_encoder.encoder) { |
| 1917 DestroyVideoEncoder(&allocated_encoder_); | 1888 DestroyVideoEncoder(&allocated_encoder_); |
| 1918 allocated_encoder_ = new_encoder; | 1889 allocated_encoder_ = new_encoder; |
| 1919 } | 1890 } |
| 1920 } | 1891 } |
| 1921 | 1892 |
| 1922 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpExtensions( | |
| 1923 const std::vector<webrtc::RtpExtension>& rtp_extensions) { | |
| 1924 rtc::CritScope cs(&lock_); | |
| 1925 parameters_.config.rtp.extensions = rtp_extensions; | |
| 1926 if (stream_ != nullptr) { | |
| 1927 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetRtpExtensions"; | |
| 1928 RecreateWebRtcStream(); | |
| 1929 } | |
| 1930 } | |
| 1931 | |
| 1932 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( | 1893 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( |
| 1933 const VideoSendParameters& send_params) { | 1894 const ChangedSendParameters& params) { |
| 1934 rtc::CritScope cs(&lock_); | 1895 rtc::CritScope cs(&lock_); |
| 1935 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size | 1896 // |recreate_stream| means construction-time parameters have changed and the |
| 1936 ? webrtc::RtcpMode::kReducedSize | 1897 // sending stream needs to be reset with the new config. |
| 1937 : webrtc::RtcpMode::kCompound; | 1898 bool recreate_stream = false; |
| 1938 if (stream_ != nullptr) { | 1899 if (parameters_.config.rtp.rtcp_mode != params.rtcp_mode) { |
| 1900 parameters_.config.rtp.rtcp_mode = params.rtcp_mode; | |
| 1901 recreate_stream = true; | |
| 1902 } | |
| 1903 if (params.rtp_header_extensions) { | |
| 1904 parameters_.config.rtp.extensions = *params.rtp_header_extensions; | |
| 1905 if (capturer_) { | |
| 1906 capturer_->SetApplyRotation(!ContainsHeaderExtension( | |
| 1907 *params.rtp_header_extensions, kRtpVideoRotationHeaderExtension)); | |
| 1908 } | |
| 1909 recreate_stream = true; | |
| 1910 } | |
| 1911 if (params.max_bandwidth_bps) { | |
| 1912 // Max bitrate has changed, reconfigure encoder settings on the next frame | |
| 1913 // or stream recreation. | |
| 1914 parameters_.max_bitrate_bps = *params.max_bandwidth_bps; | |
| 1915 pending_encoder_reconfiguration_ = true; | |
| 1916 } | |
| 1917 // Set codecs and options. | |
| 1918 if (params.codec) { | |
| 1919 SetCodecAndOptions(*params.codec, | |
| 1920 params.options ? *params.options : parameters_.options); | |
| 1921 return; | |
| 1922 } else if (params.options) { | |
| 1923 // Reconfigure if codecs are already set. | |
| 1924 if (parameters_.codec_settings) { | |
| 1925 SetCodecAndOptions(*parameters_.codec_settings, *params.options); | |
| 1926 return; | |
| 1927 } else { | |
| 1928 parameters_.options = *params.options; | |
| 1929 } | |
| 1930 } | |
| 1931 if (recreate_stream) { | |
| 1939 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; | 1932 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; |
| 1940 RecreateWebRtcStream(); | 1933 RecreateWebRtcStream(); |
| 1941 } | 1934 } |
| 1942 } | 1935 } |
| 1943 | 1936 |
| 1944 webrtc::VideoEncoderConfig | 1937 webrtc::VideoEncoderConfig |
| 1945 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( | 1938 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( |
| 1946 const Dimensions& dimensions, | 1939 const Dimensions& dimensions, |
| 1947 const VideoCodec& codec) const { | 1940 const VideoCodec& codec) const { |
| 1948 webrtc::VideoEncoderConfig encoder_config; | 1941 webrtc::VideoEncoderConfig encoder_config; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2000 config.tl0_bitrate_kbps * 1000); | 1993 config.tl0_bitrate_kbps * 1000); |
| 2001 } | 1994 } |
| 2002 return encoder_config; | 1995 return encoder_config; |
| 2003 } | 1996 } |
| 2004 | 1997 |
| 2005 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( | 1998 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( |
| 2006 int width, | 1999 int width, |
| 2007 int height, | 2000 int height, |
| 2008 bool is_screencast) { | 2001 bool is_screencast) { |
| 2009 if (last_dimensions_.width == width && last_dimensions_.height == height && | 2002 if (last_dimensions_.width == width && last_dimensions_.height == height && |
| 2010 last_dimensions_.is_screencast == is_screencast) { | 2003 last_dimensions_.is_screencast == is_screencast && |
| 2004 !pending_encoder_reconfiguration_) { | |
| 2011 // Configured using the same parameters, do not reconfigure. | 2005 // Configured using the same parameters, do not reconfigure. |
| 2012 return; | 2006 return; |
| 2013 } | 2007 } |
| 2014 LOG(LS_INFO) << "SetDimensions: " << width << "x" << height | 2008 LOG(LS_INFO) << "SetDimensions: " << width << "x" << height |
| 2015 << (is_screencast ? " (screencast)" : " (not screencast)"); | 2009 << (is_screencast ? " (screencast)" : " (not screencast)"); |
| 2016 | 2010 |
| 2017 last_dimensions_.width = width; | 2011 last_dimensions_.width = width; |
| 2018 last_dimensions_.height = height; | 2012 last_dimensions_.height = height; |
| 2019 last_dimensions_.is_screencast = is_screencast; | 2013 last_dimensions_.is_screencast = is_screencast; |
| 2020 | 2014 |
| 2021 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); | 2015 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
| 2022 | 2016 |
| 2023 RTC_CHECK(parameters_.codec_settings); | 2017 RTC_CHECK(parameters_.codec_settings); |
| 2024 VideoCodecSettings codec_settings = *parameters_.codec_settings; | 2018 VideoCodecSettings codec_settings = *parameters_.codec_settings; |
| 2025 | 2019 |
| 2026 webrtc::VideoEncoderConfig encoder_config = | 2020 webrtc::VideoEncoderConfig encoder_config = |
| 2027 CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); | 2021 CreateVideoEncoderConfig(last_dimensions_, codec_settings.codec); |
| 2028 | 2022 |
| 2029 encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( | 2023 encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( |
| 2030 codec_settings.codec, parameters_.options, is_screencast); | 2024 codec_settings.codec, parameters_.options, is_screencast); |
| 2031 | 2025 |
| 2032 bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); | 2026 bool stream_reconfigured = stream_->ReconfigureVideoEncoder(encoder_config); |
| 2033 | 2027 |
| 2034 encoder_config.encoder_specific_settings = NULL; | 2028 encoder_config.encoder_specific_settings = NULL; |
| 2029 pending_encoder_reconfiguration_ = false; | |
| 2035 | 2030 |
| 2036 if (!stream_reconfigured) { | 2031 if (!stream_reconfigured) { |
| 2037 LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " | 2032 LOG(LS_WARNING) << "Failed to reconfigure video encoder for dimensions: " |
| 2038 << width << "x" << height; | 2033 << width << "x" << height; |
| 2039 return; | 2034 return; |
| 2040 } | 2035 } |
| 2041 | 2036 |
| 2042 parameters_.encoder_config = encoder_config; | 2037 parameters_.encoder_config = encoder_config; |
| 2043 } | 2038 } |
| 2044 | 2039 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2161 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = | 2156 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = |
| 2162 stats.substreams.begin(); | 2157 stats.substreams.begin(); |
| 2163 it != stats.substreams.end(); ++it) { | 2158 it != stats.substreams.end(); ++it) { |
| 2164 bwe_info->transmit_bitrate += it->second.total_bitrate_bps; | 2159 bwe_info->transmit_bitrate += it->second.total_bitrate_bps; |
| 2165 bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; | 2160 bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; |
| 2166 } | 2161 } |
| 2167 bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; | 2162 bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; |
| 2168 bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; | 2163 bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; |
| 2169 } | 2164 } |
| 2170 | 2165 |
| 2171 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetMaxBitrateBps( | |
| 2172 int max_bitrate_bps) { | |
| 2173 rtc::CritScope cs(&lock_); | |
| 2174 parameters_.max_bitrate_bps = max_bitrate_bps; | |
| 2175 | |
| 2176 // No need to reconfigure if the stream hasn't been configured yet. | |
| 2177 if (parameters_.encoder_config.streams.empty()) | |
| 2178 return; | |
| 2179 | |
| 2180 // Force a stream reconfigure to set the new max bitrate. | |
| 2181 int width = last_dimensions_.width; | |
| 2182 last_dimensions_.width = 0; | |
| 2183 SetDimensions(width, last_dimensions_.height, last_dimensions_.is_screencast); | |
| 2184 } | |
| 2185 | |
| 2186 void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { | 2166 void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { |
| 2187 if (stream_ != NULL) { | 2167 if (stream_ != NULL) { |
| 2188 call_->DestroyVideoSendStream(stream_); | 2168 call_->DestroyVideoSendStream(stream_); |
| 2189 } | 2169 } |
| 2190 | 2170 |
| 2191 RTC_CHECK(parameters_.codec_settings); | 2171 RTC_CHECK(parameters_.codec_settings); |
| 2192 parameters_.encoder_config.encoder_specific_settings = | 2172 parameters_.encoder_config.encoder_specific_settings = |
| 2193 ConfigureVideoEncoderSettings( | 2173 ConfigureVideoEncoderSettings( |
| 2194 parameters_.codec_settings->codec, parameters_.options, | 2174 parameters_.codec_settings->codec, parameters_.options, |
| 2195 parameters_.encoder_config.content_type == | 2175 parameters_.encoder_config.content_type == |
| 2196 webrtc::VideoEncoderConfig::ContentType::kScreen); | 2176 webrtc::VideoEncoderConfig::ContentType::kScreen); |
| 2197 | 2177 |
| 2198 webrtc::VideoSendStream::Config config = parameters_.config; | 2178 webrtc::VideoSendStream::Config config = parameters_.config; |
| 2199 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { | 2179 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { |
| 2200 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 2180 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
| 2201 "payload type the set codec. Ignoring RTX."; | 2181 "payload type the set codec. Ignoring RTX."; |
| 2202 config.rtp.rtx.ssrcs.clear(); | 2182 config.rtp.rtx.ssrcs.clear(); |
| 2203 } | 2183 } |
| 2204 stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); | 2184 stream_ = call_->CreateVideoSendStream(config, parameters_.encoder_config); |
| 2205 | 2185 |
| 2206 parameters_.encoder_config.encoder_specific_settings = NULL; | 2186 parameters_.encoder_config.encoder_specific_settings = NULL; |
| 2187 pending_encoder_reconfiguration_ = false; | |
| 2207 | 2188 |
| 2208 if (sending_) { | 2189 if (sending_) { |
| 2209 stream_->Start(); | 2190 stream_->Start(); |
| 2210 } | 2191 } |
| 2211 } | 2192 } |
| 2212 | 2193 |
| 2213 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( | 2194 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( |
| 2214 webrtc::Call* call, | 2195 webrtc::Call* call, |
| 2215 const StreamParams& sp, | 2196 const StreamParams& sp, |
| 2216 const webrtc::VideoReceiveStream::Config& config, | 2197 const webrtc::VideoReceiveStream::Config& config, |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2626 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2607 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2627 } | 2608 } |
| 2628 } | 2609 } |
| 2629 | 2610 |
| 2630 return video_codecs; | 2611 return video_codecs; |
| 2631 } | 2612 } |
| 2632 | 2613 |
| 2633 } // namespace cricket | 2614 } // namespace cricket |
| 2634 | 2615 |
| 2635 #endif // HAVE_WEBRTC_VIDEO | 2616 #endif // HAVE_WEBRTC_VIDEO |
| OLD | NEW |