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

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

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

Powered by Google App Engine
This is Rietveld 408576698