| 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 | 
|---|