Move TemporalLayers to api/video_codecs.
Also renaming it Vp8TemporalLayers to show that it is codec specific. Bug: webrtc:9012 Change-Id: I18187538b8142cdd7538f1a4ed1bada09d040f1f Reviewed-on: https://webrtc-review.googlesource.com/c/104643 Commit-Queue: Erik Språng <sprang@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25137}
This commit is contained in:
parent
28d200c246
commit
4529fbcfab
@ -28,6 +28,7 @@ rtc_source_set("video_codecs_api") {
|
||||
"video_encoder_config.cc",
|
||||
"video_encoder_config.h",
|
||||
"video_encoder_factory.h",
|
||||
"vp8_temporal_layers.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
@ -80,6 +81,24 @@ rtc_static_library("builtin_video_encoder_factory") {
|
||||
]
|
||||
}
|
||||
|
||||
rtc_static_library("create_vp8_temporal_layers") {
|
||||
visibility = [ "*" ]
|
||||
allow_poison = [ "software_video_codecs" ]
|
||||
sources = [
|
||||
"create_vp8_temporal_layers.cc",
|
||||
"create_vp8_temporal_layers.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":video_codecs_api",
|
||||
"../..:webrtc_common",
|
||||
"../../modules/video_coding:video_codec_interface",
|
||||
"../../modules/video_coding:webrtc_vp8_temporal_layers",
|
||||
"../../system_wrappers:system_wrappers",
|
||||
"//third_party/abseil-cpp/absl/memory:memory",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_static_library("rtc_software_fallback_wrappers") {
|
||||
visibility = [ "*" ]
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
/*
|
||||
* Copyright (c) 2018 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
|
||||
@ -7,32 +8,22 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
|
||||
#include "api/video_codecs/create_vp8_temporal_layers.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/screenshare_layers.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
bool TemporalLayers::FrameConfig::operator==(const FrameConfig& o) const {
|
||||
return drop_frame == o.drop_frame &&
|
||||
last_buffer_flags == o.last_buffer_flags &&
|
||||
golden_buffer_flags == o.golden_buffer_flags &&
|
||||
arf_buffer_flags == o.arf_buffer_flags && layer_sync == o.layer_sync &&
|
||||
freeze_entropy == o.freeze_entropy &&
|
||||
encoder_layer_id == o.encoder_layer_id &&
|
||||
packetizer_temporal_idx == o.packetizer_temporal_idx;
|
||||
}
|
||||
|
||||
std::unique_ptr<TemporalLayers> TemporalLayers::CreateTemporalLayers(
|
||||
TemporalLayersType type,
|
||||
std::unique_ptr<Vp8TemporalLayers> CreateVp8TemporalLayers(
|
||||
Vp8TemporalLayersType type,
|
||||
int num_temporal_layers) {
|
||||
switch (type) {
|
||||
case TemporalLayersType::kFixedPattern:
|
||||
case Vp8TemporalLayersType::kFixedPattern:
|
||||
return absl::make_unique<DefaultTemporalLayers>(num_temporal_layers);
|
||||
case TemporalLayersType::kBitrateDynamic:
|
||||
case Vp8TemporalLayersType::kBitrateDynamic:
|
||||
// Conference mode temporal layering for screen content in base stream.
|
||||
return absl::make_unique<ScreenshareLayers>(num_temporal_layers,
|
||||
Clock::GetRealTimeClock());
|
||||
26
api/video_codecs/create_vp8_temporal_layers.h
Normal file
26
api/video_codecs/create_vp8_temporal_layers.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.
|
||||
*/
|
||||
|
||||
#ifndef API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
|
||||
#define API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<Vp8TemporalLayers> CreateVp8TemporalLayers(
|
||||
Vp8TemporalLayersType type,
|
||||
int num_temporal_layers);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_VIDEO_CODECS_CREATE_VP8_TEMPORAL_LAYERS_H_
|
||||
@ -8,14 +8,13 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video/video_bitrate_allocation.h"
|
||||
#include "api/video_codecs/video_encoder_software_fallback_wrapper.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "modules/video_coding/include/video_error_codes.h"
|
||||
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
|
||||
#define MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
|
||||
#ifndef API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
#define API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@ -17,8 +17,8 @@
|
||||
namespace webrtc {
|
||||
|
||||
// Some notes on the prerequisites of the TemporalLayers interface.
|
||||
// * Implementations of TemporalLayers may not contain internal synchronization
|
||||
// so caller must make sure doing so thread safe.
|
||||
// * Vp8TemporalLayers is not thread safe, synchronization is the caller's
|
||||
// responsibility.
|
||||
// * The encoder is assumed to encode all frames in order, and callbacks to
|
||||
// PopulateCodecSpecific() / FrameEncoded() must happen in the same order.
|
||||
//
|
||||
@ -36,15 +36,13 @@ namespace webrtc {
|
||||
// FrameEncoded() for a previous one, but calls themselves must be both
|
||||
// synchronized (e.g. run on a task queue) and in order (per type).
|
||||
|
||||
enum class TemporalLayersType { kFixedPattern, kBitrateDynamic };
|
||||
// Two different flavors of temporal layers are currently available:
|
||||
// kFixedPattern uses a fixed repeating pattern of 1-4 layers.
|
||||
// kBitrateDynamic can allocate frames dynamically to 1 or 2 layers, based on
|
||||
// the bitrate produced.
|
||||
enum class Vp8TemporalLayersType { kFixedPattern, kBitrateDynamic };
|
||||
|
||||
struct CodecSpecificInfoVP8;
|
||||
enum class Vp8BufferReference : uint8_t {
|
||||
kNone = 0,
|
||||
kLast = 1,
|
||||
kGolden = 2,
|
||||
kAltref = 4
|
||||
};
|
||||
|
||||
struct Vp8EncoderConfig {
|
||||
static constexpr size_t kMaxPeriodicity = 16;
|
||||
@ -72,9 +70,17 @@ struct Vp8EncoderConfig {
|
||||
uint32_t rc_max_quantizer;
|
||||
};
|
||||
|
||||
// Defined bit-maskable reference to the three buffers available in VP8.
|
||||
enum class Vp8BufferReference : uint8_t {
|
||||
kNone = 0,
|
||||
kLast = 1,
|
||||
kGolden = 2,
|
||||
kAltref = 4
|
||||
};
|
||||
|
||||
// This interface defines a way of getting the encoder settings needed to
|
||||
// realize a temporal layer structure of predefined size.
|
||||
class TemporalLayers {
|
||||
// realize a temporal layer structure.
|
||||
class Vp8TemporalLayers {
|
||||
public:
|
||||
enum BufferFlags : int {
|
||||
kNone = 0,
|
||||
@ -124,9 +130,6 @@ class TemporalLayers {
|
||||
Vp8BufferReference first_reference;
|
||||
Vp8BufferReference second_reference;
|
||||
|
||||
bool operator==(const FrameConfig& o) const;
|
||||
bool operator!=(const FrameConfig& o) const { return !(*this == o); }
|
||||
|
||||
private:
|
||||
FrameConfig(BufferFlags last,
|
||||
BufferFlags golden,
|
||||
@ -134,13 +137,7 @@ class TemporalLayers {
|
||||
bool freeze_entropy);
|
||||
};
|
||||
|
||||
// Factory for TemporalLayer strategy. Default behavior is a fixed pattern
|
||||
// of temporal layers. See default_temporal_layers.cc
|
||||
static std::unique_ptr<TemporalLayers> CreateTemporalLayers(
|
||||
TemporalLayersType type,
|
||||
int num_temporal_layers);
|
||||
|
||||
virtual ~TemporalLayers() = default;
|
||||
virtual ~Vp8TemporalLayers() = default;
|
||||
|
||||
// If this method returns true, the encoder is free to drop frames for
|
||||
// instance in an effort to uphold encoding bitrate.
|
||||
@ -195,4 +192,4 @@ class TemporalLayers {
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_TEMPORAL_LAYERS_H_
|
||||
#endif // API_VIDEO_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
@ -10,12 +10,11 @@
|
||||
*/
|
||||
|
||||
#include "media/engine/vp8_encoder_simulcast_proxy.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "api/test/mock_video_encoder_factory.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "media/engine/webrtcvideoencoderfactory.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
@ -393,22 +393,13 @@ rtc_static_library("webrtc_vp8") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "software_video_codecs" ]
|
||||
sources = [
|
||||
"codecs/vp8/default_temporal_layers.cc",
|
||||
"codecs/vp8/default_temporal_layers.h",
|
||||
"codecs/vp8/include/temporal_layers_checker.h",
|
||||
"codecs/vp8/include/vp8.h",
|
||||
"codecs/vp8/include/vp8_temporal_layers.h",
|
||||
"codecs/vp8/libvpx_interface.cc",
|
||||
"codecs/vp8/libvpx_interface.h",
|
||||
"codecs/vp8/libvpx_vp8_decoder.cc",
|
||||
"codecs/vp8/libvpx_vp8_decoder.h",
|
||||
"codecs/vp8/libvpx_vp8_encoder.cc",
|
||||
"codecs/vp8/libvpx_vp8_encoder.h",
|
||||
"codecs/vp8/screenshare_layers.cc",
|
||||
"codecs/vp8/screenshare_layers.h",
|
||||
"codecs/vp8/temporal_layers.h",
|
||||
"codecs/vp8/temporal_layers_checker.cc",
|
||||
"codecs/vp8/vp8_temporal_layers.cc",
|
||||
]
|
||||
|
||||
if (!build_with_chromium && is_clang) {
|
||||
@ -420,10 +411,12 @@ rtc_static_library("webrtc_vp8") {
|
||||
":codec_globals_headers",
|
||||
":video_codec_interface",
|
||||
":video_coding_utility",
|
||||
":webrtc_vp8_temporal_layers",
|
||||
"..:module_api",
|
||||
"../..:webrtc_common",
|
||||
"../../api/video:encoded_image",
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video_codecs:create_vp8_temporal_layers",
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../common_video",
|
||||
"../../rtc_base:checks",
|
||||
@ -441,6 +434,41 @@ rtc_static_library("webrtc_vp8") {
|
||||
}
|
||||
}
|
||||
|
||||
rtc_static_library("webrtc_vp8_temporal_layers") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
"codecs/vp8/default_temporal_layers.cc",
|
||||
"codecs/vp8/default_temporal_layers.h",
|
||||
"codecs/vp8/include/temporal_layers_checker.h",
|
||||
"codecs/vp8/screenshare_layers.cc",
|
||||
"codecs/vp8/screenshare_layers.h",
|
||||
"codecs/vp8/temporal_layers.h",
|
||||
"codecs/vp8/temporal_layers_checker.cc",
|
||||
]
|
||||
|
||||
if (!build_with_chromium && is_clang) {
|
||||
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
|
||||
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":codec_globals_headers",
|
||||
":video_codec_interface",
|
||||
":video_coding_utility",
|
||||
"..:module_api",
|
||||
"../..:webrtc_common",
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:rtc_numerics",
|
||||
"../../system_wrappers",
|
||||
"../../system_wrappers:field_trial",
|
||||
"../../system_wrappers:metrics",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
|
||||
# This target includes VP9 files that may be used for any VP9 codec, internal SW or external HW.
|
||||
rtc_static_library("webrtc_vp9_helpers") {
|
||||
sources = [
|
||||
@ -848,6 +876,7 @@ if (rtc_include_tests) {
|
||||
":videocodec_test_impl",
|
||||
":webrtc_h264",
|
||||
":webrtc_vp8",
|
||||
":webrtc_vp8_temporal_layers",
|
||||
":webrtc_vp9",
|
||||
":webrtc_vp9_helpers",
|
||||
"..:module_api",
|
||||
@ -858,6 +887,7 @@ if (rtc_include_tests) {
|
||||
"../../api/video:video_bitrate_allocator",
|
||||
"../../api/video:video_frame",
|
||||
"../../api/video:video_frame_i420",
|
||||
"../../api/video_codecs:create_vp8_temporal_layers",
|
||||
"../../api/video_codecs:video_codecs_api",
|
||||
"../../common_video:common_video",
|
||||
"../../media:rtc_media_base",
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -20,6 +18,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "modules/include/module_common_types.h"
|
||||
#include "modules/video_coding/codecs/vp8/default_temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@ -27,27 +26,30 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TemporalLayers::FrameConfig::FrameConfig()
|
||||
Vp8TemporalLayers::FrameConfig::FrameConfig()
|
||||
: FrameConfig(kNone, kNone, kNone, false) {}
|
||||
|
||||
TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
|
||||
TemporalLayers::BufferFlags golden,
|
||||
TemporalLayers::BufferFlags arf)
|
||||
Vp8TemporalLayers::FrameConfig::FrameConfig(
|
||||
Vp8TemporalLayers::BufferFlags last,
|
||||
Vp8TemporalLayers::BufferFlags golden,
|
||||
Vp8TemporalLayers::BufferFlags arf)
|
||||
: FrameConfig(last, golden, arf, false) {}
|
||||
|
||||
TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
|
||||
TemporalLayers::BufferFlags golden,
|
||||
TemporalLayers::BufferFlags arf,
|
||||
FreezeEntropy)
|
||||
Vp8TemporalLayers::FrameConfig::FrameConfig(
|
||||
Vp8TemporalLayers::BufferFlags last,
|
||||
Vp8TemporalLayers::BufferFlags golden,
|
||||
Vp8TemporalLayers::BufferFlags arf,
|
||||
FreezeEntropy)
|
||||
: FrameConfig(last, golden, arf, true) {}
|
||||
|
||||
TemporalLayers::FrameConfig::FrameConfig(TemporalLayers::BufferFlags last,
|
||||
TemporalLayers::BufferFlags golden,
|
||||
TemporalLayers::BufferFlags arf,
|
||||
bool freeze_entropy)
|
||||
: drop_frame(last == TemporalLayers::kNone &&
|
||||
golden == TemporalLayers::kNone &&
|
||||
arf == TemporalLayers::kNone),
|
||||
Vp8TemporalLayers::FrameConfig::FrameConfig(
|
||||
Vp8TemporalLayers::BufferFlags last,
|
||||
Vp8TemporalLayers::BufferFlags golden,
|
||||
Vp8TemporalLayers::BufferFlags arf,
|
||||
bool freeze_entropy)
|
||||
: drop_frame(last == Vp8TemporalLayers::kNone &&
|
||||
golden == Vp8TemporalLayers::kNone &&
|
||||
arf == Vp8TemporalLayers::kNone),
|
||||
last_buffer_flags(last),
|
||||
golden_buffer_flags(golden),
|
||||
arf_buffer_flags(arf),
|
||||
@ -106,15 +108,15 @@ std::vector<unsigned int> GetTemporalIds(size_t num_layers) {
|
||||
return {0};
|
||||
}
|
||||
|
||||
uint8_t GetUpdatedBuffers(const TemporalLayers::FrameConfig& config) {
|
||||
uint8_t GetUpdatedBuffers(const Vp8TemporalLayers::FrameConfig& config) {
|
||||
uint8_t flags = 0;
|
||||
if (config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (config.last_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
flags |= static_cast<uint8_t>(Vp8BufferReference::kLast);
|
||||
}
|
||||
if (config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (config.golden_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
flags |= static_cast<uint8_t>(Vp8BufferReference::kGolden);
|
||||
}
|
||||
if (config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (config.arf_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
flags |= static_cast<uint8_t>(Vp8BufferReference::kAltref);
|
||||
}
|
||||
return flags;
|
||||
@ -122,10 +124,10 @@ uint8_t GetUpdatedBuffers(const TemporalLayers::FrameConfig& config) {
|
||||
|
||||
// Find the set of buffers that are never updated by the given pattern.
|
||||
std::set<Vp8BufferReference> FindKfBuffers(
|
||||
const std::vector<TemporalLayers::FrameConfig>& frame_configs) {
|
||||
const std::vector<Vp8TemporalLayers::FrameConfig>& frame_configs) {
|
||||
std::set<Vp8BufferReference> kf_buffers(kAllBuffers.begin(),
|
||||
kAllBuffers.end());
|
||||
for (TemporalLayers::FrameConfig config : frame_configs) {
|
||||
for (Vp8TemporalLayers::FrameConfig config : frame_configs) {
|
||||
// Get bit-masked set of update buffers for this frame config.
|
||||
uint8_t updated_buffers = GetUpdatedBuffers(config);
|
||||
for (Vp8BufferReference buffer : kAllBuffers) {
|
||||
@ -138,7 +140,7 @@ std::set<Vp8BufferReference> FindKfBuffers(
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::vector<TemporalLayers::FrameConfig>
|
||||
std::vector<Vp8TemporalLayers::FrameConfig>
|
||||
DefaultTemporalLayers::GetTemporalPattern(size_t num_layers) {
|
||||
// For indexing in the patterns described below (which temporal layers they
|
||||
// belong to), see the diagram above.
|
||||
@ -262,7 +264,7 @@ DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers)
|
||||
kf_buffers_(FindKfBuffers(temporal_pattern_)),
|
||||
pattern_idx_(kUninitializedPatternIndex),
|
||||
checker_(TemporalLayersChecker::CreateTemporalLayersChecker(
|
||||
TemporalLayersType::kFixedPattern,
|
||||
Vp8TemporalLayersType::kFixedPattern,
|
||||
number_of_temporal_layers)) {
|
||||
RTC_CHECK_GE(kMaxTemporalStreams, number_of_temporal_layers);
|
||||
RTC_CHECK_GE(number_of_temporal_layers, 0);
|
||||
@ -278,6 +280,8 @@ DefaultTemporalLayers::DefaultTemporalLayers(int number_of_temporal_layers)
|
||||
}
|
||||
}
|
||||
|
||||
DefaultTemporalLayers::~DefaultTemporalLayers() = default;
|
||||
|
||||
bool DefaultTemporalLayers::SupportsEncoderFrameDropping() const {
|
||||
// This class allows the encoder drop frames as it sees fit.
|
||||
return true;
|
||||
@ -346,13 +350,13 @@ bool DefaultTemporalLayers::IsSyncFrame(const FrameConfig& config) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig(
|
||||
Vp8TemporalLayers::FrameConfig DefaultTemporalLayers::UpdateLayerConfig(
|
||||
uint32_t timestamp) {
|
||||
RTC_DCHECK_GT(num_layers_, 0);
|
||||
RTC_DCHECK_LT(0, temporal_pattern_.size());
|
||||
|
||||
pattern_idx_ = (pattern_idx_ + 1) % temporal_pattern_.size();
|
||||
TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_];
|
||||
Vp8TemporalLayers::FrameConfig tl_config = temporal_pattern_[pattern_idx_];
|
||||
tl_config.encoder_layer_id = tl_config.packetizer_temporal_idx =
|
||||
temporal_ids_[pattern_idx_ % temporal_ids_.size()];
|
||||
|
||||
@ -560,9 +564,11 @@ DefaultTemporalLayersChecker::DefaultTemporalLayersChecker(
|
||||
}
|
||||
}
|
||||
|
||||
DefaultTemporalLayersChecker::~DefaultTemporalLayersChecker() = default;
|
||||
|
||||
bool DefaultTemporalLayersChecker::CheckTemporalConfig(
|
||||
bool frame_is_keyframe,
|
||||
const TemporalLayers::FrameConfig& frame_config) {
|
||||
const Vp8TemporalLayers::FrameConfig& frame_config) {
|
||||
if (!TemporalLayersChecker::CheckTemporalConfig(frame_is_keyframe,
|
||||
frame_config)) {
|
||||
return false;
|
||||
@ -613,7 +619,7 @@ bool DefaultTemporalLayersChecker::CheckTemporalConfig(
|
||||
std::vector<int> dependencies;
|
||||
|
||||
if (frame_config.last_buffer_flags &
|
||||
TemporalLayers::BufferFlags::kReference) {
|
||||
Vp8TemporalLayers::BufferFlags::kReference) {
|
||||
uint8_t referenced_layer = temporal_ids_[last_.pattern_idx];
|
||||
if (referenced_layer > 0) {
|
||||
need_sync = false;
|
||||
@ -628,7 +634,8 @@ bool DefaultTemporalLayersChecker::CheckTemporalConfig(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kReference) {
|
||||
if (frame_config.arf_buffer_flags &
|
||||
Vp8TemporalLayers::BufferFlags::kReference) {
|
||||
uint8_t referenced_layer = temporal_ids_[arf_.pattern_idx];
|
||||
if (referenced_layer > 0) {
|
||||
need_sync = false;
|
||||
@ -644,7 +651,7 @@ bool DefaultTemporalLayersChecker::CheckTemporalConfig(
|
||||
}
|
||||
|
||||
if (frame_config.golden_buffer_flags &
|
||||
TemporalLayers::BufferFlags::kReference) {
|
||||
Vp8TemporalLayers::BufferFlags::kReference) {
|
||||
uint8_t referenced_layer = temporal_ids_[golden_.pattern_idx];
|
||||
if (referenced_layer > 0) {
|
||||
need_sync = false;
|
||||
@ -680,17 +687,19 @@ bool DefaultTemporalLayersChecker::CheckTemporalConfig(
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_config.last_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (frame_config.last_buffer_flags &
|
||||
Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
last_.is_updated_this_cycle = true;
|
||||
last_.pattern_idx = pattern_idx_;
|
||||
last_.is_keyframe = false;
|
||||
}
|
||||
if (frame_config.arf_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (frame_config.arf_buffer_flags & Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
arf_.is_updated_this_cycle = true;
|
||||
arf_.pattern_idx = pattern_idx_;
|
||||
arf_.is_keyframe = false;
|
||||
}
|
||||
if (frame_config.golden_buffer_flags & TemporalLayers::BufferFlags::kUpdate) {
|
||||
if (frame_config.golden_buffer_flags &
|
||||
Vp8TemporalLayers::BufferFlags::kUpdate) {
|
||||
golden_.is_updated_this_cycle = true;
|
||||
golden_.pattern_idx = pattern_idx_;
|
||||
golden_.is_keyframe = false;
|
||||
|
||||
@ -18,23 +18,23 @@
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DefaultTemporalLayers : public TemporalLayers {
|
||||
class DefaultTemporalLayers : public Vp8TemporalLayers {
|
||||
public:
|
||||
explicit DefaultTemporalLayers(int number_of_temporal_layers);
|
||||
virtual ~DefaultTemporalLayers() {}
|
||||
~DefaultTemporalLayers() override;
|
||||
|
||||
bool SupportsEncoderFrameDropping() const override;
|
||||
|
||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||
// and/or update the reference buffers.
|
||||
TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) override;
|
||||
Vp8TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) override;
|
||||
|
||||
// New target bitrate, per temporal layer.
|
||||
void OnRatesUpdated(const std::vector<uint32_t>& bitrates_bps,
|
||||
@ -50,7 +50,7 @@ class DefaultTemporalLayers : public TemporalLayers {
|
||||
|
||||
private:
|
||||
static constexpr size_t kKeyframeBuffer = std::numeric_limits<size_t>::max();
|
||||
static std::vector<TemporalLayers::FrameConfig> GetTemporalPattern(
|
||||
static std::vector<Vp8TemporalLayers::FrameConfig> GetTemporalPattern(
|
||||
size_t num_layers);
|
||||
bool IsSyncFrame(const FrameConfig& config) const;
|
||||
void ValidateReferences(BufferFlags* flags, Vp8BufferReference ref) const;
|
||||
@ -58,7 +58,7 @@ class DefaultTemporalLayers : public TemporalLayers {
|
||||
|
||||
const size_t num_layers_;
|
||||
const std::vector<unsigned int> temporal_ids_;
|
||||
const std::vector<TemporalLayers::FrameConfig> temporal_pattern_;
|
||||
const std::vector<Vp8TemporalLayers::FrameConfig> temporal_pattern_;
|
||||
// Set of buffers that are never updated except by keyframes.
|
||||
const std::set<Vp8BufferReference> kf_buffers_;
|
||||
|
||||
@ -95,9 +95,11 @@ class DefaultTemporalLayers : public TemporalLayers {
|
||||
class DefaultTemporalLayersChecker : public TemporalLayersChecker {
|
||||
public:
|
||||
explicit DefaultTemporalLayersChecker(int number_of_temporal_layers);
|
||||
~DefaultTemporalLayersChecker() override;
|
||||
|
||||
bool CheckTemporalConfig(
|
||||
bool frame_is_keyframe,
|
||||
const TemporalLayers::FrameConfig& frame_config) override;
|
||||
const Vp8TemporalLayers::FrameConfig& frame_config) override;
|
||||
|
||||
private:
|
||||
struct BufferState {
|
||||
|
||||
@ -74,7 +74,7 @@ constexpr int kDefaultBytesPerFrame =
|
||||
constexpr int kDefaultQp = 2;
|
||||
} // namespace
|
||||
|
||||
using BufferFlags = TemporalLayers::BufferFlags;
|
||||
using BufferFlags = Vp8TemporalLayers::BufferFlags;
|
||||
|
||||
TEST(TemporalLayersTest, 2Layers) {
|
||||
constexpr int kNumLayers = 2;
|
||||
@ -114,7 +114,7 @@ TEST(TemporalLayersTest, 2Layers) {
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||
&vp8_info);
|
||||
@ -166,7 +166,7 @@ TEST(TemporalLayersTest, 3Layers) {
|
||||
|
||||
unsigned int timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||
&vp8_info);
|
||||
@ -207,7 +207,7 @@ TEST(TemporalLayersTest, Alternative3Layers) {
|
||||
|
||||
unsigned int timestamp = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||
&vp8_info);
|
||||
@ -238,7 +238,7 @@ TEST(TemporalLayersTest, SearchOrder) {
|
||||
|
||||
// Start with a key-frame. tl_config flags can be ignored.
|
||||
uint32_t timestamp = 0;
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
|
||||
@ -282,7 +282,7 @@ TEST(TemporalLayersTest, SearchOrderWithDrop) {
|
||||
|
||||
// Start with a key-frame. tl_config flags can be ignored.
|
||||
uint32_t timestamp = 0;
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
|
||||
@ -343,7 +343,7 @@ TEST(TemporalLayersTest, 4Layers) {
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
EXPECT_EQ(expected_flags[i], LibvpxVp8Encoder::EncodeFlags(tl_config)) << i;
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||
&vp8_info);
|
||||
@ -373,7 +373,7 @@ TEST(TemporalLayersTest, DoesNotReferenceDroppedFrames) {
|
||||
|
||||
// Start with a keyframe.
|
||||
uint32_t timestamp = 0;
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
|
||||
@ -460,7 +460,7 @@ TEST(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExist) {
|
||||
|
||||
// Start with a keyframe.
|
||||
uint32_t timestamp = 0;
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
|
||||
@ -530,7 +530,7 @@ TEST(TemporalLayersTest, DoesNotReferenceUnlessGuaranteedToExistLongDelay) {
|
||||
|
||||
// Start with a keyframe.
|
||||
uint32_t timestamp = 0;
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
|
||||
@ -610,7 +610,8 @@ TEST(TemporalLayersTest, KeyFrame) {
|
||||
for (int j = 1; j <= i; ++j) {
|
||||
// Since last frame was always a keyframe and thus index 0 in the pattern,
|
||||
// this loop starts at index 1.
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config =
|
||||
tl.UpdateLayerConfig(timestamp);
|
||||
EXPECT_EQ(expected_flags[j], LibvpxVp8Encoder::EncodeFlags(tl_config))
|
||||
<< j;
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, false, kDefaultQp,
|
||||
@ -622,7 +623,7 @@ TEST(TemporalLayersTest, KeyFrame) {
|
||||
timestamp += 3000;
|
||||
}
|
||||
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp);
|
||||
tl.OnEncodeDone(timestamp, kDefaultBytesPerFrame, true, kDefaultQp,
|
||||
&vp8_info);
|
||||
EXPECT_TRUE(vp8_info.layerSync) << "Key frame should be marked layer sync.";
|
||||
@ -652,9 +653,9 @@ class TemporalLayersReferenceTest : public ::testing::TestWithParam<int> {
|
||||
bool sync;
|
||||
};
|
||||
|
||||
bool UpdateSyncRefState(const TemporalLayers::BufferFlags& flags,
|
||||
bool UpdateSyncRefState(const Vp8TemporalLayers::BufferFlags& flags,
|
||||
BufferState* buffer_state) {
|
||||
if (flags & TemporalLayers::kReference) {
|
||||
if (flags & Vp8TemporalLayers::kReference) {
|
||||
if (buffer_state->temporal_idx == -1)
|
||||
return true; // References key-frame.
|
||||
if (buffer_state->temporal_idx == 0) {
|
||||
@ -668,10 +669,10 @@ class TemporalLayersReferenceTest : public ::testing::TestWithParam<int> {
|
||||
return true; // No reference, does not affect sync frame status.
|
||||
}
|
||||
|
||||
void ValidateReference(const TemporalLayers::BufferFlags& flags,
|
||||
void ValidateReference(const Vp8TemporalLayers::BufferFlags& flags,
|
||||
const BufferState& buffer_state,
|
||||
int temporal_layer) {
|
||||
if (flags & TemporalLayers::kReference) {
|
||||
if (flags & Vp8TemporalLayers::kReference) {
|
||||
if (temporal_layer > 0 && buffer_state.timestamp > 0) {
|
||||
// Check that high layer reference does not go past last sync frame.
|
||||
EXPECT_GE(buffer_state.timestamp, last_sync_timestamp_);
|
||||
@ -709,9 +710,9 @@ TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) {
|
||||
// (any). If a given buffer is never updated, it is legal to reference it
|
||||
// even for sync frames. In order to be general, don't assume TL0 always
|
||||
// updates |last|.
|
||||
std::vector<TemporalLayers::FrameConfig> tl_configs(kMaxPatternLength);
|
||||
std::vector<Vp8TemporalLayers::FrameConfig> tl_configs(kMaxPatternLength);
|
||||
for (int i = 0; i < kMaxPatternLength; ++i) {
|
||||
TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp_);
|
||||
Vp8TemporalLayers::FrameConfig tl_config = tl.UpdateLayerConfig(timestamp_);
|
||||
tl.OnEncodeDone(timestamp_, kDefaultBytesPerFrame, i == 0, kDefaultQp,
|
||||
&vp8_specifics);
|
||||
++timestamp_;
|
||||
@ -752,11 +753,11 @@ TEST_P(TemporalLayersReferenceTest, ValidFrameConfigs) {
|
||||
|
||||
// Update the current layer state.
|
||||
BufferState state = {temporal_idx, timestamp_, is_sync_frame};
|
||||
if (tl_config.last_buffer_flags & TemporalLayers::kUpdate)
|
||||
if (tl_config.last_buffer_flags & Vp8TemporalLayers::kUpdate)
|
||||
last_state = state;
|
||||
if (tl_config.golden_buffer_flags & TemporalLayers::kUpdate)
|
||||
if (tl_config.golden_buffer_flags & Vp8TemporalLayers::kUpdate)
|
||||
golden_state = state;
|
||||
if (tl_config.arf_buffer_flags & TemporalLayers::kUpdate)
|
||||
if (tl_config.arf_buffer_flags & Vp8TemporalLayers::kUpdate)
|
||||
altref_state = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -29,10 +29,10 @@ class TemporalLayersChecker {
|
||||
|
||||
virtual bool CheckTemporalConfig(
|
||||
bool frame_is_keyframe,
|
||||
const TemporalLayers::FrameConfig& frame_config);
|
||||
const Vp8TemporalLayers::FrameConfig& frame_config);
|
||||
|
||||
static std::unique_ptr<TemporalLayersChecker> CreateTemporalLayersChecker(
|
||||
TemporalLayersType type,
|
||||
Vp8TemporalLayersType type,
|
||||
int num_temporal_layers);
|
||||
|
||||
private:
|
||||
@ -46,7 +46,7 @@ class TemporalLayersChecker {
|
||||
bool* need_sync,
|
||||
bool frame_is_keyframe,
|
||||
uint8_t temporal_layer,
|
||||
webrtc::TemporalLayers::BufferFlags flags,
|
||||
webrtc::Vp8TemporalLayers::BufferFlags flags,
|
||||
uint32_t sequence_number,
|
||||
uint32_t* lowest_sequence_referenced);
|
||||
BufferState last_;
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
#include "api/video_codecs/create_vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
|
||||
#include "modules/video_coding/utility/simulcast_rate_allocator.h"
|
||||
@ -113,7 +115,7 @@ static void FillInEncoderConfig(vpx_codec_enc_cfg* vpx_config,
|
||||
vpx_config->rc_max_quantizer = config.rc_max_quantizer;
|
||||
}
|
||||
|
||||
bool UpdateVpxConfiguration(TemporalLayers* temporal_layers,
|
||||
bool UpdateVpxConfiguration(Vp8TemporalLayers* temporal_layers,
|
||||
vpx_codec_enc_cfg_t* cfg) {
|
||||
Vp8EncoderConfig config = GetEncoderConfig(cfg);
|
||||
const bool res = temporal_layers->UpdateConfiguration(&config);
|
||||
@ -129,22 +131,22 @@ std::unique_ptr<VideoEncoder> VP8Encoder::Create() {
|
||||
}
|
||||
|
||||
vpx_enc_frame_flags_t LibvpxVp8Encoder::EncodeFlags(
|
||||
const TemporalLayers::FrameConfig& references) {
|
||||
const Vp8TemporalLayers::FrameConfig& references) {
|
||||
RTC_DCHECK(!references.drop_frame);
|
||||
|
||||
vpx_enc_frame_flags_t flags = 0;
|
||||
|
||||
if ((references.last_buffer_flags & TemporalLayers::kReference) == 0)
|
||||
if ((references.last_buffer_flags & Vp8TemporalLayers::kReference) == 0)
|
||||
flags |= VP8_EFLAG_NO_REF_LAST;
|
||||
if ((references.last_buffer_flags & TemporalLayers::kUpdate) == 0)
|
||||
if ((references.last_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
|
||||
flags |= VP8_EFLAG_NO_UPD_LAST;
|
||||
if ((references.golden_buffer_flags & TemporalLayers::kReference) == 0)
|
||||
if ((references.golden_buffer_flags & Vp8TemporalLayers::kReference) == 0)
|
||||
flags |= VP8_EFLAG_NO_REF_GF;
|
||||
if ((references.golden_buffer_flags & TemporalLayers::kUpdate) == 0)
|
||||
if ((references.golden_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
|
||||
flags |= VP8_EFLAG_NO_UPD_GF;
|
||||
if ((references.arf_buffer_flags & TemporalLayers::kReference) == 0)
|
||||
if ((references.arf_buffer_flags & Vp8TemporalLayers::kReference) == 0)
|
||||
flags |= VP8_EFLAG_NO_REF_ARF;
|
||||
if ((references.arf_buffer_flags & TemporalLayers::kUpdate) == 0)
|
||||
if ((references.arf_buffer_flags & Vp8TemporalLayers::kUpdate) == 0)
|
||||
flags |= VP8_EFLAG_NO_UPD_ARF;
|
||||
if (references.freeze_entropy)
|
||||
flags |= VP8_EFLAG_NO_UPD_ENTROPY;
|
||||
@ -167,7 +169,6 @@ LibvpxVp8Encoder::LibvpxVp8Encoder(std::unique_ptr<LibvpxInterface> interface)
|
||||
rc_max_intra_target_(0),
|
||||
key_frame_request_(kMaxSimulcastStreams, false) {
|
||||
temporal_layers_.reserve(kMaxSimulcastStreams);
|
||||
temporal_layers_checkers_.reserve(kMaxSimulcastStreams);
|
||||
raw_images_.reserve(kMaxSimulcastStreams);
|
||||
encoded_images_.reserve(kMaxSimulcastStreams);
|
||||
send_stream_.reserve(kMaxSimulcastStreams);
|
||||
@ -206,7 +207,6 @@ int LibvpxVp8Encoder::Release() {
|
||||
raw_images_.pop_back();
|
||||
}
|
||||
temporal_layers_.clear();
|
||||
temporal_layers_checkers_.clear();
|
||||
inited_ = false;
|
||||
return ret_val;
|
||||
}
|
||||
@ -294,21 +294,18 @@ void LibvpxVp8Encoder::SetupTemporalLayers(const VideoCodec& codec) {
|
||||
RTC_DCHECK(temporal_layers_.empty());
|
||||
int num_streams = SimulcastUtility::NumberOfSimulcastStreams(codec);
|
||||
for (int i = 0; i < num_streams; ++i) {
|
||||
TemporalLayersType type;
|
||||
Vp8TemporalLayersType type;
|
||||
int num_temporal_layers =
|
||||
SimulcastUtility::NumberOfTemporalLayers(codec, i);
|
||||
if (SimulcastUtility::IsConferenceModeScreenshare(codec) && i == 0) {
|
||||
type = TemporalLayersType::kBitrateDynamic;
|
||||
type = Vp8TemporalLayersType::kBitrateDynamic;
|
||||
// Legacy screenshare layers supports max 2 layers.
|
||||
num_temporal_layers = std::max<int>(2, num_temporal_layers);
|
||||
} else {
|
||||
type = TemporalLayersType::kFixedPattern;
|
||||
type = Vp8TemporalLayersType::kFixedPattern;
|
||||
}
|
||||
temporal_layers_.emplace_back(
|
||||
TemporalLayers::CreateTemporalLayers(type, num_temporal_layers));
|
||||
temporal_layers_checkers_.emplace_back(
|
||||
TemporalLayersChecker::CreateTemporalLayersChecker(
|
||||
type, num_temporal_layers));
|
||||
CreateVp8TemporalLayers(type, num_temporal_layers));
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,7 +747,7 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
|
||||
}
|
||||
}
|
||||
vpx_enc_frame_flags_t flags[kMaxSimulcastStreams];
|
||||
TemporalLayers::FrameConfig tl_configs[kMaxSimulcastStreams];
|
||||
Vp8TemporalLayers::FrameConfig tl_configs[kMaxSimulcastStreams];
|
||||
for (size_t i = 0; i < encoders_.size(); ++i) {
|
||||
tl_configs[i] = temporal_layers_[i]->UpdateLayerConfig(frame.timestamp());
|
||||
if (tl_configs[i].drop_frame) {
|
||||
|
||||
@ -17,10 +17,9 @@
|
||||
#include "api/video/encoded_image.h"
|
||||
#include "api/video/video_frame.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/libvpx_interface.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
|
||||
@ -57,7 +56,7 @@ class LibvpxVp8Encoder : public VideoEncoder {
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
static vpx_enc_frame_flags_t EncodeFlags(
|
||||
const TemporalLayers::FrameConfig& references);
|
||||
const Vp8TemporalLayers::FrameConfig& references);
|
||||
|
||||
private:
|
||||
void SetupTemporalLayers(const VideoCodec& codec);
|
||||
@ -97,8 +96,7 @@ class LibvpxVp8Encoder : public VideoEncoder {
|
||||
int cpu_speed_default_;
|
||||
int number_of_cores_;
|
||||
uint32_t rc_max_intra_target_;
|
||||
std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_;
|
||||
std::vector<std::unique_ptr<TemporalLayersChecker>> temporal_layers_checkers_;
|
||||
std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_;
|
||||
std::vector<bool> key_frame_request_;
|
||||
std::vector<bool> send_stream_;
|
||||
std::vector<int> cpu_speed_;
|
||||
|
||||
@ -53,7 +53,7 @@ ScreenshareLayers::ScreenshareLayers(int num_temporal_layers, Clock* clock)
|
||||
encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale.
|
||||
bitrate_updated_(false),
|
||||
checker_(TemporalLayersChecker::CreateTemporalLayersChecker(
|
||||
TemporalLayersType::kBitrateDynamic,
|
||||
Vp8TemporalLayersType::kBitrateDynamic,
|
||||
num_temporal_layers)) {
|
||||
RTC_CHECK_GT(number_of_temporal_layers_, 0);
|
||||
RTC_CHECK_LE(number_of_temporal_layers_, kMaxNumTemporalLayers);
|
||||
@ -68,7 +68,7 @@ bool ScreenshareLayers::SupportsEncoderFrameDropping() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
Vp8TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
uint32_t timestamp) {
|
||||
auto it = pending_frame_configs_.find(timestamp);
|
||||
if (it != pending_frame_configs_.end()) {
|
||||
@ -79,7 +79,7 @@ TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
if (number_of_temporal_layers_ <= 1) {
|
||||
// No flags needed for 1 layer screenshare.
|
||||
// TODO(pbos): Consider updating only last, and not all buffers.
|
||||
TemporalLayers::FrameConfig tl_config(
|
||||
Vp8TemporalLayers::FrameConfig tl_config(
|
||||
kReferenceAndUpdate, kReferenceAndUpdate, kReferenceAndUpdate);
|
||||
pending_frame_configs_[timestamp] = tl_config;
|
||||
return tl_config;
|
||||
@ -100,7 +100,7 @@ TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
// averaging window, or if frame interval is below 90% of desired value,
|
||||
// drop frame.
|
||||
if (encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_)
|
||||
return TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
|
||||
// Primarily check if frame interval is too short using frame timestamps,
|
||||
// as if they are correct they won't be affected by queuing in webrtc.
|
||||
@ -108,7 +108,7 @@ TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
kOneSecond90Khz / *target_framerate_;
|
||||
if (last_timestamp_ != -1 && ts_diff > 0) {
|
||||
if (ts_diff < 85 * expected_frame_interval_90khz / 100) {
|
||||
return TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
}
|
||||
} else {
|
||||
// Timestamps looks off, use realtime clock here instead.
|
||||
@ -116,7 +116,7 @@ TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
if (last_frame_time_ms_ != -1 &&
|
||||
now_ms - last_frame_time_ms_ <
|
||||
(85 * expected_frame_interval_ms) / 100) {
|
||||
return TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
return Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,30 +182,30 @@ TemporalLayers::FrameConfig ScreenshareLayers::UpdateLayerConfig(
|
||||
RTC_NOTREACHED();
|
||||
}
|
||||
|
||||
TemporalLayers::FrameConfig tl_config;
|
||||
Vp8TemporalLayers::FrameConfig tl_config;
|
||||
// TODO(pbos): Consider referencing but not updating the 'alt' buffer for all
|
||||
// layers.
|
||||
switch (layer_state) {
|
||||
case TemporalLayerState::kDrop:
|
||||
tl_config = TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
tl_config = Vp8TemporalLayers::FrameConfig(kNone, kNone, kNone);
|
||||
break;
|
||||
case TemporalLayerState::kTl0:
|
||||
// TL0 only references and updates 'last'.
|
||||
tl_config =
|
||||
TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone);
|
||||
Vp8TemporalLayers::FrameConfig(kReferenceAndUpdate, kNone, kNone);
|
||||
tl_config.packetizer_temporal_idx = 0;
|
||||
break;
|
||||
case TemporalLayerState::kTl1:
|
||||
// TL1 references both 'last' and 'golden' but only updates 'golden'.
|
||||
tl_config =
|
||||
TemporalLayers::FrameConfig(kReference, kReferenceAndUpdate, kNone);
|
||||
tl_config = Vp8TemporalLayers::FrameConfig(kReference,
|
||||
kReferenceAndUpdate, kNone);
|
||||
tl_config.packetizer_temporal_idx = 1;
|
||||
break;
|
||||
case TemporalLayerState::kTl1Sync:
|
||||
// Predict from only TL0 to allow participants to switch to the high
|
||||
// bitrate stream. Updates 'golden' so that TL1 can continue to refer to
|
||||
// and update 'golden' from this point on.
|
||||
tl_config = TemporalLayers::FrameConfig(kReference, kUpdate, kNone);
|
||||
tl_config = Vp8TemporalLayers::FrameConfig(kReference, kUpdate, kNone);
|
||||
tl_config.packetizer_temporal_idx = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/temporal_layers_checker.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/utility/frame_dropper.h"
|
||||
#include "rtc_base/rate_statistics.h"
|
||||
#include "rtc_base/timeutils.h"
|
||||
@ -24,7 +24,7 @@ namespace webrtc {
|
||||
struct CodecSpecificInfoVP8;
|
||||
class Clock;
|
||||
|
||||
class ScreenshareLayers : public TemporalLayers {
|
||||
class ScreenshareLayers : public Vp8TemporalLayers {
|
||||
public:
|
||||
static const double kMaxTL0FpsReduction;
|
||||
static const double kAcceptableTargetOvershoot;
|
||||
@ -38,7 +38,7 @@ class ScreenshareLayers : public TemporalLayers {
|
||||
|
||||
// Returns the recommended VP8 encode flags needed. May refresh the decoder
|
||||
// and/or update the reference buffers.
|
||||
TemporalLayers::FrameConfig UpdateLayerConfig(
|
||||
Vp8TemporalLayers::FrameConfig UpdateLayerConfig(
|
||||
uint32_t rtp_timestamp) override;
|
||||
|
||||
// New target bitrate, per temporal layer.
|
||||
@ -74,7 +74,7 @@ class ScreenshareLayers : public TemporalLayers {
|
||||
int max_qp_;
|
||||
uint32_t max_debt_bytes_;
|
||||
|
||||
std::map<uint32_t, TemporalLayers::FrameConfig> pending_frame_configs_;
|
||||
std::map<uint32_t, Vp8TemporalLayers::FrameConfig> pending_frame_configs_;
|
||||
|
||||
// Configured max framerate.
|
||||
absl::optional<uint32_t> target_framerate_;
|
||||
|
||||
@ -87,7 +87,7 @@ class ScreenshareLayerTest : public ::testing::Test {
|
||||
return flags;
|
||||
}
|
||||
|
||||
TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) {
|
||||
Vp8TemporalLayers::FrameConfig UpdateLayerConfig(uint32_t timestamp) {
|
||||
int64_t timestamp_ms = timestamp / 90;
|
||||
clock_.AdvanceTimeMilliseconds(timestamp_ms - clock_.TimeInMilliseconds());
|
||||
return layers_->UpdateLayerConfig(timestamp);
|
||||
@ -167,7 +167,7 @@ class ScreenshareLayerTest : public ::testing::Test {
|
||||
std::unique_ptr<ScreenshareLayers> layers_;
|
||||
|
||||
uint32_t timestamp_;
|
||||
TemporalLayers::FrameConfig tl_config_;
|
||||
Vp8TemporalLayers::FrameConfig tl_config_;
|
||||
Vp8EncoderConfig cfg_;
|
||||
bool config_updated_;
|
||||
CodecSpecificInfoVP8 vp8_info_;
|
||||
|
||||
@ -12,6 +12,6 @@
|
||||
#define MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
// TODO(webrtc:9012) Remove this file when downstream projects have updated.
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
|
||||
#endif // MODULES_VIDEO_CODING_CODECS_VP8_TEMPORAL_LAYERS_H_
|
||||
|
||||
@ -17,13 +17,13 @@
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<TemporalLayersChecker>
|
||||
TemporalLayersChecker::CreateTemporalLayersChecker(TemporalLayersType type,
|
||||
TemporalLayersChecker::CreateTemporalLayersChecker(Vp8TemporalLayersType type,
|
||||
int num_temporal_layers) {
|
||||
switch (type) {
|
||||
case TemporalLayersType::kFixedPattern:
|
||||
case Vp8TemporalLayersType::kFixedPattern:
|
||||
return absl::make_unique<DefaultTemporalLayersChecker>(
|
||||
num_temporal_layers);
|
||||
case TemporalLayersType::kBitrateDynamic:
|
||||
case Vp8TemporalLayersType::kBitrateDynamic:
|
||||
// Conference mode temporal layering for screen content in base stream.
|
||||
return absl::make_unique<TemporalLayersChecker>(num_temporal_layers);
|
||||
}
|
||||
@ -40,10 +40,10 @@ bool TemporalLayersChecker::CheckAndUpdateBufferState(
|
||||
bool* need_sync,
|
||||
bool frame_is_keyframe,
|
||||
uint8_t temporal_layer,
|
||||
webrtc::TemporalLayers::BufferFlags flags,
|
||||
webrtc::Vp8TemporalLayers::BufferFlags flags,
|
||||
uint32_t sequence_number,
|
||||
uint32_t* lowest_sequence_referenced) {
|
||||
if (flags & TemporalLayers::BufferFlags::kReference) {
|
||||
if (flags & Vp8TemporalLayers::BufferFlags::kReference) {
|
||||
if (state->temporal_layer > 0 && !state->is_keyframe) {
|
||||
*need_sync = false;
|
||||
}
|
||||
@ -57,7 +57,7 @@ bool TemporalLayersChecker::CheckAndUpdateBufferState(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((flags & TemporalLayers::BufferFlags::kUpdate)) {
|
||||
if ((flags & Vp8TemporalLayers::BufferFlags::kUpdate)) {
|
||||
state->temporal_layer = temporal_layer;
|
||||
state->sequence_number = sequence_number;
|
||||
state->is_keyframe = frame_is_keyframe;
|
||||
@ -69,7 +69,7 @@ bool TemporalLayersChecker::CheckAndUpdateBufferState(
|
||||
|
||||
bool TemporalLayersChecker::CheckTemporalConfig(
|
||||
bool frame_is_keyframe,
|
||||
const TemporalLayers::FrameConfig& frame_config) {
|
||||
const Vp8TemporalLayers::FrameConfig& frame_config) {
|
||||
if (frame_config.drop_frame ||
|
||||
frame_config.packetizer_temporal_idx == kNoTemporalIdx) {
|
||||
return true;
|
||||
|
||||
@ -12,10 +12,10 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "modules/video_coding/codecs/test/video_codec_unittest.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
|
||||
#include "modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h"
|
||||
#include "modules/video_coding/include/mock/mock_video_codec_interface.h"
|
||||
|
||||
@ -15,8 +15,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
@ -34,9 +33,9 @@ constexpr uint32_t kLegacyScreenshareMaxBitrateKbps = 1000;
|
||||
constexpr uint32_t kSimulcastScreenshareMinBitrateKbps = 600;
|
||||
constexpr uint32_t kSimulcastScreenshareMaxBitrateKbps = 1250;
|
||||
|
||||
class MockTemporalLayers : public TemporalLayers {
|
||||
class MockTemporalLayers : public Vp8TemporalLayers {
|
||||
public:
|
||||
MOCK_METHOD1(UpdateLayerConfig, TemporalLayers::FrameConfig(uint32_t));
|
||||
MOCK_METHOD1(UpdateLayerConfig, Vp8TemporalLayers::FrameConfig(uint32_t));
|
||||
MOCK_METHOD2(OnRatesUpdated, void(const std::vector<uint32_t>&, int));
|
||||
MOCK_METHOD1(UpdateConfiguration, bool(Vp8EncoderConfig*));
|
||||
MOCK_METHOD5(OnEncodeDone,
|
||||
@ -44,7 +43,7 @@ class MockTemporalLayers : public TemporalLayers {
|
||||
MOCK_METHOD3(FrameEncoded, void(uint32_t, size_t, int));
|
||||
MOCK_CONST_METHOD0(Tl0PicIdx, uint8_t());
|
||||
MOCK_CONST_METHOD1(GetTemporalLayerId,
|
||||
int(const TemporalLayers::FrameConfig&));
|
||||
int(const Vp8TemporalLayers::FrameConfig&));
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@ -10,9 +10,10 @@
|
||||
|
||||
#include "modules/video_coding/include/video_codec_initializer.h"
|
||||
#include "api/video/video_bitrate_allocator.h"
|
||||
#include "api/video_codecs/create_vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
||||
#include "rtc_base/refcountedobject.h"
|
||||
#include "test/gtest.h"
|
||||
@ -86,9 +87,9 @@ class VideoCodecInitializerTest : public ::testing::Test {
|
||||
// Make sure temporal layers instances have been created.
|
||||
if (codec_out_.codecType == VideoCodecType::kVideoCodecVP8) {
|
||||
for (int i = 0; i < codec_out_.numberOfSimulcastStreams; ++i) {
|
||||
temporal_layers_.emplace_back(TemporalLayers::CreateTemporalLayers(
|
||||
TemporalLayersType::kFixedPattern,
|
||||
codec_out_.VP8()->numberOfTemporalLayers));
|
||||
temporal_layers_.emplace_back(
|
||||
CreateVp8TemporalLayers(Vp8TemporalLayersType::kFixedPattern,
|
||||
codec_out_.VP8()->numberOfTemporalLayers));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -126,7 +127,7 @@ class VideoCodecInitializerTest : public ::testing::Test {
|
||||
// Output.
|
||||
VideoCodec codec_out_;
|
||||
std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_out_;
|
||||
std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_;
|
||||
std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_;
|
||||
};
|
||||
|
||||
TEST_F(VideoCodecInitializerTest, SingleStreamVp8Screenshare) {
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/include/mock/mock_vcm_callbacks.h"
|
||||
#include "modules/video_coding/include/mock/mock_video_codec_interface.h"
|
||||
#include "modules/video_coding/include/video_coding.h"
|
||||
|
||||
@ -541,6 +541,7 @@ rtc_source_set("fake_video_codecs") {
|
||||
"..:webrtc_common",
|
||||
"../api/video:encoded_image",
|
||||
"../api/video:video_frame_i420",
|
||||
"../api/video_codecs:create_vp8_temporal_layers",
|
||||
"../api/video_codecs:video_codecs_api",
|
||||
"../common_video:common_video",
|
||||
"../modules/video_coding:video_codec_interface",
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "system_wrappers/include/sleep.h"
|
||||
|
||||
@ -10,8 +10,9 @@
|
||||
|
||||
#include "test/fake_vp8_encoder.h"
|
||||
|
||||
#include "api/video_codecs/create_vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "modules/video_coding/include/video_error_codes.h"
|
||||
#include "modules/video_coding/utility/simulcast_utility.h"
|
||||
@ -83,18 +84,18 @@ void FakeVP8Encoder::SetupTemporalLayers(const VideoCodec& codec) {
|
||||
|
||||
int num_streams = SimulcastUtility::NumberOfSimulcastStreams(codec);
|
||||
for (int i = 0; i < num_streams; ++i) {
|
||||
TemporalLayersType type;
|
||||
Vp8TemporalLayersType type;
|
||||
int num_temporal_layers =
|
||||
SimulcastUtility::NumberOfTemporalLayers(codec, i);
|
||||
if (SimulcastUtility::IsConferenceModeScreenshare(codec) && i == 0) {
|
||||
type = TemporalLayersType::kBitrateDynamic;
|
||||
type = Vp8TemporalLayersType::kBitrateDynamic;
|
||||
// Legacy screenshare layers supports max 2 layers.
|
||||
num_temporal_layers = std::max<int>(2, num_temporal_layers);
|
||||
} else {
|
||||
type = TemporalLayersType::kFixedPattern;
|
||||
type = Vp8TemporalLayersType::kFixedPattern;
|
||||
}
|
||||
temporal_layers_.emplace_back(
|
||||
TemporalLayers::CreateTemporalLayers(type, num_temporal_layers));
|
||||
CreateVp8TemporalLayers(type, num_temporal_layers));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "test/fake_encoder.h"
|
||||
|
||||
#include "rtc_base/criticalsection.h"
|
||||
@ -54,7 +54,7 @@ class FakeVP8Encoder : public FakeEncoder, public EncodedImageCallback {
|
||||
rtc::SequencedTaskChecker sequence_checker_;
|
||||
EncodedImageCallback* callback_ RTC_GUARDED_BY(sequence_checker_);
|
||||
|
||||
std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_
|
||||
std::vector<std::unique_ptr<Vp8TemporalLayers>> temporal_layers_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
|
||||
@ -429,6 +429,7 @@ if (rtc_include_tests) {
|
||||
"../api/video:encoded_image",
|
||||
"../api/video:video_frame",
|
||||
"../api/video:video_frame_i420",
|
||||
"../api/video_codecs:create_vp8_temporal_layers",
|
||||
"../api/video_codecs:video_codecs_api",
|
||||
"../call:call_interfaces",
|
||||
"../call:fake_network",
|
||||
|
||||
@ -8,13 +8,16 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "video/video_stream_encoder.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include "api/video/i420_buffer.h"
|
||||
#include "api/video_codecs/create_vp8_temporal_layers.h"
|
||||
#include "api/video_codecs/vp8_temporal_layers.h"
|
||||
#include "media/base/videoadapter.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8_temporal_layers.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
|
||||
#include "modules/video_coding/utility/default_video_bitrate_allocator.h"
|
||||
#include "rtc_base/fakeclock.h"
|
||||
@ -30,7 +33,6 @@
|
||||
#include "test/gtest.h"
|
||||
#include "test/video_encoder_proxy_factory.h"
|
||||
#include "video/send_statistics_proxy.h"
|
||||
#include "video/video_stream_encoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -569,9 +571,8 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
||||
int num_streams = std::max<int>(1, config->numberOfSimulcastStreams);
|
||||
for (int i = 0; i < num_streams; ++i) {
|
||||
allocated_temporal_layers_.emplace_back(
|
||||
TemporalLayers::CreateTemporalLayers(
|
||||
TemporalLayersType::kFixedPattern,
|
||||
config->VP8().numberOfTemporalLayers));
|
||||
CreateVp8TemporalLayers(Vp8TemporalLayersType::kFixedPattern,
|
||||
config->VP8().numberOfTemporalLayers));
|
||||
}
|
||||
}
|
||||
if (force_init_encode_failed_)
|
||||
@ -587,7 +588,7 @@ class VideoStreamEncoderTest : public ::testing::Test {
|
||||
int last_input_width_ RTC_GUARDED_BY(local_crit_sect_) = 0;
|
||||
int last_input_height_ RTC_GUARDED_BY(local_crit_sect_) = 0;
|
||||
bool quality_scaling_ RTC_GUARDED_BY(local_crit_sect_) = true;
|
||||
std::vector<std::unique_ptr<TemporalLayers>> allocated_temporal_layers_
|
||||
std::vector<std::unique_ptr<Vp8TemporalLayers>> allocated_temporal_layers_
|
||||
RTC_GUARDED_BY(local_crit_sect_);
|
||||
bool force_init_encode_failed_ RTC_GUARDED_BY(local_crit_sect_) = false;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user