webrtc_m130/video/video_stream_encoder.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

2244 lines
90 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/video_stream_encoder.h"
#include <algorithm>
#include <array>
#include <limits>
Use std::make_unique instead of absl::make_unique. WebRTC is now using C++14 so there is no need to use the Abseil version of std::make_unique. This CL has been created with the following steps: git grep -l absl::make_unique | sort | uniq > /tmp/make_unique.txt git grep -l absl::WrapUnique | sort | uniq > /tmp/wrap_unique.txt git grep -l "#include <memory>" | sort | uniq > /tmp/memory.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/make_unique.txt /tmp/wrap_unique.txt | sort | \ uniq > /tmp/only_make_unique.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/only_make_unique.txt /tmp/memory.txt | \ xargs grep -l "absl/memory" > /tmp/add-memory.txt git grep -l "\babsl::make_unique\b" | \ xargs sed -i "s/\babsl::make_unique\b/std::make_unique/g" git checkout PRESUBMIT.py abseil-in-webrtc.md cat /tmp/add-memory.txt | \ xargs sed -i \ 's/#include "absl\/memory\/memory.h"/#include <memory>/g' git cl format # Manual fix order of the new inserted #include <memory> cat /tmp/only_make_unique | xargs grep -l "#include <memory>" | \ xargs sed -i '/#include "absl\/memory\/memory.h"/d' git ls-files | grep BUILD.gn | \ xargs sed -i '/\/\/third_party\/abseil-cpp\/absl\/memory/d' python tools_webrtc/gn_check_autofix.py \ -m tryserver.webrtc -b linux_rel # Repead the gn_check_autofix step for other platforms git ls-files | grep BUILD.gn | \ xargs sed -i 's/absl\/memory:memory/absl\/memory/g' git cl format Bug: webrtc:10945 Change-Id: I3fe28ea80f4dd3ba3cf28effd151d5e1f19aff89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153221 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29209}
2019-09-17 17:06:18 +02:00
#include <memory>
Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2783183003/ ) Reason for revert: Seem to be a flaky test rather than an issue with this cl. Creating reland, will add code to reduce flakiness to that test. Original issue's description: > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #8 id:410001 of https://codereview.webrtc.org/2781433002/ ) > > Reason for revert: > This has resulted in failure of CallPerfTest.ReceivesCpuOveruseAndUnderuse test on the Win7 build bot https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1780 > > Original issue's description: > > Reland of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #1 id:1 of https://codereview.webrtc.org/2764133002/ ) > > > > Reason for revert: > > Found issue with test case, will add fix to reland cl. > > > > Original issue's description: > > > Revert of Add framerate to VideoSinkWants and ability to signal on overuse (patchset #14 id:250001 of https://codereview.webrtc.org/2716643002/ ) > > > > > > Reason for revert: > > > Breaks perf tests: > > > https://build.chromium.org/p/client.webrtc.perf/builders/Win7/builds/1679 > > > https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20%28L%20Nexus5%29/builds/2325 > > > > > > Original issue's description: > > > > Add framerate to VideoSinkWants and ability to signal on overuse > > > > > > > > In ViEEncoder, try to reduce framerate instead of resolution if the > > > > current degradation preference is maintain-resolution rather than > > > > balanced. > > > > > > > > BUG=webrtc:4172 > > > > > > > > Review-Url: https://codereview.webrtc.org/2716643002 > > > > Cr-Commit-Position: refs/heads/master@{#17327} > > > > Committed: https://chromium.googlesource.com/external/webrtc/+/72acf2526177bb4dbb5103cd6e165eb4361a5ae6 > > > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,sprang@webrtc.org > > > # Skipping CQ checks because original CL landed less than 1 days ago. > > > NOPRESUBMIT=true > > > NOTREECHECKS=true > > > NOTRY=true > > > BUG=webrtc:4172 > > > > > > Review-Url: https://codereview.webrtc.org/2764133002 > > > Cr-Commit-Position: refs/heads/master@{#17331} > > > Committed: https://chromium.googlesource.com/external/webrtc/+/8b45b11144c968b4173215c76f78c710c9a2ed0b > > > > TBR=nisse@webrtc.org,magjed@webrtc.org,kthelgason@webrtc.org,ilnik@webrtc.org,stefan@webrtc.org,skvlad@webrtc.org > > # Not skipping CQ checks because original CL landed more than 1 days ago. > > BUG=webrtc:4172 > > > > Review-Url: https://codereview.webrtc.org/2781433002 > > Cr-Commit-Position: refs/heads/master@{#17474} > > Committed: https://chromium.googlesource.com/external/webrtc/+/3ea3c77e93121b1ab9d5e46641e6764f2cca0d51 > > TBR=ilnik@webrtc.org,stefan@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:4172 > > Review-Url: https://codereview.webrtc.org/2783183003 > Cr-Commit-Position: refs/heads/master@{#17477} > Committed: https://chromium.googlesource.com/external/webrtc/+/f9ed235c9b7248694edcb46feb1f29ce7456ab59 R=ilnik@webrtc.org,stefan@webrtc.org BUG=webrtc:4172 Review-Url: https://codereview.webrtc.org/2789823002 Cr-Commit-Position: refs/heads/master@{#17498}
2017-04-02 23:53:04 -07:00
#include <numeric>
#include <utility>
#include "absl/algorithm/container.h"
#include "absl/types/optional.h"
#include "api/task_queue/queued_task.h"
#include "api/task_queue/task_queue_base.h"
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_adaptation_reason.h"
#include "api/video/video_bitrate_allocator_factory.h"
#include "api/video/video_codec_constants.h"
#include "api/video/video_layers_allocation.h"
#include "api/video_codecs/video_encoder.h"
#include "call/adaptation/resource_adaptation_processor.h"
#include "call/adaptation/video_stream_adapter.h"
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
#include "modules/video_coding/include/video_codec_initializer.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/event.h"
#include "rtc_base/experiments/alr_experiment.h"
#include "rtc_base/experiments/rate_control_settings.h"
#include "rtc_base/location.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/synchronization/sequence_checker.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/trace_event.h"
#include "system_wrappers/include/field_trial.h"
#include "video/adaptation/video_stream_encoder_resource_manager.h"
#include "video/alignment_adjuster.h"
namespace webrtc {
namespace {
// Time interval for logging frame counts.
const int64_t kFrameLogIntervalMs = 60000;
// Time to keep a single cached pending frame in paused state.
const int64_t kPendingFrameTimeoutMs = 1000;
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
constexpr char kFrameDropperFieldTrial[] = "WebRTC-FrameDropper";
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
// Averaging window spanning 90 frames at default 30fps, matching old media
// optimization module defaults.
const int64_t kFrameRateAvergingWindowSizeMs = (1000 / 30) * 90;
const size_t kDefaultPayloadSize = 1440;
const int64_t kParameterUpdateIntervalMs = 1000;
// Animation is capped to 720p.
constexpr int kMaxAnimationPixels = 1280 * 720;
bool RequiresEncoderReset(const VideoCodec& prev_send_codec,
const VideoCodec& new_send_codec,
bool was_encode_called_since_last_initialization) {
// Does not check max/minBitrate or maxFramerate.
if (new_send_codec.codecType != prev_send_codec.codecType ||
new_send_codec.width != prev_send_codec.width ||
new_send_codec.height != prev_send_codec.height ||
new_send_codec.qpMax != prev_send_codec.qpMax ||
new_send_codec.numberOfSimulcastStreams !=
prev_send_codec.numberOfSimulcastStreams ||
new_send_codec.mode != prev_send_codec.mode) {
return true;
}
if (!was_encode_called_since_last_initialization &&
(new_send_codec.startBitrate != prev_send_codec.startBitrate)) {
// If start bitrate has changed reconfigure encoder only if encoding had not
// yet started.
return true;
}
switch (new_send_codec.codecType) {
case kVideoCodecVP8:
if (new_send_codec.VP8() != prev_send_codec.VP8()) {
return true;
}
break;
case kVideoCodecVP9:
if (new_send_codec.VP9() != prev_send_codec.VP9()) {
return true;
}
break;
case kVideoCodecH264:
if (new_send_codec.H264() != prev_send_codec.H264()) {
return true;
}
break;
default:
break;
}
for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) {
if (!new_send_codec.simulcastStream[i].active) {
// No need to reset when stream is inactive.
continue;
}
if (!prev_send_codec.simulcastStream[i].active ||
new_send_codec.simulcastStream[i].width !=
prev_send_codec.simulcastStream[i].width ||
new_send_codec.simulcastStream[i].height !=
prev_send_codec.simulcastStream[i].height ||
new_send_codec.simulcastStream[i].numberOfTemporalLayers !=
prev_send_codec.simulcastStream[i].numberOfTemporalLayers ||
new_send_codec.simulcastStream[i].qpMax !=
prev_send_codec.simulcastStream[i].qpMax) {
return true;
}
}
if (new_send_codec.codecType == kVideoCodecVP9) {
size_t num_spatial_layers = new_send_codec.VP9().numberOfSpatialLayers;
for (unsigned char i = 0; i < num_spatial_layers; ++i) {
if (new_send_codec.spatialLayers[i].width !=
prev_send_codec.spatialLayers[i].width ||
new_send_codec.spatialLayers[i].height !=
prev_send_codec.spatialLayers[i].height ||
new_send_codec.spatialLayers[i].numberOfTemporalLayers !=
prev_send_codec.spatialLayers[i].numberOfTemporalLayers ||
new_send_codec.spatialLayers[i].qpMax !=
prev_send_codec.spatialLayers[i].qpMax) {
return true;
}
}
}
if (new_send_codec.ScalabilityMode() != prev_send_codec.ScalabilityMode()) {
return true;
}
return false;
}
std::array<uint8_t, 2> GetExperimentGroups() {
std::array<uint8_t, 2> experiment_groups;
absl::optional<AlrExperimentSettings> experiment_settings =
AlrExperimentSettings::CreateFromFieldTrial(
AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
if (experiment_settings) {
experiment_groups[0] = experiment_settings->group_id + 1;
} else {
experiment_groups[0] = 0;
}
experiment_settings = AlrExperimentSettings::CreateFromFieldTrial(
AlrExperimentSettings::kScreenshareProbingBweExperimentName);
if (experiment_settings) {
experiment_groups[1] = experiment_settings->group_id + 1;
} else {
experiment_groups[1] = 0;
}
return experiment_groups;
}
// Limit allocation across TLs in bitrate allocation according to number of TLs
// in EncoderInfo.
VideoBitrateAllocation UpdateAllocationFromEncoderInfo(
const VideoBitrateAllocation& allocation,
const VideoEncoder::EncoderInfo& encoder_info) {
if (allocation.get_sum_bps() == 0) {
return allocation;
}
VideoBitrateAllocation new_allocation;
for (int si = 0; si < kMaxSpatialLayers; ++si) {
if (encoder_info.fps_allocation[si].size() == 1 &&
allocation.IsSpatialLayerUsed(si)) {
// One TL is signalled to be used by the encoder. Do not distribute
// bitrate allocation across TLs (use sum at ti:0).
new_allocation.SetBitrate(si, 0, allocation.GetSpatialLayerSum(si));
} else {
for (int ti = 0; ti < kMaxTemporalStreams; ++ti) {
if (allocation.HasBitrate(si, ti))
new_allocation.SetBitrate(si, ti, allocation.GetBitrate(si, ti));
}
}
}
new_allocation.set_bw_limited(allocation.is_bw_limited());
return new_allocation;
}
Reland "Wire up internal libvpx VP9 scaler to statistics proxy" This reverts commit a2cb93d8b9659292f7ec73db53421d481f84c22c. Reason for revert: Reland with no changes after downstream projects are updated. Original change's description: > Revert "Wire up internal libvpx VP9 scaler to statistics proxy" > > This reverts commit 50327a51007c3e25bc3bcd35b5d0945fe0f27d05. > > Reason for revert: Breaks downstream tests > > Original change's description: > > Wire up internal libvpx VP9 scaler to statistics proxy > > > > Bug: webrtc:11396 > > Change-Id: I5ac69208b00cc75d4e5dbb3ab86f234b3e1f29f8 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169922 > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Reviewed-by: Henrik Boström <hbos@webrtc.org> > > Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#30725} > > TBR=ilnik@webrtc.org,hbos@webrtc.org,nisse@webrtc.org > > Change-Id: I53dcb41bdf8f8dccfcd43b717509ec047f590648 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:11396 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170102 > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Commit-Queue: Sebastian Jansson <srte@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30734} TBR=ilnik@webrtc.org,hbos@webrtc.org,nisse@webrtc.org,srte@webrtc.org Change-Id: Ie47df4aec199701256c1dba8fa64176683becabc No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:11396 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170105 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30738}
2020-03-10 09:50:26 +00:00
// Converts a VideoBitrateAllocation that contains allocated bitrate per layer,
// and an EncoderInfo that contains information about the actual encoder
// structure used by a codec. Stream structures can be Ksvc, Full SVC, Simulcast
// etc.
VideoLayersAllocation CreateVideoLayersAllocation(
const VideoCodec& encoder_config,
const VideoEncoder::RateControlParameters& current_rate,
const VideoEncoder::EncoderInfo& encoder_info) {
const VideoBitrateAllocation& target_bitrate = current_rate.target_bitrate;
VideoLayersAllocation layers_allocation;
if (target_bitrate.get_sum_bps() == 0) {
return layers_allocation;
}
if (encoder_config.numberOfSimulcastStreams > 0) {
layers_allocation.resolution_and_frame_rate_is_valid = true;
for (int si = 0; si < encoder_config.numberOfSimulcastStreams; ++si) {
if (!target_bitrate.IsSpatialLayerUsed(si) ||
target_bitrate.GetSpatialLayerSum(si) == 0) {
break;
}
layers_allocation.active_spatial_layers.emplace_back();
VideoLayersAllocation::SpatialLayer& spatial_layer =
layers_allocation.active_spatial_layers.back();
spatial_layer.width = encoder_config.simulcastStream[si].width;
spatial_layer.height = encoder_config.simulcastStream[si].height;
spatial_layer.rtp_stream_index = si;
spatial_layer.spatial_id = 0;
auto frame_rate_fraction =
VideoEncoder::EncoderInfo::kMaxFramerateFraction;
if (encoder_info.fps_allocation[si].size() == 1) {
// One TL is signalled to be used by the encoder. Do not distribute
// bitrate allocation across TLs (use sum at tl:0).
spatial_layer.target_bitrate_per_temporal_layer.push_back(
DataRate::BitsPerSec(target_bitrate.GetSpatialLayerSum(si)));
frame_rate_fraction = encoder_info.fps_allocation[si][0];
} else { // Temporal layers are supported.
uint32_t temporal_layer_bitrate_bps = 0;
for (size_t ti = 0;
ti < encoder_config.simulcastStream[si].numberOfTemporalLayers;
++ti) {
if (!target_bitrate.HasBitrate(si, ti)) {
break;
}
if (ti < encoder_info.fps_allocation[si].size()) {
// Use frame rate of the top used temporal layer.
frame_rate_fraction = encoder_info.fps_allocation[si][ti];
}
temporal_layer_bitrate_bps += target_bitrate.GetBitrate(si, ti);
spatial_layer.target_bitrate_per_temporal_layer.push_back(
DataRate::BitsPerSec(temporal_layer_bitrate_bps));
}
}
// Encoder may drop frames internally if `maxFramerate` is set.
spatial_layer.frame_rate_fps = std::min(
static_cast<uint8_t>(encoder_config.simulcastStream[si].maxFramerate),
static_cast<uint8_t>(
(current_rate.framerate_fps * frame_rate_fraction) /
VideoEncoder::EncoderInfo::kMaxFramerateFraction));
}
} else {
// TODO(bugs.webrtc.org/12000): Implement support for kSVC and full SVC.
}
return layers_allocation;
}
} // namespace
VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings()
: rate_control(),
encoder_target(DataRate::Zero()),
stable_encoder_target(DataRate::Zero()) {}
VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings(
const VideoBitrateAllocation& bitrate,
double framerate_fps,
DataRate bandwidth_allocation,
DataRate encoder_target,
DataRate stable_encoder_target)
: rate_control(bitrate, framerate_fps, bandwidth_allocation),
encoder_target(encoder_target),
stable_encoder_target(stable_encoder_target) {}
bool VideoStreamEncoder::EncoderRateSettings::operator==(
const EncoderRateSettings& rhs) const {
return rate_control == rhs.rate_control &&
encoder_target == rhs.encoder_target &&
stable_encoder_target == rhs.stable_encoder_target;
}
bool VideoStreamEncoder::EncoderRateSettings::operator!=(
const EncoderRateSettings& rhs) const {
return !(*this == rhs);
}
class VideoStreamEncoder::DegradationPreferenceManager
: public DegradationPreferenceProvider {
public:
explicit DegradationPreferenceManager(
VideoStreamAdapter* video_stream_adapter)
: degradation_preference_(DegradationPreference::DISABLED),
is_screenshare_(false),
effective_degradation_preference_(DegradationPreference::DISABLED),
video_stream_adapter_(video_stream_adapter) {
RTC_DCHECK(video_stream_adapter_);
sequence_checker_.Detach();
}
~DegradationPreferenceManager() override = default;
DegradationPreference degradation_preference() const override {
RTC_DCHECK_RUN_ON(&sequence_checker_);
return effective_degradation_preference_;
}
void SetDegradationPreference(DegradationPreference degradation_preference) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
degradation_preference_ = degradation_preference;
MaybeUpdateEffectiveDegradationPreference();
}
void SetIsScreenshare(bool is_screenshare) {
RTC_DCHECK_RUN_ON(&sequence_checker_);
is_screenshare_ = is_screenshare;
MaybeUpdateEffectiveDegradationPreference();
}
private:
void MaybeUpdateEffectiveDegradationPreference()
RTC_RUN_ON(&sequence_checker_) {
DegradationPreference effective_degradation_preference =
(is_screenshare_ &&
degradation_preference_ == DegradationPreference::BALANCED)
? DegradationPreference::MAINTAIN_RESOLUTION
: degradation_preference_;
if (effective_degradation_preference != effective_degradation_preference_) {
effective_degradation_preference_ = effective_degradation_preference;
video_stream_adapter_->SetDegradationPreference(
effective_degradation_preference);
}
}
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
DegradationPreference degradation_preference_
RTC_GUARDED_BY(&sequence_checker_);
bool is_screenshare_ RTC_GUARDED_BY(&sequence_checker_);
DegradationPreference effective_degradation_preference_
RTC_GUARDED_BY(&sequence_checker_);
VideoStreamAdapter* video_stream_adapter_ RTC_GUARDED_BY(&sequence_checker_);
};
VideoStreamEncoder::VideoStreamEncoder(
Clock* clock,
uint32_t number_of_cores,
VideoStreamEncoderObserver* encoder_stats_observer,
const VideoStreamEncoderSettings& settings,
std::unique_ptr<OveruseFrameDetector> overuse_detector,
TaskQueueFactory* task_queue_factory)
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
: main_queue_(TaskQueueBase::Current()),
number_of_cores_(number_of_cores),
quality_scaling_experiment_enabled_(QualityScalingExperiment::Enabled()),
sink_(nullptr),
settings_(settings),
rate_control_settings_(RateControlSettings::ParseFromFieldTrials()),
encoder_selector_(settings.encoder_factory->GetEncoderSelector()),
encoder_stats_observer_(encoder_stats_observer),
encoder_initialized_(false),
max_framerate_(-1),
pending_encoder_reconfiguration_(false),
Revert "Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo" This reverts commit cdc5eb0de179dcc866ef770ea303879c64466879. Reason for revert: Causes wrong CPU adaptation to be used for some HW codecs since GetEncoderInfo() is polled before InitEncode(). Original change's description: > Replace VideoEncoderFactory::QueryVideoEncoder with VideoEncoder::GetEncoderInfo > > Make implementation of VideoEncoderFactory::QueryVideoEncoder optional > until it is removed downstream and remove all implementations of it. > > Bug: webrtc:10065 > Change-Id: Ibb1f9612234e536651ce53f05ee048a5d172a41f > Reviewed-on: https://webrtc-review.googlesource.com/c/113065 > Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org> > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Reviewed-by: Per Kjellander <perkj@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> > Reviewed-by: Kári Helgason <kthelgason@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#25924} TBR=brandtr@webrtc.org,sakal@webrtc.org,kthelgason@webrtc.org,sprang@webrtc.org,srte@webrtc.org,perkj@webrtc.org,mirtad@webrtc.org # Not skipping CQ checks because original CL landed > 1 day ago. Bug: webrtc:10065 Change-Id: Idaa452e1d8c1c58cdb4ec69b88fce9042589cc3c Reviewed-on: https://webrtc-review.googlesource.com/c/113800 Reviewed-by: Mirta Dvornicic <mirtad@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Reviewed-by: Kári Helgason <kthelgason@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Commit-Queue: Mirta Dvornicic <mirtad@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25943}
2018-12-10 09:47:34 +00:00
pending_encoder_creation_(false),
crop_width_(0),
crop_height_(0),
encoder_target_bitrate_bps_(absl::nullopt),
max_data_payload_length_(0),
encoder_paused_and_dropped_frame_(false),
was_encode_called_since_last_initialization_(false),
encoder_failed_(false),
clock_(clock),
posted_frames_waiting_for_encode_(0),
last_captured_timestamp_(0),
delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
clock_->TimeInMilliseconds()),
last_frame_log_ms_(clock_->TimeInMilliseconds()),
captured_frame_count_(0),
dropped_frame_cwnd_pushback_count_(0),
dropped_frame_encoder_block_count_(0),
pending_frame_post_time_us_(0),
accumulated_update_rect_{0, 0, 0, 0},
accumulated_update_rect_is_valid_(true),
animation_start_time_(Timestamp::PlusInfinity()),
cap_resolution_due_to_video_content_(false),
expect_resize_state_(ExpectResizeState::kNoResize),
fec_controller_override_(nullptr),
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
force_disable_frame_dropper_(false),
input_framerate_(kFrameRateAvergingWindowSizeMs, 1000),
pending_frame_drops_(0),
cwnd_frame_counter_(0),
next_frame_types_(1, VideoFrameType::kVideoFrameDelta),
frame_encode_metadata_writer_(this),
experiment_groups_(GetExperimentGroups()),
encoder_switch_experiment_(ParseEncoderSwitchFieldTrial()),
automatic_animation_detection_experiment_(
ParseAutomatincAnimationDetectionFieldTrial()),
encoder_switch_requested_(false),
input_state_provider_(encoder_stats_observer),
video_stream_adapter_(
std::make_unique<VideoStreamAdapter>(&input_state_provider_,
encoder_stats_observer)),
resource_adaptation_processor_(
std::make_unique<ResourceAdaptationProcessor>(
video_stream_adapter_.get())),
degradation_preference_manager_(
std::make_unique<DegradationPreferenceManager>(
video_stream_adapter_.get())),
adaptation_constraints_(),
stream_resource_manager_(&input_state_provider_,
encoder_stats_observer,
clock_,
settings_.experiment_cpu_load_estimator,
std::move(overuse_detector),
degradation_preference_manager_.get()),
video_source_sink_controller_(/*sink=*/this,
/*source=*/nullptr),
encoder_queue_(task_queue_factory->CreateTaskQueue(
"EncoderQueue",
TaskQueueFactory::Priority::NORMAL)) {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK(main_queue_);
RTC_DCHECK(encoder_stats_observer);
RTC_DCHECK_GE(number_of_cores, 1);
stream_resource_manager_.Initialize(&encoder_queue_);
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
rtc::Event initialize_processor_event;
encoder_queue_.PostTask([this, &initialize_processor_event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
resource_adaptation_processor_->SetTaskQueue(encoder_queue_.Get());
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
stream_resource_manager_.SetAdaptationProcessor(
resource_adaptation_processor_.get(), video_stream_adapter_.get());
resource_adaptation_processor_->AddResourceLimitationsListener(
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
&stream_resource_manager_);
video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_);
video_stream_adapter_->AddRestrictionsListener(this);
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
// Add the stream resource manager's resources to the processor.
adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
for (auto* constraint : adaptation_constraints_) {
video_stream_adapter_->AddAdaptationConstraint(constraint);
}
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
initialize_processor_event.Set();
});
initialize_processor_event.Wait(rtc::Event::kForever);
}
VideoStreamEncoder::~VideoStreamEncoder() {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
RTC_DCHECK(!video_source_sink_controller_.HasSource())
<< "Must call ::Stop() before destruction.";
}
void VideoStreamEncoder::Stop() {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
video_source_sink_controller_.SetSource(nullptr);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
rtc::Event shutdown_event;
encoder_queue_.PostTask([this, &shutdown_event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
if (resource_adaptation_processor_) {
stream_resource_manager_.StopManagedResources();
for (auto* constraint : adaptation_constraints_) {
video_stream_adapter_->RemoveAdaptationConstraint(constraint);
}
for (auto& resource : additional_resources_) {
stream_resource_manager_.RemoveResource(resource);
}
additional_resources_.clear();
video_stream_adapter_->RemoveRestrictionsListener(this);
video_stream_adapter_->RemoveRestrictionsListener(
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
&stream_resource_manager_);
resource_adaptation_processor_->RemoveResourceLimitationsListener(
&stream_resource_manager_);
stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr);
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
resource_adaptation_processor_.reset();
}
rate_allocator_ = nullptr;
ReleaseEncoder();
encoder_ = nullptr;
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
shutdown_event.Set();
});
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
shutdown_event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::SetFecControllerOverride(
FecControllerOverride* fec_controller_override) {
encoder_queue_.PostTask([this, fec_controller_override] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_DCHECK(!fec_controller_override_);
fec_controller_override_ = fec_controller_override;
if (encoder_) {
encoder_->SetFecControllerOverride(fec_controller_override_);
}
});
}
void VideoStreamEncoder::AddAdaptationResource(
rtc::scoped_refptr<Resource> resource) {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
// Map any externally added resources as kCpu for the sake of stats reporting.
// TODO(hbos): Make the manager map any unknown resources to kCpu and get rid
// of this MapResourceToReason() call.
rtc::Event map_resource_event;
encoder_queue_.PostTask([this, resource, &map_resource_event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
additional_resources_.push_back(resource);
stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu);
map_resource_event.Set();
});
map_resource_event.Wait(rtc::Event::kForever);
}
std::vector<rtc::scoped_refptr<Resource>>
VideoStreamEncoder::GetAdaptationResources() {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
return resource_adaptation_processor_->GetResources();
}
void VideoStreamEncoder::SetSource(
rtc::VideoSourceInterface<VideoFrame>* source,
const DegradationPreference& degradation_preference) {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
video_source_sink_controller_.SetSource(source);
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
input_state_provider_.OnHasInputChanged(source);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
// This may trigger reconfiguring the QualityScaler on the encoder queue.
encoder_queue_.PostTask([this, degradation_preference] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
degradation_preference_manager_->SetDegradationPreference(
degradation_preference);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
stream_resource_manager_.SetDegradationPreferences(degradation_preference);
if (encoder_) {
stream_resource_manager_.ConfigureQualityScaler(
encoder_->GetEncoderInfo());
}
});
}
void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_DCHECK_RUN_ON(main_queue_);
video_source_sink_controller_.SetRotationApplied(rotation_applied);
video_source_sink_controller_.PushSourceSinkSettings();
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
encoder_queue_.PostTask([this, sink] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
sink_ = sink;
});
}
void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
encoder_queue_.PostTask([this, start_bitrate_bps] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps;
encoder_target_bitrate_bps_ =
start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
: absl::nullopt;
stream_resource_manager_.SetStartBitrate(
DataRate::BitsPerSec(start_bitrate_bps));
});
}
void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
size_t max_data_payload_length) {
encoder_queue_.PostTask(
[this, config = std::move(config), max_data_payload_length]() mutable {
RTC_DCHECK_RUN_ON(&encoder_queue_);
RTC_DCHECK(sink_);
RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
pending_encoder_creation_ =
(!encoder_ || encoder_config_.video_format != config.video_format ||
max_data_payload_length_ != max_data_payload_length);
encoder_config_ = std::move(config);
max_data_payload_length_ = max_data_payload_length;
pending_encoder_reconfiguration_ = true;
// Reconfigure the encoder now if the encoder has an internal source or
// if the frame resolution is known. Otherwise, the reconfiguration is
// deferred until the next frame to minimize the number of
// reconfigurations. The codec configuration depends on incoming video
// frame size.
if (last_frame_info_) {
ReconfigureEncoder();
} else {
codec_info_ = settings_.encoder_factory->QueryVideoEncoder(
encoder_config_.video_format);
if (HasInternalSource()) {
last_frame_info_ = VideoFrameInfo(kDefaultInputPixelsWidth,
kDefaultInputPixelsHeight, false);
ReconfigureEncoder();
}
}
});
}
// TODO(bugs.webrtc.org/8807): Currently this always does a hard
// reconfiguration, but this isn't always necessary. Add in logic to only update
// the VideoBitrateAllocator and call OnEncoderConfigurationChanged with a
// "soft" reconfiguration.
void VideoStreamEncoder::ReconfigureEncoder() {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
// Running on the encoder queue.
RTC_DCHECK(pending_encoder_reconfiguration_);
if (!encoder_selector_ &&
encoder_switch_experiment_.IsPixelCountBelowThreshold(
last_frame_info_->width * last_frame_info_->height) &&
!encoder_switch_requested_ && settings_.encoder_switch_request_callback) {
EncoderSwitchRequestCallback::Config conf;
conf.codec_name = encoder_switch_experiment_.to_codec;
conf.param = encoder_switch_experiment_.to_param;
conf.value = encoder_switch_experiment_.to_value;
QueueRequestEncoderSwitch(conf);
encoder_switch_requested_ = true;
}
bool encoder_reset_required = false;
if (pending_encoder_creation_) {
// Destroy existing encoder instance before creating a new one. Otherwise
// attempt to create another instance will fail if encoder factory
// supports only single instance of encoder of given type.
encoder_.reset();
encoder_ = settings_.encoder_factory->CreateVideoEncoder(
encoder_config_.video_format);
// TODO(nisse): What to do if creating the encoder fails? Crash,
// or just discard incoming frames?
RTC_CHECK(encoder_);
if (encoder_selector_) {
encoder_selector_->OnCurrentEncoder(encoder_config_.video_format);
}
encoder_->SetFecControllerOverride(fec_controller_override_);
codec_info_ = settings_.encoder_factory->QueryVideoEncoder(
encoder_config_.video_format);
encoder_reset_required = true;
}
// Possibly adjusts scale_resolution_down_by in |encoder_config_| to limit the
// alignment value.
int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
encoder_->GetEncoderInfo(), &encoder_config_);
std::vector<VideoStream> streams =
encoder_config_.video_stream_factory->CreateEncoderStreams(
last_frame_info_->width, last_frame_info_->height, encoder_config_);
// Check that the higher layers do not try to set number of temporal layers
// to less than 1.
// TODO(brandtr): Get rid of the wrapping optional as it serves no purpose
// at this layer.
#if RTC_DCHECK_IS_ON
for (const auto& stream : streams) {
RTC_DCHECK_GE(stream.num_temporal_layers.value_or(1), 1);
}
#endif
// TODO(ilnik): If configured resolution is significantly less than provided,
// e.g. because there are not enough SSRCs for all simulcast streams,
// signal new resolutions via SinkWants to video source.
// Stream dimensions may be not equal to given because of a simulcast
// restrictions.
auto highest_stream = absl::c_max_element(
streams, [](const webrtc::VideoStream& a, const webrtc::VideoStream& b) {
return std::tie(a.width, a.height) < std::tie(b.width, b.height);
});
int highest_stream_width = static_cast<int>(highest_stream->width);
int highest_stream_height = static_cast<int>(highest_stream->height);
// Dimension may be reduced to be, e.g. divisible by 4.
RTC_CHECK_GE(last_frame_info_->width, highest_stream_width);
RTC_CHECK_GE(last_frame_info_->height, highest_stream_height);
crop_width_ = last_frame_info_->width - highest_stream_width;
crop_height_ = last_frame_info_->height - highest_stream_height;
encoder_bitrate_limits_ =
encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
last_frame_info_->width * last_frame_info_->height);
if (streams.size() == 1 && encoder_bitrate_limits_) {
// Bitrate limits can be set by app (in SDP or RtpEncodingParameters) or/and
// can be provided by encoder. In presence of both set of limits, the final
// set is derived as their intersection.
int min_bitrate_bps;
if (encoder_config_.simulcast_layers.empty() ||
encoder_config_.simulcast_layers[0].min_bitrate_bps <= 0) {
min_bitrate_bps = encoder_bitrate_limits_->min_bitrate_bps;
} else {
min_bitrate_bps = std::max(encoder_bitrate_limits_->min_bitrate_bps,
streams.back().min_bitrate_bps);
}
int max_bitrate_bps;
// We don't check encoder_config_.simulcast_layers[0].max_bitrate_bps
// here since encoder_config_.max_bitrate_bps is derived from it (as
// well as from other inputs).
if (encoder_config_.max_bitrate_bps <= 0) {
max_bitrate_bps = encoder_bitrate_limits_->max_bitrate_bps;
} else {
max_bitrate_bps = std::min(encoder_bitrate_limits_->max_bitrate_bps,
streams.back().max_bitrate_bps);
}
if (min_bitrate_bps < max_bitrate_bps) {
streams.back().min_bitrate_bps = min_bitrate_bps;
streams.back().max_bitrate_bps = max_bitrate_bps;
streams.back().target_bitrate_bps =
std::min(streams.back().target_bitrate_bps,
encoder_bitrate_limits_->max_bitrate_bps);
} else {
RTC_LOG(LS_WARNING) << "Bitrate limits provided by encoder"
<< " (min="
<< encoder_bitrate_limits_->min_bitrate_bps
<< ", max="
<< encoder_bitrate_limits_->min_bitrate_bps
<< ") do not intersect with limits set by app"
<< " (min=" << streams.back().min_bitrate_bps
<< ", max=" << encoder_config_.max_bitrate_bps
<< "). The app bitrate limits will be used.";
}
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
VideoCodec codec;
if (!VideoCodecInitializer::SetupCodec(encoder_config_, streams, &codec)) {
RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
}
if (encoder_config_.codec_type == kVideoCodecVP9) {
// Spatial layers configuration might impose some parity restrictions,
// thus some cropping might be needed.
crop_width_ = last_frame_info_->width - codec.width;
crop_height_ = last_frame_info_->height - codec.height;
}
char log_stream_buf[4 * 1024];
rtc::SimpleStringBuilder log_stream(log_stream_buf);
log_stream << "ReconfigureEncoder:\n";
log_stream << "Simulcast streams:\n";
for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
log_stream << i << ": " << codec.simulcastStream[i].width << "x"
<< codec.simulcastStream[i].height
<< " fps: " << codec.simulcastStream[i].maxFramerate
<< " min_kbps: " << codec.simulcastStream[i].minBitrate
<< " target_kbps: " << codec.simulcastStream[i].targetBitrate
<< " max_kbps: " << codec.simulcastStream[i].maxBitrate
<< " max_fps: " << codec.simulcastStream[i].maxFramerate
<< " max_qp: " << codec.simulcastStream[i].qpMax
<< " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers
<< " active: "
<< (codec.simulcastStream[i].active ? "true" : "false") << "\n";
}
if (encoder_config_.codec_type == kVideoCodecVP9) {
size_t num_spatial_layers = codec.VP9()->numberOfSpatialLayers;
log_stream << "Spatial layers:\n";
for (size_t i = 0; i < num_spatial_layers; ++i) {
log_stream << i << ": " << codec.spatialLayers[i].width << "x"
<< codec.spatialLayers[i].height
<< " fps: " << codec.spatialLayers[i].maxFramerate
<< " min_kbps: " << codec.spatialLayers[i].minBitrate
<< " target_kbps: " << codec.spatialLayers[i].targetBitrate
<< " max_kbps: " << codec.spatialLayers[i].maxBitrate
<< " max_qp: " << codec.spatialLayers[i].qpMax
<< " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers
<< " active: "
<< (codec.spatialLayers[i].active ? "true" : "false") << "\n";
}
}
RTC_LOG(LS_INFO) << log_stream.str();
codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
codec.minBitrate);
codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
codec.expect_encode_from_texture = last_frame_info_->is_texture;
// Make sure the start bit rate is sane...
RTC_DCHECK_LE(codec.startBitrate, 1000000);
max_framerate_ = codec.maxFramerate;
Reland "Add initial support for RtpEncodingParameters max_framerate." This reverts commit 948b7e37557af68b3bc9b81b29ae2daffb2784ad. Reason for revert: downstream project fixed. Original change's description: > Revert "Add initial support for RtpEncodingParameters max_framerate." > > This reverts commit ced5cfdb35a20c684df927eab37e16d35979555f. > > Reason for revert: Breaks downstream project. > > Original change's description: > > Add initial support for RtpEncodingParameters max_framerate. > > > > Add support to set the framerate to the maximum of |max_framerate|. > > Different framerates are currently not supported per stream for video. > > > > Bug: webrtc:9597 > > Change-Id: Ie326617b66bd97be387f809a7f82b97b8f3ff5fe > > Reviewed-on: https://webrtc-review.googlesource.com/92392 > > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > > Reviewed-by: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org> > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Commit-Queue: Åsa Persson <asapersson@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#24270} > > TBR=steveanton@webrtc.org,magjed@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org,srte@webrtc.org > > Change-Id: I508fe48e0c53996654f657357913ac307dc256bd > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:9597 > Reviewed-on: https://webrtc-review.googlesource.com/94060 > Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> > Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#24277} TBR=steveanton@webrtc.org,mbonadei@webrtc.org,magjed@webrtc.org,asapersson@webrtc.org,sprang@webrtc.org,srte@webrtc.org Bug: webrtc:9597 Change-Id: Ieed9d62787f3e9dcb439399bfe7529012292381e Reviewed-on: https://webrtc-review.googlesource.com/100080 Reviewed-by: Åsa Persson <asapersson@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24720}
2018-09-13 10:42:19 +02:00
// Inform source about max configured framerate.
int max_framerate = 0;
for (const auto& stream : streams) {
max_framerate = std::max(stream.max_framerate, max_framerate);
}
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
main_queue_->PostTask(
ToQueuedTask(task_safety_, [this, max_framerate, alignment]() {
RTC_DCHECK_RUN_ON(main_queue_);
if (max_framerate !=
video_source_sink_controller_.frame_rate_upper_limit() ||
alignment != video_source_sink_controller_.resolution_alignment()) {
video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate);
video_source_sink_controller_.SetResolutionAlignment(alignment);
video_source_sink_controller_.PushSourceSinkSettings();
}
}));
if (codec.maxBitrate == 0) {
// max is one bit per pixel
codec.maxBitrate =
(static_cast<int>(codec.height) * static_cast<int>(codec.width) *
static_cast<int>(codec.maxFramerate)) /
1000;
if (codec.startBitrate > codec.maxBitrate) {
// But if the user tries to set a higher start bit rate we will
// increase the max accordingly.
codec.maxBitrate = codec.startBitrate;
}
}
if (codec.startBitrate > codec.maxBitrate) {
codec.startBitrate = codec.maxBitrate;
}
rate_allocator_ =
settings_.bitrate_allocator_factory->CreateVideoBitrateAllocator(codec);
rate_allocator_->SetLegacyConferenceMode(
encoder_config_.legacy_conference_mode);
// Reset (release existing encoder) if one exists and anything except
// start bitrate or max framerate has changed.
if (!encoder_reset_required) {
encoder_reset_required = RequiresEncoderReset(
send_codec_, codec, was_encode_called_since_last_initialization_);
}
send_codec_ = codec;
encoder_switch_experiment_.SetCodec(send_codec_.codecType);
// Keep the same encoder, as long as the video_format is unchanged.
// Encoder creation block is split in two since EncoderInfo needed to start
// CPU adaptation with the correct settings should be polled after
// encoder_->InitEncode().
bool success = true;
if (encoder_reset_required) {
ReleaseEncoder();
const size_t max_data_payload_length = max_data_payload_length_ > 0
? max_data_payload_length_
: kDefaultPayloadSize;
if (encoder_->InitEncode(
&send_codec_,
VideoEncoder::Settings(settings_.capabilities, number_of_cores_,
max_data_payload_length)) != 0) {
RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
"codec type: "
<< CodecTypeToPayloadString(send_codec_.codecType)
<< " (" << send_codec_.codecType << ")";
ReleaseEncoder();
success = false;
} else {
encoder_initialized_ = true;
encoder_->RegisterEncodeCompleteCallback(this);
frame_encode_metadata_writer_.OnEncoderInit(send_codec_,
HasInternalSource());
next_frame_types_.clear();
next_frame_types_.resize(
std::max(static_cast<int>(codec.numberOfSimulcastStreams), 1),
VideoFrameType::kVideoFrameKey);
}
frame_encode_metadata_writer_.Reset();
last_encode_info_ms_ = absl::nullopt;
was_encode_called_since_last_initialization_ = false;
}
Revert "Remove VCMEncoderDataBase and put remaining code into VideoStreamEncoder" This reverts commit 715c4765b1ac20017e6e3b8b925d02536c6610c3. Reason for revert: Breaks WebRTC roll to Chromium. https://chromium-review.googlesource.com/c/chromium/src/+/1484629 # Fatal error in: ../../third_party/webrtc/modules/rtp_rtcp/source/rtp_sender.cc, line 796 # last system error: 0 # Check failed: diff_ms >= static_cast<int64_t>(0) (-307 vs. 0) # Original change's description: > Remove VCMEncoderDataBase and put remaining code into VideoStreamEncoder > > Since this "data base" only holds a single encoder instance it just > serves to confuse object ownership. Removing it and giving ownership > of generic encoder instance to VideoStreamEncoder. > > This CL also removes VideoSender interface from video_coding_impl.h, > which is mostly a leftover from > https://webrtc-review.googlesource.com/c/src/+/123540 > > Bug: webrtc:10164 > Change-Id: I9b7fec940dbcbccf3aa1278c2555da3bd5169ae1 > Reviewed-on: https://webrtc-review.googlesource.com/c/123920 > Commit-Queue: Erik Språng <sprang@webrtc.org> > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > Reviewed-by: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26835} TBR=brandtr@webrtc.org,nisse@webrtc.org,sprang@webrtc.org Change-Id: I5432878c4c2e497cd848c4ce1b190e0307df03ca Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/124402 Commit-Queue: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26841}
2019-02-25 15:56:27 +00:00
[Adaptation] Introduce VideoStreamInputState and its Provider. This CL is part of the Call-Level Adaptation Processing design doc: https://docs.google.com/document/d/1ZyC26yOCknrrcYa839ZWLxD6o6Gig5A3lVTh4E41074/edit?usp=sharing The "input state" of a VideoStream, needed for adaptation and decision-making, are: source resolution and frame rate, codec type and min pixels per frame (based on encoder scaling settings). These values are modified on the encoder queue of the VideoStreamEncoder. But in order to unblock call-level adaptation processing, where adaptation and decision making happens off the encoder queue, a snapshot of the input states need to be available at point of processing: introducing the VideoStreamInputState. In this CL, the VideoStreamInputStateProvider is added to provide input state snapshots across threads based on input from VideoStreamEncoder and VideoStreamEncoderObserver. The input state's HasInputFrameSizeAndFramesPerSecond() can now be DCHECKed inside the VideoStreamAdapter in favor of having less Adaptation::Status codes. Whether input is "sufficient" for adaptation is now the responsibility of the Processor. (Goal: adapter is purely a Adaptation generator and apply-er.) Somewhat tangental, this CL also deletes VideoStreamEncoder-specific methods from ResourceAdaptationProcessorInterface making them an implementation detail of ResourceAdaptationProcessor. In a future CL, the "processor" will be split up into a "processor" part and a "video stream encoder resource manager" part - more on that later. Bug: webrtc:11172 Change-Id: Id9b158f569db0140b75360aaf0f7e2e28fb924f4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172928 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Cr-Commit-Position: refs/heads/master@{#31098}
2020-04-17 12:10:59 +02:00
// Inform dependents of updated encoder settings.
OnEncoderSettingsChanged();
if (success) {
RTC_LOG(LS_VERBOSE) << " max bitrate " << codec.maxBitrate
<< " start bitrate " << codec.startBitrate
<< " max frame rate " << codec.maxFramerate
<< " max payload size " << max_data_payload_length_;
} else {
RTC_LOG(LS_ERROR) << "Failed to configure encoder.";
rate_allocator_ = nullptr;
}
if (pending_encoder_creation_) {
stream_resource_manager_.EnsureEncodeUsageResourceStarted();
pending_encoder_creation_ = false;
}
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
int num_layers;
if (codec.codecType == kVideoCodecVP8) {
num_layers = codec.VP8()->numberOfTemporalLayers;
} else if (codec.codecType == kVideoCodecVP9) {
num_layers = codec.VP9()->numberOfTemporalLayers;
} else if (codec.codecType == kVideoCodecH264) {
num_layers = codec.H264()->numberOfTemporalLayers;
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
} else if (codec.codecType == kVideoCodecGeneric &&
codec.numberOfSimulcastStreams > 0) {
// This is mainly for unit testing, disabling frame dropping.
// TODO(sprang): Add a better way to disable frame dropping.
num_layers = codec.simulcastStream[0].numberOfTemporalLayers;
} else {
num_layers = 1;
}
frame_dropper_.Reset();
frame_dropper_.SetRates(codec.startBitrate, max_framerate_);
// Force-disable frame dropper if either:
// * We have screensharing with layers.
// * "WebRTC-FrameDropper" field trial is "Disabled".
force_disable_frame_dropper_ =
field_trial::IsDisabled(kFrameDropperFieldTrial) ||
(num_layers > 1 && codec.mode == VideoCodecMode::kScreensharing);
VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
if (rate_control_settings_.UseEncoderBitrateAdjuster()) {
Use std::make_unique instead of absl::make_unique. WebRTC is now using C++14 so there is no need to use the Abseil version of std::make_unique. This CL has been created with the following steps: git grep -l absl::make_unique | sort | uniq > /tmp/make_unique.txt git grep -l absl::WrapUnique | sort | uniq > /tmp/wrap_unique.txt git grep -l "#include <memory>" | sort | uniq > /tmp/memory.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/make_unique.txt /tmp/wrap_unique.txt | sort | \ uniq > /tmp/only_make_unique.txt diff --new-line-format="" --unchanged-line-format="" \ /tmp/only_make_unique.txt /tmp/memory.txt | \ xargs grep -l "absl/memory" > /tmp/add-memory.txt git grep -l "\babsl::make_unique\b" | \ xargs sed -i "s/\babsl::make_unique\b/std::make_unique/g" git checkout PRESUBMIT.py abseil-in-webrtc.md cat /tmp/add-memory.txt | \ xargs sed -i \ 's/#include "absl\/memory\/memory.h"/#include <memory>/g' git cl format # Manual fix order of the new inserted #include <memory> cat /tmp/only_make_unique | xargs grep -l "#include <memory>" | \ xargs sed -i '/#include "absl\/memory\/memory.h"/d' git ls-files | grep BUILD.gn | \ xargs sed -i '/\/\/third_party\/abseil-cpp\/absl\/memory/d' python tools_webrtc/gn_check_autofix.py \ -m tryserver.webrtc -b linux_rel # Repead the gn_check_autofix step for other platforms git ls-files | grep BUILD.gn | \ xargs sed -i 's/absl\/memory:memory/absl\/memory/g' git cl format Bug: webrtc:10945 Change-Id: I3fe28ea80f4dd3ba3cf28effd151d5e1f19aff89 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/153221 Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#29209}
2019-09-17 17:06:18 +02:00
bitrate_adjuster_ = std::make_unique<EncoderBitrateAdjuster>(codec);
bitrate_adjuster_->OnEncoderInfo(info);
}
if (rate_allocator_ && last_encoder_rate_settings_) {
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
// We have a new rate allocator instance and already configured target
// bitrate. Update the rate allocation and notify observers.
// We must invalidate the last_encoder_rate_settings_ to ensure
// the changes get propagated to all listeners.
EncoderRateSettings rate_settings = *last_encoder_rate_settings_;
last_encoder_rate_settings_.reset();
rate_settings.rate_control.framerate_fps = GetInputFramerateFps();
SetEncoderRates(UpdateBitrateAllocation(rate_settings));
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
encoder_stats_observer_->OnEncoderReconfigured(encoder_config_, streams);
pending_encoder_reconfiguration_ = false;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
bool is_svc = false;
// Set min_bitrate_bps, max_bitrate_bps, and max padding bit rate for VP9
// and leave only one stream containing all necessary information.
if (encoder_config_.codec_type == kVideoCodecVP9) {
// Lower max bitrate to the level codec actually can produce.
streams[0].max_bitrate_bps =
std::min(streams[0].max_bitrate_bps,
SvcRateAllocator::GetMaxBitrate(codec).bps<int>());
streams[0].min_bitrate_bps = codec.spatialLayers[0].minBitrate * 1000;
// target_bitrate_bps specifies the maximum padding bitrate.
streams[0].target_bitrate_bps =
SvcRateAllocator::GetPaddingBitrate(codec).bps<int>();
streams[0].width = streams.back().width;
streams[0].height = streams.back().height;
is_svc = codec.VP9()->numberOfSpatialLayers > 1;
streams.resize(1);
}
sink_->OnEncoderConfigurationChanged(
std::move(streams), is_svc, encoder_config_.content_type,
encoder_config_.min_transmit_bitrate_bps);
stream_resource_manager_.ConfigureQualityScaler(info);
}
[Adaptation] Introduce VideoStreamInputState and its Provider. This CL is part of the Call-Level Adaptation Processing design doc: https://docs.google.com/document/d/1ZyC26yOCknrrcYa839ZWLxD6o6Gig5A3lVTh4E41074/edit?usp=sharing The "input state" of a VideoStream, needed for adaptation and decision-making, are: source resolution and frame rate, codec type and min pixels per frame (based on encoder scaling settings). These values are modified on the encoder queue of the VideoStreamEncoder. But in order to unblock call-level adaptation processing, where adaptation and decision making happens off the encoder queue, a snapshot of the input states need to be available at point of processing: introducing the VideoStreamInputState. In this CL, the VideoStreamInputStateProvider is added to provide input state snapshots across threads based on input from VideoStreamEncoder and VideoStreamEncoderObserver. The input state's HasInputFrameSizeAndFramesPerSecond() can now be DCHECKed inside the VideoStreamAdapter in favor of having less Adaptation::Status codes. Whether input is "sufficient" for adaptation is now the responsibility of the Processor. (Goal: adapter is purely a Adaptation generator and apply-er.) Somewhat tangental, this CL also deletes VideoStreamEncoder-specific methods from ResourceAdaptationProcessorInterface making them an implementation detail of ResourceAdaptationProcessor. In a future CL, the "processor" will be split up into a "processor" part and a "video stream encoder resource manager" part - more on that later. Bug: webrtc:11172 Change-Id: Id9b158f569db0140b75360aaf0f7e2e28fb924f4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172928 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Cr-Commit-Position: refs/heads/master@{#31098}
2020-04-17 12:10:59 +02:00
void VideoStreamEncoder::OnEncoderSettingsChanged() {
EncoderSettings encoder_settings(encoder_->GetEncoderInfo(),
encoder_config_.Copy(), send_codec_);
stream_resource_manager_.SetEncoderSettings(encoder_settings);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
input_state_provider_.OnEncoderSettingsChanged(encoder_settings);
bool is_screenshare = encoder_settings.encoder_config().content_type ==
VideoEncoderConfig::ContentType::kScreen;
degradation_preference_manager_->SetIsScreenshare(is_screenshare);
[Adaptation] Introduce VideoStreamInputState and its Provider. This CL is part of the Call-Level Adaptation Processing design doc: https://docs.google.com/document/d/1ZyC26yOCknrrcYa839ZWLxD6o6Gig5A3lVTh4E41074/edit?usp=sharing The "input state" of a VideoStream, needed for adaptation and decision-making, are: source resolution and frame rate, codec type and min pixels per frame (based on encoder scaling settings). These values are modified on the encoder queue of the VideoStreamEncoder. But in order to unblock call-level adaptation processing, where adaptation and decision making happens off the encoder queue, a snapshot of the input states need to be available at point of processing: introducing the VideoStreamInputState. In this CL, the VideoStreamInputStateProvider is added to provide input state snapshots across threads based on input from VideoStreamEncoder and VideoStreamEncoderObserver. The input state's HasInputFrameSizeAndFramesPerSecond() can now be DCHECKed inside the VideoStreamAdapter in favor of having less Adaptation::Status codes. Whether input is "sufficient" for adaptation is now the responsibility of the Processor. (Goal: adapter is purely a Adaptation generator and apply-er.) Somewhat tangental, this CL also deletes VideoStreamEncoder-specific methods from ResourceAdaptationProcessorInterface making them an implementation detail of ResourceAdaptationProcessor. In a future CL, the "processor" will be split up into a "processor" part and a "video stream encoder resource manager" part - more on that later. Bug: webrtc:11172 Change-Id: Id9b158f569db0140b75360aaf0f7e2e28fb924f4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172928 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Cr-Commit-Position: refs/heads/master@{#31098}
2020-04-17 12:10:59 +02:00
}
void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) {
RTC_DCHECK_RUNS_SERIALIZED(&incoming_frame_race_checker_);
VideoFrame incoming_frame = video_frame;
// Local time in webrtc time base.
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
Timestamp now = clock_->CurrentTime();
// In some cases, e.g., when the frame from decoder is fed to encoder,
// the timestamp may be set to the future. As the encoding pipeline assumes
// capture time to be less than present time, we should reset the capture
// timestamps here. Otherwise there may be issues with RTP send stream.
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
if (incoming_frame.timestamp_us() > now.us())
incoming_frame.set_timestamp_us(now.us());
// Capture time may come from clock with an offset and drift from clock_.
int64_t capture_ntp_time_ms;
if (video_frame.ntp_time_ms() > 0) {
capture_ntp_time_ms = video_frame.ntp_time_ms();
} else if (video_frame.render_time_ms() != 0) {
capture_ntp_time_ms = video_frame.render_time_ms() + delta_ntp_internal_ms_;
} else {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
capture_ntp_time_ms = now.ms() + delta_ntp_internal_ms_;
}
incoming_frame.set_ntp_time_ms(capture_ntp_time_ms);
// Convert NTP time, in ms, to RTP timestamp.
const int kMsToRtpTimestamp = 90;
incoming_frame.set_timestamp(
kMsToRtpTimestamp * static_cast<uint32_t>(incoming_frame.ntp_time_ms()));
if (incoming_frame.ntp_time_ms() <= last_captured_timestamp_) {
// We don't allow the same capture time for two frames, drop this one.
RTC_LOG(LS_WARNING) << "Same/old NTP timestamp ("
<< incoming_frame.ntp_time_ms()
<< " <= " << last_captured_timestamp_
<< ") for incoming frame. Dropping.";
encoder_queue_.PostTask([this, incoming_frame]() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
accumulated_update_rect_.Union(incoming_frame.update_rect());
accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
});
return;
}
bool log_stats = false;
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
if (now.ms() - last_frame_log_ms_ > kFrameLogIntervalMs) {
last_frame_log_ms_ = now.ms();
log_stats = true;
}
last_captured_timestamp_ = incoming_frame.ntp_time_ms();
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
int64_t post_time_us = clock_->CurrentTime().us();
++posted_frames_waiting_for_encode_;
encoder_queue_.PostTask(
[this, incoming_frame, post_time_us, log_stats]() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
encoder_stats_observer_->OnIncomingFrame(incoming_frame.width(),
incoming_frame.height());
++captured_frame_count_;
const int posted_frames_waiting_for_encode =
posted_frames_waiting_for_encode_.fetch_sub(1);
RTC_DCHECK_GT(posted_frames_waiting_for_encode, 0);
CheckForAnimatedContent(incoming_frame, post_time_us);
bool cwnd_frame_drop =
cwnd_frame_drop_interval_ &&
(cwnd_frame_counter_++ % cwnd_frame_drop_interval_.value() == 0);
if (posted_frames_waiting_for_encode == 1 && !cwnd_frame_drop) {
MaybeEncodeVideoFrame(incoming_frame, post_time_us);
} else {
if (cwnd_frame_drop) {
// Frame drop by congestion window pusback. Do not encode this
// frame.
++dropped_frame_cwnd_pushback_count_;
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kCongestionWindow);
} else {
// There is a newer frame in flight. Do not encode this frame.
RTC_LOG(LS_VERBOSE)
<< "Incoming frame dropped due to that the encoder is blocked.";
++dropped_frame_encoder_block_count_;
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kEncoderQueue);
}
accumulated_update_rect_.Union(incoming_frame.update_rect());
accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
}
if (log_stats) {
RTC_LOG(LS_INFO) << "Number of frames: captured "
<< captured_frame_count_
<< ", dropped (due to congestion window pushback) "
<< dropped_frame_cwnd_pushback_count_
<< ", dropped (due to encoder blocked) "
<< dropped_frame_encoder_block_count_
<< ", interval_ms " << kFrameLogIntervalMs;
captured_frame_count_ = 0;
dropped_frame_cwnd_pushback_count_ = 0;
dropped_frame_encoder_block_count_ = 0;
}
});
}
void VideoStreamEncoder::OnDiscardedFrame() {
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kSource);
}
bool VideoStreamEncoder::EncoderPaused() const {
RTC_DCHECK_RUN_ON(&encoder_queue_);
// Pause video if paused by caller or as long as the network is down or the
// pacer queue has grown too large in buffered mode.
// If the pacer queue has grown too large or the network is down,
// |last_encoder_rate_settings_->encoder_target| will be 0.
return !last_encoder_rate_settings_ ||
last_encoder_rate_settings_->encoder_target == DataRate::Zero();
}
void VideoStreamEncoder::TraceFrameDropStart() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
// Start trace event only on the first frame after encoder is paused.
if (!encoder_paused_and_dropped_frame_) {
TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
}
encoder_paused_and_dropped_frame_ = true;
}
void VideoStreamEncoder::TraceFrameDropEnd() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
// End trace event on first frame after encoder resumes, if frame was dropped.
if (encoder_paused_and_dropped_frame_) {
TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
}
encoder_paused_and_dropped_frame_ = false;
}
VideoStreamEncoder::EncoderRateSettings
VideoStreamEncoder::UpdateBitrateAllocation(
const EncoderRateSettings& rate_settings) {
VideoBitrateAllocation new_allocation;
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
// Only call allocators if bitrate > 0 (ie, not suspended), otherwise they
// might cap the bitrate to the min bitrate configured.
if (rate_allocator_ && rate_settings.encoder_target > DataRate::Zero()) {
new_allocation = rate_allocator_->Allocate(VideoBitrateAllocationParameters(
rate_settings.encoder_target, rate_settings.stable_encoder_target,
rate_settings.rate_control.framerate_fps));
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
EncoderRateSettings new_rate_settings = rate_settings;
new_rate_settings.rate_control.target_bitrate = new_allocation;
new_rate_settings.rate_control.bitrate = new_allocation;
// VideoBitrateAllocator subclasses may allocate a bitrate higher than the
// target in order to sustain the min bitrate of the video codec. In this
// case, make sure the bandwidth allocation is at least equal the allocation
// as that is part of the document contract for that field.
new_rate_settings.rate_control.bandwidth_allocation =
std::max(new_rate_settings.rate_control.bandwidth_allocation,
DataRate::BitsPerSec(
new_rate_settings.rate_control.bitrate.get_sum_bps()));
if (bitrate_adjuster_) {
VideoBitrateAllocation adjusted_allocation =
bitrate_adjuster_->AdjustRateAllocation(new_rate_settings.rate_control);
RTC_LOG(LS_VERBOSE) << "Adjusting allocation, fps = "
<< rate_settings.rate_control.framerate_fps << ", from "
<< new_allocation.ToString() << ", to "
<< adjusted_allocation.ToString();
new_rate_settings.rate_control.bitrate = adjusted_allocation;
}
return new_rate_settings;
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
uint32_t VideoStreamEncoder::GetInputFramerateFps() {
const uint32_t default_fps = max_framerate_ != -1 ? max_framerate_ : 30;
absl::optional<uint32_t> input_fps =
input_framerate_.Rate(clock_->TimeInMilliseconds());
if (!input_fps || *input_fps == 0) {
return default_fps;
}
return *input_fps;
}
void VideoStreamEncoder::SetEncoderRates(
const EncoderRateSettings& rate_settings) {
RTC_DCHECK_GT(rate_settings.rate_control.framerate_fps, 0.0);
bool rate_control_changed =
(!last_encoder_rate_settings_.has_value() ||
last_encoder_rate_settings_->rate_control != rate_settings.rate_control);
// For layer allocation signal we care only about the target bitrate (not the
// adjusted one) and the target fps.
bool layer_allocation_changed =
!last_encoder_rate_settings_.has_value() ||
last_encoder_rate_settings_->rate_control.target_bitrate !=
rate_settings.rate_control.target_bitrate ||
last_encoder_rate_settings_->rate_control.framerate_fps !=
rate_settings.rate_control.framerate_fps;
if (last_encoder_rate_settings_ != rate_settings) {
last_encoder_rate_settings_ = rate_settings;
}
if (!encoder_) {
return;
}
// |bitrate_allocation| is 0 it means that the network is down or the send
// pacer is full. We currently only report this if the encoder has an internal
// source. If the encoder does not have an internal source, higher levels
// are expected to not call AddVideoFrame. We do this since its unclear
// how current encoder implementations behave when given a zero target
// bitrate.
// TODO(perkj): Make sure all known encoder implementations handle zero
// target bitrate and remove this check.
if (!HasInternalSource() &&
rate_settings.rate_control.bitrate.get_sum_bps() == 0) {
return;
}
if (rate_control_changed) {
encoder_->SetRates(rate_settings.rate_control);
encoder_stats_observer_->OnBitrateAllocationUpdated(
send_codec_, rate_settings.rate_control.bitrate);
frame_encode_metadata_writer_.OnSetRates(
rate_settings.rate_control.bitrate,
static_cast<uint32_t>(rate_settings.rate_control.framerate_fps + 0.5));
stream_resource_manager_.SetEncoderRates(rate_settings.rate_control);
if (layer_allocation_changed &&
settings_.allocation_cb_type ==
VideoStreamEncoderSettings::BitrateAllocationCallbackType::
kVideoLayersAllocation) {
sink_->OnVideoLayersAllocationUpdated(CreateVideoLayersAllocation(
send_codec_, rate_settings.rate_control, encoder_->GetEncoderInfo()));
}
}
if ((settings_.allocation_cb_type ==
VideoStreamEncoderSettings::BitrateAllocationCallbackType::
kVideoBitrateAllocation) ||
(encoder_config_.content_type ==
VideoEncoderConfig::ContentType::kScreen &&
settings_.allocation_cb_type ==
VideoStreamEncoderSettings::BitrateAllocationCallbackType::
kVideoBitrateAllocationWhenScreenSharing)) {
sink_->OnBitrateAllocationUpdated(
// Update allocation according to info from encoder. An encoder may
// choose to not use all layers due to for example HW.
UpdateAllocationFromEncoderInfo(
rate_settings.rate_control.target_bitrate,
encoder_->GetEncoderInfo()));
}
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
int64_t time_when_posted_us) {
RTC_DCHECK_RUN_ON(&encoder_queue_);
input_state_provider_.OnFrameSizeObserved(video_frame.size());
if (!last_frame_info_ || video_frame.width() != last_frame_info_->width ||
video_frame.height() != last_frame_info_->height ||
video_frame.is_texture() != last_frame_info_->is_texture) {
pending_encoder_reconfiguration_ = true;
last_frame_info_ = VideoFrameInfo(video_frame.width(), video_frame.height(),
video_frame.is_texture());
RTC_LOG(LS_INFO) << "Video frame parameters changed: dimensions="
<< last_frame_info_->width << "x"
<< last_frame_info_->height
<< ", texture=" << last_frame_info_->is_texture << ".";
// Force full frame update, since resolution has changed.
accumulated_update_rect_ =
VideoFrame::UpdateRect{0, 0, video_frame.width(), video_frame.height()};
}
// We have to create then encoder before the frame drop logic,
// because the latter depends on encoder_->GetScalingSettings.
// According to the testcase
// InitialFrameDropOffWhenEncoderDisabledScaling, the return value
// from GetScalingSettings should enable or disable the frame drop.
// Update input frame rate before we start using it. If we update it after
// any potential frame drop we are going to artificially increase frame sizes.
// Poll the rate before updating, otherwise we risk the rate being estimated
// a little too high at the start of the call when then window is small.
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
uint32_t framerate_fps = GetInputFramerateFps();
input_framerate_.Update(1u, clock_->TimeInMilliseconds());
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
int64_t now_ms = clock_->TimeInMilliseconds();
if (pending_encoder_reconfiguration_) {
ReconfigureEncoder();
last_parameters_update_ms_.emplace(now_ms);
} else if (!last_parameters_update_ms_ ||
now_ms - *last_parameters_update_ms_ >=
kParameterUpdateIntervalMs) {
if (last_encoder_rate_settings_) {
// Clone rate settings before update, so that SetEncoderRates() will
// actually detect the change between the input and
// |last_encoder_rate_setings_|, triggering the call to SetRate() on the
// encoder.
EncoderRateSettings new_rate_settings = *last_encoder_rate_settings_;
new_rate_settings.rate_control.framerate_fps =
static_cast<double>(framerate_fps);
SetEncoderRates(UpdateBitrateAllocation(new_rate_settings));
}
last_parameters_update_ms_.emplace(now_ms);
}
// Because pending frame will be dropped in any case, we need to
// remember its updated region.
if (pending_frame_) {
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kEncoderQueue);
accumulated_update_rect_.Union(pending_frame_->update_rect());
accumulated_update_rect_is_valid_ &= pending_frame_->has_update_rect();
}
if (DropDueToSize(video_frame.size())) {
RTC_LOG(LS_INFO) << "Dropping frame. Too large for target bitrate.";
stream_resource_manager_.OnFrameDroppedDueToSize();
// Storing references to a native buffer risks blocking frame capture.
if (video_frame.video_frame_buffer()->type() !=
VideoFrameBuffer::Type::kNative) {
pending_frame_ = video_frame;
pending_frame_post_time_us_ = time_when_posted_us;
} else {
// Ensure that any previously stored frame is dropped.
pending_frame_.reset();
accumulated_update_rect_.Union(video_frame.update_rect());
accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
}
Reland of Drop frames until specified bitrate is achieved. (patchset #1 id:1 of https://codereview.webrtc.org/2666303002/ ) Reason for revert: Perf test broke as it made assumptions that quality scaling was turned off. This turns out not to be the case. Fixed by turning quality scaling off for the tests. Original issue's description: > Revert of Drop frames until specified bitrate is achieved. (patchset #12 id:240001 of https://codereview.webrtc.org/2630333002/ ) > > Reason for revert: > due to failures on perf tests (not on perf stats, but fails running due to dcheck failures), see e.g., https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20(K%20Nexus5) > > Original issue's description: > > Drop frames until specified bitrate is achieved. > > > > This CL fixes a regression introduced with the new quality scaler > > where the video would no longer start in a scaled mode. This CL adds > > code that compares incoming captured frames to the target bitrate, > > and if they are found to be too large, they are dropped and sinkWants > > set to a lower resolution. The number of dropped frames should be low > > (0-4 in most cases) and should not introduce a noticeable delay, or > > at least should be preferrable to having the first 2-4 seconds of video > > have very low quality. > > > > BUG=webrtc:6953 > > > > Review-Url: https://codereview.webrtc.org/2630333002 > > Cr-Commit-Position: refs/heads/master@{#16391} > > Committed: https://chromium.googlesource.com/external/webrtc/+/83399caec5762d2dad038b8e9d86163e92c18c9f > > TBR=perkj@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,kthelgason@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:6953 > > Review-Url: https://codereview.webrtc.org/2666303002 > Cr-Commit-Position: refs/heads/master@{#16395} > Committed: https://chromium.googlesource.com/external/webrtc/+/35fc2aa82fb5a562f3f76f2b91a55f05ebfd4874 TBR=perkj@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,minyue@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:6953 Review-Url: https://codereview.webrtc.org/2675223002 Cr-Commit-Position: refs/heads/master@{#16473}
2017-02-07 07:02:22 -08:00
return;
}
stream_resource_manager_.OnMaybeEncodeFrame();
Reland of Drop frames until specified bitrate is achieved. (patchset #1 id:1 of https://codereview.webrtc.org/2666303002/ ) Reason for revert: Perf test broke as it made assumptions that quality scaling was turned off. This turns out not to be the case. Fixed by turning quality scaling off for the tests. Original issue's description: > Revert of Drop frames until specified bitrate is achieved. (patchset #12 id:240001 of https://codereview.webrtc.org/2630333002/ ) > > Reason for revert: > due to failures on perf tests (not on perf stats, but fails running due to dcheck failures), see e.g., https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20(K%20Nexus5) > > Original issue's description: > > Drop frames until specified bitrate is achieved. > > > > This CL fixes a regression introduced with the new quality scaler > > where the video would no longer start in a scaled mode. This CL adds > > code that compares incoming captured frames to the target bitrate, > > and if they are found to be too large, they are dropped and sinkWants > > set to a lower resolution. The number of dropped frames should be low > > (0-4 in most cases) and should not introduce a noticeable delay, or > > at least should be preferrable to having the first 2-4 seconds of video > > have very low quality. > > > > BUG=webrtc:6953 > > > > Review-Url: https://codereview.webrtc.org/2630333002 > > Cr-Commit-Position: refs/heads/master@{#16391} > > Committed: https://chromium.googlesource.com/external/webrtc/+/83399caec5762d2dad038b8e9d86163e92c18c9f > > TBR=perkj@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,kthelgason@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:6953 > > Review-Url: https://codereview.webrtc.org/2666303002 > Cr-Commit-Position: refs/heads/master@{#16395} > Committed: https://chromium.googlesource.com/external/webrtc/+/35fc2aa82fb5a562f3f76f2b91a55f05ebfd4874 TBR=perkj@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,minyue@webrtc.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=webrtc:6953 Review-Url: https://codereview.webrtc.org/2675223002 Cr-Commit-Position: refs/heads/master@{#16473}
2017-02-07 07:02:22 -08:00
if (EncoderPaused()) {
// Storing references to a native buffer risks blocking frame capture.
if (video_frame.video_frame_buffer()->type() !=
VideoFrameBuffer::Type::kNative) {
if (pending_frame_)
TraceFrameDropStart();
pending_frame_ = video_frame;
pending_frame_post_time_us_ = time_when_posted_us;
} else {
// Ensure that any previously stored frame is dropped.
pending_frame_.reset();
TraceFrameDropStart();
accumulated_update_rect_.Union(video_frame.update_rect());
accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
}
return;
}
pending_frame_.reset();
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
frame_dropper_.Leak(framerate_fps);
// Frame dropping is enabled iff frame dropping is not force-disabled, and
// rate controller is not trusted.
const bool frame_dropping_enabled =
!force_disable_frame_dropper_ &&
!encoder_info_.has_trusted_rate_controller;
frame_dropper_.Enable(frame_dropping_enabled);
if (frame_dropping_enabled && frame_dropper_.DropFrame()) {
RTC_LOG(LS_VERBOSE)
<< "Drop Frame: "
"target bitrate "
<< (last_encoder_rate_settings_
? last_encoder_rate_settings_->encoder_target.bps()
: 0)
<< ", input frame rate " << framerate_fps;
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
OnDroppedFrame(
EncodedImageCallback::DropReason::kDroppedByMediaOptimizations);
accumulated_update_rect_.Union(video_frame.update_rect());
accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
return;
}
EncodeVideoFrame(video_frame, time_when_posted_us);
}
void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
int64_t time_when_posted_us) {
RTC_DCHECK_RUN_ON(&encoder_queue_);
// If the encoder fail we can't continue to encode frames. When this happens
// the WebrtcVideoSender is notified and the whole VideoSendStream is
// recreated.
if (encoder_failed_)
return;
TraceFrameDropEnd();
// Encoder metadata needs to be updated before encode complete callback.
VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
if (info.implementation_name != encoder_info_.implementation_name) {
encoder_stats_observer_->OnEncoderImplementationChanged(
info.implementation_name);
if (bitrate_adjuster_) {
// Encoder implementation changed, reset overshoot detector states.
bitrate_adjuster_->Reset();
}
}
if (encoder_info_ != info) {
[Adaptation] Introduce VideoStreamInputState and its Provider. This CL is part of the Call-Level Adaptation Processing design doc: https://docs.google.com/document/d/1ZyC26yOCknrrcYa839ZWLxD6o6Gig5A3lVTh4E41074/edit?usp=sharing The "input state" of a VideoStream, needed for adaptation and decision-making, are: source resolution and frame rate, codec type and min pixels per frame (based on encoder scaling settings). These values are modified on the encoder queue of the VideoStreamEncoder. But in order to unblock call-level adaptation processing, where adaptation and decision making happens off the encoder queue, a snapshot of the input states need to be available at point of processing: introducing the VideoStreamInputState. In this CL, the VideoStreamInputStateProvider is added to provide input state snapshots across threads based on input from VideoStreamEncoder and VideoStreamEncoderObserver. The input state's HasInputFrameSizeAndFramesPerSecond() can now be DCHECKed inside the VideoStreamAdapter in favor of having less Adaptation::Status codes. Whether input is "sufficient" for adaptation is now the responsibility of the Processor. (Goal: adapter is purely a Adaptation generator and apply-er.) Somewhat tangental, this CL also deletes VideoStreamEncoder-specific methods from ResourceAdaptationProcessorInterface making them an implementation detail of ResourceAdaptationProcessor. In a future CL, the "processor" will be split up into a "processor" part and a "video stream encoder resource manager" part - more on that later. Bug: webrtc:11172 Change-Id: Id9b158f569db0140b75360aaf0f7e2e28fb924f4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/172928 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Cr-Commit-Position: refs/heads/master@{#31098}
2020-04-17 12:10:59 +02:00
OnEncoderSettingsChanged();
RTC_LOG(LS_INFO) << "Encoder settings changed from "
<< encoder_info_.ToString() << " to " << info.ToString();
}
if (bitrate_adjuster_) {
for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
if (info.fps_allocation[si] != encoder_info_.fps_allocation[si]) {
bitrate_adjuster_->OnEncoderInfo(info);
break;
}
}
}
encoder_info_ = info;
last_encode_info_ms_ = clock_->TimeInMilliseconds();
VideoFrame out_frame(video_frame);
if (out_frame.video_frame_buffer()->type() ==
VideoFrameBuffer::Type::kNative &&
!info.supports_native_handle) {
// This module only supports software encoding.
rtc::scoped_refptr<VideoFrameBuffer> buffer =
out_frame.video_frame_buffer()->GetMappedFrameBuffer(
info.preferred_pixel_formats);
bool buffer_was_converted = false;
if (!buffer) {
buffer = out_frame.video_frame_buffer()->ToI420();
// TODO(https://crbug.com/webrtc/12021): Once GetI420 is pure virtual,
// this just true as an I420 buffer would return from
// GetMappedFrameBuffer.
buffer_was_converted =
(out_frame.video_frame_buffer()->GetI420() == nullptr);
}
if (!buffer) {
RTC_LOG(LS_ERROR) << "Frame conversion failed, dropping frame.";
return;
}
VideoFrame::UpdateRect update_rect = out_frame.update_rect();
if (!update_rect.IsEmpty() &&
out_frame.video_frame_buffer()->GetI420() == nullptr) {
// UpdatedRect is reset to full update if it's not empty, and buffer was
// converted, therefore we can't guarantee that pixels outside of
// UpdateRect didn't change comparing to the previous frame.
update_rect =
VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
}
out_frame.set_video_frame_buffer(buffer);
out_frame.set_update_rect(update_rect);
}
// Crop frame if needed.
if ((crop_width_ > 0 || crop_height_ > 0) &&
out_frame.video_frame_buffer()->type() !=
VideoFrameBuffer::Type::kNative) {
// If the frame can't be converted to I420, drop it.
int cropped_width = video_frame.width() - crop_width_;
int cropped_height = video_frame.height() - crop_height_;
rtc::scoped_refptr<VideoFrameBuffer> cropped_buffer;
// TODO(ilnik): Remove scaling if cropping is too big, as it should never
// happen after SinkWants signaled correctly from ReconfigureEncoder.
VideoFrame::UpdateRect update_rect = video_frame.update_rect();
if (crop_width_ < 4 && crop_height_ < 4) {
cropped_buffer = video_frame.video_frame_buffer()->CropAndScale(
crop_width_ / 2, crop_height_ / 2, cropped_width, cropped_height,
cropped_width, cropped_height);
update_rect.offset_x -= crop_width_ / 2;
update_rect.offset_y -= crop_height_ / 2;
update_rect.Intersect(
VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height});
} else {
cropped_buffer = video_frame.video_frame_buffer()->Scale(cropped_width,
cropped_height);
if (!update_rect.IsEmpty()) {
// Since we can't reason about pixels after scaling, we invalidate whole
// picture, if anything changed.
update_rect =
VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height};
}
}
if (!cropped_buffer) {
RTC_LOG(LS_ERROR) << "Cropping and scaling frame failed, dropping frame.";
return;
}
out_frame.set_video_frame_buffer(cropped_buffer);
out_frame.set_update_rect(update_rect);
out_frame.set_ntp_time_ms(video_frame.ntp_time_ms());
// Since accumulated_update_rect_ is constructed before cropping,
// we can't trust it. If any changes were pending, we invalidate whole
// frame here.
if (!accumulated_update_rect_.IsEmpty()) {
accumulated_update_rect_ =
VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
accumulated_update_rect_is_valid_ = false;
}
}
if (!accumulated_update_rect_is_valid_) {
out_frame.clear_update_rect();
} else if (!accumulated_update_rect_.IsEmpty() &&
out_frame.has_update_rect()) {
accumulated_update_rect_.Union(out_frame.update_rect());
accumulated_update_rect_.Intersect(
VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()});
out_frame.set_update_rect(accumulated_update_rect_);
accumulated_update_rect_.MakeEmptyUpdate();
}
accumulated_update_rect_is_valid_ = true;
TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
"Encode");
stream_resource_manager_.OnEncodeStarted(out_frame, time_when_posted_us);
RTC_DCHECK_LE(send_codec_.width, out_frame.width());
RTC_DCHECK_LE(send_codec_.height, out_frame.height());
// Native frames should be scaled by the client.
// For internal encoders we scale everything in one place here.
RTC_DCHECK((out_frame.video_frame_buffer()->type() ==
VideoFrameBuffer::Type::kNative) ||
(send_codec_.width == out_frame.width() &&
send_codec_.height == out_frame.height()));
TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp",
out_frame.timestamp());
frame_encode_metadata_writer_.OnEncodeStarted(out_frame);
const int32_t encode_status = encoder_->Encode(out_frame, &next_frame_types_);
was_encode_called_since_last_initialization_ = true;
if (encode_status < 0) {
if (encode_status == WEBRTC_VIDEO_CODEC_ENCODER_FAILURE) {
RTC_LOG(LS_ERROR) << "Encoder failed, failing encoder format: "
<< encoder_config_.video_format.ToString();
if (settings_.encoder_switch_request_callback) {
if (encoder_selector_) {
if (auto encoder = encoder_selector_->OnEncoderBroken()) {
QueueRequestEncoderSwitch(*encoder);
}
} else {
encoder_failed_ = true;
main_queue_->PostTask(ToQueuedTask(task_safety_, [this]() {
RTC_DCHECK_RUN_ON(main_queue_);
settings_.encoder_switch_request_callback->RequestEncoderFallback();
}));
}
} else {
RTC_LOG(LS_ERROR)
<< "Encoder failed but no encoder fallback callback is registered";
}
} else {
RTC_LOG(LS_ERROR) << "Failed to encode frame. Error code: "
<< encode_status;
}
return;
}
for (auto& it : next_frame_types_) {
it = VideoFrameType::kVideoFrameDelta;
}
}
void VideoStreamEncoder::SendKeyFrame() {
if (!encoder_queue_.IsCurrent()) {
encoder_queue_.PostTask([this] { SendKeyFrame(); });
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
RTC_DCHECK(!next_frame_types_.empty());
// TODO(webrtc:10615): Map keyframe request to spatial layer.
std::fill(next_frame_types_.begin(), next_frame_types_.end(),
VideoFrameType::kVideoFrameKey);
if (HasInternalSource()) {
// Try to request the frame if we have an external encoder with
// internal source since AddVideoFrame never will be called.
// TODO(nisse): Used only with internal source. Delete as soon as
// that feature is removed. The only implementation I've been able
// to find ignores what's in the frame. With one exception: It seems
// a few test cases, e.g.,
// VideoSendStreamTest.VideoSendStreamStopSetEncoderRateToZero, set
// internal_source to true and use FakeEncoder. And the latter will
// happily encode this 1x1 frame and pass it on down the pipeline.
if (encoder_->Encode(VideoFrame::Builder()
.set_video_frame_buffer(I420Buffer::Create(1, 1))
.set_rotation(kVideoRotation_0)
.set_timestamp_us(0)
.build(),
&next_frame_types_) == WEBRTC_VIDEO_CODEC_OK) {
// Try to remove just-performed keyframe request, if stream still exists.
std::fill(next_frame_types_.begin(), next_frame_types_.end(),
VideoFrameType::kVideoFrameDelta);
}
}
}
void VideoStreamEncoder::OnLossNotification(
const VideoEncoder::LossNotification& loss_notification) {
if (!encoder_queue_.IsCurrent()) {
encoder_queue_.PostTask(
[this, loss_notification] { OnLossNotification(loss_notification); });
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (encoder_) {
encoder_->OnLossNotification(loss_notification);
}
}
EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage(
const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info) {
TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
"timestamp", encoded_image.Timestamp());
const size_t spatial_idx = encoded_image.SpatialIndex().value_or(0);
EncodedImage image_copy(encoded_image);
frame_encode_metadata_writer_.FillTimingInfo(spatial_idx, &image_copy);
frame_encode_metadata_writer_.UpdateBitstream(codec_specific_info,
&image_copy);
// Piggyback ALR experiment group id and simulcast id into the content type.
const uint8_t experiment_id =
experiment_groups_[videocontenttypehelpers::IsScreenshare(
image_copy.content_type_)];
// TODO(ilnik): This will force content type extension to be present even
// for realtime video. At the expense of miniscule overhead we will get
// sliced receive statistics.
RTC_CHECK(videocontenttypehelpers::SetExperimentId(&image_copy.content_type_,
experiment_id));
// We count simulcast streams from 1 on the wire. That's why we set simulcast
// id in content type to +1 of that is actual simulcast index. This is because
// value 0 on the wire is reserved for 'no simulcast stream specified'.
RTC_CHECK(videocontenttypehelpers::SetSimulcastId(
&image_copy.content_type_, static_cast<uint8_t>(spatial_idx + 1)));
Reland "Wire up internal libvpx VP9 scaler to statistics proxy" This reverts commit a2cb93d8b9659292f7ec73db53421d481f84c22c. Reason for revert: Reland with no changes after downstream projects are updated. Original change's description: > Revert "Wire up internal libvpx VP9 scaler to statistics proxy" > > This reverts commit 50327a51007c3e25bc3bcd35b5d0945fe0f27d05. > > Reason for revert: Breaks downstream tests > > Original change's description: > > Wire up internal libvpx VP9 scaler to statistics proxy > > > > Bug: webrtc:11396 > > Change-Id: I5ac69208b00cc75d4e5dbb3ab86f234b3e1f29f8 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169922 > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Reviewed-by: Henrik Boström <hbos@webrtc.org> > > Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#30725} > > TBR=ilnik@webrtc.org,hbos@webrtc.org,nisse@webrtc.org > > Change-Id: I53dcb41bdf8f8dccfcd43b717509ec047f590648 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:11396 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170102 > Reviewed-by: Sebastian Jansson <srte@webrtc.org> > Commit-Queue: Sebastian Jansson <srte@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#30734} TBR=ilnik@webrtc.org,hbos@webrtc.org,nisse@webrtc.org,srte@webrtc.org Change-Id: Ie47df4aec199701256c1dba8fa64176683becabc No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:11396 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170105 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30738}
2020-03-10 09:50:26 +00:00
// Currently internal quality scaler is used for VP9 instead of webrtc qp
// scaler (in no-svc case or if only a single spatial layer is encoded).
// It has to be explicitly detected and reported to adaptation metrics.
// Post a task because |send_codec_| requires |encoder_queue_| lock.
unsigned int image_width = image_copy._encodedWidth;
unsigned int image_height = image_copy._encodedHeight;
VideoCodecType codec = codec_specific_info
? codec_specific_info->codecType
: VideoCodecType::kVideoCodecGeneric;
encoder_queue_.PostTask([this, codec, image_width, image_height] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (codec == VideoCodecType::kVideoCodecVP9 &&
send_codec_.VP9()->automaticResizeOn) {
unsigned int expected_width = send_codec_.width;
unsigned int expected_height = send_codec_.height;
int num_active_layers = 0;
for (int i = 0; i < send_codec_.VP9()->numberOfSpatialLayers; ++i) {
if (send_codec_.spatialLayers[i].active) {
++num_active_layers;
expected_width = send_codec_.spatialLayers[i].width;
expected_height = send_codec_.spatialLayers[i].height;
}
}
RTC_DCHECK_LE(num_active_layers, 1)
<< "VP9 quality scaling is enabled for "
"SVC with several active layers.";
encoder_stats_observer_->OnEncoderInternalScalerUpdate(
image_width < expected_width || image_height < expected_height);
}
});
// Encoded is called on whatever thread the real encoder implementation run
// on. In the case of hardware encoders, there might be several encoders
// running in parallel on different threads.
encoder_stats_observer_->OnSendEncodedImage(image_copy, codec_specific_info);
// The simulcast id is signaled in the SpatialIndex. This makes it impossible
// to do simulcast for codecs that actually support spatial layers since we
// can't distinguish between an actual spatial layer and a simulcast stream.
// TODO(bugs.webrtc.org/10520): Signal the simulcast id explicitly.
int simulcast_id = 0;
if (codec_specific_info &&
(codec_specific_info->codecType == kVideoCodecVP8 ||
codec_specific_info->codecType == kVideoCodecH264 ||
codec_specific_info->codecType == kVideoCodecGeneric)) {
simulcast_id = encoded_image.SpatialIndex().value_or(0);
}
EncodedImageCallback::Result result =
sink_->OnEncodedImage(image_copy, codec_specific_info);
// We are only interested in propagating the meta-data about the image, not
// encoded data itself, to the post encode function. Since we cannot be sure
// the pointer will still be valid when run on the task queue, set it to null.
DataSize frame_size = DataSize::Bytes(image_copy.size());
image_copy.ClearEncodedData();
int temporal_index = 0;
if (codec_specific_info) {
if (codec_specific_info->codecType == kVideoCodecVP9) {
temporal_index = codec_specific_info->codecSpecific.VP9.temporal_idx;
} else if (codec_specific_info->codecType == kVideoCodecVP8) {
temporal_index = codec_specific_info->codecSpecific.VP8.temporalIdx;
}
}
if (temporal_index == kNoTemporalIdx) {
temporal_index = 0;
}
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RunPostEncode(image_copy, clock_->CurrentTime().us(), temporal_index,
frame_size);
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
if (result.error == Result::OK) {
// In case of an internal encoder running on a separate thread, the
// decision to drop a frame might be a frame late and signaled via
// atomic flag. This is because we can't easily wait for the worker thread
// without risking deadlocks, eg during shutdown when the worker thread
// might be waiting for the internal encoder threads to stop.
if (pending_frame_drops_.load() > 0) {
int pending_drops = pending_frame_drops_.fetch_sub(1);
RTC_DCHECK_GT(pending_drops, 0);
result.drop_next_frame = true;
}
}
return result;
}
void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
switch (reason) {
case DropReason::kDroppedByMediaOptimizations:
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kMediaOptimization);
break;
case DropReason::kDroppedByEncoder:
encoder_stats_observer_->OnFrameDropped(
VideoStreamEncoderObserver::DropReason::kEncoder);
break;
}
sink_->OnDroppedFrame(reason);
encoder_queue_.PostTask([this, reason] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
stream_resource_manager_.OnFrameDropped(reason);
});
}
DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate,
double cwnd_reduce_ratio) {
RTC_DCHECK_RUN_ON(&encoder_queue_);
DataRate updated_target_bitrate = target_bitrate;
// Drop frames when congestion window pushback ratio is larger than 1
// percent and target bitrate is larger than codec min bitrate.
// When target_bitrate is 0 means codec is paused, skip frame dropping.
if (cwnd_reduce_ratio > 0.01 && target_bitrate.bps() > 0 &&
target_bitrate.bps() > send_codec_.minBitrate * 1000) {
int reduce_bitrate_bps = std::min(
static_cast<int>(target_bitrate.bps() * cwnd_reduce_ratio),
static_cast<int>(target_bitrate.bps() - send_codec_.minBitrate * 1000));
if (reduce_bitrate_bps > 0) {
// At maximum the congestion window can drop 1/2 frames.
cwnd_frame_drop_interval_ = std::max(
2, static_cast<int>(target_bitrate.bps() / reduce_bitrate_bps));
// Reduce target bitrate accordingly.
updated_target_bitrate =
target_bitrate - (target_bitrate / cwnd_frame_drop_interval_.value());
return updated_target_bitrate;
}
}
cwnd_frame_drop_interval_.reset();
return updated_target_bitrate;
}
void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
DataRate stable_target_bitrate,
DataRate link_allocation,
uint8_t fraction_lost,
int64_t round_trip_time_ms,
double cwnd_reduce_ratio) {
RTC_DCHECK_GE(link_allocation, target_bitrate);
if (!encoder_queue_.IsCurrent()) {
encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate,
link_allocation, fraction_lost, round_trip_time_ms,
cwnd_reduce_ratio] {
DataRate updated_target_bitrate =
UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio);
OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate,
link_allocation, fraction_lost, round_trip_time_ms,
cwnd_reduce_ratio);
});
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
const bool video_is_suspended = target_bitrate == DataRate::Zero();
const bool video_suspension_changed = video_is_suspended != EncoderPaused();
if (!video_is_suspended && settings_.encoder_switch_request_callback) {
if (encoder_selector_) {
if (auto encoder =
encoder_selector_->OnAvailableBitrate(link_allocation)) {
QueueRequestEncoderSwitch(*encoder);
}
} else if (encoder_switch_experiment_.IsBitrateBelowThreshold(
target_bitrate) &&
!encoder_switch_requested_) {
EncoderSwitchRequestCallback::Config conf;
conf.codec_name = encoder_switch_experiment_.to_codec;
conf.param = encoder_switch_experiment_.to_param;
conf.value = encoder_switch_experiment_.to_value;
QueueRequestEncoderSwitch(conf);
encoder_switch_requested_ = true;
}
}
RTC_DCHECK(sink_) << "sink_ must be set before the encoder is active.";
RTC_LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << target_bitrate.bps()
<< " stable bitrate = " << stable_target_bitrate.bps()
<< " link allocation bitrate = " << link_allocation.bps()
<< " packet loss " << static_cast<int>(fraction_lost)
<< " rtt " << round_trip_time_ms;
if (encoder_) {
encoder_->OnPacketLossRateUpdate(static_cast<float>(fraction_lost) / 256.f);
encoder_->OnRttUpdate(round_trip_time_ms);
}
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
uint32_t framerate_fps = GetInputFramerateFps();
frame_dropper_.SetRates((target_bitrate.bps() + 500) / 1000, framerate_fps);
EncoderRateSettings new_rate_settings{
VideoBitrateAllocation(), static_cast<double>(framerate_fps),
link_allocation, target_bitrate, stable_target_bitrate};
SetEncoderRates(UpdateBitrateAllocation(new_rate_settings));
if (target_bitrate.bps() != 0)
encoder_target_bitrate_bps_ = target_bitrate.bps();
stream_resource_manager_.SetTargetBitrate(target_bitrate);
if (video_suspension_changed) {
RTC_LOG(LS_INFO) << "Video suspend state changed to: "
<< (video_is_suspended ? "suspended" : "not suspended");
encoder_stats_observer_->OnSuspendChange(video_is_suspended);
}
if (video_suspension_changed && !video_is_suspended && pending_frame_ &&
!DropDueToSize(pending_frame_->size())) {
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
int64_t pending_time_us =
clock_->CurrentTime().us() - pending_frame_post_time_us_;
if (pending_time_us < kPendingFrameTimeoutMs * 1000)
EncodeVideoFrame(*pending_frame_, pending_frame_post_time_us_);
pending_frame_.reset();
}
}
bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
if (!stream_resource_manager_.DropInitialFrames() ||
!encoder_target_bitrate_bps_.has_value()) {
return false;
}
bool simulcast_or_svc =
(send_codec_.codecType == VideoCodecType::kVideoCodecVP9 &&
send_codec_.VP9().numberOfSpatialLayers > 1) ||
(send_codec_.numberOfSimulcastStreams > 1 ||
encoder_config_.simulcast_layers.size() > 1);
if (simulcast_or_svc) {
if (stream_resource_manager_.SingleActiveStreamPixels()) {
pixel_count = stream_resource_manager_.SingleActiveStreamPixels().value();
} else {
return false;
}
}
absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
pixel_count);
if (encoder_bitrate_limits.has_value()) {
// Use bitrate limits provided by encoder.
return encoder_target_bitrate_bps_.value() <
static_cast<uint32_t>(encoder_bitrate_limits->min_start_bitrate_bps);
}
if (encoder_target_bitrate_bps_.value() < 300000 /* qvga */) {
return pixel_count > 320 * 240;
} else if (encoder_target_bitrate_bps_.value() < 500000 /* vga */) {
return pixel_count > 640 * 480;
}
return false;
}
Introduce ResourceAdaptationModuleListener and VideoSourceRestrictions. The VideoSourceRestrictions describe the maximum pixels per frame and max frame rate of a video source. This CL makes the ResourceAdaptationModuleInterface responsible for the reconfiguration of video sources. The VideoSourceRestrictions is the output of an adaptation module, and the ResourceAdaptationModuleListener handles the callback for when the source restrictions change. The OveruseFrameDetectorResourceAdaptationModule is updated to output its changes using these interfaces, and VideoStreamEncoder - now a listener - is made responsible for triggering the reconfiguring the video source. Performing the reconfiguration still requires interacting with the VideoSourceProxy - it is still partially responsible for keeping track of rtc::VideoSinkWants settings and performing AddOrUpdateSink(). For now this may look a bit weird: the VideoSourceProxy tells the VideoStreamEncoder about the new restrictions, and then the VideoStreamEncoder tells the VideoSourceProxy to apply these restrictions on the source/sink. This exercises the listener though, and unblocks the next CL. The next CL should move all "configuring the source" logic to the VideoStreamEncoder instead, so that the only information that is tracked by OveruseFrameDetectorResourceAdaptationModule is what it actually outputs to the listener. See the next CL (https://webrtc-review.googlesource.com/c/src/+/162802) where a VideoSourceController is introduced, to be owned by the VideoStreamEncoder rather than the adaptation module. Bug: webrtc:11222 Change-Id: I450ce74f51d96c4b98009a06134db671893d8fdc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/162522 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30227}
2020-01-10 15:44:01 +01:00
void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
VideoSourceRestrictions restrictions,
const VideoAdaptationCounters& adaptation_counters,
rtc::scoped_refptr<Resource> reason,
const VideoSourceRestrictions& unfiltered_restrictions) {
RTC_DCHECK_RUN_ON(&encoder_queue_);
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
RTC_LOG(INFO) << "Updating sink restrictions from "
<< (reason ? reason->Name() : std::string("<null>")) << " to "
<< restrictions.ToString();
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
main_queue_->PostTask(ToQueuedTask(
task_safety_, [this, restrictions = std::move(restrictions)]() {
RTC_DCHECK_RUN_ON(main_queue_);
video_source_sink_controller_.SetRestrictions(std::move(restrictions));
video_source_sink_controller_.PushSourceSinkSettings();
}));
Introduce ResourceAdaptationModuleListener and VideoSourceRestrictions. The VideoSourceRestrictions describe the maximum pixels per frame and max frame rate of a video source. This CL makes the ResourceAdaptationModuleInterface responsible for the reconfiguration of video sources. The VideoSourceRestrictions is the output of an adaptation module, and the ResourceAdaptationModuleListener handles the callback for when the source restrictions change. The OveruseFrameDetectorResourceAdaptationModule is updated to output its changes using these interfaces, and VideoStreamEncoder - now a listener - is made responsible for triggering the reconfiguring the video source. Performing the reconfiguration still requires interacting with the VideoSourceProxy - it is still partially responsible for keeping track of rtc::VideoSinkWants settings and performing AddOrUpdateSink(). For now this may look a bit weird: the VideoSourceProxy tells the VideoStreamEncoder about the new restrictions, and then the VideoStreamEncoder tells the VideoSourceProxy to apply these restrictions on the source/sink. This exercises the listener though, and unblocks the next CL. The next CL should move all "configuring the source" logic to the VideoStreamEncoder instead, so that the only information that is tracked by OveruseFrameDetectorResourceAdaptationModule is what it actually outputs to the listener. See the next CL (https://webrtc-review.googlesource.com/c/src/+/162802) where a VideoSourceController is introduced, to be owned by the VideoStreamEncoder rather than the adaptation module. Bug: webrtc:11222 Change-Id: I450ce74f51d96c4b98009a06134db671893d8fdc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/162522 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30227}
2020-01-10 15:44:01 +01:00
}
void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image,
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
int64_t time_sent_us,
int temporal_index,
DataSize frame_size) {
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
if (!encoder_queue_.IsCurrent()) {
encoder_queue_.PostTask([this, encoded_image, time_sent_us, temporal_index,
frame_size] {
RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size);
});
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
return;
}
RTC_DCHECK_RUN_ON(&encoder_queue_);
absl::optional<int> encode_duration_us;
if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
encode_duration_us =
// TODO(nisse): Maybe use capture_time_ms_ rather than encode_start_ms_?
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
TimeDelta::Millis(encoded_image.timing_.encode_finish_ms -
encoded_image.timing_.encode_start_ms)
.us();
}
// Run post encode tasks, such as overuse detection and frame rate/drop
// stats for internal encoders.
const bool keyframe =
encoded_image._frameType == VideoFrameType::kVideoFrameKey;
if (!frame_size.IsZero()) {
frame_dropper_.Fill(frame_size.bytes(), !keyframe);
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
if (HasInternalSource()) {
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
// Update frame dropper after the fact for internal sources.
input_framerate_.Update(1u, clock_->TimeInMilliseconds());
frame_dropper_.Leak(GetInputFramerateFps());
// Signal to encoder to drop next frame.
if (frame_dropper_.DropFrame()) {
pending_frame_drops_.fetch_add(1);
}
}
stream_resource_manager_.OnEncodeCompleted(encoded_image, time_sent_us,
encode_duration_us);
if (bitrate_adjuster_) {
bitrate_adjuster_->OnEncodedFrame(encoded_image, temporal_index);
}
Reland "Refactor and remove media_optimization::MediaOptimization." This reverts commit 6613f8e98ab3654ade7e8f5352d8d6711b157499. Reason for revert: This change seemed innocent after all, so undoing speculative revert. Original change's description: > Revert "Refactor and remove media_optimization::MediaOptimization." > > This reverts commit 07276e4f89a93b1479d7aeefa53b4fc32daf001b. > > Reason for revert: Speculative revert due to downstream crashes. > > Original change's description: > > Refactor and remove media_optimization::MediaOptimization. > > > > This CL removes MediaOptmization and folds some of its functionality > > into VideoStreamEncoder. > > > > The FPS tracking is now handled by a RateStatistics instance. Frame > > dropping is still handled by FrameDropper. Both of these now live > > directly in VideoStreamEncoder. > > There is no intended change in behavior from this CL, but due to a new > > way of measuring frame rate, some minor perf changes can be expected. > > > > A small change in behavior is that OnBitrateUpdated is now called > > directly rather than on the next frame. Since both encoding frame and > > setting rate allocations happen on the encoder worker thread, there's > > really no reason to cache bitrates and wait until the next frame. > > An edge case though is that if a new bitrate is set before the first > > frame, we must remember that bitrate and then apply it after the video > > bitrate allocator has been first created. > > > > In addition to existing unit tests, manual tests have been used to > > confirm that frame dropping works as expected with misbehaving encoders. > > > > Bug: webrtc:10164 > > Change-Id: I7ee9c8d3c4f2bcf23c8c420310b05a4d35d94744 > > Reviewed-on: https://webrtc-review.googlesource.com/c/115620 > > Commit-Queue: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#26147} > > TBR=nisse@webrtc.org,sprang@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10164 > Change-Id: Ie0dae19dd012bc09e793c9661a45823fd760c20c > Reviewed-on: https://webrtc-review.googlesource.com/c/116780 > Reviewed-by: Niels Moller <nisse@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Commit-Queue: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#26191} TBR=nisse@webrtc.org,sprang@webrtc.org Change-Id: Ieda1fad301de002460bb0bf5a75267ea065176a8 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:10164 Reviewed-on: https://webrtc-review.googlesource.com/c/116960 Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26213}
2019-01-11 11:11:10 +01:00
}
bool VideoStreamEncoder::HasInternalSource() const {
// TODO(sprang): Checking both info from encoder and from encoder factory
// until we have deprecated and removed the encoder factory info.
return codec_info_.has_internal_source || encoder_info_.has_internal_source;
}
void VideoStreamEncoder::ReleaseEncoder() {
if (!encoder_ || !encoder_initialized_) {
return;
}
encoder_->Release();
encoder_initialized_ = false;
TRACE_EVENT0("webrtc", "VCMGenericEncoder::Release");
}
bool VideoStreamEncoder::EncoderSwitchExperiment::IsBitrateBelowThreshold(
const DataRate& target_bitrate) {
DataRate rate = DataRate::KilobitsPerSec(
bitrate_filter.Apply(1.0, target_bitrate.kbps()));
return current_thresholds.bitrate && rate < *current_thresholds.bitrate;
}
bool VideoStreamEncoder::EncoderSwitchExperiment::IsPixelCountBelowThreshold(
int pixel_count) const {
return current_thresholds.pixel_count &&
pixel_count < *current_thresholds.pixel_count;
}
void VideoStreamEncoder::EncoderSwitchExperiment::SetCodec(
VideoCodecType codec) {
auto it = codec_thresholds.find(codec);
if (it == codec_thresholds.end()) {
current_thresholds = {};
} else {
current_thresholds = it->second;
}
}
VideoStreamEncoder::EncoderSwitchExperiment
VideoStreamEncoder::ParseEncoderSwitchFieldTrial() const {
EncoderSwitchExperiment result;
// Each "codec threshold" have the format
// "<codec name>;<bitrate kbps>;<pixel count>", and are separated by the "|"
// character.
webrtc::FieldTrialOptional<std::string> codec_thresholds_string{
"codec_thresholds"};
webrtc::FieldTrialOptional<std::string> to_codec{"to_codec"};
webrtc::FieldTrialOptional<std::string> to_param{"to_param"};
webrtc::FieldTrialOptional<std::string> to_value{"to_value"};
webrtc::FieldTrialOptional<double> window{"window"};
webrtc::ParseFieldTrial(
{&codec_thresholds_string, &to_codec, &to_param, &to_value, &window},
webrtc::field_trial::FindFullName(
"WebRTC-NetworkCondition-EncoderSwitch"));
if (!codec_thresholds_string || !to_codec || !window) {
return {};
}
result.bitrate_filter.Reset(1.0 - 1.0 / *window);
result.to_codec = *to_codec;
result.to_param = to_param.GetOptional();
result.to_value = to_value.GetOptional();
std::vector<std::string> codecs_thresholds;
if (rtc::split(*codec_thresholds_string, '|', &codecs_thresholds) == 0) {
return {};
}
for (const std::string& codec_threshold : codecs_thresholds) {
std::vector<std::string> thresholds_split;
if (rtc::split(codec_threshold, ';', &thresholds_split) != 3) {
return {};
}
VideoCodecType codec = PayloadStringToCodecType(thresholds_split[0]);
int bitrate_kbps;
rtc::FromString(thresholds_split[1], &bitrate_kbps);
int pixel_count;
rtc::FromString(thresholds_split[2], &pixel_count);
if (bitrate_kbps > 0) {
result.codec_thresholds[codec].bitrate =
DataRate::KilobitsPerSec(bitrate_kbps);
}
if (pixel_count > 0) {
result.codec_thresholds[codec].pixel_count = pixel_count;
}
if (!result.codec_thresholds[codec].bitrate &&
!result.codec_thresholds[codec].pixel_count) {
return {};
}
}
rtc::StringBuilder ss;
ss << "Successfully parsed WebRTC-NetworkCondition-EncoderSwitch field "
"trial."
" to_codec:"
<< result.to_codec << " to_param:" << result.to_param.value_or("<none>")
<< " to_value:" << result.to_value.value_or("<none>")
<< " codec_thresholds:";
for (auto kv : result.codec_thresholds) {
std::string codec_name = CodecTypeToPayloadString(kv.first);
std::string bitrate = kv.second.bitrate
? std::to_string(kv.second.bitrate->kbps())
: "<none>";
std::string pixels = kv.second.pixel_count
? std::to_string(*kv.second.pixel_count)
: "<none>";
ss << " (" << codec_name << ":" << bitrate << ":" << pixels << ")";
}
RTC_LOG(LS_INFO) << ss.str();
return result;
}
VideoStreamEncoder::AutomaticAnimationDetectionExperiment
VideoStreamEncoder::ParseAutomatincAnimationDetectionFieldTrial() const {
AutomaticAnimationDetectionExperiment result;
result.Parser()->Parse(webrtc::field_trial::FindFullName(
"WebRTC-AutomaticAnimationDetectionScreenshare"));
if (!result.enabled) {
RTC_LOG(LS_INFO) << "Automatic animation detection experiment is disabled.";
return result;
}
RTC_LOG(LS_INFO) << "Automatic animation detection experiment settings:"
" min_duration_ms="
<< result.min_duration_ms
<< " min_area_ration=" << result.min_area_ratio
<< " min_fps=" << result.min_fps;
return result;
}
void VideoStreamEncoder::CheckForAnimatedContent(
const VideoFrame& frame,
int64_t time_when_posted_in_us) {
if (!automatic_animation_detection_experiment_.enabled ||
encoder_config_.content_type !=
VideoEncoderConfig::ContentType::kScreen ||
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
stream_resource_manager_.degradation_preference() !=
DegradationPreference::BALANCED) {
return;
}
if (expect_resize_state_ == ExpectResizeState::kResize && last_frame_info_ &&
last_frame_info_->width != frame.width() &&
last_frame_info_->height != frame.height()) {
// On applying resolution cap there will be one frame with no/different
// update, which should be skipped.
// It can be delayed by several frames.
expect_resize_state_ = ExpectResizeState::kFirstFrameAfterResize;
return;
}
if (expect_resize_state_ == ExpectResizeState::kFirstFrameAfterResize) {
// The first frame after resize should have new, scaled update_rect.
if (frame.has_update_rect()) {
last_update_rect_ = frame.update_rect();
} else {
last_update_rect_ = absl::nullopt;
}
expect_resize_state_ = ExpectResizeState::kNoResize;
}
bool should_cap_resolution = false;
if (!frame.has_update_rect()) {
last_update_rect_ = absl::nullopt;
animation_start_time_ = Timestamp::PlusInfinity();
} else if ((!last_update_rect_ ||
frame.update_rect() != *last_update_rect_)) {
last_update_rect_ = frame.update_rect();
Use newer version of TimeDelta and TimeStamp factories in webrtc find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Micros<\(.*\)>()/TimeDelta::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Millis<\(.*\)>()/TimeDelta::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Seconds<\(.*\)>()/TimeDelta::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::us/TimeDelta::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::ms/TimeDelta::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::seconds/TimeDelta::Seconds/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Micros<\(.*\)>()/Timestamp::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Millis<\(.*\)>()/Timestamp::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Seconds<\(.*\)>()/Timestamp::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::us/Timestamp::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::ms/Timestamp::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::seconds/Timestamp::Seconds/g" git cl format Bug: None Change-Id: I87469d2e4a38369654da839ab7c838215a7911e7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168402 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30491}
2020-02-10 11:16:00 +01:00
animation_start_time_ = Timestamp::Micros(time_when_posted_in_us);
} else {
TimeDelta animation_duration =
Use newer version of TimeDelta and TimeStamp factories in webrtc find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Micros<\(.*\)>()/TimeDelta::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Millis<\(.*\)>()/TimeDelta::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::Seconds<\(.*\)>()/TimeDelta::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::us/TimeDelta::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::ms/TimeDelta::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/TimeDelta::seconds/TimeDelta::Seconds/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Micros<\(.*\)>()/Timestamp::Micros(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Millis<\(.*\)>()/Timestamp::Millis(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::Seconds<\(.*\)>()/Timestamp::Seconds(\1)/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::us/Timestamp::Micros/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::ms/Timestamp::Millis/g" find . -type f \( -name "*.h" -o -name "*.cc" \) | xargs sed -i -e "s/Timestamp::seconds/Timestamp::Seconds/g" git cl format Bug: None Change-Id: I87469d2e4a38369654da839ab7c838215a7911e7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168402 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30491}
2020-02-10 11:16:00 +01:00
Timestamp::Micros(time_when_posted_in_us) - animation_start_time_;
float area_ratio = static_cast<float>(last_update_rect_->width *
last_update_rect_->height) /
(frame.width() * frame.height());
if (animation_duration.ms() >=
automatic_animation_detection_experiment_.min_duration_ms &&
area_ratio >=
automatic_animation_detection_experiment_.min_area_ratio &&
encoder_stats_observer_->GetInputFrameRate() >=
automatic_animation_detection_experiment_.min_fps) {
should_cap_resolution = true;
}
}
if (cap_resolution_due_to_video_content_ != should_cap_resolution) {
expect_resize_state_ = should_cap_resolution ? ExpectResizeState::kResize
: ExpectResizeState::kNoResize;
cap_resolution_due_to_video_content_ = should_cap_resolution;
if (should_cap_resolution) {
RTC_LOG(LS_INFO) << "Applying resolution cap due to animation detection.";
} else {
RTC_LOG(LS_INFO) << "Removing resolution cap due to no consistent "
"animation detection.";
}
Remove use of asyncinvoker from WebRtcVideoSendStream. This turned out to be a bit complicated, mostly related to the tests, but here's what's changed: * No AsyncInvoker (and avoid ClearInternal) in WebRtcVideoSendStream (WVSS) * The reason it was there is due to a "design leak" from VideoSourceSinkController/VideoStreamEncoder where the former uses locks in all methods and is unaware of a threading model. That design affected downstream objects, pushed the need for an async hop into WVSS and added a lock. A suggestion was made to address this in a follow-up change, here: https://webrtc-review.googlesource.com/c/src/+/165684 * All methods in VideoSourceSinkController are now called on a known and checked sequence and this CL removes the lock. This also makes checking state consistent (i.e. calling a getter twice in a row on the same sequence, will always return the same value, avoiding race with other threads). * Handling of reporting state changes from the encoder queue to the VSSC, is done by VideoStreamEncoder. * VideoSendStreamImpl is still instantiated on the incorrect thread [1] but has two initialization steps [2]. The second one already runs on the right thread. Addressing that TODO [1] is something we should do but it has side effects to consider. For the purposes of this CL the steps relating to the encoder (setting the sink pointer) have been moved to [2]. [1] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;l=94 [2] https://source.chromium.org/chromium/chromium/src/+/master:third_party/webrtc/video/video_send_stream.cc;drc=f4a9991cce74a37d006438ec0e366313ed33162e;l=115 Bug: webrtc:11222, webrtc:11908 Change-Id: Ie46d46e3a52bbe225951b4bd580ecb8cc9cad873 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184508 Reviewed-by: Henrik Boström <hbos@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32150}
2020-09-21 14:31:23 +02:00
main_queue_->PostTask(ToQueuedTask(task_safety_, [this,
should_cap_resolution]() {
RTC_DCHECK_RUN_ON(main_queue_);
video_source_sink_controller_.SetPixelsPerFrameUpperLimit(
should_cap_resolution ? absl::optional<size_t>(kMaxAnimationPixels)
: absl::nullopt);
video_source_sink_controller_.PushSourceSinkSettings();
}));
}
}
// RTC_RUN_ON(&encoder_queue_)
void VideoStreamEncoder::QueueRequestEncoderSwitch(
const EncoderSwitchRequestCallback::Config& conf) {
main_queue_->PostTask(ToQueuedTask(task_safety_, [this, conf]() {
RTC_DCHECK_RUN_ON(main_queue_);
settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf);
}));
}
// RTC_RUN_ON(&encoder_queue_)
void VideoStreamEncoder::QueueRequestEncoderSwitch(
const webrtc::SdpVideoFormat& format) {
main_queue_->PostTask(ToQueuedTask(task_safety_, [this, format]() {
RTC_DCHECK_RUN_ON(main_queue_);
settings_.encoder_switch_request_callback->RequestEncoderSwitch(format);
}));
}
void VideoStreamEncoder::InjectAdaptationResource(
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
rtc::scoped_refptr<Resource> resource,
VideoAdaptationReason reason) {
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
rtc::Event map_resource_event;
encoder_queue_.PostTask([this, resource, reason, &map_resource_event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
additional_resources_.push_back(resource);
stream_resource_manager_.AddResource(resource, reason);
map_resource_event.Set();
});
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
map_resource_event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::InjectAdaptationConstraint(
AdaptationConstraint* adaptation_constraint) {
rtc::Event event;
encoder_queue_.PostTask([this, adaptation_constraint, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
if (!resource_adaptation_processor_) {
// The VideoStreamEncoder was stopped and the processor destroyed before
// this task had a chance to execute. No action needed.
return;
}
adaptation_constraints_.push_back(adaptation_constraint);
video_stream_adapter_->AddAdaptationConstraint(adaptation_constraint);
event.Set();
[Adaptation] Make Resources reference counted and add more DCHECKs. In a future CL, adaptation processing and stream encoder resource management will happen on different task queues. When this is the case, asynchronous tasks will be posted in both directions and some resources will have internal states used on multiple threads. This CL makes the Resource class reference counted in order to support posting tasks to a different threads without risk of use-after-free when a posted task is executed with a delay. This is preferred over WeakPtr strategies because WeakPtrs are single-threaded and preferred over raw pointer usage because the reference counted approach enables more compile-time and run-time assurance. This is also "future proof"; when resources can be injected through public APIs, ownership needs to be shared between libwebrtc and the application (e.g. Chrome). To reduce the risk of making mistakes in the future CL, sequence checkers and task queue DCHECKs are added as well as other DCHECKs to make sure things have been cleaned up before destruction, e.g: - Processor gets a sequence checker. It is entirely single-threaded. - Processor must not have any attached listeners or resources on destruction. - Resources must not have any listeners on destruction. - The Manager, EncodeUsageResource and QualityScalerResource DCHECKs they are running on the encoder queue. - TODOs are added illustrating where we want to add PostTasks in the future CL. Lastly, upon VideoStreamEncoder::Stop() we delete the ResourceAdaptationProcessor. Because the Processor is already used in posted tasks, some if statements are added to ensure the Processor is not used after destruction. Bug: webrtc:11542, webrtc:11520 Change-Id: Ibaa8a61d86d87a71f477d1075a117c28d9d2d285 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174760 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31217}
2020-05-11 16:29:22 +02:00
});
event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::AddRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
rtc::Event event;
encoder_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
event.Set();
});
event.Wait(rtc::Event::kForever);
}
void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
VideoSourceRestrictionsListener* restrictions_listener) {
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
rtc::Event event;
encoder_queue_.PostTask([this, restrictions_listener, &event] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
RTC_DCHECK(resource_adaptation_processor_);
video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
[Adaptation] Move adaptation logic to a separate task queue. This CL unblocks future Call-Level Mitigation strategies by moving the ResourceAdaptationProcessor to a separate task queue. This signifies a major milestone in the new resource adaptation architecture because with this CL the threading model is in place and moving the Processor to the Call and increasing its responsibilities is made possible. In this CL, we still have one Processor per VideoStreamEncoder and the VideoStreamEncoder is responsible for the creation and the destruction of its Processor and that Processor's task queue. But the PostTasks are in place and the decision-making is executed on a separate queue. This CL: - Moves ResourceAdaptationProcessor to an adaptation task queue. It continues to be entirely single-threaded, but now operates on a separate task queue. - Makes Resources thread-safe: Interaction with the Processor, i.e. OnResourceUsageStateMeasured() and IsAdaptationUpAllowed(), happens on the adaptation task queue. State updates are pushed from the encoder task queue with PostTasks. - QualityScalerResource operates on both task queues; the QP usage callbacks are invoked asynchronously. - The VideoStreamEncoderResourceManager operates on the encoder task queue with the following exceptions: 1) Its resources are accessible on any thread (using a mutex). This is OK because resources are reference counted and thread safe. This aids adding and removing resources to the Processor on the adaptation task queue. 2) |active_counts_| is moved to the adaptation task queue. This makes it possible for PreventAdaptUpDueToActiveCounts to run IsAdaptationUpAllowed() on the adaptation task queue. A side-effect of this is that some stats reporting now happen on the adaptation task queue, but that is OK because VideoStreamEncoderObserver is thread-safe. The Manager is updated to take the new threading model into account: - OnFrameDroppedDueToSize() posts to the adaptation task queue to invoke the Processor. - OnVideoSourceRestrictionsUpdated(), now invoked on the adaptation task queue, updates |active_counts_| synchronously but posts to the encoder task queue to update video source restrictions (which it only uses to calculate target frame rate). - MaybePerformQualityRampupExperiment() posts to the adaptation task queue to maybe reset video source restrictions on the Processor. |quality_rampup_done_| is made std::atomic. Bug: webrtc:11542, webrtc:11520 Change-Id: I1cfd76e0cd42f006a6d2527f5aa2aeb5266ba6d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174441 Reviewed-by: Evan Shrubsole <eshr@google.com> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31231}
2020-05-12 18:49:07 +02:00
event.Set();
});
event.Wait(rtc::Event::kForever);
}
} // namespace webrtc