Move VideoCodecTest configuration classes to api/test.

These files are required when implementing tests based on the test fixture,
and should be exposed as part of the test api.

This CL also removes a usage of stringstream and fixes some chromium-style
lint issues.

Bug: webrtc:8982, webrtc:163
Change-Id: I132aea0da79a79587887f21897236fc9802b7574
Reviewed-on: https://webrtc-review.googlesource.com/74586
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23346}
This commit is contained in:
Kári Tristan Helgason 2018-05-22 13:34:14 +02:00 committed by Commit Bot
parent dac94538a8
commit 169005d8c1
27 changed files with 881 additions and 842 deletions

View file

@ -351,9 +351,12 @@ if (rtc_include_tests) {
testonly = true
sources = [
"test/videocodec_test_fixture.h",
"test/videocodec_test_stats.cc",
"test/videocodec_test_stats.h",
]
deps = [
"../modules/video_coding:video_codecs_test_framework",
"..:webrtc_common",
"../modules/video_coding:video_codec_interface",
"video_codecs:video_codecs_api",
]
}

View file

@ -23,5 +23,6 @@ specific_include_rules = {
".*\.cc": [
"+modules/audio_coding",
"+modules/audio_processing",
"+modules/video_coding",
],
}

View file

@ -1,6 +1,5 @@
# TODO(kthelgason): Move the relevant included files to api/test.
specific_include_rules = {
".*": [
"+modules/video_coding/codecs/test",
"+modules/video_coding",
],
}

View file

@ -20,14 +20,16 @@
namespace webrtc {
namespace test {
using Config = VideoCodecTestFixture::Config;
std::unique_ptr<VideoCodecTestFixture>
CreateVideoCodecTestFixture(const TestConfig& config) {
CreateVideoCodecTestFixture(const Config& config) {
return rtc::MakeUnique<VideoCodecTestFixtureImpl>(config);
}
std::unique_ptr<VideoCodecTestFixture>
CreateVideoCodecTestFixture(
const TestConfig& config,
const Config& config,
std::unique_ptr<VideoDecoderFactory> decoder_factory,
std::unique_ptr<VideoEncoderFactory> encoder_factory) {
return rtc::MakeUnique<VideoCodecTestFixtureImpl>(

View file

@ -16,17 +16,15 @@
#include "api/test/videocodec_test_fixture.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/codecs/test/test_config.h"
namespace webrtc {
namespace test {
std::unique_ptr<VideoCodecTestFixture>
CreateVideoCodecTestFixture(const TestConfig& config);
std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
const VideoCodecTestFixture::Config& config);
std::unique_ptr<VideoCodecTestFixture>
CreateVideoCodecTestFixture(
const TestConfig& config,
std::unique_ptr<VideoCodecTestFixture> CreateVideoCodecTestFixture(
const VideoCodecTestFixture::Config& config,
std::unique_ptr<VideoDecoderFactory> decoder_factory,
std::unique_ptr<VideoEncoderFactory> encoder_factory);

View file

@ -11,11 +11,13 @@
#ifndef API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
#define API_TEST_VIDEOCODEC_TEST_FIXTURE_H_
#include <string>
#include <vector>
#include "api/test/videocodec_test_stats.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/include/video_codec_interface.h"
namespace webrtc {
namespace test {
@ -58,6 +60,89 @@ struct VisualizationParams {
class VideoCodecTestFixture {
public:
class EncodedFrameChecker {
public:
virtual ~EncodedFrameChecker() = default;
virtual void CheckEncodedFrame(webrtc::VideoCodecType codec,
const EncodedImage& encoded_frame) const = 0;
};
struct Config {
Config();
void SetCodecSettings(std::string codec_name,
size_t num_simulcast_streams,
size_t num_spatial_layers,
size_t num_temporal_layers,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on,
size_t width,
size_t height);
size_t NumberOfCores() const;
size_t NumberOfTemporalLayers() const;
size_t NumberOfSpatialLayers() const;
size_t NumberOfSimulcastStreams() const;
std::string ToString() const;
std::string CodecName() const;
bool IsAsyncCodec() const;
// Plain name of YUV file to process without file extension.
std::string filename;
// File to process. This must be a video file in the YUV format.
std::string filepath;
// Number of frames to process.
size_t num_frames = 0;
// Bitstream constraints.
size_t max_payload_size_bytes = 1440;
// Should we decode the encoded frames?
bool decode = true;
// Force the encoder and decoder to use a single core for processing.
bool use_single_core = false;
// Should cpu usage be measured?
// If set to true, the encoding will run in real-time.
bool measure_cpu = false;
// If > 0: forces the encoder to create a keyframe every Nth frame.
size_t keyframe_interval = 0;
// Codec settings to use.
webrtc::VideoCodec codec_settings;
// Name of the codec being tested.
std::string codec_name;
// H.264 specific settings.
struct H264CodecSettings {
H264::Profile profile = H264::kProfileConstrainedBaseline;
H264PacketizationMode packetization_mode =
webrtc::H264PacketizationMode::NonInterleaved;
} h264_codec_settings;
// Should hardware accelerated codecs be used?
bool hw_encoder = false;
bool hw_decoder = false;
// Should the encoder be wrapped in a SimulcastEncoderAdapter?
bool simulcast_adapted_encoder = false;
// Should the hardware codecs be wrapped in software fallbacks?
bool sw_fallback_encoder = false;
bool sw_fallback_decoder = false;
// Custom checker that will be called for each frame.
const EncodedFrameChecker* encoded_frame_checker = nullptr;
// Print out frame level stats.
bool print_frame_level_stats = false;
};
virtual ~VideoCodecTestFixture() = default;
virtual void RunTest(const std::vector<RateProfile>& rate_profiles,
@ -65,7 +150,7 @@ class VideoCodecTestFixture {
const std::vector<QualityThresholds>* quality_thresholds,
const BitstreamThresholds* bs_thresholds,
const VisualizationParams* visualization_params) = 0;
virtual Stats GetStats() = 0;
virtual VideoCodecTestStats& GetStats() = 0;
};
} // namespace test

View file

@ -0,0 +1,95 @@
/*
* 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 "api/test/videocodec_test_stats.h"
namespace webrtc {
namespace test {
std::string VideoCodecTestStats::FrameStatistics::ToString() const {
std::stringstream ss;
ss << "frame_number " << frame_number;
ss << " decoded_width " << decoded_width;
ss << " decoded_height " << decoded_height;
ss << " spatial_idx " << spatial_idx;
ss << " temporal_idx " << temporal_idx;
ss << " inter_layer_predicted " << inter_layer_predicted;
ss << " non_ref_for_inter_layer_pred " << non_ref_for_inter_layer_pred;
ss << " frame_type " << frame_type;
ss << " length_bytes " << length_bytes;
ss << " qp " << qp;
ss << " psnr " << psnr;
ss << " psnr_y " << psnr_y;
ss << " psnr_u " << psnr_u;
ss << " psnr_v " << psnr_v;
ss << " ssim " << ssim;
ss << " encode_time_us " << encode_time_us;
ss << " decode_time_us " << decode_time_us;
ss << " rtp_timestamp " << rtp_timestamp;
ss << " target_bitrate_kbps " << target_bitrate_kbps;
return ss.str();
}
VideoCodecTestStats::VideoStatistics::VideoStatistics() = default;
VideoCodecTestStats::VideoStatistics::VideoStatistics(const VideoStatistics&) =
default;
std::string VideoCodecTestStats::VideoStatistics::ToString(
std::string prefix) const {
std::stringstream ss;
ss << prefix << "target_bitrate_kbps: " << target_bitrate_kbps;
ss << "\n" << prefix << "input_framerate_fps: " << input_framerate_fps;
ss << "\n" << prefix << "spatial_idx: " << spatial_idx;
ss << "\n" << prefix << "temporal_idx: " << temporal_idx;
ss << "\n" << prefix << "width: " << width;
ss << "\n" << prefix << "height: " << height;
ss << "\n" << prefix << "length_bytes: " << length_bytes;
ss << "\n" << prefix << "bitrate_kbps: " << bitrate_kbps;
ss << "\n" << prefix << "framerate_fps: " << framerate_fps;
ss << "\n" << prefix << "enc_speed_fps: " << enc_speed_fps;
ss << "\n" << prefix << "dec_speed_fps: " << dec_speed_fps;
ss << "\n" << prefix << "avg_delay_sec: " << avg_delay_sec;
ss << "\n"
<< prefix << "max_key_frame_delay_sec: " << max_key_frame_delay_sec;
ss << "\n"
<< prefix << "max_delta_frame_delay_sec: " << max_delta_frame_delay_sec;
ss << "\n"
<< prefix << "time_to_reach_target_bitrate_sec: "
<< time_to_reach_target_bitrate_sec;
ss << "\n"
<< prefix << "avg_key_frame_size_bytes: " << avg_key_frame_size_bytes;
ss << "\n"
<< prefix << "avg_delta_frame_size_bytes: " << avg_delta_frame_size_bytes;
ss << "\n" << prefix << "avg_qp: " << avg_qp;
ss << "\n" << prefix << "avg_psnr: " << avg_psnr;
ss << "\n" << prefix << "min_psnr: " << min_psnr;
ss << "\n" << prefix << "avg_ssim: " << avg_ssim;
ss << "\n" << prefix << "min_ssim: " << min_ssim;
ss << "\n" << prefix << "num_input_frames: " << num_input_frames;
ss << "\n" << prefix << "num_encoded_frames: " << num_encoded_frames;
ss << "\n" << prefix << "num_decoded_frames: " << num_decoded_frames;
ss << "\n"
<< prefix
<< "num_dropped_frames: " << num_input_frames - num_encoded_frames;
ss << "\n" << prefix << "num_key_frames: " << num_key_frames;
ss << "\n" << prefix << "num_spatial_resizes: " << num_spatial_resizes;
ss << "\n" << prefix << "max_nalu_size_bytes: " << max_nalu_size_bytes;
return ss.str();
}
VideoCodecTestStats::FrameStatistics::FrameStatistics(size_t frame_number,
size_t rtp_timestamp)
: frame_number(frame_number), rtp_timestamp(rtp_timestamp) {}
VideoCodecTestStats::FrameStatistics::FrameStatistics(
const FrameStatistics& rhs) = default;
} // namespace test
} // namespace webrtc

View file

@ -0,0 +1,149 @@
/*
* 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_TEST_VIDEOCODEC_TEST_STATS_H_
#define API_TEST_VIDEOCODEC_TEST_STATS_H_
#include <map>
#include <string>
#include <vector>
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
// Statistics for a sequence of processed frames. This class is not thread safe.
class VideoCodecTestStats {
public:
// Statistics for one processed frame.
struct FrameStatistics {
FrameStatistics(size_t frame_number, size_t rtp_timestamp);
FrameStatistics(const FrameStatistics& rhs);
std::string ToString() const;
size_t frame_number = 0;
size_t rtp_timestamp = 0;
// Encoding.
int64_t encode_start_ns = 0;
int encode_return_code = 0;
bool encoding_successful = false;
size_t encode_time_us = 0;
size_t target_bitrate_kbps = 0;
size_t length_bytes = 0;
webrtc::FrameType frame_type = kVideoFrameDelta;
// Layering.
size_t spatial_idx = 0;
size_t temporal_idx = 0;
bool inter_layer_predicted = false;
bool non_ref_for_inter_layer_pred = true;
// H264 specific.
size_t max_nalu_size_bytes = 0;
// Decoding.
int64_t decode_start_ns = 0;
int decode_return_code = 0;
bool decoding_successful = false;
size_t decode_time_us = 0;
size_t decoded_width = 0;
size_t decoded_height = 0;
// Quantization.
int qp = -1;
// Quality.
float psnr_y = 0.0f;
float psnr_u = 0.0f;
float psnr_v = 0.0f;
float psnr = 0.0f; // 10 * log10(255^2 / (mse_y + mse_u + mse_v)).
float ssim = 0.0f; // 0.8 * ssim_y + 0.1 * (ssim_u + ssim_v).
};
struct VideoStatistics {
VideoStatistics();
VideoStatistics(const VideoStatistics&);
std::string ToString(std::string prefix) const;
size_t target_bitrate_kbps = 0;
float input_framerate_fps = 0.0f;
size_t spatial_idx = 0;
size_t temporal_idx = 0;
size_t width = 0;
size_t height = 0;
size_t length_bytes = 0;
size_t bitrate_kbps = 0;
float framerate_fps = 0;
float enc_speed_fps = 0.0f;
float dec_speed_fps = 0.0f;
float avg_delay_sec = 0.0f;
float max_key_frame_delay_sec = 0.0f;
float max_delta_frame_delay_sec = 0.0f;
float time_to_reach_target_bitrate_sec = 0.0f;
float avg_key_frame_size_bytes = 0.0f;
float avg_delta_frame_size_bytes = 0.0f;
float avg_qp = 0.0f;
float avg_psnr_y = 0.0f;
float avg_psnr_u = 0.0f;
float avg_psnr_v = 0.0f;
float avg_psnr = 0.0f;
float min_psnr = 0.0f;
float avg_ssim = 0.0f;
float min_ssim = 0.0f;
size_t num_input_frames = 0;
size_t num_encoded_frames = 0;
size_t num_decoded_frames = 0;
size_t num_key_frames = 0;
size_t num_spatial_resizes = 0;
size_t max_nalu_size_bytes = 0;
};
virtual ~VideoCodecTestStats() = default;
// Creates a FrameStatistics for the next frame to be processed.
virtual FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx) = 0;
// Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
virtual FrameStatistics* GetFrame(size_t frame_number,
size_t spatial_idx) = 0;
virtual FrameStatistics* GetFrameWithTimestamp(size_t timestamp,
size_t spatial_idx) = 0;
virtual std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) = 0;
virtual VideoStatistics SliceAndCalcAggregatedVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) = 0;
virtual void PrintFrameStatistics() = 0;
virtual size_t Size(size_t spatial_idx) = 0;
virtual void Clear() = 0;
};
} // namespace test
} // namespace webrtc
#endif // API_TEST_VIDEOCODEC_TEST_STATS_H_

View file

@ -587,10 +587,6 @@ if (rtc_include_tests) {
rtc_source_set("video_codecs_test_framework") {
testonly = true
sources = [
"codecs/test/stats.cc",
"codecs/test/stats.h",
"codecs/test/test_config.cc",
"codecs/test/test_config.h",
"codecs/test/video_codec_unittest.cc",
"codecs/test/video_codec_unittest.h",
"codecs/test/videoprocessor.cc",
@ -603,7 +599,6 @@ if (rtc_include_tests) {
}
deps = [
":codec_globals_headers",
":video_codec_interface",
":video_coding",
":video_coding_utility",
@ -611,21 +606,16 @@ if (rtc_include_tests) {
":webrtc_vp9_helpers",
"../..:webrtc_common",
"../../:typedefs",
"../../api:videocodec_test_fixture_api",
"../../api/video:video_frame",
"../../api/video:video_frame_i420",
"../../api/video_codecs:video_codecs_api",
"../../common_video:common_video",
"../../media:rtc_audio_video",
"../../media:rtc_h264_profile_id",
"../../media:rtc_media_base",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_task_queue",
"../../rtc_base:rtc_task_queue_for_test",
"../../rtc_base:sequenced_task_checker",
"../../system_wrappers",
"../../test:fileutils",
"../../test:test_common",
"../../test:test_support",
"../../test:video_test_common",
"../../test:video_test_support",
@ -674,6 +664,8 @@ if (rtc_include_tests) {
sources = [
"codecs/test/videocodec_test_fixture_impl.cc",
"codecs/test/videocodec_test_fixture_impl.h",
"codecs/test/videocodec_test_stats_impl.cc",
"codecs/test/videocodec_test_stats_impl.h",
]
deps = [
":video_codec_interface",
@ -686,7 +678,10 @@ if (rtc_include_tests) {
"../..:webrtc_common",
"../../api:videocodec_test_fixture_api",
"../../api/video_codecs:video_codecs_api",
"../../call:video_stream_api",
"../../common_video",
"../../media:rtc_audio_video",
"../../media:rtc_h264_profile_id",
"../../media:rtc_internal_video_codecs",
"../../media:rtc_software_fallback_wrappers",
"../../rtc_base:checks",
@ -695,8 +690,11 @@ if (rtc_include_tests) {
"../../rtc_base:rtc_task_queue_for_test",
"../../system_wrappers",
"../../test:fileutils",
"../../test:test_common",
"../../test:test_support",
"../../test:video_test_common",
"../../test:video_test_support",
"../rtp_rtcp:rtp_rtcp_format",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
@ -778,8 +776,8 @@ if (rtc_include_tests) {
testonly = true
sources = [
"codecs/test/stats_unittest.cc",
"codecs/test/test_config_unittest.cc",
"codecs/test/videocodec_test_fixture_config_unittest.cc",
"codecs/test/videocodec_test_stats_impl_unittest.cc",
"codecs/test/videoprocessor_unittest.cc",
"codecs/vp8/default_temporal_layers_unittest.cc",
"codecs/vp8/screenshare_layers_unittest.cc",
@ -829,6 +827,7 @@ if (rtc_include_tests) {
":video_codecs_test_framework",
":video_coding",
":video_coding_utility",
":videocodec_test_impl",
":webrtc_h264",
":webrtc_vp8",
":webrtc_vp8_helpers",
@ -837,6 +836,7 @@ if (rtc_include_tests) {
"..:module_api",
"../..:webrtc_common",
"../../:typedefs",
"../../api:videocodec_test_fixture_api",
"../../api/video:video_frame",
"../../api/video:video_frame_i420",
"../../api/video_codecs:video_codecs_api",

View file

@ -1,171 +0,0 @@
/*
* Copyright (c) 2011 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 MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_
#define MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_
#include <map>
#include <string>
#include <vector>
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
// Statistics for one processed frame.
struct FrameStatistics {
FrameStatistics(size_t frame_number, size_t rtp_timestamp)
: frame_number(frame_number), rtp_timestamp(rtp_timestamp) {}
std::string ToString() const;
size_t frame_number = 0;
size_t rtp_timestamp = 0;
// Encoding.
int64_t encode_start_ns = 0;
int encode_return_code = 0;
bool encoding_successful = false;
size_t encode_time_us = 0;
size_t target_bitrate_kbps = 0;
size_t length_bytes = 0;
webrtc::FrameType frame_type = kVideoFrameDelta;
// Layering.
size_t spatial_idx = 0;
size_t temporal_idx = 0;
bool inter_layer_predicted = false;
bool non_ref_for_inter_layer_pred = true;
// H264 specific.
size_t max_nalu_size_bytes = 0;
// Decoding.
int64_t decode_start_ns = 0;
int decode_return_code = 0;
bool decoding_successful = false;
size_t decode_time_us = 0;
size_t decoded_width = 0;
size_t decoded_height = 0;
// Quantization.
int qp = -1;
// Quality.
float psnr_y = 0.0f;
float psnr_u = 0.0f;
float psnr_v = 0.0f;
float psnr = 0.0f; // 10 * log10(255^2 / (mse_y + mse_u + mse_v)).
float ssim = 0.0f; // 0.8 * ssim_y + 0.1 * (ssim_u + ssim_v).
};
struct VideoStatistics {
std::string ToString(std::string prefix) const;
size_t target_bitrate_kbps = 0;
float input_framerate_fps = 0.0f;
size_t spatial_idx = 0;
size_t temporal_idx = 0;
size_t width = 0;
size_t height = 0;
size_t length_bytes = 0;
size_t bitrate_kbps = 0;
float framerate_fps = 0;
float enc_speed_fps = 0.0f;
float dec_speed_fps = 0.0f;
float avg_delay_sec = 0.0f;
float max_key_frame_delay_sec = 0.0f;
float max_delta_frame_delay_sec = 0.0f;
float time_to_reach_target_bitrate_sec = 0.0f;
float avg_key_frame_size_bytes = 0.0f;
float avg_delta_frame_size_bytes = 0.0f;
float avg_qp = 0.0f;
float avg_psnr_y = 0.0f;
float avg_psnr_u = 0.0f;
float avg_psnr_v = 0.0f;
float avg_psnr = 0.0f;
float min_psnr = 0.0f;
float avg_ssim = 0.0f;
float min_ssim = 0.0f;
size_t num_input_frames = 0;
size_t num_encoded_frames = 0;
size_t num_decoded_frames = 0;
size_t num_key_frames = 0;
size_t num_spatial_resizes = 0;
size_t max_nalu_size_bytes = 0;
};
// Statistics for a sequence of processed frames. This class is not thread safe.
class Stats {
public:
Stats() = default;
~Stats() = default;
// Creates a FrameStatistics for the next frame to be processed.
FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx);
// Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
FrameStatistics* GetFrame(size_t frame_number, size_t spatial_idx);
FrameStatistics* GetFrameWithTimestamp(size_t timestamp, size_t spatial_idx);
std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
size_t first_frame_num,
size_t last_frame_num);
VideoStatistics SliceAndCalcAggregatedVideoStatistic(size_t first_frame_num,
size_t last_frame_num);
void PrintFrameStatistics();
size_t Size(size_t spatial_idx);
void Clear();
private:
FrameStatistics AggregateFrameStatistic(size_t frame_num,
size_t spatial_idx,
bool aggregate_independent_layers);
size_t CalcLayerTargetBitrateKbps(size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
size_t temporal_idx,
bool aggregate_independent_layers);
VideoStatistics SliceAndCalcVideoStatistic(size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
size_t temporal_idx,
bool aggregate_independent_layers);
void GetNumberOfEncodedLayers(size_t first_frame_num,
size_t last_frame_num,
size_t* num_encoded_spatial_layers,
size_t* num_encoded_temporal_layers);
// layer_idx -> stats.
std::map<size_t, std::vector<FrameStatistics>> layer_stats_;
// layer_idx -> rtp_timestamp -> frame_num.
std::map<size_t, std::map<size_t, size_t>> rtp_timestamp_to_frame_num_;
};
} // namespace test
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_CODECS_TEST_STATS_H_

View file

@ -1,282 +0,0 @@
/*
* Copyright (c) 2017 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 "modules/video_coding/codecs/test/test_config.h"
#include <sstream>
#include "media/base/h264_profile_level_id.h"
#include "media/base/mediaconstants.h"
#include "media/engine/simulcast.h"
#include "modules/video_coding/codecs/vp9/svc_config.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/checks.h"
#include "system_wrappers/include/cpu_info.h"
#include "test/video_codec_settings.h"
namespace webrtc {
namespace test {
namespace {
const int kBaseKeyFrameInterval = 3000;
const int kMaxBitrateBps = 5000 * 1000; // From kSimulcastFormats.
const int kMaxFramerateFps = 30;
const int kMaxQp = 56;
void ConfigureSimulcast(VideoCodec* codec_settings) {
const std::vector<webrtc::VideoStream> streams = cricket::GetSimulcastConfig(
codec_settings->numberOfSimulcastStreams, codec_settings->width,
codec_settings->height, kMaxBitrateBps, kMaxQp, kMaxFramerateFps, false);
for (size_t i = 0; i < streams.size(); ++i) {
SimulcastStream* ss = &codec_settings->simulcastStream[i];
ss->width = static_cast<uint16_t>(streams[i].width);
ss->height = static_cast<uint16_t>(streams[i].height);
ss->numberOfTemporalLayers =
static_cast<unsigned char>(*streams[i].num_temporal_layers);
ss->maxBitrate = streams[i].max_bitrate_bps / 1000;
ss->targetBitrate = streams[i].target_bitrate_bps / 1000;
ss->minBitrate = streams[i].min_bitrate_bps / 1000;
ss->qpMax = streams[i].max_qp;
ss->active = true;
}
}
void ConfigureSvc(VideoCodec* codec_settings) {
RTC_CHECK_EQ(kVideoCodecVP9, codec_settings->codecType);
const std::vector<SpatialLayer> layers =
GetSvcConfig(codec_settings->width, codec_settings->height,
codec_settings->VP9()->numberOfSpatialLayers,
codec_settings->VP9()->numberOfTemporalLayers, false);
for (size_t i = 0; i < layers.size(); ++i) {
codec_settings->spatialLayers[i] = layers[i];
}
}
std::string CodecSpecificToString(const VideoCodec& codec) {
std::stringstream ss;
switch (codec.codecType) {
case kVideoCodecVP8:
ss << "complexity: " << codec.VP8().complexity;
ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP8().numberOfTemporalLayers);
ss << "\ndenoising: " << codec.VP8().denoisingOn;
ss << "\nautomatic_resize: " << codec.VP8().automaticResizeOn;
ss << "\nframe_dropping: " << codec.VP8().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval;
break;
case kVideoCodecVP9:
ss << "complexity: " << codec.VP9().complexity;
ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP9().numberOfTemporalLayers);
ss << "\nnum_spatial_layers: "
<< static_cast<int>(codec.VP9().numberOfSpatialLayers);
ss << "\ndenoising: " << codec.VP9().denoisingOn;
ss << "\nframe_dropping: " << codec.VP9().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.VP9().keyFrameInterval;
ss << "\nadaptive_qp_mode: " << codec.VP9().adaptiveQpMode;
ss << "\nautomatic_resize: " << codec.VP9().automaticResizeOn;
ss << "\nflexible_mode: " << codec.VP9().flexibleMode;
break;
case kVideoCodecH264:
ss << "frame_dropping: " << codec.H264().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.H264().keyFrameInterval;
ss << "\nprofile: " << codec.H264().profile;
break;
default:
break;
}
ss << "\n";
return ss.str();
}
} // namespace
void TestConfig::SetCodecSettings(std::string codec_name,
size_t num_simulcast_streams,
size_t num_spatial_layers,
size_t num_temporal_layers,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on,
size_t width,
size_t height) {
this->codec_name = codec_name;
VideoCodecType codec_type = PayloadStringToCodecType(codec_name);
webrtc::test::CodecSettings(codec_type, &codec_settings);
// TODO(brandtr): Move the setting of |width| and |height| to the tests, and
// DCHECK that they are set before initializing the codec instead.
codec_settings.width = static_cast<uint16_t>(width);
codec_settings.height = static_cast<uint16_t>(height);
RTC_CHECK(num_simulcast_streams >= 1 &&
num_simulcast_streams <= kMaxSimulcastStreams);
RTC_CHECK(num_spatial_layers >= 1 && num_spatial_layers <= kMaxSpatialLayers);
RTC_CHECK(num_temporal_layers >= 1 &&
num_temporal_layers <= kMaxTemporalStreams);
// Simulcast is only available with VP8.
RTC_CHECK(num_simulcast_streams < 2 || codec_type == kVideoCodecVP8);
// Spatial scalability is only available with VP9.
RTC_CHECK(num_spatial_layers < 2 || codec_type == kVideoCodecVP9);
// Some base code requires numberOfSimulcastStreams to be set to zero
// when simulcast is not used.
codec_settings.numberOfSimulcastStreams =
num_simulcast_streams <= 1 ? 0
: static_cast<uint8_t>(num_simulcast_streams);
switch (codec_settings.codecType) {
case kVideoCodecVP8:
codec_settings.VP8()->numberOfTemporalLayers =
static_cast<uint8_t>(num_temporal_layers);
codec_settings.VP8()->denoisingOn = denoising_on;
codec_settings.VP8()->automaticResizeOn = spatial_resize_on;
codec_settings.VP8()->frameDroppingOn = frame_dropper_on;
codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval;
break;
case kVideoCodecVP9:
codec_settings.VP9()->numberOfTemporalLayers =
static_cast<uint8_t>(num_temporal_layers);
codec_settings.VP9()->denoisingOn = denoising_on;
codec_settings.VP9()->frameDroppingOn = frame_dropper_on;
codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval;
codec_settings.VP9()->automaticResizeOn = spatial_resize_on;
codec_settings.VP9()->numberOfSpatialLayers =
static_cast<uint8_t>(num_spatial_layers);
break;
case kVideoCodecH264:
codec_settings.H264()->frameDroppingOn = frame_dropper_on;
codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval;
break;
default:
break;
}
if (codec_settings.numberOfSimulcastStreams > 1) {
ConfigureSimulcast(&codec_settings);
} else if (codec_settings.codecType == kVideoCodecVP9 &&
codec_settings.VP9()->numberOfSpatialLayers > 1) {
ConfigureSvc(&codec_settings);
}
}
size_t TestConfig::NumberOfCores() const {
return use_single_core ? 1 : CpuInfo::DetectNumberOfCores();
}
size_t TestConfig::NumberOfTemporalLayers() const {
if (codec_settings.codecType == kVideoCodecVP8) {
return codec_settings.VP8().numberOfTemporalLayers;
} else if (codec_settings.codecType == kVideoCodecVP9) {
return codec_settings.VP9().numberOfTemporalLayers;
} else {
return 1;
}
}
size_t TestConfig::NumberOfSpatialLayers() const {
if (codec_settings.codecType == kVideoCodecVP9) {
return codec_settings.VP9().numberOfSpatialLayers;
} else {
return 1;
}
}
size_t TestConfig::NumberOfSimulcastStreams() const {
return codec_settings.numberOfSimulcastStreams;
}
std::vector<FrameType> TestConfig::FrameTypeForFrame(size_t frame_idx) const {
if (keyframe_interval > 0 && (frame_idx % keyframe_interval == 0)) {
return {kVideoFrameKey};
}
return {kVideoFrameDelta};
}
std::string TestConfig::ToString() const {
std::string codec_type = CodecTypeToPayloadString(codec_settings.codecType);
std::stringstream ss;
ss << "filename: " << filename;
ss << "\nnum_frames: " << num_frames;
ss << "\nmax_payload_size_bytes: " << max_payload_size_bytes;
ss << "\ndecode: " << decode;
ss << "\nuse_single_core: " << use_single_core;
ss << "\nmeasure_cpu: " << measure_cpu;
ss << "\nnum_cores: " << NumberOfCores();
ss << "\nkeyframe_interval: " << keyframe_interval;
ss << "\ncodec_type: " << codec_type;
ss << "\n--> codec_settings";
ss << "\nwidth: " << codec_settings.width;
ss << "\nheight: " << codec_settings.height;
ss << "\nmax_framerate_fps: " << codec_settings.maxFramerate;
ss << "\nstart_bitrate_kbps: " << codec_settings.startBitrate;
ss << "\nmax_bitrate_kbps: " << codec_settings.maxBitrate;
ss << "\nmin_bitrate_kbps: " << codec_settings.minBitrate;
ss << "\nmax_qp: " << codec_settings.qpMax;
ss << "\nnum_simulcast_streams : "
<< static_cast<int>(codec_settings.numberOfSimulcastStreams);
ss << "\n"
<< "--> codec_settings." << codec_type << "\n";
ss << CodecSpecificToString(codec_settings);
return ss.str();
}
SdpVideoFormat TestConfig::ToSdpVideoFormat() const {
if (codec_settings.codecType == kVideoCodecH264) {
const char* packetization_mode =
h264_codec_settings.packetization_mode ==
H264PacketizationMode::NonInterleaved
? "1"
: "0";
return SdpVideoFormat(
codec_name,
{{cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(H264::ProfileLevelId(
h264_codec_settings.profile, H264::kLevel3_1))},
{cricket::kH264FmtpPacketizationMode, packetization_mode}});
}
return SdpVideoFormat(codec_name);
}
std::string TestConfig::CodecName() const {
std::string name = codec_name;
if (name.empty()) {
name = CodecTypeToPayloadString(codec_settings.codecType);
}
if (codec_settings.codecType == kVideoCodecH264) {
if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
return name + "-CHP";
} else {
RTC_DCHECK_EQ(h264_codec_settings.profile,
H264::kProfileConstrainedBaseline);
return name + "-CBP";
}
}
return name;
}
std::string TestConfig::FilenameWithParams() const {
std::string implementation_type = hw_encoder ? "hw" : "sw";
return filename + "_" + CodecName() + "_" + implementation_type + "_" +
std::to_string(codec_settings.startBitrate);
}
bool TestConfig::IsAsyncCodec() const {
return hw_encoder || hw_decoder;
}
} // namespace test
} // namespace webrtc

View file

@ -1,115 +0,0 @@
/*
* Copyright (c) 2017 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 MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_
#define MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_
#include <string>
#include <vector>
#include "api/video_codecs/sdp_video_format.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/include/video_codec_interface.h"
namespace webrtc {
namespace test {
struct TestConfig {
class EncodedFrameChecker {
public:
virtual ~EncodedFrameChecker() = default;
virtual void CheckEncodedFrame(webrtc::VideoCodecType codec,
const EncodedImage& encoded_frame) const = 0;
};
void SetCodecSettings(std::string codec_name,
size_t num_simulcast_streams,
size_t num_spatial_layers,
size_t num_temporal_layers,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on,
size_t width,
size_t height);
size_t NumberOfCores() const;
size_t NumberOfTemporalLayers() const;
size_t NumberOfSpatialLayers() const;
size_t NumberOfSimulcastStreams() const;
std::vector<FrameType> FrameTypeForFrame(size_t frame_idx) const;
std::string ToString() const;
SdpVideoFormat ToSdpVideoFormat() const;
std::string CodecName() const;
std::string FilenameWithParams() const;
bool IsAsyncCodec() const;
// Plain name of YUV file to process without file extension.
std::string filename;
// File to process. This must be a video file in the YUV format.
std::string filepath;
// Number of frames to process.
size_t num_frames = 0;
// Bitstream constraints.
size_t max_payload_size_bytes = 1440;
// Should we decode the encoded frames?
bool decode = true;
// Force the encoder and decoder to use a single core for processing.
bool use_single_core = false;
// Should cpu usage be measured?
// If set to true, the encoding will run in real-time.
bool measure_cpu = false;
// If > 0: forces the encoder to create a keyframe every Nth frame.
size_t keyframe_interval = 0;
// Codec settings to use.
webrtc::VideoCodec codec_settings;
// Name of the codec being tested.
std::string codec_name;
// H.264 specific settings.
struct H264CodecSettings {
H264::Profile profile = H264::kProfileConstrainedBaseline;
H264PacketizationMode packetization_mode =
webrtc::H264PacketizationMode::NonInterleaved;
} h264_codec_settings;
// Should hardware accelerated codecs be used?
bool hw_encoder = false;
bool hw_decoder = false;
// Should the encoder be wrapped in a SimulcastEncoderAdapter?
bool simulcast_adapted_encoder = false;
// Should the hardware codecs be wrapped in software fallbacks?
bool sw_fallback_encoder = false;
bool sw_fallback_decoder = false;
// Custom checker that will be called for each frame.
const EncodedFrameChecker* encoded_frame_checker = nullptr;
// Print out frame level stats.
bool print_frame_level_stats = false;
};
} // namespace test
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_CODECS_TEST_TEST_CONFIG_H_

View file

@ -1,86 +0,0 @@
/*
* Copyright (c) 2017 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 "modules/video_coding/codecs/test/test_config.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/video_codec_settings.h"
using ::testing::ElementsAre;
namespace webrtc {
namespace test {
namespace {
const size_t kNumTemporalLayers = 2;
} // namespace
TEST(TestConfig, NumberOfCoresWithUseSingleCore) {
TestConfig config;
config.use_single_core = true;
EXPECT_EQ(1u, config.NumberOfCores());
}
TEST(TestConfig, NumberOfCoresWithoutUseSingleCore) {
TestConfig config;
config.use_single_core = false;
EXPECT_GE(config.NumberOfCores(), 1u);
}
TEST(TestConfig, NumberOfTemporalLayersIsOne) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecH264, &config.codec_settings);
EXPECT_EQ(1u, config.NumberOfTemporalLayers());
}
TEST(TestConfig, NumberOfTemporalLayers_Vp8) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.codec_settings.VP8()->numberOfTemporalLayers = kNumTemporalLayers;
EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
}
TEST(TestConfig, NumberOfTemporalLayers_Vp9) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecVP9, &config.codec_settings);
config.codec_settings.VP9()->numberOfTemporalLayers = kNumTemporalLayers;
EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
}
TEST(TestConfig, ForcedKeyFrameIntervalOff) {
TestConfig config;
config.keyframe_interval = 0;
EXPECT_THAT(config.FrameTypeForFrame(0), ElementsAre(kVideoFrameDelta));
EXPECT_THAT(config.FrameTypeForFrame(1), ElementsAre(kVideoFrameDelta));
EXPECT_THAT(config.FrameTypeForFrame(2), ElementsAre(kVideoFrameDelta));
}
TEST(TestConfig, ForcedKeyFrameIntervalOn) {
TestConfig config;
config.keyframe_interval = 3;
EXPECT_THAT(config.FrameTypeForFrame(0), ElementsAre(kVideoFrameKey));
EXPECT_THAT(config.FrameTypeForFrame(1), ElementsAre(kVideoFrameDelta));
EXPECT_THAT(config.FrameTypeForFrame(2), ElementsAre(kVideoFrameDelta));
EXPECT_THAT(config.FrameTypeForFrame(3), ElementsAre(kVideoFrameKey));
EXPECT_THAT(config.FrameTypeForFrame(4), ElementsAre(kVideoFrameDelta));
EXPECT_THAT(config.FrameTypeForFrame(5), ElementsAre(kVideoFrameDelta));
}
TEST(TestConfig, FilenameWithParams) {
TestConfig config;
config.filename = "filename";
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.hw_encoder = true;
config.codec_settings.startBitrate = 400;
EXPECT_EQ("filename_VP8_hw_400", config.FilenameWithParams());
}
} // namespace test
} // namespace webrtc

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017 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 "api/test/videocodec_test_fixture.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/video_codec_settings.h"
using ::testing::ElementsAre;
namespace webrtc {
namespace test {
using Config = VideoCodecTestFixture::Config;
namespace {
const size_t kNumTemporalLayers = 2;
} // namespace
TEST(Config, NumberOfCoresWithUseSingleCore) {
Config config;
config.use_single_core = true;
EXPECT_EQ(1u, config.NumberOfCores());
}
TEST(Config, NumberOfCoresWithoutUseSingleCore) {
Config config;
config.use_single_core = false;
EXPECT_GE(config.NumberOfCores(), 1u);
}
TEST(Config, NumberOfTemporalLayersIsOne) {
Config config;
webrtc::test::CodecSettings(kVideoCodecH264, &config.codec_settings);
EXPECT_EQ(1u, config.NumberOfTemporalLayers());
}
TEST(Config, NumberOfTemporalLayers_Vp8) {
Config config;
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.codec_settings.VP8()->numberOfTemporalLayers = kNumTemporalLayers;
EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
}
TEST(Config, NumberOfTemporalLayers_Vp9) {
Config config;
webrtc::test::CodecSettings(kVideoCodecVP9, &config.codec_settings);
config.codec_settings.VP9()->numberOfTemporalLayers = kNumTemporalLayers;
EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
}
} // namespace test
} // namespace webrtc

View file

@ -19,13 +19,17 @@
#endif
#include "api/video_codecs/sdp_video_format.h"
#include "call/video_config.h"
#include "common_types.h" // NOLINT(build/include)
#include "media/base/h264_profile_level_id.h"
#include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/simulcast.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
#include "media/engine/videoencodersoftwarefallbackwrapper.h"
#include "modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "modules/video_coding/codecs/vp9/svc_config.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_coding.h"
#include "rtc_base/checks.h"
@ -33,16 +37,95 @@
#include "rtc_base/event.h"
#include "rtc_base/file.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/cpu_info.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
#include "test/video_codec_settings.h"
namespace webrtc {
namespace test {
namespace {
using VideoStatistics = VideoCodecTestStats::VideoStatistics;
bool RunEncodeInRealTime(const TestConfig& config) {
namespace {
const int kBaseKeyFrameInterval = 3000;
const int kMaxBitrateBps = 5000 * 1000; // From kSimulcastFormats.
const int kMaxFramerateFps = 30;
const int kMaxQp = 56;
void ConfigureSimulcast(VideoCodec* codec_settings) {
const std::vector<webrtc::VideoStream> streams = cricket::GetSimulcastConfig(
codec_settings->numberOfSimulcastStreams, codec_settings->width,
codec_settings->height, kMaxBitrateBps, kMaxQp, kMaxFramerateFps, false);
for (size_t i = 0; i < streams.size(); ++i) {
SimulcastStream* ss = &codec_settings->simulcastStream[i];
ss->width = static_cast<uint16_t>(streams[i].width);
ss->height = static_cast<uint16_t>(streams[i].height);
ss->numberOfTemporalLayers =
static_cast<unsigned char>(*streams[i].num_temporal_layers);
ss->maxBitrate = streams[i].max_bitrate_bps / 1000;
ss->targetBitrate = streams[i].target_bitrate_bps / 1000;
ss->minBitrate = streams[i].min_bitrate_bps / 1000;
ss->qpMax = streams[i].max_qp;
ss->active = true;
}
}
void ConfigureSvc(VideoCodec* codec_settings) {
RTC_CHECK_EQ(kVideoCodecVP9, codec_settings->codecType);
const std::vector<SpatialLayer> layers =
GetSvcConfig(codec_settings->width, codec_settings->height,
codec_settings->VP9()->numberOfSpatialLayers,
codec_settings->VP9()->numberOfTemporalLayers, false);
for (size_t i = 0; i < layers.size(); ++i) {
codec_settings->spatialLayers[i] = layers[i];
}
}
std::string CodecSpecificToString(const VideoCodec& codec) {
char buf[1024];
rtc::SimpleStringBuilder ss(buf);
switch (codec.codecType) {
case kVideoCodecVP8:
ss << "complexity: " << codec.VP8().complexity;
ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP8().numberOfTemporalLayers);
ss << "\ndenoising: " << codec.VP8().denoisingOn;
ss << "\nautomatic_resize: " << codec.VP8().automaticResizeOn;
ss << "\nframe_dropping: " << codec.VP8().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.VP8().keyFrameInterval;
break;
case kVideoCodecVP9:
ss << "complexity: " << codec.VP9().complexity;
ss << "\nnum_temporal_layers: "
<< static_cast<int>(codec.VP9().numberOfTemporalLayers);
ss << "\nnum_spatial_layers: "
<< static_cast<int>(codec.VP9().numberOfSpatialLayers);
ss << "\ndenoising: " << codec.VP9().denoisingOn;
ss << "\nframe_dropping: " << codec.VP9().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.VP9().keyFrameInterval;
ss << "\nadaptive_qp_mode: " << codec.VP9().adaptiveQpMode;
ss << "\nautomatic_resize: " << codec.VP9().automaticResizeOn;
ss << "\nflexible_mode: " << codec.VP9().flexibleMode;
break;
case kVideoCodecH264:
ss << "frame_dropping: " << codec.H264().frameDroppingOn;
ss << "\nkey_frame_interval: " << codec.H264().keyFrameInterval;
ss << "\nprofile: " << codec.H264().profile;
break;
default:
break;
}
ss << "\n";
return ss.str();
}
bool RunEncodeInRealTime(const VideoCodecTestFixtureImpl::Config& config) {
if (config.measure_cpu) {
return true;
}
@ -54,8 +137,165 @@ bool RunEncodeInRealTime(const TestConfig& config) {
#endif
}
std::string FilenameWithParams(
const VideoCodecTestFixtureImpl::Config& config) {
std::string implementation_type = config.hw_encoder ? "hw" : "sw";
return config.filename + "_" + config.CodecName() + "_" +
implementation_type + "_" +
std::to_string(config.codec_settings.startBitrate);
}
} // namespace
VideoCodecTestFixtureImpl::Config::Config() = default;
void VideoCodecTestFixtureImpl::Config::SetCodecSettings(
std::string codec_name,
size_t num_simulcast_streams,
size_t num_spatial_layers,
size_t num_temporal_layers,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on,
size_t width,
size_t height) {
this->codec_name = codec_name;
VideoCodecType codec_type = PayloadStringToCodecType(codec_name);
webrtc::test::CodecSettings(codec_type, &codec_settings);
// TODO(brandtr): Move the setting of |width| and |height| to the tests, and
// DCHECK that they are set before initializing the codec instead.
codec_settings.width = static_cast<uint16_t>(width);
codec_settings.height = static_cast<uint16_t>(height);
RTC_CHECK(num_simulcast_streams >= 1 &&
num_simulcast_streams <= kMaxSimulcastStreams);
RTC_CHECK(num_spatial_layers >= 1 && num_spatial_layers <= kMaxSpatialLayers);
RTC_CHECK(num_temporal_layers >= 1 &&
num_temporal_layers <= kMaxTemporalStreams);
// Simulcast is only available with VP8.
RTC_CHECK(num_simulcast_streams < 2 || codec_type == kVideoCodecVP8);
// Spatial scalability is only available with VP9.
RTC_CHECK(num_spatial_layers < 2 || codec_type == kVideoCodecVP9);
// Some base code requires numberOfSimulcastStreams to be set to zero
// when simulcast is not used.
codec_settings.numberOfSimulcastStreams =
num_simulcast_streams <= 1 ? 0
: static_cast<uint8_t>(num_simulcast_streams);
switch (codec_settings.codecType) {
case kVideoCodecVP8:
codec_settings.VP8()->numberOfTemporalLayers =
static_cast<uint8_t>(num_temporal_layers);
codec_settings.VP8()->denoisingOn = denoising_on;
codec_settings.VP8()->automaticResizeOn = spatial_resize_on;
codec_settings.VP8()->frameDroppingOn = frame_dropper_on;
codec_settings.VP8()->keyFrameInterval = kBaseKeyFrameInterval;
break;
case kVideoCodecVP9:
codec_settings.VP9()->numberOfTemporalLayers =
static_cast<uint8_t>(num_temporal_layers);
codec_settings.VP9()->denoisingOn = denoising_on;
codec_settings.VP9()->frameDroppingOn = frame_dropper_on;
codec_settings.VP9()->keyFrameInterval = kBaseKeyFrameInterval;
codec_settings.VP9()->automaticResizeOn = spatial_resize_on;
codec_settings.VP9()->numberOfSpatialLayers =
static_cast<uint8_t>(num_spatial_layers);
break;
case kVideoCodecH264:
codec_settings.H264()->frameDroppingOn = frame_dropper_on;
codec_settings.H264()->keyFrameInterval = kBaseKeyFrameInterval;
break;
default:
break;
}
if (codec_settings.numberOfSimulcastStreams > 1) {
ConfigureSimulcast(&codec_settings);
} else if (codec_settings.codecType == kVideoCodecVP9 &&
codec_settings.VP9()->numberOfSpatialLayers > 1) {
ConfigureSvc(&codec_settings);
}
}
size_t VideoCodecTestFixtureImpl::Config::NumberOfCores() const {
return use_single_core ? 1 : CpuInfo::DetectNumberOfCores();
}
size_t VideoCodecTestFixtureImpl::Config::NumberOfTemporalLayers() const {
if (codec_settings.codecType == kVideoCodecVP8) {
return codec_settings.VP8().numberOfTemporalLayers;
} else if (codec_settings.codecType == kVideoCodecVP9) {
return codec_settings.VP9().numberOfTemporalLayers;
} else {
return 1;
}
}
size_t VideoCodecTestFixtureImpl::Config::NumberOfSpatialLayers() const {
if (codec_settings.codecType == kVideoCodecVP9) {
return codec_settings.VP9().numberOfSpatialLayers;
} else {
return 1;
}
}
size_t VideoCodecTestFixtureImpl::Config::NumberOfSimulcastStreams() const {
return codec_settings.numberOfSimulcastStreams;
}
std::string VideoCodecTestFixtureImpl::Config::ToString() const {
std::string codec_type = CodecTypeToPayloadString(codec_settings.codecType);
std::stringstream ss;
ss << "filename: " << filename;
ss << "\nnum_frames: " << num_frames;
ss << "\nmax_payload_size_bytes: " << max_payload_size_bytes;
ss << "\ndecode: " << decode;
ss << "\nuse_single_core: " << use_single_core;
ss << "\nmeasure_cpu: " << measure_cpu;
ss << "\nnum_cores: " << NumberOfCores();
ss << "\nkeyframe_interval: " << keyframe_interval;
ss << "\ncodec_type: " << codec_type;
ss << "\n--> codec_settings";
ss << "\nwidth: " << codec_settings.width;
ss << "\nheight: " << codec_settings.height;
ss << "\nmax_framerate_fps: " << codec_settings.maxFramerate;
ss << "\nstart_bitrate_kbps: " << codec_settings.startBitrate;
ss << "\nmax_bitrate_kbps: " << codec_settings.maxBitrate;
ss << "\nmin_bitrate_kbps: " << codec_settings.minBitrate;
ss << "\nmax_qp: " << codec_settings.qpMax;
ss << "\nnum_simulcast_streams : "
<< static_cast<int>(codec_settings.numberOfSimulcastStreams);
ss << "\n"
<< "--> codec_settings." << codec_type << "\n";
ss << CodecSpecificToString(codec_settings);
return ss.str();
}
std::string VideoCodecTestFixtureImpl::Config::CodecName() const {
std::string name = codec_name;
if (name.empty()) {
name = CodecTypeToPayloadString(codec_settings.codecType);
}
if (codec_settings.codecType == kVideoCodecH264) {
if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
return name + "-CHP";
} else {
RTC_DCHECK_EQ(h264_codec_settings.profile,
H264::kProfileConstrainedBaseline);
return name + "-CBP";
}
}
return name;
}
bool VideoCodecTestFixtureImpl::Config::IsAsyncCodec() const {
return hw_encoder || hw_decoder;
}
// TODO(kthelgason): Move this out of the test fixture impl and
// make available as a shared utility class.
void VideoCodecTestFixtureImpl::H264KeyframeChecker::
@ -94,7 +334,7 @@ void VideoCodecTestFixtureImpl::H264KeyframeChecker::
class VideoCodecTestFixtureImpl::CpuProcessTime final {
public:
explicit CpuProcessTime(const TestConfig& config) : config_(config) {}
explicit CpuProcessTime(const Config& config) : config_(config) {}
~CpuProcessTime() {}
void Start() {
@ -122,13 +362,13 @@ class VideoCodecTestFixtureImpl::CpuProcessTime final {
return static_cast<double>(cpu_time_) / wallclock_time_ * 100.0;
}
const TestConfig config_;
const Config config_;
int64_t cpu_time_ = 0;
int64_t wallclock_time_ = 0;
};
VideoCodecTestFixtureImpl::
VideoCodecTestFixtureImpl(TestConfig config)
VideoCodecTestFixtureImpl(Config config)
: config_(config) {
#if defined(WEBRTC_ANDROID)
InitializeAndroidObjects();
@ -137,7 +377,7 @@ VideoCodecTestFixtureImpl::
VideoCodecTestFixtureImpl::
VideoCodecTestFixtureImpl(
TestConfig config,
Config config,
std::unique_ptr<VideoDecoderFactory> decoder_factory,
std::unique_ptr<VideoEncoderFactory> encoder_factory)
: decoder_factory_(std::move(decoder_factory)),
@ -345,7 +585,21 @@ VideoCodecTestFixtureImpl::CreateEncoderFactory() {
}
void VideoCodecTestFixtureImpl::CreateEncoderAndDecoder() {
const SdpVideoFormat format = config_.ToSdpVideoFormat();
SdpVideoFormat::Parameters params;
if (config_.codec_settings.codecType == kVideoCodecH264) {
const char* packetization_mode =
config_.h264_codec_settings.packetization_mode ==
H264PacketizationMode::NonInterleaved
? "1"
: "0";
params = {{cricket::kH264FmtpProfileLevelId,
*H264::ProfileLevelIdToString(H264::ProfileLevelId(
config_.h264_codec_settings.profile, H264::kLevel3_1))},
{cricket::kH264FmtpPacketizationMode, packetization_mode}};
} else {
params = {};
}
SdpVideoFormat format(config_.codec_name);
if (!decoder_factory_)
decoder_factory_ = CreateDecoderFactory();
if (!encoder_factory_)
@ -393,7 +647,7 @@ void VideoCodecTestFixtureImpl::DestroyEncoderAndDecoder() {
encoder_.reset();
}
Stats VideoCodecTestFixtureImpl::GetStats() {
VideoCodecTestStats& VideoCodecTestFixtureImpl::GetStats() {
return stats_;
}
@ -422,7 +676,7 @@ void VideoCodecTestFixtureImpl::SetUpAndInitObjects(
simulcast_svc_idx < num_simulcast_or_spatial_layers;
++simulcast_svc_idx) {
const std::string output_filename_base =
OutputPath() + config_.FilenameWithParams() + "_" +
OutputPath() + FilenameWithParams(config_) + "_" +
std::to_string(simulcast_svc_idx);
if (visualization_params->save_encoded_ivf) {
@ -480,7 +734,7 @@ void VideoCodecTestFixtureImpl::ReleaseAndCloseObjects(
void VideoCodecTestFixtureImpl::PrintSettings(
rtc::test::TaskQueueForTest* task_queue) const {
printf("==> TestConfig\n");
printf("==> Config\n");
printf("%s\n", config_.ToString().c_str());
printf("==> Codec names\n");

View file

@ -20,8 +20,7 @@
#include "api/video_codecs/video_encoder_factory.h"
#include "common_types.h" // NOLINT(build/include)
#include "common_video/h264/h264_common.h"
#include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/test_config.h"
#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
#include "modules/video_coding/codecs/test/videoprocessor.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/task_queue_for_test.h"
@ -38,15 +37,15 @@ namespace test {
class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
// Verifies that all H.264 keyframes contain SPS/PPS/IDR NALUs.
public:
class H264KeyframeChecker : public TestConfig::EncodedFrameChecker {
class H264KeyframeChecker : public EncodedFrameChecker {
public:
void CheckEncodedFrame(webrtc::VideoCodecType codec,
const EncodedImage& encoded_frame) const override;
};
explicit VideoCodecTestFixtureImpl(TestConfig config);
explicit VideoCodecTestFixtureImpl(Config config);
VideoCodecTestFixtureImpl(
TestConfig config,
Config config,
std::unique_ptr<VideoDecoderFactory> decoder_factory,
std::unique_ptr<VideoEncoderFactory> encoder_factory);
~VideoCodecTestFixtureImpl() override;
@ -57,7 +56,7 @@ class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
const BitstreamThresholds* bs_thresholds,
const VisualizationParams* visualization_params) override;
Stats GetStats() override;
VideoCodecTestStats& GetStats() override;
private:
class CpuProcessTime;
@ -78,7 +77,8 @@ class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
const std::vector<QualityThresholds>* quality_thresholds,
const BitstreamThresholds* bs_thresholds);
void VerifyVideoStatistic(const VideoStatistics& video_stat,
void VerifyVideoStatistic(
const VideoCodecTestStats::VideoStatistics& video_stat,
const RateControlThresholds* rc_thresholds,
const QualityThresholds* quality_thresholds,
const BitstreamThresholds* bs_thresholds,
@ -96,8 +96,8 @@ class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
VideoProcessor::VideoDecoderList decoders_;
// Helper objects.
TestConfig config_;
Stats stats_;
Config config_;
VideoCodecTestStatsImpl stats_;
std::unique_ptr<FrameReader> source_frame_reader_;
VideoProcessor::IvfFileWriterList encoded_frame_writers_;
VideoProcessor::FrameWriterList decoded_frame_writers_;

View file

@ -12,7 +12,6 @@
#include "api/test/create_videocodec_test_fixture.h"
#include "media/base/mediaconstants.h"
#include "modules/video_coding/codecs/test/test_config.h"
#include "modules/video_coding/utility/vp8_header_parser.h"
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"
#include "rtc_base/ptr_util.h"
@ -22,6 +21,8 @@
namespace webrtc {
namespace test {
using VideoStatistics = VideoCodecTestStats::VideoStatistics;
namespace {
// Codec settings.
const int kCifWidth = 352;
@ -33,7 +34,7 @@ const size_t kBitrateRdPerfKbps[] = {100, 200, 300, 400, 500, 600,
1800, 2000, 2200, 2500};
const size_t kNumFirstFramesToSkipAtRdPerfAnalysis = 60;
class QpFrameChecker : public TestConfig::EncodedFrameChecker {
class QpFrameChecker : public VideoCodecTestFixture::EncodedFrameChecker {
public:
void CheckEncodedFrame(webrtc::VideoCodecType codec,
const EncodedImage& encoded_frame) const override {
@ -51,8 +52,8 @@ class QpFrameChecker : public TestConfig::EncodedFrameChecker {
}
};
TestConfig CreateTestConfig() {
TestConfig config;
VideoCodecTestFixture::Config CreateConfig() {
VideoCodecTestFixture::Config config;
config.filename = "foreman_cif";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = kNumFramesLong;
@ -88,7 +89,7 @@ void PrintRdPerf(std::map<size_t, std::vector<VideoStatistics>> rd_stats) {
#if !defined(RTC_DISABLE_VP9)
TEST(VideoCodecTestLibvpx, HighBitrateVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
kCifWidth, kCifHeight);
config.num_frames = kNumFramesShort;
@ -108,7 +109,7 @@ TEST(VideoCodecTestLibvpx, HighBitrateVP9) {
}
TEST(VideoCodecTestLibvpx, ChangeBitrateVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -133,7 +134,7 @@ TEST(VideoCodecTestLibvpx, ChangeBitrateVP9) {
}
TEST(VideoCodecTestLibvpx, ChangeFramerateVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, false,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -160,7 +161,7 @@ TEST(VideoCodecTestLibvpx, ChangeFramerateVP9) {
}
TEST(VideoCodecTestLibvpx, DenoiserOnVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, true, true, false,
kCifWidth, kCifHeight);
config.num_frames = kNumFramesShort;
@ -180,7 +181,7 @@ TEST(VideoCodecTestLibvpx, DenoiserOnVP9) {
}
TEST(VideoCodecTestLibvpx, VeryLowBitrateVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp9CodecName, 1, 1, 1, false, true, true,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -204,7 +205,7 @@ TEST(VideoCodecTestLibvpx, VeryLowBitrateVP9) {
#endif // !defined(RTC_DISABLE_VP9)
TEST(VideoCodecTestLibvpx, HighBitrateVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
kCifWidth, kCifHeight);
config.num_frames = kNumFramesShort;
@ -242,7 +243,7 @@ TEST(VideoCodecTestLibvpx, HighBitrateVP8) {
#define MAYBE_ChangeBitrateVP8 ChangeBitrateVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_ChangeBitrateVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -277,7 +278,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_ChangeBitrateVP8) {
#define MAYBE_ChangeFramerateVP8 ChangeFramerateVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_ChangeFramerateVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, true, true, false,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -317,7 +318,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_ChangeFramerateVP8) {
#define MAYBE_TemporalLayersVP8 TemporalLayersVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_TemporalLayersVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 3, true, true, false,
kCifWidth, kCifHeight);
const auto frame_checker = rtc::MakeUnique<QpFrameChecker>();
@ -353,7 +354,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_TemporalLayersVP8) {
#define MAYBE_MultiresVP8 MultiresVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_MultiresVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
@ -379,7 +380,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_MultiresVP8) {
#define MAYBE_SimulcastVP8 SimulcastVP8
#endif
TEST(VideoCodecTestLibvpx, MAYBE_SimulcastVP8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
@ -406,7 +407,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_SimulcastVP8) {
#define MAYBE_SvcVP9 SvcVP9
#endif
TEST(VideoCodecTestLibvpx, MAYBE_SvcVP9) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.filename = "ConferenceMotion_1280_720_50";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 100;
@ -427,7 +428,7 @@ TEST(VideoCodecTestLibvpx, MAYBE_SvcVP9) {
}
TEST(VideoCodecTestLibvpx, DISABLED_MultiresVP8RdPerf) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.filename = "FourPeople_1280x720_30";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 300;
@ -454,7 +455,7 @@ TEST(VideoCodecTestLibvpx, DISABLED_MultiresVP8RdPerf) {
}
TEST(VideoCodecTestLibvpx, DISABLED_SvcVP9RdPerf) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.filename = "FourPeople_1280x720_30";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = 300;

View file

@ -26,8 +26,8 @@ namespace {
const int kForemanNumFrames = 300;
const int kForemanFramerateFps = 30;
TestConfig CreateTestConfig() {
TestConfig config;
VideoCodecTestFixture::Config CreateConfig() {
VideoCodecTestFixture::Config config;
config.filename = "foreman_cif";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = kForemanNumFrames;
@ -38,7 +38,7 @@ TestConfig CreateTestConfig() {
} // namespace
TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsVp8) {
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kVp8CodecName, 1, 1, 1, false, false, false,
352, 288);
auto fixture = CreateVideoCodecTestFixture(config);
@ -59,7 +59,7 @@ TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsVp8) {
}
TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsH264CBP) {
auto config = CreateTestConfig();
auto config = CreateConfig();
const auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
config.encoded_frame_checker = frame_checker.get();
@ -85,7 +85,7 @@ TEST(VideoCodecTestMediaCodec, ForemanCif500kbpsH264CBP) {
// TODO(brandtr): Enable this test when we have trybots/buildbots with
// HW encoders that support CHP.
TEST(VideoCodecTestMediaCodec, DISABLED_ForemanCif500kbpsH264CHP) {
auto config = CreateTestConfig();
auto config = CreateConfig();
const auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
@ -111,7 +111,7 @@ TEST(VideoCodecTestMediaCodec, DISABLED_ForemanCif500kbpsH264CHP) {
}
TEST(VideoCodecTestMediaCodec, ForemanMixedRes100kbpsVp8H264) {
auto config = CreateTestConfig();
auto config = CreateConfig();
const int kNumFrames = 30;
const std::vector<std::string> codecs = {cricket::kVp8CodecName,
cricket::kH264CodecName};

View file

@ -25,8 +25,8 @@ const int kCifWidth = 352;
const int kCifHeight = 288;
const int kNumFrames = 100;
TestConfig CreateTestConfig() {
TestConfig config;
VideoCodecTestFixture::Config CreateConfig() {
VideoCodecTestFixture::Config config;
config.filename = "foreman_cif";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = kNumFrames;
@ -41,7 +41,7 @@ TestConfig CreateTestConfig() {
TEST(VideoCodecTestOpenH264, ConstantHighBitrate) {
auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, true, false,
kCifWidth, kCifHeight);
config.encoded_frame_checker = frame_checker.get();
@ -63,7 +63,7 @@ TEST(VideoCodecTestOpenH264, ConstantHighBitrate) {
TEST(VideoCodecTestOpenH264, SingleNalUnit) {
auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
auto config = CreateTestConfig();
auto config = CreateConfig();
config.h264_codec_settings.packetization_mode =
H264PacketizationMode::SingleNalUnit;
config.max_payload_size_bytes = 500;

View file

@ -55,7 +55,7 @@ class VideoCodecTestParameterized
size_t height,
size_t framerate,
const std::string& filename) {
TestConfig config;
VideoCodecTestFixture::Config config;
config.filename = filename;
config.filepath = ResourcePath(filename, "yuv");
config.use_single_core = kUseSingleCore;

View file

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
#include <algorithm>
#include <cmath>
@ -21,77 +21,18 @@
namespace webrtc {
namespace test {
using FrameStatistics = VideoCodecTestStats::FrameStatistics;
using VideoStatistics = VideoCodecTestStats::VideoStatistics;
namespace {
const int kMaxBitrateMismatchPercent = 20;
}
std::string FrameStatistics::ToString() const {
std::stringstream ss;
ss << "frame_number " << frame_number;
ss << " decoded_width " << decoded_width;
ss << " decoded_height " << decoded_height;
ss << " spatial_idx " << spatial_idx;
ss << " temporal_idx " << temporal_idx;
ss << " inter_layer_predicted " << inter_layer_predicted;
ss << " non_ref_for_inter_layer_pred " << non_ref_for_inter_layer_pred;
ss << " frame_type " << frame_type;
ss << " length_bytes " << length_bytes;
ss << " qp " << qp;
ss << " psnr " << psnr;
ss << " psnr_y " << psnr_y;
ss << " psnr_u " << psnr_u;
ss << " psnr_v " << psnr_v;
ss << " ssim " << ssim;
ss << " encode_time_us " << encode_time_us;
ss << " decode_time_us " << decode_time_us;
ss << " rtp_timestamp " << rtp_timestamp;
ss << " target_bitrate_kbps " << target_bitrate_kbps;
return ss.str();
}
VideoCodecTestStatsImpl::VideoCodecTestStatsImpl() = default;
VideoCodecTestStatsImpl::~VideoCodecTestStatsImpl() = default;
std::string VideoStatistics::ToString(std::string prefix) const {
std::stringstream ss;
ss << prefix << "target_bitrate_kbps: " << target_bitrate_kbps;
ss << "\n" << prefix << "input_framerate_fps: " << input_framerate_fps;
ss << "\n" << prefix << "spatial_idx: " << spatial_idx;
ss << "\n" << prefix << "temporal_idx: " << temporal_idx;
ss << "\n" << prefix << "width: " << width;
ss << "\n" << prefix << "height: " << height;
ss << "\n" << prefix << "length_bytes: " << length_bytes;
ss << "\n" << prefix << "bitrate_kbps: " << bitrate_kbps;
ss << "\n" << prefix << "framerate_fps: " << framerate_fps;
ss << "\n" << prefix << "enc_speed_fps: " << enc_speed_fps;
ss << "\n" << prefix << "dec_speed_fps: " << dec_speed_fps;
ss << "\n" << prefix << "avg_delay_sec: " << avg_delay_sec;
ss << "\n"
<< prefix << "max_key_frame_delay_sec: " << max_key_frame_delay_sec;
ss << "\n"
<< prefix << "max_delta_frame_delay_sec: " << max_delta_frame_delay_sec;
ss << "\n"
<< prefix << "time_to_reach_target_bitrate_sec: "
<< time_to_reach_target_bitrate_sec;
ss << "\n"
<< prefix << "avg_key_frame_size_bytes: " << avg_key_frame_size_bytes;
ss << "\n"
<< prefix << "avg_delta_frame_size_bytes: " << avg_delta_frame_size_bytes;
ss << "\n" << prefix << "avg_qp: " << avg_qp;
ss << "\n" << prefix << "avg_psnr: " << avg_psnr;
ss << "\n" << prefix << "min_psnr: " << min_psnr;
ss << "\n" << prefix << "avg_ssim: " << avg_ssim;
ss << "\n" << prefix << "min_ssim: " << min_ssim;
ss << "\n" << prefix << "num_input_frames: " << num_input_frames;
ss << "\n" << prefix << "num_encoded_frames: " << num_encoded_frames;
ss << "\n" << prefix << "num_decoded_frames: " << num_decoded_frames;
ss << "\n"
<< prefix
<< "num_dropped_frames: " << num_input_frames - num_encoded_frames;
ss << "\n" << prefix << "num_key_frames: " << num_key_frames;
ss << "\n" << prefix << "num_spatial_resizes: " << num_spatial_resizes;
ss << "\n" << prefix << "max_nalu_size_bytes: " << max_nalu_size_bytes;
return ss.str();
}
FrameStatistics* Stats::AddFrame(size_t timestamp, size_t layer_idx) {
FrameStatistics* VideoCodecTestStatsImpl::AddFrame(size_t timestamp,
size_t layer_idx) {
RTC_DCHECK(rtp_timestamp_to_frame_num_[layer_idx].find(timestamp) ==
rtp_timestamp_to_frame_num_[layer_idx].end());
const size_t frame_num = layer_stats_[layer_idx].size();
@ -100,12 +41,14 @@ FrameStatistics* Stats::AddFrame(size_t timestamp, size_t layer_idx) {
return &layer_stats_[layer_idx].back();
}
FrameStatistics* Stats::GetFrame(size_t frame_num, size_t layer_idx) {
FrameStatistics* VideoCodecTestStatsImpl::GetFrame(size_t frame_num,
size_t layer_idx) {
RTC_CHECK_LT(frame_num, layer_stats_[layer_idx].size());
return &layer_stats_[layer_idx][frame_num];
}
FrameStatistics* Stats::GetFrameWithTimestamp(size_t timestamp,
FrameStatistics* VideoCodecTestStatsImpl::GetFrameWithTimestamp(
size_t timestamp,
size_t layer_idx) {
RTC_DCHECK(rtp_timestamp_to_frame_num_[layer_idx].find(timestamp) !=
rtp_timestamp_to_frame_num_[layer_idx].end());
@ -113,7 +56,8 @@ FrameStatistics* Stats::GetFrameWithTimestamp(size_t timestamp,
return GetFrame(rtp_timestamp_to_frame_num_[layer_idx][timestamp], layer_idx);
}
std::vector<VideoStatistics> Stats::SliceAndCalcLayerVideoStatistic(
std::vector<VideoStatistics>
VideoCodecTestStatsImpl::SliceAndCalcLayerVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) {
std::vector<VideoStatistics> layer_stats;
@ -138,7 +82,7 @@ std::vector<VideoStatistics> Stats::SliceAndCalcLayerVideoStatistic(
return layer_stats;
}
VideoStatistics Stats::SliceAndCalcAggregatedVideoStatistic(
VideoStatistics VideoCodecTestStatsImpl::SliceAndCalcAggregatedVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) {
size_t num_spatial_layers = 0;
@ -153,7 +97,7 @@ VideoStatistics Stats::SliceAndCalcAggregatedVideoStatistic(
num_temporal_layers - 1, true);
}
void Stats::PrintFrameStatistics() {
void VideoCodecTestStatsImpl::PrintFrameStatistics() {
for (size_t frame_num = 0; frame_num < layer_stats_[0].size(); ++frame_num) {
for (const auto& it : layer_stats_) {
const FrameStatistics& frame_stat = it.second[frame_num];
@ -162,16 +106,16 @@ void Stats::PrintFrameStatistics() {
}
}
size_t Stats::Size(size_t spatial_idx) {
size_t VideoCodecTestStatsImpl::Size(size_t spatial_idx) {
return layer_stats_[spatial_idx].size();
}
void Stats::Clear() {
void VideoCodecTestStatsImpl::Clear() {
layer_stats_.clear();
rtp_timestamp_to_frame_num_.clear();
}
FrameStatistics Stats::AggregateFrameStatistic(
FrameStatistics VideoCodecTestStatsImpl::AggregateFrameStatistic(
size_t frame_num,
size_t spatial_idx,
bool aggregate_independent_layers) {
@ -190,7 +134,8 @@ FrameStatistics Stats::AggregateFrameStatistic(
return frame_stat;
}
size_t Stats::CalcLayerTargetBitrateKbps(size_t first_frame_num,
size_t VideoCodecTestStatsImpl::CalcLayerTargetBitrateKbps(
size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
size_t temporal_idx,
@ -216,7 +161,7 @@ size_t Stats::CalcLayerTargetBitrateKbps(size_t first_frame_num,
return target_bitrate_kbps;
}
VideoStatistics Stats::SliceAndCalcVideoStatistic(
VideoStatistics VideoCodecTestStatsImpl::SliceAndCalcVideoStatistic(
size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
@ -380,7 +325,8 @@ VideoStatistics Stats::SliceAndCalcVideoStatistic(
return video_stat;
}
void Stats::GetNumberOfEncodedLayers(size_t first_frame_num,
void VideoCodecTestStatsImpl::GetNumberOfEncodedLayers(
size_t first_frame_num,
size_t last_frame_num,
size_t* num_encoded_spatial_layers,
size_t* num_encoded_temporal_layers) {

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2011 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 MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_
#define MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_
#include <map>
#include <string>
#include <vector>
#include "api/test/videocodec_test_stats.h" // NOLINT(build/include)
#include "common_types.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
// Statistics for a sequence of processed frames. This class is not thread safe.
class VideoCodecTestStatsImpl : public VideoCodecTestStats {
public:
VideoCodecTestStatsImpl();
~VideoCodecTestStatsImpl() override;
// Creates a FrameStatistics for the next frame to be processed.
FrameStatistics* AddFrame(size_t timestamp, size_t spatial_idx) override;
// Returns the FrameStatistics corresponding to |frame_number| or |timestamp|.
FrameStatistics* GetFrame(size_t frame_number, size_t spatial_idx) override;
FrameStatistics* GetFrameWithTimestamp(size_t timestamp,
size_t spatial_idx) override;
std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) override;
VideoStatistics SliceAndCalcAggregatedVideoStatistic(
size_t first_frame_num,
size_t last_frame_num) override;
void PrintFrameStatistics() override;
size_t Size(size_t spatial_idx) override;
void Clear() override;
private:
VideoCodecTestStats::FrameStatistics AggregateFrameStatistic(
size_t frame_num,
size_t spatial_idx,
bool aggregate_independent_layers);
size_t CalcLayerTargetBitrateKbps(size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
size_t temporal_idx,
bool aggregate_independent_layers);
VideoCodecTestStats::VideoStatistics SliceAndCalcVideoStatistic(
size_t first_frame_num,
size_t last_frame_num,
size_t spatial_idx,
size_t temporal_idx,
bool aggregate_independent_layers);
void GetNumberOfEncodedLayers(size_t first_frame_num,
size_t last_frame_num,
size_t* num_encoded_spatial_layers,
size_t* num_encoded_temporal_layers);
// layer_idx -> stats.
std::map<size_t, std::vector<FrameStatistics>> layer_stats_;
// layer_idx -> rtp_timestamp -> frame_num.
std::map<size_t, std::map<size_t, size_t>> rtp_timestamp_to_frame_num_;
};
} // namespace test
} // namespace webrtc
#endif // MODULES_VIDEO_CODING_CODECS_TEST_VIDEOCODEC_TEST_STATS_IMPL_H_

View file

@ -8,18 +8,19 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
using FrameStatistics = VideoCodecTestStatsImpl::FrameStatistics;
namespace {
const size_t kTimestamp = 12345;
} // namespace
TEST(StatsTest, AddFrame) {
Stats stats;
VideoCodecTestStatsImpl stats;
FrameStatistics* frame_stat = stats.AddFrame(kTimestamp, 0);
EXPECT_EQ(0ull, frame_stat->frame_number);
EXPECT_EQ(kTimestamp, frame_stat->rtp_timestamp);
@ -27,7 +28,7 @@ TEST(StatsTest, AddFrame) {
}
TEST(StatsTest, GetFrame) {
Stats stats;
VideoCodecTestStatsImpl stats;
stats.AddFrame(kTimestamp, 0);
FrameStatistics* frame_stat = stats.GetFrame(0u, 0);
EXPECT_EQ(0u, frame_stat->frame_number);
@ -35,7 +36,7 @@ TEST(StatsTest, GetFrame) {
}
TEST(StatsTest, AddFrames) {
Stats stats;
VideoCodecTestStatsImpl stats;
const size_t kNumFrames = 1000;
for (size_t i = 0; i < kNumFrames; ++i) {
FrameStatistics* frame_stat = stats.AddFrame(kTimestamp + i, 0);
@ -51,7 +52,7 @@ TEST(StatsTest, AddFrames) {
}
TEST(StatsTest, AddFrameLayering) {
Stats stats;
VideoCodecTestStatsImpl stats;
for (size_t i = 0; i < 3; ++i) {
stats.AddFrame(kTimestamp + i, i);
FrameStatistics* frame_stat = stats.GetFrame(0u, i);

View file

@ -23,8 +23,8 @@ namespace test {
namespace {
const int kForemanNumFrames = 300;
TestConfig CreateTestConfig() {
TestConfig config;
VideoCodecTestFixture::Config CreateConfig() {
VideoCodecTestFixture::Config config;
config.filename = "foreman_cif";
config.filepath = ResourcePath(config.filename, "yuv");
config.num_frames = kForemanNumFrames;
@ -34,7 +34,7 @@ TestConfig CreateTestConfig() {
}
std::unique_ptr<VideoCodecTestFixture> CreateTestFixtureWithConfig(
TestConfig config) {
VideoCodecTestFixture::Config config) {
auto decoder_factory = CreateObjCDecoderFactory();
auto encoder_factory = CreateObjCEncoderFactory();
return CreateVideoCodecTestFixture(
@ -55,7 +55,7 @@ std::unique_ptr<VideoCodecTestFixture> CreateTestFixtureWithConfig(
MAYBE_TEST(VideoCodecTestVideoToolbox, ForemanCif500kbpsH264CBP) {
const auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
auto config = CreateTestConfig();
auto config = CreateConfig();
config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
352, 288);
config.encoded_frame_checker = frame_checker.get();
@ -72,7 +72,7 @@ MAYBE_TEST(VideoCodecTestVideoToolbox, ForemanCif500kbpsH264CBP) {
MAYBE_TEST(VideoCodecTestVideoToolbox, ForemanCif500kbpsH264CHP) {
const auto frame_checker = rtc::MakeUnique<
VideoCodecTestFixtureImpl::H264KeyframeChecker>();
auto config = CreateTestConfig();
auto config = CreateConfig();
config.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
352, 288);

View file

@ -32,13 +32,14 @@
namespace webrtc {
namespace test {
namespace {
using FrameStatistics = VideoCodecTestStats::FrameStatistics;
namespace {
const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
const int kMaxBufferedInputFrames = 10;
size_t GetMaxNaluSizeBytes(const EncodedImage& encoded_frame,
const TestConfig& config) {
const VideoCodecTestFixture::Config& config) {
if (config.codec_settings.codecType != kVideoCodecH264)
return 0;
@ -151,13 +152,23 @@ void CalculateFrameQuality(const I420BufferInterface& ref_buffer,
}
}
std::vector<FrameType> FrameTypeForFrame(
const VideoCodecTestFixture::Config& config,
size_t frame_idx) {
if (config.keyframe_interval > 0 &&
(frame_idx % config.keyframe_interval == 0)) {
return {kVideoFrameKey};
}
return {kVideoFrameDelta};
}
} // namespace
VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
VideoDecoderList* decoders,
FrameReader* input_frame_reader,
const TestConfig& config,
Stats* stats,
const VideoCodecTestFixture::Config& config,
VideoCodecTestStats* stats,
IvfFileWriterList* encoded_frame_writers,
FrameWriterList* decoded_frame_writers)
: config_(config),
@ -279,7 +290,7 @@ void VideoProcessor::ProcessFrame() {
// Encode.
const std::vector<FrameType> frame_types =
config_.FrameTypeForFrame(frame_number);
FrameTypeForFrame(config_, frame_number);
const int encode_return_code =
encoder_->Encode(input_frame, nullptr, &frame_types);
for (size_t i = 0; i < num_simulcast_or_spatial_layers_; ++i) {

View file

@ -16,10 +16,11 @@
#include <string>
#include <vector>
#include "api/test/videocodec_test_fixture.h"
#include "api/test/videocodec_test_stats.h"
#include "api/video/video_frame.h"
#include "common_video/include/video_bitrate_allocator.h"
#include "modules/video_coding/codecs/test/stats.h"
#include "modules/video_coding/codecs/test/test_config.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/buffer.h"
#include "rtc_base/constructormagic.h"
@ -45,8 +46,8 @@ class VideoProcessor {
VideoProcessor(webrtc::VideoEncoder* encoder,
VideoDecoderList* decoders,
FrameReader* input_frame_reader,
const TestConfig& config,
Stats* stats,
const VideoCodecTestFixture::Config& config,
VideoCodecTestStats* stats,
IvfFileWriterList* encoded_frame_writers,
FrameWriterList* decoded_frame_writers);
~VideoProcessor();
@ -180,9 +181,9 @@ class VideoProcessor {
bool inter_layer_predicted) RTC_RUN_ON(sequence_checker_);
// Test input/output.
TestConfig config_ RTC_GUARDED_BY(sequence_checker_);
VideoCodecTestFixture::Config config_ RTC_GUARDED_BY(sequence_checker_);
const size_t num_simulcast_or_spatial_layers_;
Stats* const stats_;
VideoCodecTestStats* const stats_;
// Codecs.
webrtc::VideoEncoder* const encoder_;

View file

@ -10,9 +10,11 @@
#include <memory>
#include "api/test/videocodec_test_fixture.h"
#include "api/video/i420_buffer.h"
#include "common_types.h" // NOLINT(build/include)
#include "media/base/mediaconstants.h"
#include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
#include "modules/video_coding/codecs/test/videoprocessor.h"
#include "modules/video_coding/include/mock/mock_video_codec_interface.h"
#include "modules/video_coding/include/video_coding.h"
@ -79,13 +81,13 @@ class VideoProcessorTest : public testing::Test {
rtc::test::TaskQueueForTest q_;
TestConfig config_;
VideoCodecTestFixture::Config config_;
MockVideoEncoder encoder_mock_;
MockVideoDecoder* decoder_mock_;
std::vector<std::unique_ptr<VideoDecoder>> decoders_;
MockFrameReader frame_reader_mock_;
Stats stats_;
VideoCodecTestStatsImpl stats_;
std::unique_ptr<VideoProcessor> video_processor_;
};