Revert "Move FakeCodec to separate target and behave like real encoder."

This reverts commit 223eba5f72b5228847eeebaaef1c4305a29e8b3d.

Reason for revert: Breaks perf tests and downstream projects.

Original change's description:
> Move FakeCodec to separate target and behave like real encoder.
> 
> Add FakeVp8Encoder, change FakeEncoder to use BitrateAllocator for simulcast.
> Change call_test to use VP8 payload name for simulcast tests.
> 
> Bug: none
> Change-Id: I5a34c52e66bbd6c05859729ed14ae87ac26b5969
> Reviewed-on: https://webrtc-review.googlesource.com/91861
> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Reviewed-by: Per Kjellander <perkj@webrtc.org>
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#24359}

TBR=mbonadei@webrtc.org,ilnik@webrtc.org,sprang@webrtc.org,srte@webrtc.org,perkj@webrtc.org

Change-Id: I602acecb3f340cc8d737ca074bf52496593419c8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: none
Reviewed-on: https://webrtc-review.googlesource.com/95181
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24365}
This commit is contained in:
Ilya Nikolaevskiy
2018-08-21 15:20:21 +00:00
committed by Commit Bot
parent ac50c6a204
commit 7d13a6e5b9
16 changed files with 120 additions and 515 deletions

View File

@ -347,13 +347,11 @@ if (rtc_include_tests) {
"../system_wrappers",
"../test:audio_codec_mocks",
"../test:direct_transport",
"../test:fake_video_codecs",
"../test:field_trial",
"../test:test_common",
"../test:test_support",
"../test:video_test_common",
"../video:video",
"//testing/gmock",
"//testing/gtest",
"//third_party/abseil-cpp/absl/memory",
]
@ -392,7 +390,6 @@ if (rtc_include_tests) {
"../system_wrappers:metrics_default",
"../system_wrappers:runtime_enabled_features_default",
"../test:direct_transport",
"../test:fake_video_codecs",
"../test:field_trial",
"../test:fileutils",
"../test:perf_test",

View File

@ -357,9 +357,6 @@ void RtpVideoSender::OnBitrateAllocationUpdated(
// inactive.
if (layer_bitrates[i]) {
rtp_modules_[i]->SetVideoBitrateAllocation(*layer_bitrates[i]);
} else {
// Signal a 0 bitrate on a simulcast stream.
rtp_modules_[i]->SetVideoBitrateAllocation(VideoBitrateAllocation());
}
}
}

View File

@ -12,8 +12,6 @@
#include <stdint.h>
#include <algorithm>
namespace webrtc {
DefaultVideoBitrateAllocator::DefaultVideoBitrateAllocator(
@ -29,23 +27,14 @@ VideoBitrateAllocation DefaultVideoBitrateAllocator::GetAllocation(
if (total_bitrate_bps == 0 || !codec_.active)
return allocation;
uint32_t allocated_bitrate_bps = total_bitrate_bps;
allocated_bitrate_bps =
std::max(allocated_bitrate_bps, codec_.minBitrate * 1000);
if (codec_.maxBitrate > 0) {
allocated_bitrate_bps =
std::min(allocated_bitrate_bps, codec_.maxBitrate * 1000);
if (total_bitrate_bps < codec_.minBitrate * 1000) {
allocation.SetBitrate(0, 0, codec_.minBitrate * 1000);
} else if (codec_.maxBitrate > 0 &&
total_bitrate_bps > codec_.maxBitrate * 1000) {
allocation.SetBitrate(0, 0, codec_.maxBitrate * 1000);
} else {
allocation.SetBitrate(0, 0, total_bitrate_bps);
}
size_t num_simulcast_streams =
std::max<size_t>(1, codec_.numberOfSimulcastStreams);
// The bitrate is split between all the streams in proportion of powers of 2
// e.g. 1:2, 1:2:4, etc.
for (size_t i = 0; i < num_simulcast_streams; i++) {
allocation.SetBitrate(
i, 0,
allocated_bitrate_bps * (1 << i) / ((1 << num_simulcast_streams) - 1));
}
return allocation;
}

View File

@ -299,32 +299,23 @@ if (rtc_include_tests) {
rtc_test("test_support_unittests") {
deps = [
":direct_transport",
":fake_video_codecs",
":fileutils",
":fileutils_unittests",
":perf_test",
":rtp_test_utils",
":test_common",
":test_main",
":test_support",
":test_support_test_artifacts",
":video_test_common",
":video_test_support",
"../api:create_simulcast_test_fixture_api",
"../api:simulcast_test_fixture_api",
"../api/video:video_frame_i420",
"../modules/rtp_rtcp:rtp_rtcp",
"../modules/video_capture",
"../modules/video_coding:simulcast_test_fixture_impl",
"../rtc_base:rtc_base_approved",
"../test:single_threaded_task_queue",
"//testing/gmock",
"//testing/gtest",
"//third_party/abseil-cpp/absl/memory",
]
sources = [
"direct_transport_unittest.cc",
"fake_vp8_encoder_unittest.cc",
"frame_generator_unittest.cc",
"rtp_file_reader_unittest.cc",
"rtp_file_writer_unittest.cc",
@ -351,7 +342,6 @@ if (rtc_include_tests) {
if (is_ios) {
deps += [ ":test_support_unittests_bundle_data" ]
}
if (!is_android && !build_with_chromium) {
# This is needed in order to avoid:
# undefined symbol: webrtc::videocapturemodule::VideoCaptureImpl::Create
@ -498,46 +488,13 @@ rtc_source_set("single_threaded_task_queue") {
]
}
rtc_source_set("fake_video_codecs") {
testonly = true
visibility = [ "*" ]
sources = [
"configurable_frame_size_encoder.cc",
"configurable_frame_size_encoder.h",
"fake_decoder.cc",
"fake_decoder.h",
"fake_encoder.cc",
"fake_encoder.h",
"fake_vp8_encoder.cc",
"fake_vp8_encoder.h",
]
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 = [
"..:webrtc_common",
"../api/video:video_frame_i420",
"../api/video_codecs:video_codecs_api",
"../common_video:common_video",
"../modules/video_coding:video_codec_interface",
"../modules/video_coding:video_coding_utility",
"../modules/video_coding:webrtc_h264",
"../modules/video_coding:webrtc_vp8",
"../modules/video_coding:webrtc_vp9",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_task_queue",
"../rtc_base:sequenced_task_checker",
"../system_wrappers",
]
}
rtc_source_set("test_common") {
testonly = true
sources = [
"call_test.cc",
"call_test.h",
"configurable_frame_size_encoder.cc",
"configurable_frame_size_encoder.h",
"constants.cc",
"constants.h",
"drifting_clock.cc",
@ -545,6 +502,10 @@ rtc_source_set("test_common") {
"encoder_proxy_factory.h",
"encoder_settings.cc",
"encoder_settings.h",
"fake_decoder.cc",
"fake_decoder.h",
"fake_encoder.cc",
"fake_encoder.h",
"fake_videorenderer.h",
"function_video_decoder_factory.h",
"function_video_encoder_factory.h",
@ -573,17 +534,18 @@ rtc_source_set("test_common") {
deps = [
":direct_transport",
":fake_video_codecs",
":fileutils",
":rtp_test_utils",
":test_support",
":video_test_common",
"..:webrtc_common",
"../api:libjingle_peerconnection_api",
"../api:simulated_network_api",
"../api:transport_api",
"../api/audio_codecs:builtin_audio_decoder_factory",
"../api/audio_codecs:builtin_audio_encoder_factory",
"../api/video:video_frame",
"../api/video:video_frame_i420",
"../api/video_codecs:video_codecs_api",
"../audio",
"../call",
@ -593,6 +555,7 @@ rtc_source_set("test_common") {
"../call:simulated_network",
"../call:simulated_packet_receiver",
"../call:video_stream_api",
"../common_video",
"../logging:rtc_event_log_api",
"../logging:rtc_event_log_impl_base",
"../media:rtc_internal_video_codecs",
@ -606,6 +569,7 @@ rtc_source_set("test_common") {
"../modules/rtp_rtcp",
"../modules/rtp_rtcp:mock_rtp_rtcp",
"../modules/rtp_rtcp:rtp_rtcp_format",
"../modules/video_coding:video_codec_interface",
"../modules/video_coding:video_coding_utility",
"../modules/video_coding:webrtc_h264",
"../modules/video_coding:webrtc_multiplex",
@ -613,6 +577,8 @@ rtc_source_set("test_common") {
"../modules/video_coding:webrtc_vp9",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_task_queue",
"../rtc_base:sequenced_task_checker",
"../rtc_base/experiments:congestion_controller_experiment",
"../system_wrappers",
"../system_wrappers:field_trial_api",

View File

@ -43,14 +43,9 @@ CallTest::CallTest()
audio_send_stream_(nullptr),
bbr_network_controller_factory_(new BbrNetworkControllerFactory()),
fake_encoder_factory_([this]() {
std::unique_ptr<FakeEncoder> fake_encoder;
if (video_encoder_configs_[0].codec_type == kVideoCodecVP8) {
fake_encoder = absl::make_unique<FakeVP8Encoder>(clock_);
} else {
fake_encoder = absl::make_unique<FakeEncoder>(clock_);
}
fake_encoder->SetMaxBitrate(fake_encoder_max_bitrate_);
return fake_encoder;
auto encoder = absl::make_unique<test::FakeEncoder>(clock_);
encoder->SetMaxBitrate(fake_encoder_max_bitrate_);
return encoder;
}),
num_video_streams_(1),
num_audio_streams_(0),

View File

@ -20,7 +20,6 @@
#include "test/encoder_settings.h"
#include "test/fake_decoder.h"
#include "test/fake_videorenderer.h"
#include "test/fake_vp8_encoder.h"
#include "test/frame_generator_capturer.h"
#include "test/function_video_encoder_factory.h"
#include "test/rtp_rtcp_observer.h"

View File

@ -15,6 +15,7 @@
#include "common_video/include/video_frame.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {

View File

@ -22,7 +22,7 @@ namespace test {
class ConfigurableFrameSizeEncoder : public VideoEncoder {
public:
explicit ConfigurableFrameSizeEncoder(size_t max_frame_size);
~ConfigurableFrameSizeEncoder() override;
virtual ~ConfigurableFrameSizeEncoder();
int32_t InitEncode(const VideoCodec* codec_settings,
int32_t number_of_cores,

View File

@ -12,17 +12,16 @@
#include "api/video/i420_buffer.h"
#include "rtc_base/timeutils.h"
#include "test/call_test.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
const int kDefaultWidth = 320;
const int kDefaultHeight = 180;
} // namespace
FakeDecoder::FakeDecoder()
: callback_(NULL), width_(kDefaultWidth), height_(kDefaultHeight) {}
: callback_(NULL),
width_(CallTest::kDefaultWidth),
height_(CallTest::kDefaultHeight) {}
int32_t FakeDecoder::InitDecode(const VideoCodec* config,
int32_t number_of_cores) {
@ -76,7 +75,7 @@ int32_t FakeH264Decoder::Decode(const EncodedImage& input,
i += sizeof(kStartCode) + 1; // Skip start code and NAL header.
}
if (input._buffer[i] != value) {
RTC_CHECK_EQ(value, input._buffer[i])
EXPECT_EQ(value, input._buffer[i])
<< "Bitstream mismatch between sender and receiver.";
return -1;
}

View File

@ -16,10 +16,10 @@
#include <memory>
#include "common_types.h" // NOLINT(build/include)
#include "modules/video_coding/codecs/vp8/temporal_layers.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/checks.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
@ -37,9 +37,6 @@ FakeEncoder::FakeEncoder(Clock* clock)
for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) {
encoded_buffer_[i] = static_cast<uint8_t>(i);
}
for (bool& used : used_layers_) {
used = false;
}
}
void FakeEncoder::SetMaxBitrate(int max_kbps) {
@ -56,7 +53,6 @@ int32_t FakeEncoder::InitEncode(const VideoCodec* config,
target_bitrate_.SetBitrate(0, 0, config_.startBitrate * 1000);
configured_input_framerate_ = config_.maxFramerate;
pending_keyframe_ = true;
last_frame_info_ = FrameInfo();
return 0;
}
@ -67,7 +63,9 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
unsigned char num_simulcast_streams;
SimulcastStream simulcast_streams[kMaxSimulcastStreams];
EncodedImageCallback* callback;
VideoBitrateAllocation target_bitrate;
uint32_t target_bitrate_sum_kbps;
int max_target_bitrate_kbps;
size_t num_encoded_bytes;
int framerate;
VideoCodecMode mode;
bool keyframe;
@ -79,7 +77,9 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
simulcast_streams[i] = config_.simulcastStream[i];
}
callback = callback_;
target_bitrate = target_bitrate_;
target_bitrate_sum_kbps = target_bitrate_.get_sum_kbps();
max_target_bitrate_kbps = max_target_bitrate_kbps_;
num_encoded_bytes = sizeof(encoded_buffer_);
mode = config_.mode;
if (configured_input_framerate_ > 0) {
framerate = configured_input_framerate_;
@ -90,28 +90,63 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
pending_keyframe_ = false;
}
FrameInfo frame_info =
NextFrame(frame_types, keyframe, num_simulcast_streams, target_bitrate,
simulcast_streams, framerate);
for (uint8_t i = 0; i < frame_info.layers.size(); ++i) {
if (frame_info.layers[i].size == 0) {
// Drop this temporal layer.
continue;
for (FrameType frame_type : *frame_types) {
if (frame_type == kVideoFrameKey) {
keyframe = true;
break;
}
}
RTC_DCHECK_GT(max_framerate, 0);
size_t bitrate =
std::max(target_bitrate_sum_kbps, simulcast_streams[0].minBitrate);
if (max_target_bitrate_kbps > 0)
bitrate = std::min(bitrate, static_cast<size_t>(max_target_bitrate_kbps));
size_t bits_available = bitrate * 1000 / framerate;
RTC_DCHECK_GT(num_simulcast_streams, 0);
for (unsigned char i = 0; i < num_simulcast_streams; ++i) {
CodecSpecificInfo specifics;
memset(&specifics, 0, sizeof(specifics));
specifics.codecType = kVideoCodecGeneric;
specifics.codecSpecific.generic.simulcast_idx = i;
std::unique_ptr<uint8_t[]> encoded_buffer(
new uint8_t[frame_info.layers[i].size]);
memcpy(encoded_buffer.get(), encoded_buffer_, frame_info.layers[i].size);
EncodedImage encoded(encoded_buffer.get(), frame_info.layers[i].size,
sizeof(encoded_buffer_));
encoded._timeStamp = input_image.timestamp();
size_t min_stream_bits = static_cast<size_t>(
(simulcast_streams[i].minBitrate * 1000) / framerate);
size_t max_stream_bits = static_cast<size_t>(
(simulcast_streams[i].maxBitrate * 1000) / framerate);
size_t stream_bits =
(bits_available > max_stream_bits) ? max_stream_bits : bits_available;
size_t stream_bytes = (stream_bits + 7) / 8;
if (keyframe) {
// The first frame is a key frame and should be larger.
// Store the overshoot bytes and distribute them over the coming frames,
// so that we on average meet the bitrate target.
debt_bytes_ += (kKeyframeSizeFactor - 1) * stream_bytes;
stream_bytes *= kKeyframeSizeFactor;
} else {
if (debt_bytes_ > 0) {
// Pay at most half of the frame size for old debts.
size_t payment_size = std::min(stream_bytes / 2, debt_bytes_);
debt_bytes_ -= payment_size;
stream_bytes -= payment_size;
}
}
if (stream_bytes > num_encoded_bytes)
stream_bytes = num_encoded_bytes;
// Always encode something on the first frame.
if (min_stream_bits > bits_available && i > 0)
continue;
std::unique_ptr<uint8_t[]> encoded_buffer(new uint8_t[num_encoded_bytes]);
memcpy(encoded_buffer.get(), encoded_buffer_, num_encoded_bytes);
EncodedImage encoded(encoded_buffer.get(), stream_bytes, num_encoded_bytes);
encoded.SetTimestamp(input_image.timestamp());
encoded.capture_time_ms_ = input_image.render_time_ms();
encoded._frameType =
frame_info.keyframe ? kVideoFrameKey : kVideoFrameDelta;
encoded._frameType = (*frame_types)[i];
encoded._encodedWidth = simulcast_streams[i].width;
encoded._encodedHeight = simulcast_streams[i].height;
encoded.rotation_ = input_image.rotation();
@ -119,77 +154,17 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
? VideoContentType::SCREENSHARE
: VideoContentType::UNSPECIFIED;
specifics.codec_name = ImplementationName();
specifics.codecSpecific.generic.simulcast_idx = i;
RTC_DCHECK(callback);
if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
EncodedImageCallback::Result::OK) {
return -1;
}
bits_available -= std::min(encoded._length * 8, bits_available);
}
return 0;
}
FakeEncoder::FrameInfo FakeEncoder::NextFrame(
const std::vector<FrameType>* frame_types,
bool keyframe,
uint8_t num_simulcast_streams,
const VideoBitrateAllocation& target_bitrate,
SimulcastStream simulcast_streams[kMaxSimulcastStreams],
int framerate) {
FrameInfo frame_info;
frame_info.keyframe = keyframe;
if (frame_types) {
for (FrameType frame_type : *frame_types) {
if (frame_type == kVideoFrameKey) {
frame_info.keyframe = true;
break;
}
}
}
for (uint8_t i = 0; i < num_simulcast_streams; ++i) {
if (target_bitrate.GetBitrate(i, 0) > 0) {
int temporal_id = last_frame_info_.layers.size() > i
? ++last_frame_info_.layers[i].temporal_id %
simulcast_streams[i].numberOfTemporalLayers
: 0;
frame_info.layers.emplace_back(0, temporal_id);
}
}
if (last_frame_info_.layers.size() < frame_info.layers.size()) {
// A new keyframe is needed since a new layer will be added.
frame_info.keyframe = true;
}
for (uint8_t i = 0; i < frame_info.layers.size(); ++i) {
FrameInfo::SpatialLayer& layer_info = frame_info.layers[i];
if (frame_info.keyframe) {
layer_info.temporal_id = 0;
size_t avg_frame_size =
(target_bitrate.GetBitrate(i, 0) + 7) / (8 * framerate);
// The first frame is a key frame and should be larger.
// Store the overshoot bytes and distribute them over the coming frames,
// so that we on average meet the bitrate target.
debt_bytes_ += (kKeyframeSizeFactor - 1) * avg_frame_size;
layer_info.size = kKeyframeSizeFactor * avg_frame_size;
} else {
size_t avg_frame_size =
(target_bitrate.GetBitrate(i, layer_info.temporal_id) + 7) /
(8 * framerate);
layer_info.size = avg_frame_size;
if (debt_bytes_ > 0) {
// Pay at most half of the frame size for old debts.
size_t payment_size = std::min(avg_frame_size / 2, debt_bytes_);
debt_bytes_ -= payment_size;
layer_info.size -= payment_size;
}
}
}
last_frame_info_ = frame_info;
return frame_info;
}
int32_t FakeEncoder::RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) {
rtc::CritScope cs(&crit_sect_);

View File

@ -50,30 +50,7 @@ class FakeEncoder : public VideoEncoder {
static const char* kImplementationName;
protected:
struct FrameInfo {
bool keyframe;
struct SpatialLayer {
SpatialLayer() = default;
SpatialLayer(int size, int temporal_id)
: size(size), temporal_id(temporal_id) {}
// Size of a current frame in the layer.
int size = 0;
// Temporal index of a current frame in the layer.
int temporal_id = 0;
};
std::vector<SpatialLayer> layers;
};
FrameInfo NextFrame(const std::vector<FrameType>* frame_types,
bool keyframe,
uint8_t num_simulcast_streams,
const VideoBitrateAllocation& target_bitrate,
SimulcastStream simulcast_streams[kMaxSimulcastStreams],
int framerate);
FrameInfo last_frame_info_;
Clock* const clock_;
VideoCodec config_ RTC_GUARDED_BY(crit_sect_);
EncodedImageCallback* callback_ RTC_GUARDED_BY(crit_sect_);
VideoBitrateAllocation target_bitrate_ RTC_GUARDED_BY(crit_sect_);
@ -83,7 +60,6 @@ class FakeEncoder : public VideoEncoder {
rtc::CriticalSection crit_sect_;
uint8_t encoded_buffer_[100000];
bool used_layers_[kMaxSimulcastStreams];
// Current byte debt to be payed over a number of frames.
// The debt is acquired by keyframes overshooting the bitrate target.

View File

@ -1,118 +0,0 @@
/*
* 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.
*/
#include "test/fake_vp8_encoder.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/video_coding/codecs/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"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/random.h"
#include "rtc_base/timeutils.h"
namespace webrtc {
namespace test {
FakeVP8Encoder::FakeVP8Encoder(Clock* clock)
: FakeEncoder(clock), callback_(nullptr) {
FakeEncoder::RegisterEncodeCompleteCallback(this);
sequence_checker_.Detach();
}
int32_t FakeVP8Encoder::RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
callback_ = callback;
return 0;
}
int32_t FakeVP8Encoder::InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
auto result =
FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
if (result != WEBRTC_VIDEO_CODEC_OK) {
return result;
}
int number_of_streams = SimulcastUtility::NumberOfSimulcastStreams(*config);
bool doing_simulcast = number_of_streams > 1;
int num_temporal_layers =
doing_simulcast ? config->simulcastStream[0].numberOfTemporalLayers
: config->VP8().numberOfTemporalLayers;
RTC_DCHECK_GT(num_temporal_layers, 0);
SetupTemporalLayers(number_of_streams, num_temporal_layers, *config);
return WEBRTC_VIDEO_CODEC_OK;
}
int32_t FakeVP8Encoder::Release() {
auto result = FakeEncoder::Release();
sequence_checker_.Detach();
return result;
}
void FakeVP8Encoder::SetupTemporalLayers(int num_streams,
int num_temporal_layers,
const VideoCodec& codec) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
temporal_layers_.clear();
for (int i = 0; i < num_streams; ++i) {
temporal_layers_.emplace_back(
TemporalLayers::CreateTemporalLayers(codec, i));
}
}
void FakeVP8Encoder::PopulateCodecSpecific(
CodecSpecificInfo* codec_specific,
const TemporalLayers::FrameConfig& tl_config,
FrameType frame_type,
int stream_idx,
uint32_t timestamp) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
codec_specific->codecType = kVideoCodecVP8;
codec_specific->codec_name = ImplementationName();
CodecSpecificInfoVP8* vp8Info = &(codec_specific->codecSpecific.VP8);
vp8Info->simulcastIdx = stream_idx;
vp8Info->keyIdx = kNoKeyIdx;
vp8Info->nonReference = false;
temporal_layers_[stream_idx]->PopulateCodecSpecific(
frame_type == kVideoFrameKey, tl_config, vp8Info, timestamp);
}
EncodedImageCallback::Result FakeVP8Encoder::OnEncodedImage(
const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragments) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
uint8_t stream_idx = codec_specific_info->codecSpecific.generic.simulcast_idx;
CodecSpecificInfo overrided_specific_info;
TemporalLayers::FrameConfig tl_config =
temporal_layers_[stream_idx]->UpdateLayerConfig(encoded_image._timeStamp);
PopulateCodecSpecific(&overrided_specific_info, tl_config,
encoded_image._frameType, stream_idx,
encoded_image._timeStamp);
temporal_layers_[stream_idx]->FrameEncoded(encoded_image._timeStamp,
encoded_image._length, -1);
return callback_->OnEncodedImage(encoded_image, &overrided_specific_info,
fragments);
}
} // namespace test
} // namespace webrtc

View File

@ -1,66 +0,0 @@
/*
* 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 TEST_FAKE_VP8_ENCODER_H_
#define TEST_FAKE_VP8_ENCODER_H_
#include <memory>
#include <vector>
#include "modules/video_coding/codecs/vp8/temporal_layers.h"
#include "test/fake_encoder.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/sequenced_task_checker.h"
namespace webrtc {
namespace test {
class FakeVP8Encoder : public FakeEncoder, public EncodedImageCallback {
public:
explicit FakeVP8Encoder(Clock* clock);
virtual ~FakeVP8Encoder() = default;
int32_t RegisterEncodeCompleteCallback(
EncodedImageCallback* callback) override;
int32_t InitEncode(const VideoCodec* config,
int32_t number_of_cores,
size_t max_payload_size) override;
int32_t Release() override;
const char* ImplementationName() const override { return "FakeVp8Encoder"; }
Result OnEncodedImage(const EncodedImage& encodedImage,
const CodecSpecificInfo* codecSpecificInfo,
const RTPFragmentationHeader* fragments) override;
private:
void SetupTemporalLayers(int num_streams,
int num_temporal_layers,
const VideoCodec& codec);
void PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
const TemporalLayers::FrameConfig& tl_config,
FrameType frame_type,
int stream_idx,
uint32_t timestamp);
rtc::SequencedTaskChecker sequence_checker_;
EncodedImageCallback* callback_ RTC_GUARDED_BY(sequence_checker_);
std::vector<std::unique_ptr<TemporalLayers>> temporal_layers_
RTC_GUARDED_BY(sequence_checker_);
};
} // namespace test
} // namespace webrtc
#endif // TEST_FAKE_VP8_ENCODER_H_

View File

@ -1,103 +0,0 @@
/*
* 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.
*/
#include <memory>
#include <utility>
#include "absl/memory/memory.h"
#include "api/test/create_simulcast_test_fixture.h"
#include "api/test/simulcast_test_fixture.h"
#include "modules/video_coding/utility/simulcast_test_fixture_impl.h"
#include "test/fake_decoder.h"
#include "test/fake_vp8_encoder.h"
#include "test/function_video_decoder_factory.h"
#include "test/function_video_encoder_factory.h"
namespace webrtc {
namespace test {
namespace {
std::unique_ptr<SimulcastTestFixture> CreateSpecificSimulcastTestFixture() {
std::unique_ptr<VideoEncoderFactory> encoder_factory =
absl::make_unique<FunctionVideoEncoderFactory>([]() {
return absl::make_unique<FakeVP8Encoder>(Clock::GetRealTimeClock());
});
std::unique_ptr<VideoDecoderFactory> decoder_factory =
absl::make_unique<FunctionVideoDecoderFactory>(
[]() { return absl::make_unique<FakeDecoder>(); });
return CreateSimulcastTestFixture(std::move(encoder_factory),
std::move(decoder_factory),
SdpVideoFormat("VP8"));
}
} // namespace
TEST(TestFakeVp8Codec, TestKeyFrameRequestsOnAllStreams) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestKeyFrameRequestsOnAllStreams();
}
TEST(TestFakeVp8Codec, TestPaddingAllStreams) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestPaddingAllStreams();
}
TEST(TestFakeVp8Codec, TestPaddingTwoStreams) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestPaddingTwoStreams();
}
TEST(TestFakeVp8Codec, TestPaddingTwoStreamsOneMaxedOut) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestPaddingTwoStreamsOneMaxedOut();
}
TEST(TestFakeVp8Codec, TestPaddingOneStream) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestPaddingOneStream();
}
TEST(TestFakeVp8Codec, TestPaddingOneStreamTwoMaxedOut) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestPaddingOneStreamTwoMaxedOut();
}
TEST(TestFakeVp8Codec, TestSendAllStreams) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestSendAllStreams();
}
TEST(TestFakeVp8Codec, TestDisablingStreams) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestDisablingStreams();
}
TEST(TestFakeVp8Codec, TestSwitchingToOneStream) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestSwitchingToOneStream();
}
TEST(TestFakeVp8Codec, TestSwitchingToOneOddStream) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestSwitchingToOneOddStream();
}
TEST(TestFakeVp8Codec, TestSwitchingToOneSmallStream) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestSwitchingToOneSmallStream();
}
TEST(TestFakeVp8Codec, TestSpatioTemporalLayers333PatternEncoder) {
auto fixture = CreateSpecificSimulcastTestFixture();
fixture->TestSpatioTemporalLayers333PatternEncoder();
}
} // namespace test
} // namespace webrtc

View File

@ -361,7 +361,6 @@ if (rtc_include_tests) {
"../system_wrappers",
"../system_wrappers:metrics_default",
"../system_wrappers:runtime_enabled_features_default",
"../test:fake_video_codecs",
"../test:field_trial",
"../test:rtp_test_utils",
"../test:run_test",
@ -473,7 +472,6 @@ if (rtc_include_tests) {
"../system_wrappers:metrics_api",
"../system_wrappers:metrics_default",
"../test:direct_transport",
"../test:fake_video_codecs",
"../test:field_trial",
"../test:fileutils",
"../test:perf_test",

View File

@ -30,12 +30,7 @@ class RtcpXrObserver : public test::EndToEndTest {
sent_rtcp_rrtr_(0),
sent_rtcp_target_bitrate_(false),
sent_zero_rtcp_target_bitrate_(false),
sent_rtcp_dlrr_(0),
send_transport_(nullptr) {
forward_transport_config_.link_capacity_kbps = 500;
forward_transport_config_.queue_delay_ms = 0;
forward_transport_config_.loss_percent = 0;
}
sent_rtcp_dlrr_(0) {}
private:
// Receive stream should send RR packets (and RRTR packets if enabled).
@ -61,14 +56,6 @@ class RtcpXrObserver : public test::EndToEndTest {
test::RtcpPacketParser parser;
EXPECT_TRUE(parser.Parse(packet, length));
if (parser.sender_ssrc() == test::CallTest::kVideoSendSsrcs[1] &&
enable_zero_target_bitrate_) {
// Reduce bandwidth restriction to disable second stream after it was
// enabled for some time.
forward_transport_config_.link_capacity_kbps = 200;
send_transport_->SetConfig(forward_transport_config_);
}
sent_rtcp_sr_ += parser.sender_report()->num_packets();
EXPECT_LE(parser.xr()->num_packets(), 1);
if (parser.xr()->num_packets() > 0) {
@ -77,12 +64,8 @@ class RtcpXrObserver : public test::EndToEndTest {
++sent_rtcp_dlrr_;
if (parser.xr()->target_bitrate()) {
sent_rtcp_target_bitrate_ = true;
auto target_bitrates =
parser.xr()->target_bitrate()->GetTargetBitrates();
if (target_bitrates.empty()) {
sent_zero_rtcp_target_bitrate_ = true;
}
for (const rtcp::TargetBitrate::BitrateItem& item : target_bitrates) {
for (const rtcp::TargetBitrate::BitrateItem& item :
parser.xr()->target_bitrate()->GetTargetBitrates()) {
if (item.target_bitrate_kbps == 0) {
sent_zero_rtcp_target_bitrate_ = true;
break;
@ -115,20 +98,39 @@ class RtcpXrObserver : public test::EndToEndTest {
return enable_zero_target_bitrate_ ? 2 : 1;
}
test::PacketTransport* CreateSendTransport(
test::SingleThreadedTaskQueueForTesting* task_queue,
Call* sender_call) {
send_transport_ = new test::PacketTransport(
task_queue, sender_call, this, test::PacketTransport::kSender,
test::CallTest::payload_type_map_, forward_transport_config_);
return send_transport_;
}
// This test uses VideoStream settings different from the the default one
// implemented in DefaultVideoStreamFactory, so it implements its own
// VideoEncoderConfig::VideoStreamFactoryInterface which is created
// in ModifyVideoConfigs.
class ZeroTargetVideoStreamFactory
: public VideoEncoderConfig::VideoStreamFactoryInterface {
public:
ZeroTargetVideoStreamFactory() {}
private:
std::vector<VideoStream> CreateEncoderStreams(
int width,
int height,
const VideoEncoderConfig& encoder_config) override {
std::vector<VideoStream> streams =
test::CreateVideoStreams(width, height, encoder_config);
// Set one of the streams' target bitrates to zero to test that a
// bitrate of 0 can be signalled.
streams[encoder_config.number_of_streams - 1].min_bitrate_bps = 0;
streams[encoder_config.number_of_streams - 1].target_bitrate_bps = 0;
streams[encoder_config.number_of_streams - 1].max_bitrate_bps = 0;
return streams;
}
};
void ModifyVideoConfigs(
VideoSendStream::Config* send_config,
std::vector<VideoReceiveStream::Config>* receive_configs,
VideoEncoderConfig* encoder_config) override {
if (enable_zero_target_bitrate_) {
encoder_config->video_stream_factory =
new rtc::RefCountedObject<ZeroTargetVideoStreamFactory>();
// Configure VP8 to be able to use simulcast.
send_config->rtp.payload_name = "VP8";
encoder_config->codec_type = kVideoCodecVP8;
@ -164,8 +166,6 @@ class RtcpXrObserver : public test::EndToEndTest {
bool sent_rtcp_target_bitrate_ RTC_GUARDED_BY(&crit_);
bool sent_zero_rtcp_target_bitrate_ RTC_GUARDED_BY(&crit_);
int sent_rtcp_dlrr_;
DefaultNetworkSimulationConfig forward_transport_config_;
test::PacketTransport* send_transport_;
};
TEST_F(ExtendedReportsEndToEndTest,