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

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

Issue 2351633002: Let ViEEncoder handle resolution changes. (Closed)
Patch Set: Fix perf test Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/media/engine/webrtcvideoengine2.h" 11 #include "webrtc/media/engine/webrtcvideoengine2.h"
12 12
13 #include <stdio.h> 13 #include <stdio.h>
14 #include <algorithm> 14 #include <algorithm>
15 #include <set> 15 #include <set>
16 #include <string> 16 #include <string>
17 #include <utility>
17 18
18 #include "webrtc/base/copyonwritebuffer.h" 19 #include "webrtc/base/copyonwritebuffer.h"
19 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
20 #include "webrtc/base/stringutils.h" 21 #include "webrtc/base/stringutils.h"
21 #include "webrtc/base/timeutils.h" 22 #include "webrtc/base/timeutils.h"
22 #include "webrtc/base/trace_event.h" 23 #include "webrtc/base/trace_event.h"
23 #include "webrtc/call.h" 24 #include "webrtc/call.h"
24 #include "webrtc/media/engine/constants.h" 25 #include "webrtc/media/engine/constants.h"
25 #include "webrtc/media/engine/simulcast.h" 26 #include "webrtc/media/engine/simulcast.h"
26 #include "webrtc/media/engine/webrtcmediaengine.h" 27 #include "webrtc/media/engine/webrtcmediaengine.h"
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 } 316 }
316 317
317 int GetDefaultVp9TemporalLayers() { 318 int GetDefaultVp9TemporalLayers() {
318 int num_sl; 319 int num_sl;
319 int num_tl; 320 int num_tl;
320 if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) { 321 if (GetVp9LayersFromFieldTrialGroup(&num_sl, &num_tl)) {
321 return num_tl; 322 return num_tl;
322 } 323 }
323 return 1; 324 return 1;
324 } 325 }
326
327 class EncoderStreamFactory
328 : public webrtc::VideoEncoderConfig::VideoStreamFactoryInterface {
329 public:
330 EncoderStreamFactory(std::string codec_name,
331 int max_qp,
332 int max_framerate,
333 bool is_screencast,
334 bool conference_mode)
335 : codec_name_(codec_name),
336 max_qp_(max_qp),
337 max_framerate_(max_framerate),
338 is_screencast_(is_screencast),
339 conference_mode_(conference_mode) {}
340
341 private:
342 std::vector<webrtc::VideoStream> CreateEncoderStreams(
343 int width,
344 int height,
345 const webrtc::VideoEncoderConfig& encoder_config) override {
346 if (encoder_config.number_of_streams > 1) {
347 return GetSimulcastConfig(encoder_config.number_of_streams, width, height,
348 encoder_config.max_bitrate_bps, max_qp_,
349 max_framerate_);
350 }
351
352 // For unset max bitrates set default bitrate for non-simulcast.
353 int max_bitrate_bps =
354 (encoder_config.max_bitrate_bps > 0)
355 ? encoder_config.max_bitrate_bps
356 : GetMaxDefaultVideoBitrateKbps(width, height) * 1000;
357
358 webrtc::VideoStream stream;
359 stream.width = width;
360 stream.height = height;
361 stream.max_framerate = max_framerate_;
362 stream.min_bitrate_bps = kMinVideoBitrateKbps * 1000;
363 stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps;
364 stream.max_qp = max_qp_;
365
366 // Conference mode screencast uses 2 temporal layers split at 100kbit.
367 if (conference_mode_ && is_screencast_) {
368 ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault();
369 // For screenshare in conference mode, tl0 and tl1 bitrates are
370 // piggybacked
371 // on the VideoCodec struct as target and max bitrates, respectively.
372 // See eg. webrtc::VP8EncoderImpl::SetRates().
373 stream.target_bitrate_bps = config.tl0_bitrate_kbps * 1000;
374 stream.max_bitrate_bps = config.tl1_bitrate_kbps * 1000;
375 stream.temporal_layer_thresholds_bps.clear();
376 stream.temporal_layer_thresholds_bps.push_back(config.tl0_bitrate_kbps *
377 1000);
378 }
379
380 if (CodecNamesEq(codec_name_, kVp9CodecName) && !is_screencast_) {
381 stream.temporal_layer_thresholds_bps.resize(
382 GetDefaultVp9TemporalLayers() - 1);
383 }
384
385 std::vector<webrtc::VideoStream> streams;
386 streams.push_back(stream);
387 return streams;
388 }
389
390 const std::string codec_name_;
391 const int max_qp_;
392 const int max_framerate_;
393 const bool is_screencast_;
394 const bool conference_mode_;
395 };
396
325 } // namespace 397 } // namespace
326 398
327 // Constants defined in webrtc/media/engine/constants.h 399 // Constants defined in webrtc/media/engine/constants.h
328 // TODO(pbos): Move these to a separate constants.cc file. 400 // TODO(pbos): Move these to a separate constants.cc file.
329 const int kMinVideoBitrate = 30; 401 const int kMinVideoBitrateKbps = 30;
330 const int kStartVideoBitrate = 300;
331 402
332 const int kVideoMtu = 1200; 403 const int kVideoMtu = 1200;
333 const int kVideoRtpBufferSize = 65536; 404 const int kVideoRtpBufferSize = 65536;
334 405
335 // This constant is really an on/off, lower-level configurable NACK history 406 // This constant is really an on/off, lower-level configurable NACK history
336 // duration hasn't been implemented. 407 // duration hasn't been implemented.
337 static const int kNackHistoryMs = 1000; 408 static const int kNackHistoryMs = 1000;
338 409
339 static const int kDefaultQpMax = 56; 410 static const int kDefaultQpMax = 56;
340 411
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); 462 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1");
392 codec.SetParam(kH264FmtpPacketizationMode, "1"); 463 codec.SetParam(kH264FmtpPacketizationMode, "1");
393 AddCodecAndMaybeRtxCodec(codec, &codecs); 464 AddCodecAndMaybeRtxCodec(codec, &codecs);
394 } 465 }
395 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), 466 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName),
396 &codecs); 467 &codecs);
397 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); 468 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName));
398 return codecs; 469 return codecs;
399 } 470 }
400 471
401 std::vector<webrtc::VideoStream>
402 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateSimulcastVideoStreams(
403 const VideoCodec& codec,
404 const VideoOptions& options,
405 int max_bitrate_bps,
406 size_t num_streams) {
407 int max_qp = kDefaultQpMax;
408 codec.GetParam(kCodecParamMaxQuantization, &max_qp);
409
410 return GetSimulcastConfig(
411 num_streams, codec.width, codec.height, max_bitrate_bps, max_qp,
412 codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate);
413 }
414
415 std::vector<webrtc::VideoStream>
416 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoStreams(
417 const VideoCodec& codec,
418 const VideoOptions& options,
419 int max_bitrate_bps,
420 size_t num_streams) {
421 int codec_max_bitrate_kbps;
422 if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) {
423 max_bitrate_bps = codec_max_bitrate_kbps * 1000;
424 }
425 if (num_streams != 1) {
426 return CreateSimulcastVideoStreams(codec, options, max_bitrate_bps,
427 num_streams);
428 }
429
430 // For unset max bitrates set default bitrate for non-simulcast.
431 if (max_bitrate_bps <= 0) {
432 max_bitrate_bps =
433 GetMaxDefaultVideoBitrateKbps(codec.width, codec.height) * 1000;
434 }
435
436 webrtc::VideoStream stream;
437 stream.width = codec.width;
438 stream.height = codec.height;
439 stream.max_framerate =
440 codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate;
441
442 stream.min_bitrate_bps = kMinVideoBitrate * 1000;
443 stream.target_bitrate_bps = stream.max_bitrate_bps = max_bitrate_bps;
444
445 int max_qp = kDefaultQpMax;
446 codec.GetParam(kCodecParamMaxQuantization, &max_qp);
447 stream.max_qp = max_qp;
448 std::vector<webrtc::VideoStream> streams;
449 streams.push_back(stream);
450 return streams;
451 }
452
453 void* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( 472 void* WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings(
454 const VideoCodec& codec) { 473 const VideoCodec& codec) {
474 RTC_DCHECK_RUN_ON(&thread_checker_);
455 bool is_screencast = parameters_.options.is_screencast.value_or(false); 475 bool is_screencast = parameters_.options.is_screencast.value_or(false);
456 // No automatic resizing when using simulcast or screencast. 476 // No automatic resizing when using simulcast or screencast.
457 bool automatic_resize = 477 bool automatic_resize =
458 !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; 478 !is_screencast && parameters_.config.rtp.ssrcs.size() == 1;
459 bool frame_dropping = !is_screencast; 479 bool frame_dropping = !is_screencast;
460 bool denoising; 480 bool denoising;
461 bool codec_default_denoising = false; 481 bool codec_default_denoising = false;
462 if (is_screencast) { 482 if (is_screencast) {
463 denoising = false; 483 denoising = false;
464 } else { 484 } else {
(...skipping 1067 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 1552
1533 WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters:: 1553 WebRtcVideoChannel2::WebRtcVideoSendStream::VideoSendStreamParameters::
1534 VideoSendStreamParameters( 1554 VideoSendStreamParameters(
1535 webrtc::VideoSendStream::Config config, 1555 webrtc::VideoSendStream::Config config,
1536 const VideoOptions& options, 1556 const VideoOptions& options,
1537 int max_bitrate_bps, 1557 int max_bitrate_bps,
1538 const rtc::Optional<VideoCodecSettings>& codec_settings) 1558 const rtc::Optional<VideoCodecSettings>& codec_settings)
1539 : config(std::move(config)), 1559 : config(std::move(config)),
1540 options(options), 1560 options(options),
1541 max_bitrate_bps(max_bitrate_bps), 1561 max_bitrate_bps(max_bitrate_bps),
1562 conference_mode(false),
1542 codec_settings(codec_settings) {} 1563 codec_settings(codec_settings) {}
1543 1564
1544 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( 1565 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder(
1545 webrtc::VideoEncoder* encoder, 1566 webrtc::VideoEncoder* encoder,
1546 webrtc::VideoCodecType type, 1567 webrtc::VideoCodecType type,
1547 bool external) 1568 bool external)
1548 : encoder(encoder), 1569 : encoder(encoder),
1549 external_encoder(nullptr), 1570 external_encoder(nullptr),
1550 type(type), 1571 type(type),
1551 external(external) { 1572 external(external) {
(...skipping 24 matching lines...) Expand all
1576 cpu_restricted_counter_(0), 1597 cpu_restricted_counter_(0),
1577 number_of_cpu_adapt_changes_(0), 1598 number_of_cpu_adapt_changes_(0),
1578 frame_count_(0), 1599 frame_count_(0),
1579 cpu_restricted_frame_count_(0), 1600 cpu_restricted_frame_count_(0),
1580 source_(nullptr), 1601 source_(nullptr),
1581 external_encoder_factory_(external_encoder_factory), 1602 external_encoder_factory_(external_encoder_factory),
1582 stream_(nullptr), 1603 stream_(nullptr),
1583 encoder_sink_(nullptr), 1604 encoder_sink_(nullptr),
1584 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), 1605 parameters_(std::move(config), options, max_bitrate_bps, codec_settings),
1585 rtp_parameters_(CreateRtpParametersWithOneEncoding()), 1606 rtp_parameters_(CreateRtpParametersWithOneEncoding()),
1586 pending_encoder_reconfiguration_(false),
1587 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), 1607 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false),
1588 sending_(false), 1608 sending_(false),
1589 last_frame_timestamp_us_(0) { 1609 last_frame_timestamp_us_(0) {
1590 parameters_.config.rtp.max_packet_size = kVideoMtu; 1610 parameters_.config.rtp.max_packet_size = kVideoMtu;
1591 parameters_.conference_mode = send_params.conference_mode; 1611 parameters_.conference_mode = send_params.conference_mode;
1592 1612
1593 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs); 1613 sp.GetPrimarySsrcs(&parameters_.config.rtp.ssrcs);
1594 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, 1614 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs,
1595 &parameters_.config.rtp.rtx.ssrcs); 1615 &parameters_.config.rtp.rtx.ssrcs);
1596 parameters_.config.rtp.c_name = sp.cname; 1616 parameters_.config.rtp.c_name = sp.cname;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 rtc::CritScope cs(&lock_); 1664 rtc::CritScope cs(&lock_);
1645 1665
1646 if (video_frame.width() != last_frame_info_.width || 1666 if (video_frame.width() != last_frame_info_.width ||
1647 video_frame.height() != last_frame_info_.height || 1667 video_frame.height() != last_frame_info_.height ||
1648 video_frame.rotation() != last_frame_info_.rotation || 1668 video_frame.rotation() != last_frame_info_.rotation ||
1649 video_frame.is_texture() != last_frame_info_.is_texture) { 1669 video_frame.is_texture() != last_frame_info_.is_texture) {
1650 last_frame_info_.width = video_frame.width(); 1670 last_frame_info_.width = video_frame.width();
1651 last_frame_info_.height = video_frame.height(); 1671 last_frame_info_.height = video_frame.height();
1652 last_frame_info_.rotation = video_frame.rotation(); 1672 last_frame_info_.rotation = video_frame.rotation();
1653 last_frame_info_.is_texture = video_frame.is_texture(); 1673 last_frame_info_.is_texture = video_frame.is_texture();
1654 pending_encoder_reconfiguration_ = true;
1655 1674
1656 LOG(LS_INFO) << "Video frame parameters changed: dimensions=" 1675 LOG(LS_INFO) << "Video frame parameters changed: dimensions="
1657 << last_frame_info_.width << "x" << last_frame_info_.height 1676 << last_frame_info_.width << "x" << last_frame_info_.height
1658 << ", rotation=" << last_frame_info_.rotation 1677 << ", rotation=" << last_frame_info_.rotation
1659 << ", texture=" << last_frame_info_.is_texture; 1678 << ", texture=" << last_frame_info_.is_texture;
1660 } 1679 }
1661 1680
1662 if (encoder_sink_ == NULL) { 1681 if (encoder_sink_ == NULL) {
1663 // Frame input before send codecs are configured, dropping frame. 1682 // Frame input before send codecs are configured, dropping frame.
1664 return; 1683 return;
1665 } 1684 }
1666 1685
1667 last_frame_timestamp_us_ = video_frame.timestamp_us(); 1686 last_frame_timestamp_us_ = video_frame.timestamp_us();
1668 1687
1669 if (pending_encoder_reconfiguration_) {
1670 ReconfigureEncoder();
1671 pending_encoder_reconfiguration_ = false;
1672 }
1673
1674 // Not sending, abort after reconfiguration. Reconfiguration should still
1675 // occur to permit sending this input as quickly as possible once we start
1676 // sending (without having to reconfigure then).
1677 if (!sending_) {
1678 return;
1679 }
1680
1681 ++frame_count_; 1688 ++frame_count_;
1682 if (cpu_restricted_counter_ > 0) 1689 if (cpu_restricted_counter_ > 0)
1683 ++cpu_restricted_frame_count_; 1690 ++cpu_restricted_frame_count_;
1684 1691
1692 // Forward frame to the encoder regardless if we are sending or not. This is
1693 // to ensure that the encoder can be reconfigured with the correct frame size
1694 // as quickly as possible.
1685 encoder_sink_->OnFrame(video_frame); 1695 encoder_sink_->OnFrame(video_frame);
1686 } 1696 }
1687 1697
1688 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( 1698 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend(
1689 bool enable, 1699 bool enable,
1690 const VideoOptions* options, 1700 const VideoOptions* options,
1691 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { 1701 rtc::VideoSourceInterface<cricket::VideoFrame>* source) {
1692 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); 1702 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend");
1693 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 1703 RTC_DCHECK_RUN_ON(&thread_checker_);
1694 1704
1695 // Ignore |options| pointer if |enable| is false. 1705 // Ignore |options| pointer if |enable| is false.
1696 bool options_present = enable && options; 1706 bool options_present = enable && options;
1697 bool source_changing = source_ != source; 1707 bool source_changing = source_ != source;
1698 if (source_changing) { 1708 if (source_changing) {
1699 DisconnectSource(); 1709 DisconnectSource();
1700 } 1710 }
1701 1711
1702 if (options_present || source_changing) { 1712 if (options_present || source_changing) {
sprang_webrtc 2016/09/22 13:06:16 This looks redundant?
perkj_webrtc 2016/09/26 12:09:42 Done.
1703 rtc::CritScope cs(&lock_);
1704
1705 if (options_present) { 1713 if (options_present) {
1706 VideoOptions old_options = parameters_.options; 1714 VideoOptions old_options = parameters_.options;
1707 parameters_.options.SetAll(*options); 1715 parameters_.options.SetAll(*options);
1708 // Reconfigure encoder settings on the next frame or stream 1716 // If options has changed and SetCodec has been called.
1709 // recreation if the options changed. 1717 if (parameters_.options != old_options && stream_) {
1710 if (parameters_.options != old_options) { 1718 ReconfigureEncoder();
1711 pending_encoder_reconfiguration_ = true;
1712 } 1719 }
1713 } 1720 }
1714 1721
1715 if (source_changing) { 1722 if (source_changing) {
1716 if (source == nullptr && encoder_sink_ != nullptr) { 1723 rtc::CritScope cs(&lock_);
1724 if (source == nullptr && encoder_sink_ != nullptr &&
1725 last_frame_info_.width > 0) {
1717 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; 1726 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame.";
1718 // Force this black frame not to be dropped due to timestamp order 1727 // Force this black frame not to be dropped due to timestamp order
1719 // check. As IncomingCapturedFrame will drop the frame if this frame's 1728 // check. As IncomingCapturedFrame will drop the frame if this frame's
1720 // timestamp is less than or equal to last frame's timestamp, it is 1729 // timestamp is less than or equal to last frame's timestamp, it is
1721 // necessary to give this black frame a larger timestamp than the 1730 // necessary to give this black frame a larger timestamp than the
1722 // previous one. 1731 // previous one.
1723 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; 1732 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec;
1724 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( 1733 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer(
1725 webrtc::I420Buffer::Create(last_frame_info_.width, 1734 webrtc::I420Buffer::Create(last_frame_info_.width,
1726 last_frame_info_.height)); 1735 last_frame_info_.height));
1727 black_buffer->SetToBlack(); 1736 black_buffer->SetToBlack();
1728 1737
1729 encoder_sink_->OnFrame(webrtc::VideoFrame( 1738 encoder_sink_->OnFrame(webrtc::VideoFrame(
1730 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); 1739 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_));
1731 } 1740 }
1732 source_ = source; 1741 source_ = source;
1733 } 1742 }
1734 } 1743 }
1735 1744
1736 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
1737 // that might cause a lock order inversion.
1738 if (source_changing && source_) { 1745 if (source_changing && source_) {
1746 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
1747 // that might cause a lock order inversion.
1739 source_->AddOrUpdateSink(this, sink_wants_); 1748 source_->AddOrUpdateSink(this, sink_wants_);
1740 } 1749 }
1741 return true; 1750 return true;
1742 } 1751 }
1743 1752
1744 void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() { 1753 void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() {
1745 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 1754 RTC_DCHECK_RUN_ON(&thread_checker_);
1746 if (source_ == nullptr) { 1755 if (source_ == nullptr) {
1747 return; 1756 return;
1748 } 1757 }
1749 1758
1750 // |source_->RemoveSink| may not be called while holding |lock_| since 1759 // |source_->RemoveSink| may not be called while holding |lock_| since
1751 // that might cause a lock order inversion. 1760 // that might cause a lock order inversion.
1752 source_->RemoveSink(this); 1761 source_->RemoveSink(this);
1753 source_ = nullptr; 1762 source_ = nullptr;
1754 // Reset |cpu_restricted_counter_| if the source is changed. It is not 1763 // Reset |cpu_restricted_counter_| if the source is changed. It is not
1755 // possible to know if the video resolution is restricted by CPU usage after 1764 // possible to know if the video resolution is restricted by CPU usage after
(...skipping 14 matching lines...) Expand all
1770 return webrtc::kVideoCodecVP9; 1779 return webrtc::kVideoCodecVP9;
1771 } else if (CodecNamesEq(name, kH264CodecName)) { 1780 } else if (CodecNamesEq(name, kH264CodecName)) {
1772 return webrtc::kVideoCodecH264; 1781 return webrtc::kVideoCodecH264;
1773 } 1782 }
1774 return webrtc::kVideoCodecUnknown; 1783 return webrtc::kVideoCodecUnknown;
1775 } 1784 }
1776 1785
1777 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder 1786 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder
1778 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( 1787 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder(
1779 const VideoCodec& codec) { 1788 const VideoCodec& codec) {
1789 RTC_DCHECK_RUN_ON(&thread_checker_);
1780 webrtc::VideoCodecType type = CodecTypeFromName(codec.name); 1790 webrtc::VideoCodecType type = CodecTypeFromName(codec.name);
1781 1791
1782 // Do not re-create encoders of the same type. 1792 // Do not re-create encoders of the same type.
1783 if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { 1793 if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) {
1784 return allocated_encoder_; 1794 return allocated_encoder_;
1785 } 1795 }
1786 1796
1787 if (external_encoder_factory_ != NULL) { 1797 if (external_encoder_factory_ != NULL) {
1788 webrtc::VideoEncoder* encoder = 1798 webrtc::VideoEncoder* encoder =
1789 external_encoder_factory_->CreateVideoEncoder(type); 1799 external_encoder_factory_->CreateVideoEncoder(type);
(...skipping 14 matching lines...) Expand all
1804 } 1814 }
1805 1815
1806 // This shouldn't happen, we should not be trying to create something we don't 1816 // This shouldn't happen, we should not be trying to create something we don't
1807 // support. 1817 // support.
1808 RTC_DCHECK(false); 1818 RTC_DCHECK(false);
1809 return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); 1819 return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false);
1810 } 1820 }
1811 1821
1812 void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( 1822 void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder(
1813 AllocatedEncoder* encoder) { 1823 AllocatedEncoder* encoder) {
1824 RTC_DCHECK_RUN_ON(&thread_checker_);
1814 if (encoder->external) { 1825 if (encoder->external) {
1815 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); 1826 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder);
1816 } 1827 }
1817 delete encoder->encoder; 1828 delete encoder->encoder;
1818 } 1829 }
1819 1830
1820 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec( 1831 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetCodec(
1821 const VideoCodecSettings& codec_settings) { 1832 const VideoCodecSettings& codec_settings) {
1833 RTC_DCHECK_RUN_ON(&thread_checker_);
1822 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); 1834 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec);
1823 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); 1835 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u);
1824 1836
1825 AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec); 1837 AllocatedEncoder new_encoder = CreateVideoEncoder(codec_settings.codec);
1826 parameters_.config.encoder_settings.encoder = new_encoder.encoder; 1838 parameters_.config.encoder_settings.encoder = new_encoder.encoder;
1827 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; 1839 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external;
1828 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; 1840 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name;
1829 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; 1841 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id;
1830 if (new_encoder.external) { 1842 if (new_encoder.external) {
1831 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name); 1843 webrtc::VideoCodecType type = CodecTypeFromName(codec_settings.codec.name);
1832 parameters_.config.encoder_settings.internal_source = 1844 parameters_.config.encoder_settings.internal_source =
1833 external_encoder_factory_->EncoderTypeHasInternalSource(type); 1845 external_encoder_factory_->EncoderTypeHasInternalSource(type);
(...skipping 20 matching lines...) Expand all
1854 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec."; 1866 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec.";
1855 RecreateWebRtcStream(); 1867 RecreateWebRtcStream();
1856 if (allocated_encoder_.encoder != new_encoder.encoder) { 1868 if (allocated_encoder_.encoder != new_encoder.encoder) {
1857 DestroyVideoEncoder(&allocated_encoder_); 1869 DestroyVideoEncoder(&allocated_encoder_);
1858 allocated_encoder_ = new_encoder; 1870 allocated_encoder_ = new_encoder;
1859 } 1871 }
1860 } 1872 }
1861 1873
1862 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters( 1874 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSendParameters(
1863 const ChangedSendParameters& params) { 1875 const ChangedSendParameters& params) {
1864 { 1876 RTC_DCHECK_RUN_ON(&thread_checker_);
1865 rtc::CritScope cs(&lock_); 1877 // |recreate_stream| means construction-time parameters have changed and the
1866 // |recreate_stream| means construction-time parameters have changed and the 1878 // sending stream needs to be reset with the new config.
1867 // sending stream needs to be reset with the new config. 1879 bool recreate_stream = false;
1868 bool recreate_stream = false; 1880 if (params.rtcp_mode) {
1869 if (params.rtcp_mode) { 1881 parameters_.config.rtp.rtcp_mode = *params.rtcp_mode;
1870 parameters_.config.rtp.rtcp_mode = *params.rtcp_mode; 1882 recreate_stream = true;
1871 recreate_stream = true; 1883 }
1872 } 1884 if (params.rtp_header_extensions) {
1873 if (params.rtp_header_extensions) { 1885 parameters_.config.rtp.extensions = *params.rtp_header_extensions;
1874 parameters_.config.rtp.extensions = *params.rtp_header_extensions; 1886 recreate_stream = true;
1875 recreate_stream = true; 1887 }
1876 } 1888 if (params.max_bandwidth_bps) {
1877 if (params.max_bandwidth_bps) { 1889 parameters_.max_bitrate_bps = *params.max_bandwidth_bps;
1878 parameters_.max_bitrate_bps = *params.max_bandwidth_bps; 1890 ReconfigureEncoder();
1879 pending_encoder_reconfiguration_ = true; 1891 }
1880 } 1892 if (params.conference_mode) {
1881 if (params.conference_mode) { 1893 parameters_.conference_mode = *params.conference_mode;
1882 parameters_.conference_mode = *params.conference_mode; 1894 }
1883 }
1884 1895
1885 // Set codecs and options. 1896 // Set codecs and options.
1886 if (params.codec) { 1897 if (params.codec) {
1887 SetCodec(*params.codec); 1898 SetCodec(*params.codec);
1888 recreate_stream = false; // SetCodec has already recreated the stream. 1899 recreate_stream = false; // SetCodec has already recreated the stream.
1889 } else if (params.conference_mode && parameters_.codec_settings) { 1900 } else if (params.conference_mode && parameters_.codec_settings) {
1890 SetCodec(*parameters_.codec_settings); 1901 SetCodec(*parameters_.codec_settings);
1891 recreate_stream = false; // SetCodec has already recreated the stream. 1902 recreate_stream = false; // SetCodec has already recreated the stream.
1892 } 1903 }
1893 if (recreate_stream) { 1904 if (recreate_stream) {
1894 LOG(LS_INFO) 1905 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetSendParameters";
1895 << "RecreateWebRtcStream (send) because of SetSendParameters"; 1906 RecreateWebRtcStream();
1896 RecreateWebRtcStream(); 1907 }
1897 }
1898 } // release |lock_|
1899 1908
1900 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since 1909 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
1901 // that might cause a lock order inversion. 1910 // that might cause a lock order inversion.
1902 if (params.rtp_header_extensions) { 1911 if (params.rtp_header_extensions) {
1903 sink_wants_.rotation_applied = !ContainsHeaderExtension( 1912 sink_wants_.rotation_applied = !ContainsHeaderExtension(
1904 *params.rtp_header_extensions, webrtc::RtpExtension::kVideoRotationUri); 1913 *params.rtp_header_extensions, webrtc::RtpExtension::kVideoRotationUri);
1905 if (source_) { 1914 if (source_) {
1906 source_->AddOrUpdateSink(this, sink_wants_); 1915 source_->AddOrUpdateSink(this, sink_wants_);
1907 } 1916 }
1908 } 1917 }
1909 } 1918 }
1910 1919
1911 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( 1920 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters(
1912 const webrtc::RtpParameters& new_parameters) { 1921 const webrtc::RtpParameters& new_parameters) {
1922 RTC_DCHECK_RUN_ON(&thread_checker_);
1913 if (!ValidateRtpParameters(new_parameters)) { 1923 if (!ValidateRtpParameters(new_parameters)) {
1914 return false; 1924 return false;
1915 } 1925 }
1916 1926
1917 rtc::CritScope cs(&lock_); 1927 bool reconfigure_encoder = new_parameters.encodings[0].max_bitrate_bps !=
1918 if (new_parameters.encodings[0].max_bitrate_bps != 1928 rtp_parameters_.encodings[0].max_bitrate_bps;
1919 rtp_parameters_.encodings[0].max_bitrate_bps) {
1920 pending_encoder_reconfiguration_ = true;
1921 }
1922 rtp_parameters_ = new_parameters; 1929 rtp_parameters_ = new_parameters;
1923 // Codecs are currently handled at the WebRtcVideoChannel2 level. 1930 // Codecs are currently handled at the WebRtcVideoChannel2 level.
1924 rtp_parameters_.codecs.clear(); 1931 rtp_parameters_.codecs.clear();
1932 if (reconfigure_encoder) {
1933 ReconfigureEncoder();
1934 }
1925 // Encoding may have been activated/deactivated. 1935 // Encoding may have been activated/deactivated.
1926 UpdateSendState(); 1936 UpdateSendState();
1927 return true; 1937 return true;
1928 } 1938 }
1929 1939
1930 webrtc::RtpParameters 1940 webrtc::RtpParameters
1931 WebRtcVideoChannel2::WebRtcVideoSendStream::GetRtpParameters() const { 1941 WebRtcVideoChannel2::WebRtcVideoSendStream::GetRtpParameters() const {
1932 rtc::CritScope cs(&lock_); 1942 RTC_DCHECK_RUN_ON(&thread_checker_);
1933 return rtp_parameters_; 1943 return rtp_parameters_;
1934 } 1944 }
1935 1945
1936 bool WebRtcVideoChannel2::WebRtcVideoSendStream::ValidateRtpParameters( 1946 bool WebRtcVideoChannel2::WebRtcVideoSendStream::ValidateRtpParameters(
1937 const webrtc::RtpParameters& rtp_parameters) { 1947 const webrtc::RtpParameters& rtp_parameters) {
1938 if (rtp_parameters.encodings.size() != 1) { 1948 if (rtp_parameters.encodings.size() != 1) {
1939 LOG(LS_ERROR) 1949 LOG(LS_ERROR)
1940 << "Attempted to set RtpParameters without exactly one encoding"; 1950 << "Attempted to set RtpParameters without exactly one encoding";
1941 return false; 1951 return false;
1942 } 1952 }
1943 return true; 1953 return true;
1944 } 1954 }
1945 1955
1946 void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateSendState() { 1956 void WebRtcVideoChannel2::WebRtcVideoSendStream::UpdateSendState() {
1957 RTC_DCHECK_RUN_ON(&thread_checker_);
1947 // TODO(deadbeef): Need to handle more than one encoding in the future. 1958 // TODO(deadbeef): Need to handle more than one encoding in the future.
1948 RTC_DCHECK(rtp_parameters_.encodings.size() == 1u); 1959 RTC_DCHECK(rtp_parameters_.encodings.size() == 1u);
1949 if (sending_ && rtp_parameters_.encodings[0].active) { 1960 if (sending_ && rtp_parameters_.encodings[0].active) {
1950 RTC_DCHECK(stream_ != nullptr); 1961 RTC_DCHECK(stream_ != nullptr);
1951 stream_->Start(); 1962 stream_->Start();
1952 } else { 1963 } else {
1953 if (stream_ != nullptr) { 1964 if (stream_ != nullptr) {
1954 stream_->Stop(); 1965 stream_->Stop();
1955 } 1966 }
1956 } 1967 }
1957 } 1968 }
1958 1969
1959 webrtc::VideoEncoderConfig 1970 webrtc::VideoEncoderConfig
1960 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig( 1971 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoderConfig(
1961 const VideoCodec& codec) const { 1972 const VideoCodec& codec) const {
1973 RTC_DCHECK_RUN_ON(&thread_checker_);
1962 webrtc::VideoEncoderConfig encoder_config; 1974 webrtc::VideoEncoderConfig encoder_config;
1963 bool is_screencast = parameters_.options.is_screencast.value_or(false); 1975 bool is_screencast = parameters_.options.is_screencast.value_or(false);
1964 if (is_screencast) { 1976 if (is_screencast) {
1965 encoder_config.min_transmit_bitrate_bps = 1977 encoder_config.min_transmit_bitrate_bps =
1966 1000 * parameters_.options.screencast_min_bitrate_kbps.value_or(0); 1978 1000 * parameters_.options.screencast_min_bitrate_kbps.value_or(0);
1967 encoder_config.content_type = 1979 encoder_config.content_type =
1968 webrtc::VideoEncoderConfig::ContentType::kScreen; 1980 webrtc::VideoEncoderConfig::ContentType::kScreen;
1969 } else { 1981 } else {
1970 encoder_config.min_transmit_bitrate_bps = 0; 1982 encoder_config.min_transmit_bitrate_bps = 0;
1971 encoder_config.content_type = 1983 encoder_config.content_type =
1972 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo; 1984 webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo;
1973 } 1985 }
1974 1986
1975 // Restrict dimensions according to codec max.
1976 int width = last_frame_info_.width;
1977 int height = last_frame_info_.height;
1978 if (!is_screencast) {
1979 if (codec.width < width)
1980 width = codec.width;
1981 if (codec.height < height)
1982 height = codec.height;
1983 }
1984
1985 VideoCodec clamped_codec = codec;
1986 clamped_codec.width = width;
1987 clamped_codec.height = height;
1988
1989 // By default, the stream count for the codec configuration should match the 1987 // By default, the stream count for the codec configuration should match the
1990 // number of negotiated ssrcs. But if the codec is blacklisted for simulcast 1988 // number of negotiated ssrcs. But if the codec is blacklisted for simulcast
1991 // or a screencast, only configure a single stream. 1989 // or a screencast, only configure a single stream.
1992 size_t stream_count = parameters_.config.rtp.ssrcs.size(); 1990 encoder_config.number_of_streams = parameters_.config.rtp.ssrcs.size();
1993 if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) { 1991 if (IsCodecBlacklistedForSimulcast(codec.name) || is_screencast) {
1994 stream_count = 1; 1992 encoder_config.number_of_streams = 1;
1995 } 1993 }
1996 1994
1997 int stream_max_bitrate = 1995 int stream_max_bitrate =
1998 MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps, 1996 MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps,
1999 parameters_.max_bitrate_bps); 1997 parameters_.max_bitrate_bps);
2000 encoder_config.streams = CreateVideoStreams(
2001 clamped_codec, parameters_.options, stream_max_bitrate, stream_count);
2002 encoder_config.expect_encode_from_texture = last_frame_info_.is_texture;
2003 1998
2004 // Conference mode screencast uses 2 temporal layers split at 100kbit. 1999 int codec_max_bitrate_kbps;
2005 if (parameters_.conference_mode && is_screencast && 2000 if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) {
2006 encoder_config.streams.size() == 1) { 2001 stream_max_bitrate = codec_max_bitrate_kbps * 1000;
2007 ScreenshareLayerConfig config = ScreenshareLayerConfig::GetDefault(); 2002 }
2003 encoder_config.max_bitrate_bps = stream_max_bitrate;
2008 2004
2009 // For screenshare in conference mode, tl0 and tl1 bitrates are piggybacked 2005 int max_qp = kDefaultQpMax;
2010 // on the VideoCodec struct as target and max bitrates, respectively. 2006 codec.GetParam(kCodecParamMaxQuantization, &max_qp);
2011 // See eg. webrtc::VP8EncoderImpl::SetRates(). 2007 int max_framerate =
2012 encoder_config.streams[0].target_bitrate_bps = 2008 codec.framerate != 0 ? codec.framerate : kDefaultVideoMaxFramerate;
2013 config.tl0_bitrate_kbps * 1000; 2009
2014 encoder_config.streams[0].max_bitrate_bps = config.tl1_bitrate_kbps * 1000; 2010 encoder_config.encoder_stream_factory =
2015 encoder_config.streams[0].temporal_layer_thresholds_bps.clear(); 2011 new rtc::RefCountedObject<EncoderStreamFactory>(
2016 encoder_config.streams[0].temporal_layer_thresholds_bps.push_back( 2012 codec.name, max_qp, max_framerate, is_screencast,
2017 config.tl0_bitrate_kbps * 1000); 2013 parameters_.conference_mode);
2018 }
2019 if (CodecNamesEq(codec.name, kVp9CodecName) && !is_screencast &&
2020 encoder_config.streams.size() == 1) {
2021 encoder_config.streams[0].temporal_layer_thresholds_bps.resize(
2022 GetDefaultVp9TemporalLayers() - 1);
2023 }
2024 return encoder_config; 2014 return encoder_config;
2025 } 2015 }
2026 2016
2027 void WebRtcVideoChannel2::WebRtcVideoSendStream::ReconfigureEncoder() { 2017 void WebRtcVideoChannel2::WebRtcVideoSendStream::ReconfigureEncoder() {
2028 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); 2018 RTC_DCHECK_RUN_ON(&thread_checker_);
2019 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0u);
2029 2020
2030 RTC_CHECK(parameters_.codec_settings); 2021 RTC_CHECK(parameters_.codec_settings);
2031 VideoCodecSettings codec_settings = *parameters_.codec_settings; 2022 VideoCodecSettings codec_settings = *parameters_.codec_settings;
2032 2023
2033 webrtc::VideoEncoderConfig encoder_config = 2024 webrtc::VideoEncoderConfig encoder_config =
2034 CreateVideoEncoderConfig(codec_settings.codec); 2025 CreateVideoEncoderConfig(codec_settings.codec);
2035 2026
2036 encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings( 2027 encoder_config.encoder_specific_settings = ConfigureVideoEncoderSettings(
2037 codec_settings.codec); 2028 codec_settings.codec);
2038 2029
2039 stream_->ReconfigureVideoEncoder(encoder_config.Copy()); 2030 stream_->ReconfigureVideoEncoder(encoder_config.Copy());
2040 2031
2041 encoder_config.encoder_specific_settings = NULL; 2032 encoder_config.encoder_specific_settings = NULL;
2042 2033
2043 parameters_.encoder_config = std::move(encoder_config); 2034 parameters_.encoder_config = std::move(encoder_config);
2044 } 2035 }
2045 2036
2046 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { 2037 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) {
2047 rtc::CritScope cs(&lock_); 2038 RTC_DCHECK_RUN_ON(&thread_checker_);
2048 sending_ = send; 2039 sending_ = send;
2049 UpdateSendState(); 2040 UpdateSendState();
2050 } 2041 }
2051 2042
2052 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( 2043 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink(
2053 VideoSinkInterface<webrtc::VideoFrame>* sink, 2044 VideoSinkInterface<webrtc::VideoFrame>* sink,
2054 const rtc::VideoSinkWants& wants) { 2045 const rtc::VideoSinkWants& wants) {
2055 // TODO(perkj): Actually consider the encoder |wants| and remove 2046 // TODO(perkj): Actually consider the encoder |wants| and remove
2056 // WebRtcVideoSendStream::OnLoadUpdate(Load load). 2047 // WebRtcVideoSendStream::OnLoadUpdate(Load load).
2057 rtc::CritScope cs(&lock_); 2048 rtc::CritScope cs(&lock_);
2058 RTC_DCHECK(!encoder_sink_ || encoder_sink_ == sink); 2049 RTC_DCHECK(!encoder_sink_ || encoder_sink_ == sink);
2059 encoder_sink_ = sink; 2050 encoder_sink_ = sink;
2060 } 2051 }
2061 2052
2062 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( 2053 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink(
2063 VideoSinkInterface<webrtc::VideoFrame>* sink) { 2054 VideoSinkInterface<webrtc::VideoFrame>* sink) {
2064 rtc::CritScope cs(&lock_); 2055 rtc::CritScope cs(&lock_);
2065 RTC_DCHECK_EQ(encoder_sink_, sink); 2056 RTC_DCHECK_EQ(encoder_sink_, sink);
2066 encoder_sink_ = nullptr; 2057 encoder_sink_ = nullptr;
2067 } 2058 }
2068 2059
2069 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { 2060 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) {
2070 if (worker_thread_ != rtc::Thread::Current()) { 2061 if (worker_thread_ != rtc::Thread::Current()) {
2071 invoker_.AsyncInvoke<void>( 2062 invoker_.AsyncInvoke<void>(
2072 RTC_FROM_HERE, worker_thread_, 2063 RTC_FROM_HERE, worker_thread_,
2073 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate, 2064 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate,
2074 this, load)); 2065 this, load));
2075 return; 2066 return;
2076 } 2067 }
2077 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2068 RTC_DCHECK_RUN_ON(&thread_checker_);
2078 if (!source_) { 2069 if (!source_) {
2079 return; 2070 return;
2080 } 2071 }
2081 { 2072
2073 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: "
2074 << (parameters_.options.is_screencast
2075 ? (*parameters_.options.is_screencast ? "true" : "false")
2076 : "unset");
2077 // Do not adapt resolution for screen content as this will likely result in
2078 // blurry and unreadable text.
2079 if (parameters_.options.is_screencast.value_or(false))
2080 return;
2081
2082 rtc::Optional<int> max_pixel_count;
2083 rtc::Optional<int> max_pixel_count_step_up;
2084 if (load == kOveruse) {
2082 rtc::CritScope cs(&lock_); 2085 rtc::CritScope cs(&lock_);
2083 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " 2086 if (cpu_restricted_counter_ >= kMaxCpuDowngrades) {
2084 << (parameters_.options.is_screencast
2085 ? (*parameters_.options.is_screencast ? "true"
2086 : "false")
2087 : "unset");
2088 // Do not adapt resolution for screen content as this will likely result in
2089 // blurry and unreadable text.
2090 if (parameters_.options.is_screencast.value_or(false))
2091 return; 2087 return;
2092
2093 rtc::Optional<int> max_pixel_count;
2094 rtc::Optional<int> max_pixel_count_step_up;
2095 if (load == kOveruse) {
2096 if (cpu_restricted_counter_ >= kMaxCpuDowngrades) {
2097 return;
2098 }
2099 // The input video frame size will have a resolution with less than or
2100 // equal to |max_pixel_count| depending on how the source can scale the
2101 // input frame size.
2102 max_pixel_count = rtc::Optional<int>(
2103 (last_frame_info_.height * last_frame_info_.width * 3) / 5);
2104 // Increase |number_of_cpu_adapt_changes_| if
2105 // sink_wants_.max_pixel_count will be changed since
2106 // last time |source_->AddOrUpdateSink| was called. That is, this will
2107 // result in a new request for the source to change resolution.
2108 if (!sink_wants_.max_pixel_count ||
2109 *sink_wants_.max_pixel_count > *max_pixel_count) {
2110 ++number_of_cpu_adapt_changes_;
2111 ++cpu_restricted_counter_;
2112 }
2113 } else {
2114 RTC_DCHECK(load == kUnderuse);
2115 // The input video frame size will have a resolution with "one step up"
2116 // pixels than |max_pixel_count_step_up| where "one step up" depends on
2117 // how the source can scale the input frame size.
2118 max_pixel_count_step_up =
2119 rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width);
2120 // Increase |number_of_cpu_adapt_changes_| if
2121 // sink_wants_.max_pixel_count_step_up will be changed since
2122 // last time |source_->AddOrUpdateSink| was called. That is, this will
2123 // result in a new request for the source to change resolution.
2124 if (sink_wants_.max_pixel_count ||
2125 (sink_wants_.max_pixel_count_step_up &&
2126 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) {
2127 ++number_of_cpu_adapt_changes_;
2128 --cpu_restricted_counter_;
2129 }
2130 } 2088 }
2131 sink_wants_.max_pixel_count = max_pixel_count; 2089 // The input video frame size will have a resolution with less than or
2132 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up; 2090 // equal to |max_pixel_count| depending on how the source can scale the
2091 // input frame size.
2092 max_pixel_count = rtc::Optional<int>(
2093 (last_frame_info_.height * last_frame_info_.width * 3) / 5);
2094 // Increase |number_of_cpu_adapt_changes_| if
2095 // sink_wants_.max_pixel_count will be changed since
2096 // last time |source_->AddOrUpdateSink| was called. That is, this will
2097 // result in a new request for the source to change resolution.
2098 if (!sink_wants_.max_pixel_count ||
2099 *sink_wants_.max_pixel_count > *max_pixel_count) {
2100 ++number_of_cpu_adapt_changes_;
2101 ++cpu_restricted_counter_;
2102 }
2103 } else {
2104 RTC_DCHECK(load == kUnderuse);
2105 rtc::CritScope cs(&lock_);
2106 // The input video frame size will have a resolution with "one step up"
2107 // pixels than |max_pixel_count_step_up| where "one step up" depends on
2108 // how the source can scale the input frame size.
2109 max_pixel_count_step_up =
2110 rtc::Optional<int>(last_frame_info_.height * last_frame_info_.width);
2111 // Increase |number_of_cpu_adapt_changes_| if
2112 // sink_wants_.max_pixel_count_step_up will be changed since
2113 // last time |source_->AddOrUpdateSink| was called. That is, this will
2114 // result in a new request for the source to change resolution.
2115 if (sink_wants_.max_pixel_count ||
2116 (sink_wants_.max_pixel_count_step_up &&
2117 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) {
2118 ++number_of_cpu_adapt_changes_;
2119 --cpu_restricted_counter_;
2120 }
2133 } 2121 }
2122 sink_wants_.max_pixel_count = max_pixel_count;
2123 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up;
2134 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since 2124 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since
2135 // that might cause a lock order inversion. 2125 // that might cause a lock order inversion.
2136 source_->AddOrUpdateSink(this, sink_wants_); 2126 source_->AddOrUpdateSink(this, sink_wants_);
2137 } 2127 }
2138 2128
2139 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( 2129 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo(
2140 bool log_stats) { 2130 bool log_stats) {
2141 VideoSenderInfo info; 2131 VideoSenderInfo info;
2142 webrtc::VideoSendStream::Stats stats; 2132 webrtc::VideoSendStream::Stats stats;
2143 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2133 RTC_DCHECK_RUN_ON(&thread_checker_);
2144 { 2134 for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
2145 rtc::CritScope cs(&lock_); 2135 info.add_ssrc(ssrc);
2146 for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
2147 info.add_ssrc(ssrc);
2148 2136
2149 if (parameters_.codec_settings) 2137 if (parameters_.codec_settings)
2150 info.codec_name = parameters_.codec_settings->codec.name; 2138 info.codec_name = parameters_.codec_settings->codec.name;
2151 for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) {
2152 if (i == parameters_.encoder_config.streams.size() - 1) {
2153 info.preferred_bitrate +=
2154 parameters_.encoder_config.streams[i].max_bitrate_bps;
2155 } else {
2156 info.preferred_bitrate +=
2157 parameters_.encoder_config.streams[i].target_bitrate_bps;
2158 }
2159 }
2160 2139
2161 if (stream_ == NULL) 2140 if (stream_ == NULL)
2162 return info; 2141 return info;
2163 2142
2164 stats = stream_->GetStats(); 2143 stats = stream_->GetStats();
2165 }
2166 2144
2167 if (log_stats) 2145 if (log_stats)
2168 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis()); 2146 LOG(LS_INFO) << stats.ToString(rtc::TimeMillis());
2169 2147
2170 info.adapt_changes = number_of_cpu_adapt_changes_; 2148 info.adapt_changes = number_of_cpu_adapt_changes_;
2171 info.adapt_reason = 2149 info.adapt_reason =
2172 cpu_restricted_counter_ <= 0 ? ADAPTREASON_NONE : ADAPTREASON_CPU; 2150 cpu_restricted_counter_ <= 0 ? ADAPTREASON_NONE : ADAPTREASON_CPU;
2173 2151
2174 // Get bandwidth limitation info from stream_->GetStats(). 2152 // Get bandwidth limitation info from stream_->GetStats().
2175 // Input resolution (output from video_adapter) can be further scaled down or 2153 // Input resolution (output from video_adapter) can be further scaled down or
2176 // higher video layer(s) can be dropped due to bitrate constraints. 2154 // higher video layer(s) can be dropped due to bitrate constraints.
2177 // Note, adapt_changes only include changes from the video_adapter. 2155 // Note, adapt_changes only include changes from the video_adapter.
2178 if (stats.bw_limited_resolution) 2156 if (stats.bw_limited_resolution)
2179 info.adapt_reason |= ADAPTREASON_BANDWIDTH; 2157 info.adapt_reason |= ADAPTREASON_BANDWIDTH;
2180 2158
2181 info.encoder_implementation_name = stats.encoder_implementation_name; 2159 info.encoder_implementation_name = stats.encoder_implementation_name;
2182 info.ssrc_groups = ssrc_groups_; 2160 info.ssrc_groups = ssrc_groups_;
2183 info.framerate_input = stats.input_frame_rate; 2161 info.framerate_input = stats.input_frame_rate;
2184 info.framerate_sent = stats.encode_frame_rate; 2162 info.framerate_sent = stats.encode_frame_rate;
2185 info.avg_encode_ms = stats.avg_encode_time_ms; 2163 info.avg_encode_ms = stats.avg_encode_time_ms;
2186 info.encode_usage_percent = stats.encode_usage_percent; 2164 info.encode_usage_percent = stats.encode_usage_percent;
2187 2165
2188 info.nominal_bitrate = stats.media_bitrate_bps; 2166 info.nominal_bitrate = stats.media_bitrate_bps;
2167 info.preferred_bitrate = stats.preffered_media_bitrate_bps;
2189 2168
2190 info.send_frame_width = 0; 2169 info.send_frame_width = 0;
2191 info.send_frame_height = 0; 2170 info.send_frame_height = 0;
2192 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2171 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it =
2193 stats.substreams.begin(); 2172 stats.substreams.begin();
2194 it != stats.substreams.end(); ++it) { 2173 it != stats.substreams.end(); ++it) {
2195 // TODO(pbos): Wire up additional stats, such as padding bytes. 2174 // TODO(pbos): Wire up additional stats, such as padding bytes.
2196 webrtc::VideoSendStream::StreamStats stream_stats = it->second; 2175 webrtc::VideoSendStream::StreamStats stream_stats = it->second;
2197 info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes + 2176 info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes +
2198 stream_stats.rtp_stats.transmitted.header_bytes + 2177 stream_stats.rtp_stats.transmitted.header_bytes +
(...skipping 16 matching lines...) Expand all
2215 info.fraction_lost = 2194 info.fraction_lost =
2216 static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) / 2195 static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) /
2217 (1 << 8); 2196 (1 << 8);
2218 } 2197 }
2219 2198
2220 return info; 2199 return info;
2221 } 2200 }
2222 2201
2223 void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo( 2202 void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo(
2224 BandwidthEstimationInfo* bwe_info) { 2203 BandwidthEstimationInfo* bwe_info) {
2225 rtc::CritScope cs(&lock_); 2204 RTC_DCHECK_RUN_ON(&thread_checker_);
2226 if (stream_ == NULL) { 2205 if (stream_ == NULL) {
2227 return; 2206 return;
2228 } 2207 }
2229 webrtc::VideoSendStream::Stats stats = stream_->GetStats(); 2208 webrtc::VideoSendStream::Stats stats = stream_->GetStats();
2230 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it = 2209 for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it =
2231 stats.substreams.begin(); 2210 stats.substreams.begin();
2232 it != stats.substreams.end(); ++it) { 2211 it != stats.substreams.end(); ++it) {
2233 bwe_info->transmit_bitrate += it->second.total_bitrate_bps; 2212 bwe_info->transmit_bitrate += it->second.total_bitrate_bps;
2234 bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps; 2213 bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps;
2235 } 2214 }
2236 bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps; 2215 bwe_info->target_enc_bitrate += stats.target_media_bitrate_bps;
2237 bwe_info->actual_enc_bitrate += stats.media_bitrate_bps; 2216 bwe_info->actual_enc_bitrate += stats.media_bitrate_bps;
2238 } 2217 }
2239 2218
2240 void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { 2219 void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() {
2220 RTC_DCHECK_RUN_ON(&thread_checker_);
2241 if (stream_ != NULL) { 2221 if (stream_ != NULL) {
2242 call_->DestroyVideoSendStream(stream_); 2222 call_->DestroyVideoSendStream(stream_);
2243 } 2223 }
2244 2224
2245 RTC_CHECK(parameters_.codec_settings); 2225 RTC_CHECK(parameters_.codec_settings);
2246 RTC_DCHECK_EQ((parameters_.encoder_config.content_type == 2226 RTC_DCHECK_EQ((parameters_.encoder_config.content_type ==
2247 webrtc::VideoEncoderConfig::ContentType::kScreen), 2227 webrtc::VideoEncoderConfig::ContentType::kScreen),
2248 parameters_.options.is_screencast.value_or(false)) 2228 parameters_.options.is_screencast.value_or(false))
2249 << "encoder content type inconsistent with screencast option"; 2229 << "encoder content type inconsistent with screencast option";
2250 parameters_.encoder_config.encoder_specific_settings = 2230 parameters_.encoder_config.encoder_specific_settings =
2251 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec); 2231 ConfigureVideoEncoderSettings(parameters_.codec_settings->codec);
2252 2232
2253 webrtc::VideoSendStream::Config config = parameters_.config.Copy(); 2233 webrtc::VideoSendStream::Config config = parameters_.config.Copy();
2254 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) { 2234 if (!config.rtp.rtx.ssrcs.empty() && config.rtp.rtx.payload_type == -1) {
2255 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " 2235 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX "
2256 "payload type the set codec. Ignoring RTX."; 2236 "payload type the set codec. Ignoring RTX.";
2257 config.rtp.rtx.ssrcs.clear(); 2237 config.rtp.rtx.ssrcs.clear();
2258 } 2238 }
2259 stream_ = call_->CreateVideoSendStream(std::move(config), 2239 stream_ = call_->CreateVideoSendStream(std::move(config),
2260 parameters_.encoder_config.Copy()); 2240 parameters_.encoder_config.Copy());
2261 stream_->SetSource(this); 2241 stream_->SetSource(this);
2262 2242
2263 parameters_.encoder_config.encoder_specific_settings = NULL; 2243 parameters_.encoder_config.encoder_specific_settings = NULL;
2264 pending_encoder_reconfiguration_ = false;
2265 2244
2266 // Call stream_->Start() if necessary conditions are met. 2245 // Call stream_->Start() if necessary conditions are met.
2267 UpdateSendState(); 2246 UpdateSendState();
2268 } 2247 }
2269 2248
2270 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( 2249 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
2271 webrtc::Call* call, 2250 webrtc::Call* call,
2272 const StreamParams& sp, 2251 const StreamParams& sp,
2273 webrtc::VideoReceiveStream::Config config, 2252 webrtc::VideoReceiveStream::Config config,
2274 WebRtcVideoDecoderFactory* external_decoder_factory, 2253 WebRtcVideoDecoderFactory* external_decoder_factory,
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
2710 rtx_mapping[video_codecs[i].codec.id] != 2689 rtx_mapping[video_codecs[i].codec.id] !=
2711 fec_settings.red_payload_type) { 2690 fec_settings.red_payload_type) {
2712 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; 2691 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id];
2713 } 2692 }
2714 } 2693 }
2715 2694
2716 return video_codecs; 2695 return video_codecs;
2717 } 2696 }
2718 2697
2719 } // namespace cricket 2698 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698