Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(780)

Side by Side Diff: webrtc/media/engine/webrtcvideoengine2.cc

Issue 2304363002: Let ViEEncoder express resolution requests as Sinkwants (Closed)
Patch Set: Revert changes to OveruseFrameDetector. Fix merge mistake Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 13 matching lines...) Expand all
24 #include "webrtc/call.h" 24 #include "webrtc/call.h"
25 #include "webrtc/media/engine/constants.h" 25 #include "webrtc/media/engine/constants.h"
26 #include "webrtc/media/engine/simulcast.h" 26 #include "webrtc/media/engine/simulcast.h"
27 #include "webrtc/media/engine/webrtcmediaengine.h" 27 #include "webrtc/media/engine/webrtcmediaengine.h"
28 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" 28 #include "webrtc/media/engine/webrtcvideoencoderfactory.h"
29 #include "webrtc/media/engine/webrtcvoiceengine.h" 29 #include "webrtc/media/engine/webrtcvoiceengine.h"
30 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 30 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
31 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" 31 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h"
32 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" 32 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
33 #include "webrtc/system_wrappers/include/field_trial.h" 33 #include "webrtc/system_wrappers/include/field_trial.h"
34 #include "webrtc/system_wrappers/include/metrics.h"
35 #include "webrtc/video_decoder.h" 34 #include "webrtc/video_decoder.h"
36 #include "webrtc/video_encoder.h" 35 #include "webrtc/video_encoder.h"
37 36
38 namespace cricket { 37 namespace cricket {
39 namespace { 38 namespace {
40 39
41 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. 40 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory.
42 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { 41 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory {
43 public: 42 public:
44 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned 43 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 244 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) {
246 LOG(LS_ERROR) 245 LOG(LS_ERROR)
247 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 246 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): "
248 << sp.ToString(); 247 << sp.ToString();
249 return false; 248 return false;
250 } 249 }
251 250
252 return true; 251 return true;
253 } 252 }
254 253
255 inline bool ContainsHeaderExtension(
256 const std::vector<webrtc::RtpExtension>& extensions,
257 const std::string& uri) {
258 for (const auto& kv : extensions) {
259 if (kv.uri == uri) {
260 return true;
261 }
262 }
263 return false;
264 }
265
266 // Returns true if the given codec is disallowed from doing simulcast. 254 // Returns true if the given codec is disallowed from doing simulcast.
267 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { 255 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) {
268 return CodecNamesEq(codec_name, kH264CodecName) || 256 return CodecNamesEq(codec_name, kH264CodecName) ||
269 CodecNamesEq(codec_name, kVp9CodecName); 257 CodecNamesEq(codec_name, kVp9CodecName);
270 } 258 }
271 259
272 // The selected thresholds for QVGA and VGA corresponded to a QP around 10. 260 // The selected thresholds for QVGA and VGA corresponded to a QP around 10.
273 // The change in QP declined above the selected bitrates. 261 // The change in QP declined above the selected bitrates.
274 static int GetMaxDefaultVideoBitrateKbps(int width, int height) { 262 static int GetMaxDefaultVideoBitrateKbps(int width, int height) {
275 if (width * height <= 320 * 240) { 263 if (width * height <= 320 * 240) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 const int kVideoRtpBufferSize = 65536; 391 const int kVideoRtpBufferSize = 65536;
404 392
405 // This constant is really an on/off, lower-level configurable NACK history 393 // This constant is really an on/off, lower-level configurable NACK history
406 // duration hasn't been implemented. 394 // duration hasn't been implemented.
407 static const int kNackHistoryMs = 1000; 395 static const int kNackHistoryMs = 1000;
408 396
409 static const int kDefaultQpMax = 56; 397 static const int kDefaultQpMax = 56;
410 398
411 static const int kDefaultRtcpReceiverReportSsrc = 1; 399 static const int kDefaultRtcpReceiverReportSsrc = 1;
412 400
413 // Down grade resolution at most 2 times for CPU reasons.
414 static const int kMaxCpuDowngrades = 2;
415
416 // Minimum time interval for logging stats. 401 // Minimum time interval for logging stats.
417 static const int64_t kStatsLogIntervalMs = 10000; 402 static const int64_t kStatsLogIntervalMs = 10000;
418 403
419 // Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is 404 // Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is
420 // recognized. 405 // recognized.
421 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names we 406 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names we
422 // don't recognize? 407 // don't recognize?
423 void AddCodecAndMaybeRtxCodec(const VideoCodec& codec, 408 void AddCodecAndMaybeRtxCodec(const VideoCodec& codec,
424 std::vector<VideoCodec>* codecs) { 409 std::vector<VideoCodec>* codecs) {
425 codecs->push_back(codec); 410 codecs->push_back(codec);
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 int max_bitrate_bps, 1573 int max_bitrate_bps,
1589 const rtc::Optional<VideoCodecSettings>& codec_settings, 1574 const rtc::Optional<VideoCodecSettings>& codec_settings,
1590 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, 1575 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
1591 // TODO(deadbeef): Don't duplicate information between send_params, 1576 // TODO(deadbeef): Don't duplicate information between send_params,
1592 // rtp_extensions, options, etc. 1577 // rtp_extensions, options, etc.
1593 const VideoSendParameters& send_params) 1578 const VideoSendParameters& send_params)
1594 : worker_thread_(rtc::Thread::Current()), 1579 : worker_thread_(rtc::Thread::Current()),
1595 ssrcs_(sp.ssrcs), 1580 ssrcs_(sp.ssrcs),
1596 ssrc_groups_(sp.ssrc_groups), 1581 ssrc_groups_(sp.ssrc_groups),
1597 call_(call), 1582 call_(call),
1598 cpu_restricted_counter_(0), 1583 enable_cpu_overuse_detection_(enable_cpu_overuse_detection),
1599 number_of_cpu_adapt_changes_(0),
1600 frame_count_(0),
1601 cpu_restricted_frame_count_(0),
1602 source_(nullptr), 1584 source_(nullptr),
1603 external_encoder_factory_(external_encoder_factory), 1585 external_encoder_factory_(external_encoder_factory),
1604 stream_(nullptr), 1586 stream_(nullptr),
1605 encoder_sink_(nullptr), 1587 encoder_sink_(nullptr),
1606 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), 1588 parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
1607 rtp_parameters_(CreateRtpParametersWithOneEncoding()), 1589 rtp_parameters_(CreateRtpParametersWithOneEncoding()),
1608 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), 1590 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false),
1609 sending_(false), 1591 sending_(false),
1610 last_frame_timestamp_us_(0) { 1592 last_frame_timestamp_us_(0) {
1611 parameters_.config.rtp.max_packet_size = kVideoMtu; 1593 parameters_.config.rtp.max_packet_size = kVideoMtu;
1612 parameters_.conference_mode = send_params.conference_mode; 1594 parameters_.conference_mode = send_params.conference_mode;
1613 1595
1614 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs); 1596 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs);
1615 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 1597 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
1616 &parameters_.config.rtp.rtx.ssrcs); 1598 &parameters_.config.rtp.rtx.ssrcs);
1617 parameters_.config.rtp.c_name = sp.cname; 1599 parameters_.config.rtp.c_name = sp.cname;
1618 if (rtp_extensions) { 1600 if (rtp_extensions) {
1619 parameters_.config.rtp.extensions = *rtp_extensions; 1601 parameters_.config.rtp.extensions = *rtp_extensions;
1620 } 1602 }
1621 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 1603 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
1622 ? webrtc::RtcpMode::kReducedSize 1604 ? webrtc::RtcpMode::kReducedSize
1623 : webrtc::RtcpMode::kCompound; 1605 : webrtc::RtcpMode::kCompound;
1624 parameters_.config.overuse_callback =
1625 enable_cpu_overuse_detection ? this : nullptr;
1626
1627 // Only request rotation at the source when we positively know that the remote
1628 // side doesn't support the rotation extension. This allows us to prepare the
1629 // encoder in the expectation that rotation is supported - which is the common
1630 // case.
1631 sink_wants_.rotation_applied =
1632 rtp_extensions &&
1633 !ContainsHeaderExtension(*rtp_extensions,
1634 webrtc::RtpExtension::kVideoRotationUri);
1635
1636 if (codec_settings) { 1606 if (codec_settings) {
1637 SetCodec(*codec_settings); 1607 SetCodec(*codec_settings);
1638 } 1608 }
1639 } 1609 }
1640 1610
1641 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1611 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
1642 DisconnectSource();
1643 if (stream_ != NULL) { 1612 if (stream_ != NULL) {
1644 call_->DestroyVideoSendStream(stream_); 1613 call_->DestroyVideoSendStream(stream_);
1645 } 1614 }
1646 DestroyVideoEncoder(&allocated_encoder_); 1615 DestroyVideoEncoder(&allocated_encoder_);
1647 UpdateHistograms();
1648 }
1649
1650 void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateHistograms() const {
1651 const int kMinRequiredFrames = 200;
1652 if (frame_count_ > kMinRequiredFrames) {
1653 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.CpuLimitedResolutionInPercent",
1654 cpu_restricted_frame_count_ * 100 / frame_count_);
1655 }
1656 } 1616 }
1657 1617
1658 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( 1618 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame(
1659 const VideoFrame& frame) { 1619 const VideoFrame& frame) {
1660 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); 1620 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame");
1661 webrtc::VideoFrame video_frame(frame.video_frame_buffer(), 1621 webrtc::VideoFrame video_frame(frame.video_frame_buffer(),
1662 frame.rotation(), 1622 frame.rotation(),
1663 frame.timestamp_us()); 1623 frame.timestamp_us());
1664 1624
1665 rtc::CritScope cs(&lock_); 1625 rtc::CritScope cs(&lock_);
(...skipping 13 matching lines...) Expand all
1679 << ", texture=" << last_frame_info_.is_texture; 1639 << ", texture=" << last_frame_info_.is_texture;
1680 } 1640 }
1681 1641
1682 if (encoder_sink_ == NULL) { 1642 if (encoder_sink_ == NULL) {
1683 // Frame input before send codecs are configured, dropping frame. 1643 // Frame input before send codecs are configured, dropping frame.
1684 return; 1644 return;
1685 } 1645 }
1686 1646
1687 last_frame_timestamp_us_ = video_frame.timestamp_us(); 1647 last_frame_timestamp_us_ = video_frame.timestamp_us();
1688 1648
1689 ++frame_count_;
1690 if (cpu_restricted_counter_ > 0)
1691 ++cpu_restricted_frame_count_;
1692
1693 // Forward frame to the encoder regardless if we are sending or not. This is 1649 // Forward frame to the encoder regardless if we are sending or not. This is
1694 // to ensure that the encoder can be reconfigured with the correct frame size 1650 // to ensure that the encoder can be reconfigured with the correct frame size
1695 // as quickly as possible. 1651 // as quickly as possible.
1696 encoder_sink_->OnFrame(video_frame); 1652 encoder_sink_->OnFrame(video_frame);
1697 } 1653 }
1698 1654
1699 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( 1655 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend(
1700 bool enable, 1656 bool enable,
1701 const VideoOptions* options, 1657 const VideoOptions* options,
1702 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { 1658 rtc::VideoSourceInterface<cricket::VideoFrame>* source) {
1703 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); 1659 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend");
1704 RTC_DCHECK_RUN_ON(&thread_checker_); 1660 RTC_DCHECK_RUN_ON(&thread_checker_);
1705 1661
1706 // Ignore |options| pointer if |enable| is false. 1662 // Ignore |options| pointer if |enable| is false.
1707 bool options_present = enable && options; 1663 bool options_present = enable && options;
1708 bool source_changing = source_ != source; 1664 bool source_changing = source_ != source;
1709 if (source_changing) {
1710 DisconnectSource();
1711 }
1712 1665
1713 if (options_present) { 1666 if (options_present) {
1714 VideoOptions old_options = parameters_.options; 1667 VideoOptions old_options = parameters_.options;
1715 parameters_.options.SetAll(*options); 1668 parameters_.options.SetAll(*options);
1716 if (parameters_.options != old_options) { 1669 if (parameters_.options != old_options) {
1717 ReconfigureEncoder(); 1670 ReconfigureEncoder();
1718 } 1671 }
1719 } 1672 }
1720 1673
1721 if (source_changing) { 1674 if (source_changing) {
1722 rtc::CritScope cs(&lock_); 1675 rtc::CritScope cs(&lock_);
1723 if (source == nullptr && encoder_sink_ != nullptr && 1676 if (source == nullptr && last_frame_info_.width > 0 && encoder_sink_) {
1724 last_frame_info_.width > 0) {
1725 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1677 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame.";
1726 // Force this black frame not to be dropped due to timestamp order 1678 // Force this black frame not to be dropped due to timestamp order
1727 // check. As IncomingCapturedFrame will drop the frame if this frame's 1679 // check. As IncomingCapturedFrame will drop the frame if this frame's
1728 // timestamp is less than or equal to last frame's timestamp, it is 1680 // timestamp is less than or equal to last frame's timestamp, it is
1729 // necessary to give this black frame a larger timestamp than the 1681 // necessary to give this black frame a larger timestamp than the
1730 // previous one. 1682 // previous one.
1731 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; 1683 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec;
1732 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( 1684 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer(
1733 webrtc::I420Buffer::Create(last_frame_info_.width, 1685 webrtc::I420Buffer::Create(last_frame_info_.width,
1734 last_frame_info_.height)); 1686 last_frame_info_.height));
1735 black_buffer->SetToBlack(); 1687 black_buffer->SetToBlack();
1736 1688
1737 encoder_sink_->OnFrame(webrtc::VideoFrame( 1689 encoder_sink_->OnFrame(webrtc::VideoFrame(
1738 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); 1690 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_));
1739 } 1691 }
1740 source_ = source;
1741 } 1692 }
1742 1693
1743 if (source_changing && source_) { 1694 // TODO(perkj, nisse): Remove |source_| and directly call
1744 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since 1695 // |stream_|->SetSource(source) once the video frame types have been
1745 // that might cause a lock order inversion. 1696 // merged.
nisse-webrtc 2016/10/28 10:53:44 That time is now. ;-)
perkj_webrtc 2016/10/28 14:05:34 Great- but it is a little bit more to it so I woul
nisse-webrtc 2016/10/31 07:52:46 Sure. I'd also really like to see this change land
1746 source_->AddOrUpdateSink(this, sink_wants_); 1697 if (source_ && stream_) {
1698 stream_->SetSource(
1699 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced);
1700 }
1701 // Switch to the new source.
1702 source_ = source;
1703 if (source && stream_) {
1704 // Do not adapt resolution for screen content as this will likely
1705 // result in blurry and unreadable text.
1706 stream_->SetSource(
1707 this, enable_cpu_overuse_detection_ &&
1708 !parameters_.options.is_screencast.value_or(false)
1709 ? webrtc::VideoSendStream::DegradationPreference::kBalanced
1710 : webrtc::VideoSendStream::DegradationPreference::
1711 kMaintainResolution);
1747 } 1712 }
1748 return true; 1713 return true;
1749 } 1714 }
1750 1715
1751 void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() {
1752 RTC_DCHECK_RUN_ON(&thread_checker_);
1753 if (source_ == nullptr) {
1754 return;
1755 }
1756
1757 // |source_->RemoveSink| may not be called while holding |lock_| since
1758 // that might cause a lock order inversion.
1759 source_->RemoveSink(this);
1760 source_ = nullptr;
1761 // Reset |cpu_restricted_counter_| if the source is changed. It is not
1762 // possible to know if the video resolution is restricted by CPU usage after
1763 // the source is changed since the next source might be screen capture
1764 // with another resolution and frame rate.
1765 cpu_restricted_counter_ = 0;
1766 }
1767
1768 const std::vector<uint32_t>& 1716 const std::vector<uint32_t>&
1769 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1717 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const {
1770 return ssrcs_; 1718 return ssrcs_;
1771 } 1719 }
1772 1720
1773 webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { 1721 webrtc::VideoCodecType CodecTypeFromName(const std::string& name) {
1774 if (CodecNamesEq(name, kVp8CodecName)) { 1722 if (CodecNamesEq(name, kVp8CodecName)) {
1775 return webrtc::kVideoCodecVP8; 1723 return webrtc::kVideoCodecVP8;
1776 } else if (CodecNamesEq(name, kVp9CodecName)) { 1724 } else if (CodecNamesEq(name, kVp9CodecName)) {
1777 return webrtc::kVideoCodecVP9; 1725 return webrtc::kVideoCodecVP9;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1896 SetCodec(*params.codec); 1844 SetCodec(*params.codec);
1897 recreate_stream = false; // SetCodec has already recreated the stream. 1845 recreate_stream = false; // SetCodec has already recreated the stream.
1898 } else if (params.conference_mode && parameters_.codec_settings) { 1846 } else if (params.conference_mode && parameters_.codec_settings) {
1899 SetCodec(*parameters_.codec_settings); 1847 SetCodec(*parameters_.codec_settings);
1900 recreate_stream = false; // SetCodec has already recreated the stream. 1848 recreate_stream = false; // SetCodec has already recreated the stream.
1901 } 1849 }
1902 if (recreate_stream) { 1850 if (recreate_stream) {
1903 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; 1851 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters";
1904 RecreateWebRtcStream(); 1852 RecreateWebRtcStream();
1905 } 1853 }
1906
1907 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
1908 // that might cause a lock order inversion.
1909 if (params.rtp_header_extensions) {
1910 sink_wants_.rotation_applied = !ContainsHeaderExtension(
1911 *params.rtp_header_extensions, webrtc::RtpExtension::kVideoRotationUri);
1912 if (source_) {
1913 source_->AddOrUpdateSink(this, sink_wants_);
1914 }
1915 }
1916 } 1854 }
1917 1855
1918 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( 1856 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters(
1919 const webrtc::RtpParameters& new_parameters) { 1857 const webrtc::RtpParameters& new_parameters) {
1920 RTC_DCHECK_RUN_ON(&thread_checker_); 1858 RTC_DCHECK_RUN_ON(&thread_checker_);
1921 if (!ValidateRtpParameters(new_parameters)) { 1859 if (!ValidateRtpParameters(new_parameters)) {
1922 return false; 1860 return false;
1923 } 1861 }
1924 1862
1925 bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps != 1863 bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps !=
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 1972
2035 parameters_.encoder_config = std::move(encoder_config); 1973 parameters_.encoder_config = std::move(encoder_config);
2036 } 1974 }
2037 1975
2038 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { 1976 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) {
2039 RTC_DCHECK_RUN_ON(&thread_checker_); 1977 RTC_DCHECK_RUN_ON(&thread_checker_);
2040 sending_ = send; 1978 sending_ = send;
2041 UpdateSendState(); 1979 UpdateSendState();
2042 } 1980 }
2043 1981
1982 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink(
1983 VideoSinkInterface<webrtc::VideoFrame>* sink) {
1984 RTC_DCHECK_RUN_ON(&thread_checker_);
1985 {
1986 rtc::CritScope cs(&lock_);
1987 RTC_DCHECK(encoder_sink_ == sink);
1988 encoder_sink_ = nullptr;
1989 }
1990 source_->RemoveSink(this);
1991 }
1992
2044 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( 1993 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink(
2045 VideoSinkInterface<webrtc::VideoFrame>* sink, 1994 VideoSinkInterface<webrtc::VideoFrame>* sink,
2046 const rtc::VideoSinkWants& wants) { 1995 const rtc::VideoSinkWants& wants) {
2047 // TODO(perkj): Actually consider the encoder |wants| and remove 1996 if (worker_thread_ == rtc::Thread::Current()) {
2048 // WebRtcVideoSendStream::OnLoadUpdate(Load load). 1997 // AddOrUpdateSink is called on |worker_thread_| if this is the first
2049 rtc::CritScope cs(&lock_); 1998 // registration of |sink|.
2050 RTC_DCHECK(!encoder_sink_ || encoder_sink_ == sink); 1999 RTC_DCHECK_RUN_ON(&thread_checker_);
2051 encoder_sink_ = sink; 2000 {
2052 } 2001 rtc::CritScope cs(&lock_);
2053 2002 encoder_sink_ = sink;
2054 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( 2003 }
2055 VideoSinkInterface<webrtc::VideoFrame>* sink) { 2004 source_->AddOrUpdateSink(this, wants);
2056 rtc::CritScope cs(&lock_); 2005 } else {
2057 RTC_DCHECK_EQ(encoder_sink_, sink); 2006 // Subsequent calls to AddOrUpdateSink will happen on the encoder task
2058 encoder_sink_ = nullptr; 2007 // queue.
2059 } 2008 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, wants] {
2060 2009 RTC_DCHECK_RUN_ON(&thread_checker_);
2061 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { 2010 bool encoder_sink_valid = true;
2062 if (worker_thread_ != rtc::Thread::Current()) { 2011 {
2063 invoker_.AsyncInvoke<void>( 2012 rtc::CritScope cs(&lock_);
2064 RTC_FROM_HERE, worker_thread_, 2013 encoder_sink_valid = encoder_sink_ != nullptr;
2065 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate, 2014 }
2066 this, load)); 2015 // Since |source_| is still valid after a call to RemoveSink, check if
2067 return; 2016 // |encoder_sink_| is still valid to check if this call should be
2017 // cancelled.
2018 if (source_ && encoder_sink_valid) {
2019 source_->AddOrUpdateSink(this, wants);
2020 }
2021 });
2068 } 2022 }
2069 RTC_DCHECK_RUN_ON(&thread_checker_);
2070 if (!source_) {
2071 return;
2072 }
2073
2074 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: "
2075 << (parameters_.options.is_screencast
2076 ? (*parameters_.options.is_screencast ? "true" : "false")
2077 : "unset");
2078 // Do not adapt resolution for screen content as this will likely result in
2079 // blurry and unreadable text.
2080 if (parameters_.options.is_screencast.value_or(false))
2081 return;
2082
2083 rtc::Optional<int> max_pixel_count;
2084 rtc::Optional<int> max_pixel_count_step_up;
2085 if (load == kOveruse) {
2086 rtc::CritScope cs(&lock_);
2087 if (cpu_restricted_counter_ >= kMaxCpuDowngrades) {
2088 return;
2089 }
2090 // The input video frame size will have a resolution with less than or
2091 // equal to |max_pixel_count| depending on how the source can scale the
2092 // input frame size.
2093 max_pixel_count = rtc::Optional<int>(
2094 (last_frame_info_.height * last_frame_info_.width * 3) / 5);
2095 // Increase |number_of_cpu_adapt_changes_| if
2096 // sink_wants_.max_pixel_count will be changed since
2097 // last time |source_->AddOrUpdateSink| was called. That is, this will
2098 // result in a new request for the source to change resolution.
2099 if (!sink_wants_.max_pixel_count ||
2100 *sink_wants_.max_pixel_count > *max_pixel_count) {
2101 ++number_of_cpu_adapt_changes_;
2102 ++cpu_restricted_counter_;
2103 }
2104 } else {
2105 RTC_DCHECK(load == kUnderuse);
2106 rtc::CritScope cs(&lock_);
2107 // The input video frame size will have a resolution with "one step up"
2108 // pixels than |max_pixel_count_step_up| where "one step up" depends on
2109 // how the source can scale the input frame size.
2110 max_pixel_count_step_up =
2111 rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width);
2112 // Increase |number_of_cpu_adapt_changes_| if
2113 // sink_wants_.max_pixel_count_step_up will be changed since
2114 // last time |source_->AddOrUpdateSink| was called. That is, this will
2115 // result in a new request for the source to change resolution.
2116 if (sink_wants_.max_pixel_count ||
2117 (sink_wants_.max_pixel_count_step_up &&
2118 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) {
2119 ++number_of_cpu_adapt_changes_;
2120 --cpu_restricted_counter_;
2121 }
2122 }
2123 sink_wants_.max_pixel_count = max_pixel_count;
2124 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up;
2125 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
2126 // that might cause a lock order inversion.
2127 source_->AddOrUpdateSink(this, sink_wants_);
2128 } 2023 }
2129 2024
2130 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( 2025 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo(
2131 bool log_stats) { 2026 bool log_stats) {
2132 VideoSenderInfo info; 2027 VideoSenderInfo info;
2133 RTC_DCHECK_RUN_ON(&thread_checker_); 2028 RTC_DCHECK_RUN_ON(&thread_checker_);
2134 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 2029 for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
2135 info.add_ssrc(ssrc); 2030 info.add_ssrc(ssrc);
2136 2031
2137 if (parameters_.codec_settings) 2032 if (parameters_.codec_settings)
2138 info.codec_name = parameters_.codec_settings->codec.name; 2033 info.codec_name = parameters_.codec_settings->codec.name;
2139 2034
2140 if (stream_ == NULL) 2035 if (stream_ == NULL)
2141 return info; 2036 return info;
2142 2037
2143 webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 2038 webrtc::VideoSendStream::Stats stats = stream_->GetStats();
2144 2039
2145 if (log_stats) 2040 if (log_stats)
2146 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); 2041 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis());
2147 2042
2148 info.adapt_changes = number_of_cpu_adapt_changes_; 2043 info.adapt_changes = stats.number_of_cpu_adapt_changes;
2149 info.adapt_reason = 2044 info.adapt_reason =
2150 cpu_restricted_counter_ <= 0 ? ADAPTREASON_NONE : ADAPTREASON_CPU; 2045 stats.cpu_limited_resolution ? ADAPTREASON_CPU : ADAPTREASON_NONE;
2151 2046
2152 // Get bandwidth limitation info from stream_->GetStats(). 2047 // Get bandwidth limitation info from stream_->GetStats().
2153 // Input resolution (output from video_adapter) can be further scaled down or 2048 // Input resolution (output from video_adapter) can be further scaled down or
2154 // higher video layer(s) can be dropped due to bitrate constraints. 2049 // higher video layer(s) can be dropped due to bitrate constraints.
2155 // Note, adapt_changes only include changes from the video_adapter. 2050 // Note, adapt_changes only include changes from the video_adapter.
2156 if (stats.bw_limited_resolution) 2051 if (stats.bw_limited_resolution)
2157 info.adapt_reason |= ADAPTREASON_BANDWIDTH; 2052 info.adapt_reason |= ADAPTREASON_BANDWIDTH;
2158 2053
2159 info.encoder_implementation_name = stats.encoder_implementation_name; 2054 info.encoder_implementation_name = stats.encoder_implementation_name;
2160 info.ssrc_groups = ssrc_groups_; 2055 info.ssrc_groups = ssrc_groups_;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec); 2127 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec);
2233 2128
2234 webrtc::VideoSendStream::Config config = parameters_.config.Copy(); 2129 webrtc::VideoSendStream::Config config = parameters_.config.Copy();
2235 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2130 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) {
2236 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2131 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX "
2237 "payload type the set codec. Ignoring RTX."; 2132 "payload type the set codec. Ignoring RTX.";
2238 config.rtp.rtx.ssrcs.clear(); 2133 config.rtp.rtx.ssrcs.clear();
2239 } 2134 }
2240 stream_ = call_->CreateVideoSendStream(std::move(config), 2135 stream_ = call_->CreateVideoSendStream(std::move(config),
2241 parameters_.encoder_config.Copy()); 2136 parameters_.encoder_config.Copy());
2242 stream_->SetSource(this);
2243 2137
2244 parameters_.encoder_config.encoder_specific_settings = NULL; 2138 parameters_.encoder_config.encoder_specific_settings = NULL;
2245 2139
2140 if (source_) {
2141 // TODO(perkj, nisse): Remove |source_| and directly call
2142 // |stream_|->SetSource(source) once the video frame types have been
2143 // merged and |stream_| internally reconfigure the encoder on frame
2144 // resolution change.
2145 // Do not adapt resolution for screen content as this will likely result in
2146 // blurry and unreadable text.
2147 stream_->SetSource(
2148 this, enable_cpu_overuse_detection_ &&
2149 !parameters_.options.is_screencast.value_or(false)
2150 ? webrtc::VideoSendStream::DegradationPreference::kBalanced
2151 : webrtc::VideoSendStream::DegradationPreference::
2152 kMaintainResolution);
2153 }
2154
2246 // Call stream_->Start() if necessary conditions are met. 2155 // Call stream_->Start() if necessary conditions are met.
2247 UpdateSendState(); 2156 UpdateSendState();
2248 } 2157 }
2249 2158
2250 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2159 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
2251 webrtc::Call* call, 2160 webrtc::Call* call,
2252 const StreamParams& sp, 2161 const StreamParams& sp,
2253 webrtc::VideoReceiveStream::Config config, 2162 webrtc::VideoReceiveStream::Config config,
2254 WebRtcVideoDecoderFactory* external_decoder_factory, 2163 WebRtcVideoDecoderFactory* external_decoder_factory,
2255 bool default_stream, 2164 bool default_stream,
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 rtx_mapping[video_codecs[i].codec.id] != 2597 rtx_mapping[video_codecs[i].codec.id] !=
2689 ulpfec_config.red_payload_type) { 2598 ulpfec_config.red_payload_type) {
2690 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2599 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id];
2691 } 2600 }
2692 } 2601 }
2693 2602
2694 return video_codecs; 2603 return video_codecs;
2695 } 2604 }
2696 2605
2697 } // namespace cricket 2606 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698