OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¶meters_.config.rtp.ssrcs); | 1600 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
1619 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1601 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
1620 ¶meters_.config.rtp.rtx.ssrcs); | 1602 ¶meters_.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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |