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

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

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

Powered by Google App Engine
This is Rietveld 408576698