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

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

Issue 2304363002: Let ViEEncoder express resolution requests as Sinkwants (Closed)
Patch Set: Rebased. 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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) { 229 if (!rtx_ssrcs.empty() && primary_ssrcs.size() != rtx_ssrcs.size()) {
231 LOG(LS_ERROR) 230 LOG(LS_ERROR)
232 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): " 231 << "RTX SSRCs exist, but don't cover all SSRCs (unsupported): "
233 << sp.ToString(); 232 << sp.ToString();
234 return false; 233 return false;
235 } 234 }
236 235
237 return true; 236 return true;
238 } 237 }
239 238
240 inline bool ContainsHeaderExtension(
241 const std::vector<webrtc::RtpExtension>& extensions,
242 const std::string& uri) {
243 for (const auto& kv : extensions) {
244 if (kv.uri == uri) {
245 return true;
246 }
247 }
248 return false;
249 }
250
251 // Returns true if the given codec is disallowed from doing simulcast. 239 // Returns true if the given codec is disallowed from doing simulcast.
252 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) { 240 bool IsCodecBlacklistedForSimulcast(const std::string& codec_name) {
253 return CodecNamesEq(codec_name, kH264CodecName) || 241 return CodecNamesEq(codec_name, kH264CodecName) ||
254 CodecNamesEq(codec_name, kVp9CodecName); 242 CodecNamesEq(codec_name, kVp9CodecName);
255 } 243 }
256 244
257 // The selected thresholds for QVGA and VGA corresponded to a QP around 10. 245 // The selected thresholds for QVGA and VGA corresponded to a QP around 10.
258 // The change in QP declined above the selected bitrates. 246 // The change in QP declined above the selected bitrates.
259 static int GetMaxDefaultVideoBitrateKbps(int width, int height) { 247 static int GetMaxDefaultVideoBitrateKbps(int width, int height) {
260 if (width * height <= 320 * 240) { 248 if (width * height <= 320 * 240) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 const int kVideoRtpBufferSize = 65536; 376 const int kVideoRtpBufferSize = 65536;
389 377
390 // This constant is really an on/off, lower-level configurable NACK history 378 // This constant is really an on/off, lower-level configurable NACK history
391 // duration hasn't been implemented. 379 // duration hasn't been implemented.
392 static const int kNackHistoryMs = 1000; 380 static const int kNackHistoryMs = 1000;
393 381
394 static const int kDefaultQpMax = 56; 382 static const int kDefaultQpMax = 56;
395 383
396 static const int kDefaultRtcpReceiverReportSsrc = 1; 384 static const int kDefaultRtcpReceiverReportSsrc = 1;
397 385
398 // Down grade resolution at most 2 times for CPU reasons.
399 static const int kMaxCpuDowngrades = 2;
400
401 // Minimum time interval for logging stats. 386 // Minimum time interval for logging stats.
402 static const int64_t kStatsLogIntervalMs = 10000; 387 static const int64_t kStatsLogIntervalMs = 10000;
403 388
404 // Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is 389 // Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is
405 // recognized. 390 // recognized.
406 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names we 391 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names we
407 // don't recognize? 392 // don't recognize?
408 void AddCodecAndMaybeRtxCodec(const VideoCodec& codec, 393 void AddCodecAndMaybeRtxCodec(const VideoCodec& codec,
409 std::vector<VideoCodec>* codecs) { 394 std::vector<VideoCodec>* codecs) {
410 codecs->push_back(codec); 395 codecs->push_back(codec);
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 int max_bitrate_bps, 1545 int max_bitrate_bps,
1561 const rtc::Optional<VideoCodecSettings>& codec_settings, 1546 const rtc::Optional<VideoCodecSettings>& codec_settings,
1562 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, 1547 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions,
1563 // TODO(deadbeef): Don't duplicate information between send_params, 1548 // TODO(deadbeef): Don't duplicate information between send_params,
1564 // rtp_extensions, options, etc. 1549 // rtp_extensions, options, etc.
1565 const VideoSendParameters& send_params) 1550 const VideoSendParameters& send_params)
1566 : worker_thread_(rtc::Thread::Current()), 1551 : worker_thread_(rtc::Thread::Current()),
1567 ssrcs_(sp.ssrcs), 1552 ssrcs_(sp.ssrcs),
1568 ssrc_groups_(sp.ssrc_groups), 1553 ssrc_groups_(sp.ssrc_groups),
1569 call_(call), 1554 call_(call),
1570 cpu_restricted_counter_(0), 1555 enable_cpu_overuse_detection_(enable_cpu_overuse_detection),
1571 number_of_cpu_adapt_changes_(0),
1572 frame_count_(0),
1573 cpu_restricted_frame_count_(0),
1574 source_(nullptr), 1556 source_(nullptr),
1575 external_encoder_factory_(external_encoder_factory), 1557 external_encoder_factory_(external_encoder_factory),
1576 stream_(nullptr), 1558 stream_(nullptr),
1577 encoder_sink_(nullptr), 1559 encoder_sink_(nullptr),
1578 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), 1560 parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
1579 rtp_parameters_(CreateRtpParametersWithOneEncoding()), 1561 rtp_parameters_(CreateRtpParametersWithOneEncoding()),
1580 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), 1562 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false),
1581 sending_(false), 1563 sending_(false),
1582 last_frame_timestamp_us_(0) { 1564 last_frame_timestamp_us_(0) {
1583 parameters_.config.rtp.max_packet_size = kVideoMtu; 1565 parameters_.config.rtp.max_packet_size = kVideoMtu;
1584 parameters_.conference_mode = send_params.conference_mode; 1566 parameters_.conference_mode = send_params.conference_mode;
1585 1567
1586 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs); 1568 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs);
1587 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 1569 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
1588 &parameters_.config.rtp.rtx.ssrcs); 1570 &parameters_.config.rtp.rtx.ssrcs);
1589 parameters_.config.rtp.c_name = sp.cname; 1571 parameters_.config.rtp.c_name = sp.cname;
1590 if (rtp_extensions) { 1572 if (rtp_extensions) {
1591 parameters_.config.rtp.extensions = *rtp_extensions; 1573 parameters_.config.rtp.extensions = *rtp_extensions;
1592 } 1574 }
1593 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size 1575 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size
1594 ? webrtc::RtcpMode::kReducedSize 1576 ? webrtc::RtcpMode::kReducedSize
1595 : webrtc::RtcpMode::kCompound; 1577 : webrtc::RtcpMode::kCompound;
1596 parameters_.config.overuse_callback =
1597 enable_cpu_overuse_detection ? this : nullptr;
1598
1599 // Only request rotation at the source when we positively know that the remote
1600 // side doesn't support the rotation extension. This allows us to prepare the
1601 // encoder in the expectation that rotation is supported - which is the common
1602 // case.
1603 sink_wants_.rotation_applied =
1604 rtp_extensions &&
1605 !ContainsHeaderExtension(*rtp_extensions,
1606 webrtc::RtpExtension::kVideoRotationUri);
1607
1608 if (codec_settings) { 1578 if (codec_settings) {
1609 SetCodec(*codec_settings); 1579 SetCodec(*codec_settings);
1610 } 1580 }
1611 } 1581 }
1612 1582
1613 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { 1583 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() {
1614 DisconnectSource();
1615 if (stream_ != NULL) { 1584 if (stream_ != NULL) {
1616 call_->DestroyVideoSendStream(stream_); 1585 call_->DestroyVideoSendStream(stream_);
1617 } 1586 }
1618 DestroyVideoEncoder(&allocated_encoder_); 1587 DestroyVideoEncoder(&allocated_encoder_);
1619 UpdateHistograms();
1620 }
1621
1622 void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateHistograms() const {
1623 const int kMinRequiredFrames = 200;
1624 if (frame_count_ > kMinRequiredFrames) {
1625 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.CpuLimitedResolutionInPercent",
1626 cpu_restricted_frame_count_ * 100 / frame_count_);
1627 }
1628 } 1588 }
1629 1589
1630 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( 1590 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame(
1631 const VideoFrame& frame) { 1591 const VideoFrame& frame) {
1632 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); 1592 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame");
1633 webrtc::VideoFrame video_frame(frame.video_frame_buffer(), 1593 webrtc::VideoFrame video_frame(frame.video_frame_buffer(),
1634 frame.rotation(), 1594 frame.rotation(),
1635 frame.timestamp_us()); 1595 frame.timestamp_us());
1636 1596
1637 rtc::CritScope cs(&lock_); 1597 rtc::CritScope cs(&lock_);
(...skipping 13 matching lines...) Expand all
1651 << ", texture=" << last_frame_info_.is_texture; 1611 << ", texture=" << last_frame_info_.is_texture;
1652 } 1612 }
1653 1613
1654 if (encoder_sink_ == NULL) { 1614 if (encoder_sink_ == NULL) {
1655 // Frame input before send codecs are configured, dropping frame. 1615 // Frame input before send codecs are configured, dropping frame.
1656 return; 1616 return;
1657 } 1617 }
1658 1618
1659 last_frame_timestamp_us_ = video_frame.timestamp_us(); 1619 last_frame_timestamp_us_ = video_frame.timestamp_us();
1660 1620
1661 ++frame_count_;
1662 if (cpu_restricted_counter_ > 0)
1663 ++cpu_restricted_frame_count_;
1664
1665 // Forward frame to the encoder regardless if we are sending or not. This is 1621 // Forward frame to the encoder regardless if we are sending or not. This is
1666 // to ensure that the encoder can be reconfigured with the correct frame size 1622 // to ensure that the encoder can be reconfigured with the correct frame size
1667 // as quickly as possible. 1623 // as quickly as possible.
1668 encoder_sink_->OnFrame(video_frame); 1624 encoder_sink_->OnFrame(video_frame);
1669 } 1625 }
1670 1626
1671 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( 1627 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend(
1672 bool enable, 1628 bool enable,
1673 const VideoOptions* options, 1629 const VideoOptions* options,
1674 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { 1630 rtc::VideoSourceInterface<cricket::VideoFrame>* source) {
1675 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); 1631 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend");
1676 RTC_DCHECK_RUN_ON(&thread_checker_); 1632 RTC_DCHECK_RUN_ON(&thread_checker_);
1677 1633
1678 // Ignore |options| pointer if |enable| is false. 1634 // Ignore |options| pointer if |enable| is false.
1679 bool options_present = enable && options; 1635 bool options_present = enable && options;
1680 bool source_changing = source_ != source; 1636 bool source_changing = source_ != source;
1681 if (source_changing) {
1682 DisconnectSource();
1683 }
1684 1637
1685 if (options_present) { 1638 if (options_present) {
1686 VideoOptions old_options = parameters_.options; 1639 VideoOptions old_options = parameters_.options;
1687 parameters_.options.SetAll(*options); 1640 parameters_.options.SetAll(*options);
1688 if (parameters_.options != old_options) { 1641 if (parameters_.options != old_options) {
1689 ReconfigureEncoder(); 1642 ReconfigureEncoder();
1690 } 1643 }
1691 } 1644 }
1692 1645
1693 if (source_changing) { 1646 if (source_changing) {
1694 rtc::CritScope cs(&lock_); 1647 rtc::CritScope cs(&lock_);
1695 if (source == nullptr && encoder_sink_ != nullptr && 1648 if (source == nullptr && last_frame_info_.width > 0 && encoder_sink_) {
1696 last_frame_info_.width > 0) {
1697 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1649 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame.";
1698 // Force this black frame not to be dropped due to timestamp order 1650 // Force this black frame not to be dropped due to timestamp order
1699 // check. As IncomingCapturedFrame will drop the frame if this frame's 1651 // check. As IncomingCapturedFrame will drop the frame if this frame's
1700 // timestamp is less than or equal to last frame's timestamp, it is 1652 // timestamp is less than or equal to last frame's timestamp, it is
1701 // necessary to give this black frame a larger timestamp than the 1653 // necessary to give this black frame a larger timestamp than the
1702 // previous one. 1654 // previous one.
1703 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; 1655 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec;
1704 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( 1656 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer(
1705 webrtc::I420Buffer::Create(last_frame_info_.width, 1657 webrtc::I420Buffer::Create(last_frame_info_.width,
1706 last_frame_info_.height)); 1658 last_frame_info_.height));
1707 black_buffer->SetToBlack(); 1659 black_buffer->SetToBlack();
1708 1660
1709 encoder_sink_->OnFrame(webrtc::VideoFrame( 1661 encoder_sink_->OnFrame(webrtc::VideoFrame(
1710 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); 1662 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_));
1711 } 1663 }
1712 source_ = source;
1713 } 1664 }
1714 1665
1715 if (source_changing && source_) { 1666 // TODO(perkj, nisse): Remove |source_| and directly call
1716 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since 1667 // |stream_|->SetSource(source) once the video frame types have been
1717 // that might cause a lock order inversion. 1668 // merged.
1718 source_->AddOrUpdateSink(this, sink_wants_); 1669 if (source_ && stream_) {
1670 stream_->SetSource(
1671 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced);
1672 }
1673 // Switch to the new source.
1674 source_ = source;
1675 if (source && stream_) {
1676 // Do not adapt resolution for screen content as this will likely
1677 // result in blurry and unreadable text.
1678 stream_->SetSource(
1679 this, enable_cpu_overuse_detection_ &&
1680 !parameters_.options.is_screencast.value_or(false)
1681 ? webrtc::VideoSendStream::DegradationPreference::kBalanced
1682 : webrtc::VideoSendStream::DegradationPreference::
1683 kMaintainResolution);
1719 } 1684 }
1720 return true; 1685 return true;
1721 } 1686 }
1722 1687
1723 void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() {
1724 RTC_DCHECK_RUN_ON(&thread_checker_);
1725 if (source_ == nullptr) {
1726 return;
1727 }
1728
1729 // |source_->RemoveSink| may not be called while holding |lock_| since
1730 // that might cause a lock order inversion.
1731 source_->RemoveSink(this);
1732 source_ = nullptr;
1733 // Reset |cpu_restricted_counter_| if the source is changed. It is not
1734 // possible to know if the video resolution is restricted by CPU usage after
1735 // the source is changed since the next source might be screen capture
1736 // with another resolution and frame rate.
1737 cpu_restricted_counter_ = 0;
1738 }
1739
1740 const std::vector<uint32_t>& 1688 const std::vector<uint32_t>&
1741 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { 1689 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const {
1742 return ssrcs_; 1690 return ssrcs_;
1743 } 1691 }
1744 1692
1745 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 1693 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder
1746 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 1694 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder(
1747 const VideoCodec& codec) { 1695 const VideoCodec& codec) {
1748 RTC_DCHECK_RUN_ON(&thread_checker_); 1696 RTC_DCHECK_RUN_ON(&thread_checker_);
1749 webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 1697 webrtc::VideoCodecType type = CodecTypeFromName(codec.name);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1857 SetCodec(*params.codec); 1805 SetCodec(*params.codec);
1858 recreate_stream = false; // SetCodec has already recreated the stream. 1806 recreate_stream = false; // SetCodec has already recreated the stream.
1859 } else if (params.conference_mode && parameters_.codec_settings) { 1807 } else if (params.conference_mode && parameters_.codec_settings) {
1860 SetCodec(*parameters_.codec_settings); 1808 SetCodec(*parameters_.codec_settings);
1861 recreate_stream = false; // SetCodec has already recreated the stream. 1809 recreate_stream = false; // SetCodec has already recreated the stream.
1862 } 1810 }
1863 if (recreate_stream) { 1811 if (recreate_stream) {
1864 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters"; 1812 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters";
1865 RecreateWebRtcStream(); 1813 RecreateWebRtcStream();
1866 } 1814 }
1867
1868 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
1869 // that might cause a lock order inversion.
1870 if (params.rtp_header_extensions) {
1871 sink_wants_.rotation_applied = !ContainsHeaderExtension(
1872 *params.rtp_header_extensions, webrtc::RtpExtension::kVideoRotationUri);
1873 if (source_) {
1874 source_->AddOrUpdateSink(this, sink_wants_);
1875 }
1876 }
1877 } 1815 }
1878 1816
1879 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( 1817 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters(
1880 const webrtc::RtpParameters& new_parameters) { 1818 const webrtc::RtpParameters& new_parameters) {
1881 RTC_DCHECK_RUN_ON(&thread_checker_); 1819 RTC_DCHECK_RUN_ON(&thread_checker_);
1882 if (!ValidateRtpParameters(new_parameters)) { 1820 if (!ValidateRtpParameters(new_parameters)) {
1883 return false; 1821 return false;
1884 } 1822 }
1885 1823
1886 bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps != 1824 bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps !=
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 1933
1996 parameters_.encoder_config = std::move(encoder_config); 1934 parameters_.encoder_config = std::move(encoder_config);
1997 } 1935 }
1998 1936
1999 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { 1937 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) {
2000 RTC_DCHECK_RUN_ON(&thread_checker_); 1938 RTC_DCHECK_RUN_ON(&thread_checker_);
2001 sending_ = send; 1939 sending_ = send;
2002 UpdateSendState(); 1940 UpdateSendState();
2003 } 1941 }
2004 1942
1943 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink(
1944 VideoSinkInterface<webrtc::VideoFrame>* sink) {
1945 RTC_DCHECK_RUN_ON(&thread_checker_);
1946 {
1947 rtc::CritScope cs(&lock_);
1948 RTC_DCHECK(encoder_sink_ == sink);
1949 encoder_sink_ = nullptr;
1950 }
1951 source_->RemoveSink(this);
1952 }
1953
2005 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( 1954 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink(
2006 VideoSinkInterface<webrtc::VideoFrame>* sink, 1955 VideoSinkInterface<webrtc::VideoFrame>* sink,
2007 const rtc::VideoSinkWants& wants) { 1956 const rtc::VideoSinkWants& wants) {
2008 // TODO(perkj): Actually consider the encoder |wants| and remove 1957 if (worker_thread_ == rtc::Thread::Current()) {
2009 // WebRtcVideoSendStream::OnLoadUpdate(Load load). 1958 // AddOrUpdateSink is called on |worker_thread_| if this is the first
2010 rtc::CritScope cs(&lock_); 1959 // registration of |sink|.
2011 RTC_DCHECK(!encoder_sink_ || encoder_sink_ == sink); 1960 RTC_DCHECK_RUN_ON(&thread_checker_);
2012 encoder_sink_ = sink; 1961 {
2013 } 1962 rtc::CritScope cs(&lock_);
2014 1963 encoder_sink_ = sink;
2015 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( 1964 }
2016 VideoSinkInterface<webrtc::VideoFrame>* sink) { 1965 source_->AddOrUpdateSink(this, wants);
2017 rtc::CritScope cs(&lock_); 1966 } else {
2018 RTC_DCHECK_EQ(encoder_sink_, sink); 1967 // Subsequent calls to AddOrUpdateSink will happen on the encoder task
2019 encoder_sink_ = nullptr; 1968 // queue.
2020 } 1969 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, wants] {
2021 1970 RTC_DCHECK_RUN_ON(&thread_checker_);
2022 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { 1971 bool encoder_sink_valid = true;
2023 if (worker_thread_ != rtc::Thread::Current()) { 1972 {
2024 invoker_.AsyncInvoke<void>( 1973 rtc::CritScope cs(&lock_);
2025 RTC_FROM_HERE, worker_thread_, 1974 encoder_sink_valid = encoder_sink_ != nullptr;
2026 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate, 1975 }
2027 this, load)); 1976 // Since |source_| is still valid after a call to RemoveSink, check if
2028 return; 1977 // |encoder_sink_| is still valid to check if this call should be
1978 // cancelled.
1979 if (source_ && encoder_sink_valid) {
1980 source_->AddOrUpdateSink(this, wants);
1981 }
1982 });
2029 } 1983 }
2030 RTC_DCHECK_RUN_ON(&thread_checker_);
2031 if (!source_) {
2032 return;
2033 }
2034
2035 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: "
2036 << (parameters_.options.is_screencast
2037 ? (*parameters_.options.is_screencast ? "true" : "false")
2038 : "unset");
2039 // Do not adapt resolution for screen content as this will likely result in
2040 // blurry and unreadable text.
2041 if (parameters_.options.is_screencast.value_or(false))
2042 return;
2043
2044 rtc::Optional<int> max_pixel_count;
2045 rtc::Optional<int> max_pixel_count_step_up;
2046 if (load == kOveruse) {
2047 rtc::CritScope cs(&lock_);
2048 if (cpu_restricted_counter_ >= kMaxCpuDowngrades) {
2049 return;
2050 }
2051 // The input video frame size will have a resolution with less than or
2052 // equal to |max_pixel_count| depending on how the source can scale the
2053 // input frame size.
2054 max_pixel_count = rtc::Optional<int>(
2055 (last_frame_info_.height * last_frame_info_.width * 3) / 5);
2056 // Increase |number_of_cpu_adapt_changes_| if
2057 // sink_wants_.max_pixel_count will be changed since
2058 // last time |source_->AddOrUpdateSink| was called. That is, this will
2059 // result in a new request for the source to change resolution.
2060 if (!sink_wants_.max_pixel_count ||
2061 *sink_wants_.max_pixel_count > *max_pixel_count) {
2062 ++number_of_cpu_adapt_changes_;
2063 ++cpu_restricted_counter_;
2064 }
2065 } else {
2066 RTC_DCHECK(load == kUnderuse);
2067 rtc::CritScope cs(&lock_);
2068 // The input video frame size will have a resolution with "one step up"
2069 // pixels than |max_pixel_count_step_up| where "one step up" depends on
2070 // how the source can scale the input frame size.
2071 max_pixel_count_step_up =
2072 rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width);
2073 // Increase |number_of_cpu_adapt_changes_| if
2074 // sink_wants_.max_pixel_count_step_up will be changed since
2075 // last time |source_->AddOrUpdateSink| was called. That is, this will
2076 // result in a new request for the source to change resolution.
2077 if (sink_wants_.max_pixel_count ||
2078 (sink_wants_.max_pixel_count_step_up &&
2079 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) {
2080 ++number_of_cpu_adapt_changes_;
2081 --cpu_restricted_counter_;
2082 }
2083 }
2084 sink_wants_.max_pixel_count = max_pixel_count;
2085 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up;
2086 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
2087 // that might cause a lock order inversion.
2088 source_->AddOrUpdateSink(this, sink_wants_);
2089 } 1984 }
2090 1985
2091 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( 1986 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo(
2092 bool log_stats) { 1987 bool log_stats) {
2093 VideoSenderInfo info; 1988 VideoSenderInfo info;
2094 RTC_DCHECK_RUN_ON(&thread_checker_); 1989 RTC_DCHECK_RUN_ON(&thread_checker_);
2095 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) 1990 for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
2096 info.add_ssrc(ssrc); 1991 info.add_ssrc(ssrc);
2097 1992
2098 if (parameters_.codec_settings) 1993 if (parameters_.codec_settings)
2099 info.codec_name = parameters_.codec_settings->codec.name; 1994 info.codec_name = parameters_.codec_settings->codec.name;
2100 1995
2101 if (stream_ == NULL) 1996 if (stream_ == NULL)
2102 return info; 1997 return info;
2103 1998
2104 webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 1999 webrtc::VideoSendStream::Stats stats = stream_->GetStats();
2105 2000
2106 if (log_stats) 2001 if (log_stats)
2107 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); 2002 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis());
2108 2003
2109 info.adapt_changes = number_of_cpu_adapt_changes_; 2004 info.adapt_changes = stats.number_of_cpu_adapt_changes;
2110 info.adapt_reason = 2005 info.adapt_reason =
2111 cpu_restricted_counter_ <= 0 ? ADAPTREASON_NONE : ADAPTREASON_CPU; 2006 stats.cpu_limited_resolution ? ADAPTREASON_CPU : ADAPTREASON_NONE;
2112 2007
2113 // Get bandwidth limitation info from stream_->GetStats(). 2008 // Get bandwidth limitation info from stream_->GetStats().
2114 // Input resolution (output from video_adapter) can be further scaled down or 2009 // Input resolution (output from video_adapter) can be further scaled down or
2115 // higher video layer(s) can be dropped due to bitrate constraints. 2010 // higher video layer(s) can be dropped due to bitrate constraints.
2116 // Note, adapt_changes only include changes from the video_adapter. 2011 // Note, adapt_changes only include changes from the video_adapter.
2117 if (stats.bw_limited_resolution) 2012 if (stats.bw_limited_resolution)
2118 info.adapt_reason |= ADAPTREASON_BANDWIDTH; 2013 info.adapt_reason |= ADAPTREASON_BANDWIDTH;
2119 2014
2120 info.encoder_implementation_name = stats.encoder_implementation_name; 2015 info.encoder_implementation_name = stats.encoder_implementation_name;
2121 info.ssrc_groups = ssrc_groups_; 2016 info.ssrc_groups = ssrc_groups_;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec); 2089 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec);
2195 2090
2196 webrtc::VideoSendStream::Config config = parameters_.config.Copy(); 2091 webrtc::VideoSendStream::Config config = parameters_.config.Copy();
2197 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2092 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) {
2198 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2093 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX "
2199 "payload type the set codec. Ignoring RTX."; 2094 "payload type the set codec. Ignoring RTX.";
2200 config.rtp.rtx.ssrcs.clear(); 2095 config.rtp.rtx.ssrcs.clear();
2201 } 2096 }
2202 stream_ = call_->CreateVideoSendStream(std::move(config), 2097 stream_ = call_->CreateVideoSendStream(std::move(config),
2203 parameters_.encoder_config.Copy()); 2098 parameters_.encoder_config.Copy());
2204 stream_->SetSource(this);
2205 2099
2206 parameters_.encoder_config.encoder_specific_settings = NULL; 2100 parameters_.encoder_config.encoder_specific_settings = NULL;
2207 2101
2102 if (source_) {
2103 // TODO(perkj, nisse): Remove |source_| and directly call
2104 // |stream_|->SetSource(source) once the video frame types have been
2105 // merged and |stream_| internally reconfigure the encoder on frame
2106 // resolution change.
2107 // Do not adapt resolution for screen content as this will likely result in
2108 // blurry and unreadable text.
2109 stream_->SetSource(
2110 this, enable_cpu_overuse_detection_ &&
2111 !parameters_.options.is_screencast.value_or(false)
2112 ? webrtc::VideoSendStream::DegradationPreference::kBalanced
2113 : webrtc::VideoSendStream::DegradationPreference::
2114 kMaintainResolution);
2115 }
2116
2208 // Call stream_->Start() if necessary conditions are met. 2117 // Call stream_->Start() if necessary conditions are met.
2209 UpdateSendState(); 2118 UpdateSendState();
2210 } 2119 }
2211 2120
2212 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2121 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
2213 webrtc::Call* call, 2122 webrtc::Call* call,
2214 const StreamParams& sp, 2123 const StreamParams& sp,
2215 webrtc::VideoReceiveStream::Config config, 2124 webrtc::VideoReceiveStream::Config config,
2216 WebRtcVideoDecoderFactory* external_decoder_factory, 2125 WebRtcVideoDecoderFactory* external_decoder_factory,
2217 bool default_stream, 2126 bool default_stream,
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
2650 rtx_mapping[video_codecs[i].codec.id] != 2559 rtx_mapping[video_codecs[i].codec.id] !=
2651 ulpfec_config.red_payload_type) { 2560 ulpfec_config.red_payload_type) {
2652 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2561 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id];
2653 } 2562 }
2654 } 2563 }
2655 2564
2656 return video_codecs; 2565 return video_codecs;
2657 } 2566 }
2658 2567
2659 } // namespace cricket 2568 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/engine/webrtcvideoengine2.h ('k') | webrtc/media/engine/webrtcvideoengine2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698