Make VideoProcessor::Init/Release methods private and call from constructor/destructor.

TestConfig: Replace Print method with ToString and add test.

Bug: none
Change-Id: I9853cb16875199a51c5731d1cec326159751d001
Reviewed-on: https://webrtc-review.googlesource.com/14320
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20420}
This commit is contained in:
Åsa Persson
2017-10-24 16:03:39 +02:00
committed by Commit Bot
parent c22a3a6a7d
commit f0c44672df
8 changed files with 255 additions and 215 deletions

View File

@ -10,7 +10,7 @@
#include "modules/video_coding/codecs/test/test_config.h"
#include <string.h>
#include <sstream>
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/checks.h"
@ -22,6 +22,46 @@ namespace test {
namespace {
const int kBaseKeyFrameInterval = 3000;
std::string CodecSpecificToString(const webrtc::VideoCodec& codec) {
std::stringstream ss;
switch (codec.codecType) {
case kVideoCodecVP8:
ss << "\n Complexity : " << codec.VP8().complexity;
ss << "\n Resilience : " << codec.VP8().resilience;
ss << "\n # temporal layers : "
<< static_cast<int>(codec.VP8().numberOfTemporalLayers);
ss << "\n Denoising : " << codec.VP8().denoisingOn;
ss << "\n Error concealment : " << codec.VP8().errorConcealmentOn;
ss << "\n Automatic resize : " << codec.VP8().automaticResizeOn;
ss << "\n Frame dropping : " << codec.VP8().frameDroppingOn;
ss << "\n Key frame interval: " << codec.VP8().keyFrameInterval;
break;
case kVideoCodecVP9:
ss << "\n Complexity : " << codec.VP9().complexity;
ss << "\n Resilience : " << codec.VP9().resilienceOn;
ss << "\n # temporal layers : "
<< static_cast<int>(codec.VP9().numberOfTemporalLayers);
ss << "\n Denoising : " << codec.VP9().denoisingOn;
ss << "\n Frame dropping : " << codec.VP9().frameDroppingOn;
ss << "\n Key frame interval: " << codec.VP9().keyFrameInterval;
ss << "\n Adaptive QP mode : " << codec.VP9().adaptiveQpMode;
ss << "\n Automatic resize : " << codec.VP9().automaticResizeOn;
ss << "\n # spatial layers : "
<< static_cast<int>(codec.VP9().numberOfSpatialLayers);
ss << "\n Flexible mode : " << codec.VP9().flexibleMode;
break;
case kVideoCodecH264:
ss << "\n Frame dropping : " << codec.H264().frameDroppingOn;
ss << "\n Key frame interval: " << codec.H264().keyFrameInterval;
ss << "\n Profile : " << codec.H264().profile;
break;
default:
break;
}
ss << "\n";
return ss.str();
}
} // namespace
void TestConfig::SetCodecSettings(VideoCodecType codec_type,
@ -83,57 +123,53 @@ int TestConfig::NumberOfTemporalLayers() const {
}
}
void TestConfig::Print() const {
printf("Video config:\n");
printf(" Filename : %s\n", filename.c_str());
printf(" # CPU cores used : %u\n", NumberOfCores());
PrintCodecSettings();
printf("\n");
int TestConfig::TemporalLayerForFrame(int frame_idx) const {
int tl = -1;
switch (NumberOfTemporalLayers()) {
case 1:
tl = 0;
break;
case 2:
// temporal layer 1: 1 3
// temporal layer 0: 0 2 4 ...
tl = (frame_idx % 2 == 0) ? 0 : 1;
break;
case 3:
// temporal layer 2: 1 3 5 7
// temporal layer 1: 2 6
// temporal layer 0: 0 4 8 ...
if (frame_idx % 4 == 0) {
tl = 0;
} else if ((frame_idx + 2) % 4 == 0) {
tl = 1;
} else if ((frame_idx + 1) % 2 == 0) {
tl = 2;
}
break;
default:
RTC_NOTREACHED();
break;
}
return tl;
}
void TestConfig::PrintCodecSettings() const {
printf(" Codec settings:\n");
printf(" Codec type : %s\n",
CodecTypeToPayloadString(codec_settings.codecType));
printf(" Start bitrate : %d kbps\n", codec_settings.startBitrate);
printf(" Max bitrate : %d kbps\n", codec_settings.maxBitrate);
printf(" Min bitrate : %d kbps\n", codec_settings.minBitrate);
printf(" Width : %d\n", codec_settings.width);
printf(" Height : %d\n", codec_settings.height);
printf(" Max frame rate : %d\n", codec_settings.maxFramerate);
printf(" QPmax : %d\n", codec_settings.qpMax);
if (codec_settings.codecType == kVideoCodecVP8) {
printf(" Complexity : %d\n", codec_settings.VP8().complexity);
printf(" Resilience : %d\n", codec_settings.VP8().resilience);
printf(" # temporal layers : %d\n",
codec_settings.VP8().numberOfTemporalLayers);
printf(" Denoising : %d\n", codec_settings.VP8().denoisingOn);
printf(" Error concealment : %d\n",
codec_settings.VP8().errorConcealmentOn);
printf(" Automatic resize : %d\n",
codec_settings.VP8().automaticResizeOn);
printf(" Frame dropping : %d\n", codec_settings.VP8().frameDroppingOn);
printf(" Key frame interval: %d\n", codec_settings.VP8().keyFrameInterval);
} else if (codec_settings.codecType == kVideoCodecVP9) {
printf(" Complexity : %d\n", codec_settings.VP9().complexity);
printf(" Resilience : %d\n", codec_settings.VP9().resilienceOn);
printf(" # temporal layers : %d\n",
codec_settings.VP9().numberOfTemporalLayers);
printf(" Denoising : %d\n", codec_settings.VP9().denoisingOn);
printf(" Frame dropping : %d\n", codec_settings.VP9().frameDroppingOn);
printf(" Key frame interval: %d\n", codec_settings.VP9().keyFrameInterval);
printf(" Adaptive QP mode : %d\n", codec_settings.VP9().adaptiveQpMode);
printf(" Automatic resize : %d\n",
codec_settings.VP9().automaticResizeOn);
printf(" # spatial layers : %d\n",
codec_settings.VP9().numberOfSpatialLayers);
printf(" Flexible mode : %d\n", codec_settings.VP9().flexibleMode);
} else if (codec_settings.codecType == kVideoCodecH264) {
printf(" Frame dropping : %d\n", codec_settings.H264().frameDroppingOn);
printf(" Key frame interval: %d\n",
codec_settings.H264().keyFrameInterval);
printf(" Profile : %d\n", codec_settings.H264().profile);
}
std::string TestConfig::ToString() const {
std::stringstream ss;
ss << "Video config:";
ss << "\n Filename : " << filename;
ss << "\n # CPU cores used : " << NumberOfCores();
ss << "\n Codec settings:";
ss << "\n Codec type : "
<< CodecTypeToPayloadString(codec_settings.codecType);
ss << "\n Start bitrate : " << codec_settings.startBitrate << " kbps";
ss << "\n Max bitrate : " << codec_settings.maxBitrate << " kbps";
ss << "\n Min bitrate : " << codec_settings.minBitrate << " kbps";
ss << "\n Width : " << codec_settings.width;
ss << "\n Height : " << codec_settings.height;
ss << "\n Max frame rate : " << codec_settings.maxFramerate;
ss << "\n QPmax : " << codec_settings.qpMax;
ss << CodecSpecificToString(codec_settings);
return ss.str();
}
} // namespace test

View File

@ -52,8 +52,8 @@ struct TestConfig {
int NumberOfCores() const;
int NumberOfTemporalLayers() const;
void Print() const;
void PrintCodecSettings() const;
int TemporalLayerForFrame(int frame_idx) const;
std::string ToString() const;
// Plain name of YUV file to process without file extension.
std::string filename;

View File

@ -51,5 +51,81 @@ TEST(TestConfig, NumberOfTemporalLayers_Vp9) {
EXPECT_EQ(kNumTemporalLayers, config.NumberOfTemporalLayers());
}
TEST(TestConfig, TemporalLayersForFrame_OneLayer) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.codec_settings.VP8()->numberOfTemporalLayers = 1;
EXPECT_EQ(0, config.TemporalLayerForFrame(0));
EXPECT_EQ(0, config.TemporalLayerForFrame(1));
EXPECT_EQ(0, config.TemporalLayerForFrame(2));
}
TEST(TestConfig, TemporalLayersForFrame_TwoLayers) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.codec_settings.VP8()->numberOfTemporalLayers = 2;
EXPECT_EQ(0, config.TemporalLayerForFrame(0));
EXPECT_EQ(1, config.TemporalLayerForFrame(1));
EXPECT_EQ(0, config.TemporalLayerForFrame(2));
EXPECT_EQ(1, config.TemporalLayerForFrame(3));
}
TEST(TestConfig, TemporalLayersForFrame_ThreeLayers) {
TestConfig config;
webrtc::test::CodecSettings(kVideoCodecVP8, &config.codec_settings);
config.codec_settings.VP8()->numberOfTemporalLayers = 3;
EXPECT_EQ(0, config.TemporalLayerForFrame(0));
EXPECT_EQ(2, config.TemporalLayerForFrame(1));
EXPECT_EQ(1, config.TemporalLayerForFrame(2));
EXPECT_EQ(2, config.TemporalLayerForFrame(3));
EXPECT_EQ(0, config.TemporalLayerForFrame(4));
EXPECT_EQ(2, config.TemporalLayerForFrame(5));
EXPECT_EQ(1, config.TemporalLayerForFrame(6));
EXPECT_EQ(2, config.TemporalLayerForFrame(7));
}
TEST(TestConfig, ToString_Vp8) {
TestConfig config;
config.filename = "yuvfile";
config.use_single_core = true;
config.SetCodecSettings(kVideoCodecVP8, 2, true, // error_concealment_on,
false, // denoising_on,
false, // frame_dropper_on,
true, // spatial_resize_on,
false, // resilience_on,
320, 180);
config.codec_settings.startBitrate = 400;
config.codec_settings.maxBitrate = 500;
config.codec_settings.minBitrate = 70;
config.codec_settings.maxFramerate = 35;
config.codec_settings.qpMax = 66;
config.codec_settings.VP8()->complexity = kComplexityNormal;
config.codec_settings.VP8()->keyFrameInterval = 999;
EXPECT_EQ(
"Video config:"
"\n Filename : yuvfile"
"\n # CPU cores used : 1"
"\n Codec settings:"
"\n Codec type : VP8"
"\n Start bitrate : 400 kbps"
"\n Max bitrate : 500 kbps"
"\n Min bitrate : 70 kbps"
"\n Width : 320"
"\n Height : 180"
"\n Max frame rate : 35"
"\n QPmax : 66"
"\n Complexity : 0"
"\n Resilience : 0"
"\n # temporal layers : 2"
"\n Denoising : 0"
"\n Error concealment : 1"
"\n Automatic resize : 1"
"\n Frame dropping : 0"
"\n Key frame interval: 999\n",
config.ToString());
}
} // namespace test
} // namespace webrtc

View File

@ -68,6 +68,31 @@ int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) {
return static_cast<int>(diff_us);
}
void ExtractBufferWithSize(const VideoFrame& image,
int width,
int height,
rtc::Buffer* buffer) {
if (image.width() != width || image.height() != height) {
EXPECT_DOUBLE_EQ(static_cast<double>(width) / height,
static_cast<double>(image.width()) / image.height());
// Same aspect ratio, no cropping needed.
rtc::scoped_refptr<I420Buffer> scaled(I420Buffer::Create(width, height));
scaled->ScaleFrom(*image.video_frame_buffer()->ToI420());
size_t length =
CalcBufferSize(VideoType::kI420, scaled->width(), scaled->height());
buffer->SetSize(length);
RTC_CHECK_NE(ExtractBuffer(scaled, length, buffer->data()), -1);
return;
}
// No resize.
size_t length =
CalcBufferSize(VideoType::kI420, image.width(), image.height());
buffer->SetSize(length);
RTC_CHECK_NE(ExtractBuffer(image, length, buffer->data()), -1);
}
} // namespace
VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
@ -79,8 +104,7 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
Stats* stats,
IvfFileWriter* encoded_frame_writer,
FrameWriter* decoded_frame_writer)
: initialized_(false),
config_(config),
: config_(config),
encoder_(encoder),
decoder_(decoder),
bitrate_allocator_(CreateBitrateAllocator(&config_)),
@ -104,37 +128,24 @@ VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder,
RTC_DCHECK(analysis_frame_reader);
RTC_DCHECK(analysis_frame_writer);
RTC_DCHECK(stats);
}
VideoProcessor::~VideoProcessor() = default;
void VideoProcessor::Init() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
RTC_DCHECK(!initialized_) << "VideoProcessor already initialized.";
initialized_ = true;
// Setup required callbacks for the encoder and decoder.
RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(&encode_callback_),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to register encode complete callback";
WEBRTC_VIDEO_CODEC_OK);
RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(&decode_callback_),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to register decode complete callback";
WEBRTC_VIDEO_CODEC_OK);
// Initialize the encoder and decoder.
RTC_CHECK_EQ(
encoder_->InitEncode(&config_.codec_settings, config_.NumberOfCores(),
config_.networking_config.max_payload_size_in_bytes),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to initialize VideoEncoder";
WEBRTC_VIDEO_CODEC_OK);
RTC_CHECK_EQ(
decoder_->InitDecode(&config_.codec_settings, config_.NumberOfCores()),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to initialize VideoDecoder";
WEBRTC_VIDEO_CODEC_OK);
}
void VideoProcessor::Release() {
VideoProcessor::~VideoProcessor() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
RTC_CHECK_EQ(encoder_->Release(), WEBRTC_VIDEO_CODEC_OK);
@ -142,13 +153,10 @@ void VideoProcessor::Release() {
encoder_->RegisterEncodeCompleteCallback(nullptr);
decoder_->RegisterDecodeCompleteCallback(nullptr);
initialized_ = false;
}
void VideoProcessor::ProcessFrame() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
RTC_DCHECK(initialized_) << "VideoProcessor not initialized.";
++last_inputed_frame_num_;
// Get frame from file.
@ -233,16 +241,7 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
// For dropped frames, we write out the last decoded frame to avoid
// getting out of sync for the computation of PSNR and SSIM.
for (int i = 0; i < num_dropped_from_last_encode; i++) {
RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
analysis_frame_writer_->FrameLength());
RTC_CHECK(analysis_frame_writer_->WriteFrame(
last_decoded_frame_buffer_.data()));
if (decoded_frame_writer_) {
RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
decoded_frame_writer_->FrameLength());
RTC_CHECK(decoded_frame_writer_->WriteFrame(
last_decoded_frame_buffer_.data()));
}
WriteDecodedFrameToFile(&last_decoded_frame_buffer_);
}
}
const FrameStatistic* last_encoded_frame_stat =
@ -266,40 +265,19 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
frame_stat->total_packets =
encoded_image._length / config_.networking_config.packet_size_in_bytes +
1;
frame_stat->max_nalu_length = GetMaxNaluLength(encoded_image, config_);
// Simulate packet loss.
bool exclude_this_frame = false;
if (encoded_image._frameType == kVideoFrameKey) {
// Only keyframes can be excluded.
switch (config_.exclude_frame_types) {
case kExcludeOnlyFirstKeyFrame:
if (!first_key_frame_has_been_excluded_) {
first_key_frame_has_been_excluded_ = true;
exclude_this_frame = true;
}
break;
case kExcludeAllKeyFrames:
exclude_this_frame = true;
break;
default:
RTC_NOTREACHED();
}
}
// Make a raw copy of the |encoded_image| buffer.
// Make a raw copy of |encoded_image| to feed to the decoder.
size_t copied_buffer_size = encoded_image._length +
EncodedImage::GetBufferPaddingBytes(codec);
std::unique_ptr<uint8_t[]> copied_buffer(new uint8_t[copied_buffer_size]);
memcpy(copied_buffer.get(), encoded_image._buffer, encoded_image._length);
// The image to feed to the decoder.
EncodedImage copied_image;
memcpy(&copied_image, &encoded_image, sizeof(copied_image));
EncodedImage copied_image = encoded_image;
copied_image._size = copied_buffer_size;
copied_image._buffer = copied_buffer.get();
if (!exclude_this_frame) {
// Simulate packet loss.
if (!ExcludeFrame(copied_image)) {
frame_stat->packets_dropped =
packet_manipulator_->ManipulatePackets(&copied_image);
}
@ -314,16 +292,7 @@ void VideoProcessor::FrameEncoded(webrtc::VideoCodecType codec,
if (frame_stat->decode_return_code != WEBRTC_VIDEO_CODEC_OK) {
// Write the last successful frame the output file to avoid getting it out
// of sync with the source file for SSIM and PSNR comparisons.
RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
analysis_frame_writer_->FrameLength());
RTC_CHECK(
analysis_frame_writer_->WriteFrame(last_decoded_frame_buffer_.data()));
if (decoded_frame_writer_) {
RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(),
decoded_frame_writer_->FrameLength());
RTC_CHECK(
decoded_frame_writer_->WriteFrame(last_decoded_frame_buffer_.data()));
}
WriteDecodedFrameToFile(&last_decoded_frame_buffer_);
}
if (encoded_frame_writer_) {
@ -364,39 +333,45 @@ void VideoProcessor::FrameDecoded(const VideoFrame& image) {
RTC_CHECK_GT(frame_number, last_decoded_frame_num_);
last_decoded_frame_num_ = frame_number;
// Check if frame size is different from the original size, and if so, scale
// back to original size. This is needed for the PSNR and SSIM calculations.
size_t extracted_length;
rtc::Buffer extracted_buffer;
if (image.width() != config_.codec_settings.width ||
image.height() != config_.codec_settings.height) {
rtc::scoped_refptr<I420Buffer> scaled_buffer(I420Buffer::Create(
config_.codec_settings.width, config_.codec_settings.height));
// Should be the same aspect ratio, no cropping needed.
scaled_buffer->ScaleFrom(*image.video_frame_buffer()->ToI420());
// If the frame size is different from the original size, scale back to the
// original size. This is needed for the PSNR and SSIM calculations.
rtc::Buffer buffer;
ExtractBufferWithSize(image, config_.codec_settings.width,
config_.codec_settings.height, &buffer);
WriteDecodedFrameToFile(&buffer);
size_t length = CalcBufferSize(VideoType::kI420, scaled_buffer->width(),
scaled_buffer->height());
extracted_buffer.SetSize(length);
extracted_length =
ExtractBuffer(scaled_buffer, length, extracted_buffer.data());
} else {
// No resize.
size_t length =
CalcBufferSize(VideoType::kI420, image.width(), image.height());
extracted_buffer.SetSize(length);
extracted_length = ExtractBuffer(image.video_frame_buffer()->ToI420(),
length, extracted_buffer.data());
}
last_decoded_frame_buffer_ = std::move(buffer);
}
RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength());
RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data()));
void VideoProcessor::WriteDecodedFrameToFile(rtc::Buffer* buffer) {
RTC_DCHECK_EQ(buffer->size(), analysis_frame_writer_->FrameLength());
RTC_CHECK(analysis_frame_writer_->WriteFrame(buffer->data()));
if (decoded_frame_writer_) {
RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength());
RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data()));
RTC_DCHECK_EQ(buffer->size(), decoded_frame_writer_->FrameLength());
RTC_CHECK(decoded_frame_writer_->WriteFrame(buffer->data()));
}
}
last_decoded_frame_buffer_ = std::move(extracted_buffer);
bool VideoProcessor::ExcludeFrame(const EncodedImage& encoded_image) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
if (encoded_image._frameType != kVideoFrameKey) {
return false;
}
bool exclude_frame = false;
switch (config_.exclude_frame_types) {
case kExcludeOnlyFirstKeyFrame:
if (!first_key_frame_has_been_excluded_) {
first_key_frame_has_been_excluded_ = true;
exclude_frame = true;
}
break;
case kExcludeAllKeyFrames:
exclude_frame = true;
break;
default:
RTC_NOTREACHED();
}
return exclude_frame;
}
} // namespace test

View File

@ -70,12 +70,6 @@ class VideoProcessor {
FrameWriter* decoded_frame_writer);
~VideoProcessor();
// Sets up callbacks and initializes the encoder and decoder.
void Init();
// Tears down callbacks and releases the encoder and decoder.
void Release();
// Reads a frame from the analysis frame reader and sends it to the encoder.
// When the encode callback is received, the encoded frame is sent to the
// decoder. The decoded frame is written to disk by the analysis frame writer.
@ -189,7 +183,9 @@ class VideoProcessor {
// Invoked by the callback adapter when a frame has completed decoding.
void FrameDecoded(const webrtc::VideoFrame& image);
bool initialized_ RTC_GUARDED_BY(sequence_checker_);
void WriteDecodedFrameToFile(rtc::Buffer* buffer);
bool ExcludeFrame(const EncodedImage& encoded_image);
TestConfig config_ RTC_GUARDED_BY(sequence_checker_);
webrtc::VideoEncoder* const encoder_;

View File

@ -212,9 +212,7 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
SleepMs(1 * rtc::kNumMillisecsPerSec);
}
cpu_process_time_->Stop();
ReleaseAndCloseObjects(&task_queue);
// Calculate and print rate control statistics.
std::vector<int> num_dropped_frames;
std::vector<int> num_spatial_resizes;
sync_event.Reset();
@ -226,6 +224,9 @@ void VideoProcessorIntegrationTest::ProcessFramesAndMaybeVerify(
});
sync_event.Wait(rtc::Event::kForever);
ReleaseAndCloseObjects(&task_queue);
// Calculate and print rate control statistics.
rate_update_index = 0;
frame_number = 0;
ResetRateControlMetrics(rate_update_index, rate_profiles);
@ -416,7 +417,6 @@ void VideoProcessorIntegrationTest::SetUpAndInitObjects(
encoder_.get(), decoder_.get(), analysis_frame_reader_.get(),
analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
&stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
processor_->Init();
sync_event.Set();
});
sync_event.Wait(rtc::Event::kForever);
@ -426,12 +426,12 @@ void VideoProcessorIntegrationTest::ReleaseAndCloseObjects(
rtc::TaskQueue* task_queue) {
rtc::Event sync_event(false, false);
task_queue->PostTask([this, &sync_event]() {
processor_->Release();
processor_.reset();
sync_event.Set();
});
sync_event.Wait(rtc::Event::kForever);
// The VideoProcessor must be ::Release()'d before we destroy the codecs.
// The VideoProcessor must be destroyed before the codecs.
DestroyEncoderAndDecoder();
// Close the analysis files before we use them for SSIM/PSNR calculations.
@ -451,7 +451,7 @@ void VideoProcessorIntegrationTest::ReleaseAndCloseObjects(
void VideoProcessorIntegrationTest::UpdateRateControlMetrics(int frame_number) {
RTC_CHECK_GE(frame_number, 0);
const int tl_idx = TemporalLayerIndexForFrame(frame_number);
const int tl_idx = config_.TemporalLayerForFrame(frame_number);
++actual_.num_frames_layer[tl_idx];
++actual_.num_frames;
@ -563,7 +563,7 @@ void VideoProcessorIntegrationTest::MaybePrintSettings() const {
if (!config_.verbose)
return;
config_.Print();
printf("%s\n", config_.ToString().c_str());
printf(" Total # of frames: %d\n", analysis_frame_reader_->NumberOfFrames());
const char* encoder_name = encoder_->ImplementationName();
const char* decoder_name = decoder_->ImplementationName();
@ -585,38 +585,6 @@ void VideoProcessorIntegrationTest::VerifyBitstream(
EXPECT_LE(*(frame_stat->max_nalu_length), bs_thresholds.max_nalu_length);
}
// Temporal layer index corresponding to frame number, for up to 3 layers.
int VideoProcessorIntegrationTest::TemporalLayerIndexForFrame(
int frame_number) const {
int tl_idx = -1;
switch (config_.NumberOfTemporalLayers()) {
case 1:
tl_idx = 0;
break;
case 2:
// temporal layer 0: 0 2 4 ...
// temporal layer 1: 1 3
tl_idx = (frame_number % 2 == 0) ? 0 : 1;
break;
case 3:
// temporal layer 0: 0 4 8 ...
// temporal layer 1: 2 6
// temporal layer 2: 1 3 5 7
if (frame_number % 4 == 0) {
tl_idx = 0;
} else if ((frame_number + 2) % 4 == 0) {
tl_idx = 1;
} else if ((frame_number + 1) % 2 == 0) {
tl_idx = 2;
}
break;
default:
RTC_NOTREACHED();
break;
}
return tl_idx;
}
// Reset quantities before each encoder rate update.
void VideoProcessorIntegrationTest::ResetRateControlMetrics(
int rate_update_index,

View File

@ -164,7 +164,6 @@ class VideoProcessorIntegrationTest : public testing::Test {
const int initial_framerate_fps,
const VisualizationParams* visualization_params);
void ReleaseAndCloseObjects(rtc::TaskQueue* task_queue);
int TemporalLayerIndexForFrame(int frame_number) const;
// Rate control metrics.
void ResetRateControlMetrics(int rate_update_index,

View File

@ -27,7 +27,6 @@
#include "typedefs.h" // NOLINT(build/include)
using ::testing::_;
using ::testing::AtLeast;
using ::testing::ElementsAre;
using ::testing::Property;
using ::testing::Return;
@ -40,7 +39,6 @@ namespace {
const int kWidth = 352;
const int kHeight = 288;
const int kFrameSize = kWidth * kHeight * 3 / 2; // I420.
const int kNumFrames = 2;
} // namespace
@ -52,8 +50,7 @@ class VideoProcessorTest : public testing::Test {
config_.codec_settings.width = kWidth;
config_.codec_settings.height = kHeight;
EXPECT_CALL(frame_reader_mock_, NumberOfFrames())
.WillRepeatedly(Return(kNumFrames));
ExpectInit();
EXPECT_CALL(frame_reader_mock_, FrameLength())
.WillRepeatedly(Return(kFrameSize));
video_processor_ = rtc::MakeUnique<VideoProcessor>(
@ -88,19 +85,15 @@ class VideoProcessorTest : public testing::Test {
};
TEST_F(VideoProcessorTest, InitRelease) {
ExpectInit();
video_processor_->Init();
ExpectRelease();
video_processor_->Release();
}
TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
ExpectInit();
video_processor_->Init();
const int kBitrateKbps = 456;
const int kFramerateFps = 31;
EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kFramerateFps))
.Times(1)
.WillOnce(Return(0));
video_processor_->SetRates(kBitrateKbps, kFramerateFps);
EXPECT_CALL(frame_reader_mock_, ReadFrame())
@ -118,15 +111,14 @@ TEST_F(VideoProcessorTest, ProcessFrames_FixedFramerate) {
video_processor_->ProcessFrame();
ExpectRelease();
video_processor_->Release();
}
TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
ExpectInit();
video_processor_->Init();
const int kBitrateKbps = 456;
const int kStartFramerateFps = 27;
EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kStartFramerateFps))
.Times(1)
.WillOnce(Return(0));
video_processor_->SetRates(kBitrateKbps, kStartFramerateFps);
EXPECT_CALL(frame_reader_mock_, ReadFrame())
@ -138,6 +130,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
video_processor_->ProcessFrame();
const int kNewFramerateFps = 13;
EXPECT_CALL(encoder_mock_, SetRateAllocation(_, kNewFramerateFps))
.Times(1)
.WillOnce(Return(0));
video_processor_->SetRates(kBitrateKbps, kNewFramerateFps);
EXPECT_CALL(encoder_mock_, Encode(Property(&VideoFrame::timestamp,
@ -147,13 +142,9 @@ TEST_F(VideoProcessorTest, ProcessFrames_VariableFramerate) {
video_processor_->ProcessFrame();
ExpectRelease();
video_processor_->Release();
}
TEST_F(VideoProcessorTest, SetRates) {
ExpectInit();
video_processor_->Init();
const int kBitrateKbps = 123;
const int kFramerateFps = 17;
EXPECT_CALL(encoder_mock_,
@ -181,7 +172,6 @@ TEST_F(VideoProcessorTest, SetRates) {
ElementsAre(0, 0));
ExpectRelease();
video_processor_->Release();
}
} // namespace test