Style fixes: VideoProcessor and corresponding integration test.

This CL has no intended functional changes.

BUG=webrtc:6634

Review-Url: https://codereview.webrtc.org/2697583002
Cr-Commit-Position: refs/heads/master@{#16628}
This commit is contained in:
brandtr
2017-02-15 05:19:51 -08:00
committed by Commit bot
parent 280eb224e2
commit 8bc9385fcb
5 changed files with 205 additions and 195 deletions

View File

@ -48,8 +48,8 @@ class PlotVideoProcessorIntegrationTest
0, // update_index
bitrate_, framerate_,
0); // frame_index_rate_update
rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, codec_type_, kPacketLoss,

View File

@ -29,6 +29,18 @@
namespace webrtc {
namespace test {
const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) {
switch (e) {
case kExcludeOnlyFirstKeyFrame:
return "ExcludeOnlyFirstKeyFrame";
case kExcludeAllKeyFrames:
return "ExcludeAllKeyFrames";
default:
RTC_NOTREACHED();
return "Unknown";
}
}
TestConfig::TestConfig()
: name(""),
description(""),
@ -89,18 +101,19 @@ VideoProcessorImpl::VideoProcessorImpl(webrtc::VideoEncoder* encoder,
}
bool VideoProcessorImpl::Init() {
// Calculate a factor used for bit rate calculations:
// Calculate a factor used for bit rate calculations.
bit_rate_factor_ = config_.codec_settings->maxFramerate * 0.001 * 8; // bits
// Initialize data structures used by the encoder/decoder APIs
// Initialize data structures used by the encoder/decoder APIs.
size_t frame_length_in_bytes = frame_reader_->FrameLength();
last_successful_frame_buffer_.reset(new uint8_t[frame_length_in_bytes]);
// Set fixed properties common for all frames.
// To keep track of spatial resize actions by encoder.
last_encoder_frame_width_ = config_.codec_settings->width;
last_encoder_frame_height_ = config_.codec_settings->height;
// Setup required callbacks for the encoder/decoder:
// Setup required callbacks for the encoder/decoder.
encode_callback_.reset(new VideoProcessorEncodeCompleteCallback(this));
decode_callback_.reset(new VideoProcessorDecodeCompleteCallback(this));
RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()),
@ -110,24 +123,24 @@ bool VideoProcessorImpl::Init() {
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to register decode complete callback";
// Init the encoder and decoder
uint32_t nbr_of_cores = 1;
// Init the encoder and decoder.
uint32_t num_cores = 1;
if (!config_.use_single_core) {
nbr_of_cores = CpuInfo::DetectNumberOfCores();
num_cores = CpuInfo::DetectNumberOfCores();
}
RTC_CHECK_EQ(
encoder_->InitEncode(config_.codec_settings, nbr_of_cores,
encoder_->InitEncode(config_.codec_settings, num_cores,
config_.networking_config.max_payload_size_in_bytes),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to initialize VideoEncoder";
RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, nbr_of_cores),
RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores),
WEBRTC_VIDEO_CODEC_OK)
<< "Failed to initialize VideoDecoder";
if (config_.verbose) {
printf("Video Processor:\n");
printf(" #CPU cores used : %d\n", nbr_of_cores);
printf(" #CPU cores used : %d\n", num_cores);
printf(" Total # of frames: %d\n", frame_reader_->NumberOfFrames());
printf(" Codec settings:\n");
printf(" Start bitrate : %d kbps\n",
@ -198,17 +211,18 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
if (frame_number == 0) {
prev_time_stamp_ = -1;
}
rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame());
if (buffer) {
// Use the frame number as "timestamp" to identify frames
// Use the frame number as "timestamp" to identify frames.
VideoFrame source_frame(buffer, frame_number, 0, webrtc::kVideoRotation_0);
// Ensure we have a new statistics data object we can fill:
// Ensure we have a new statistics data object we can fill.
FrameStatistic& stat = stats_->NewFrame(frame_number);
encode_start_ns_ = rtc::TimeNanos();
// Decide if we're going to force a keyframe:
// Decide if we are going to force a keyframe.
std::vector<FrameType> frame_types(1, kVideoFrameDelta);
if (config_.keyframe_interval > 0 &&
frame_number % config_.keyframe_interval == 0) {
@ -227,9 +241,11 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
frame_number, encode_result);
}
stat.encode_return_code = encode_result;
return true;
} else {
return false; // we've reached the last frame
// Last frame has been reached.
return false;
}
}
@ -252,11 +268,11 @@ void VideoProcessorImpl::FrameEncoded(
// Frame is not dropped, so update the encoded frame size
// (encoder callback is only called for non-zero length frames).
encoded_frame_size_ = encoded_image._length;
encoded_frame_type_ = encoded_image._frameType;
int64_t encode_stop_ns = rtc::TimeNanos();
int frame_number = encoded_image._timeStamp;
FrameStatistic& stat = stats_->stats_[frame_number];
stat.encode_time_in_us =
GetElapsedTimeMicroseconds(encode_start_ns_, encode_stop_ns);
@ -269,9 +285,9 @@ void VideoProcessorImpl::FrameEncoded(
encoded_image._length / config_.networking_config.packet_size_in_bytes +
1;
// Perform packet loss if criteria is fullfilled:
// Simulate packet loss.
bool exclude_this_frame = false;
// Only keyframes can be excluded
// Only keyframes can be excluded.
if (encoded_image._frameType == kVideoFrameKey) {
switch (config_.exclude_frame_types) {
case kExcludeOnlyFirstKeyFrame:
@ -305,32 +321,35 @@ void VideoProcessorImpl::FrameEncoded(
}
// Keep track of if frames are lost due to packet loss so we can tell
// this to the encoder (this is handled by the RTP logic in the full stack)
// this to the encoder (this is handled by the RTP logic in the full stack).
decode_start_ns_ = rtc::TimeNanos();
// TODO(kjellander): Pass fragmentation header to the decoder when
// CL 172001 has been submitted and PacketManipulator supports this.
int32_t decode_result =
decoder_->Decode(copied_image, last_frame_missing_, nullptr);
stat.decode_return_code = decode_result;
if (decode_result != 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:
// of sync with the source file for SSIM and PSNR comparisons.
frame_writer_->WriteFrame(last_successful_frame_buffer_.get());
}
// save status for losses so we can inform the decoder for the next frame:
// Save status for losses so we can inform the decoder for the next frame.
last_frame_missing_ = copied_image._length == 0;
}
void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
int64_t decode_stop_ns = rtc::TimeNanos();
// Report stats.
int frame_number = image.timestamp();
// Report stats
FrameStatistic& stat = stats_->stats_[frame_number];
stat.decode_time_in_us =
GetElapsedTimeMicroseconds(decode_start_ns_, decode_stop_ns);
stat.decoding_successful = true;
// Check for resize action (either down or up):
// Check for resize action (either down or up).
if (static_cast<int>(image.width()) != last_encoder_frame_width_ ||
static_cast<int>(image.height()) != last_encoder_frame_height_) {
++num_spatial_resizes_;
@ -338,7 +357,8 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
last_encoder_frame_height_ = image.height();
}
// Check if codec size is different from native/original size, and if so,
// upsample back to original size: needed for PSNR and SSIM computations.
// upsample back to original size. This is needed for PSNR and SSIM
// calculations.
if (image.width() != config_.codec_settings->width ||
image.height() != config_.codec_settings->height) {
rtc::scoped_refptr<I420Buffer> up_image(
@ -354,7 +374,7 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]);
int extracted_length = ExtractBuffer(up_image, length, image_buffer.get());
RTC_DCHECK_GT(extracted_length, 0);
// Update our copy of the last successful frame:
// Update our copy of the last successful frame.
memcpy(last_successful_frame_buffer_.get(), image_buffer.get(),
extracted_length);
bool write_success = frame_writer_->WriteFrame(image_buffer.get());
@ -363,7 +383,7 @@ void VideoProcessorImpl::FrameDecoded(const VideoFrame& image) {
fprintf(stderr, "Failed to write frame %d to disk!", frame_number);
}
} else { // No resize.
// Update our copy of the last successful frame:
// Update our copy of the last successful frame.
// TODO(mikhal): Add as a member function, so won't be allocated per frame.
size_t length = CalcBufferSize(kI420, image.width(), image.height());
std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]);
@ -388,37 +408,5 @@ int VideoProcessorImpl::GetElapsedTimeMicroseconds(int64_t start,
return static_cast<int>(encode_time);
}
const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) {
switch (e) {
case kExcludeOnlyFirstKeyFrame:
return "ExcludeOnlyFirstKeyFrame";
case kExcludeAllKeyFrames:
return "ExcludeAllKeyFrames";
default:
RTC_NOTREACHED();
return "Unknown";
}
}
// Callbacks
EncodedImageCallback::Result
VideoProcessorImpl::VideoProcessorEncodeCompleteCallback::OnEncodedImage(
const EncodedImage& encoded_image,
const webrtc::CodecSpecificInfo* codec_specific_info,
const webrtc::RTPFragmentationHeader* fragmentation) {
// Forward to parent class.
RTC_CHECK(codec_specific_info);
video_processor_->FrameEncoded(codec_specific_info->codecType,
encoded_image,
fragmentation);
return Result(Result::OK, 0);
}
int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded(
VideoFrame& image) {
// Forward to parent class.
video_processor_->FrameDecoded(image);
return 0;
}
} // namespace test
} // namespace webrtc

View File

@ -38,10 +38,11 @@ enum ExcludeFrameTypes {
// sequence they occur.
kExcludeAllKeyFrames
};
// Returns a string representation of the enum value.
const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e);
// Test configuration for a test run
// Test configuration for a test run.
struct TestConfig {
TestConfig();
~TestConfig();
@ -136,7 +137,7 @@ class VideoProcessor {
// Processes a single frame. Returns true as long as there's more frames
// available in the source clip.
// Frame number must be an integer >=0.
// Frame number must be an integer >= 0.
virtual bool ProcessFrame(int frame_number) = 0;
// Updates the encoder with the target bit rate and the frame rate.
@ -170,59 +171,6 @@ class VideoProcessorImpl : public VideoProcessor {
bool ProcessFrame(int frame_number) override;
private:
// Invoked by the callback when a frame has completed encoding.
void FrameEncoded(webrtc::VideoCodecType codec,
const webrtc::EncodedImage& encodedImage,
const webrtc::RTPFragmentationHeader* fragmentation);
// Invoked by the callback when a frame has completed decoding.
void FrameDecoded(const webrtc::VideoFrame& image);
// Used for getting a 32-bit integer representing time
// (checks the size is within signed 32-bit bounds before casting it)
int GetElapsedTimeMicroseconds(int64_t start, int64_t stop);
// Updates the encoder with the target bit rate and the frame rate.
void SetRates(int bit_rate, int frame_rate) override;
// Return the size of the encoded frame in bytes.
size_t EncodedFrameSize() override;
// Return the encoded frame type (key or delta).
FrameType EncodedFrameType() override;
// Return the number of dropped frames.
int NumberDroppedFrames() override;
// Return the number of spatial resizes.
int NumberSpatialResizes() override;
webrtc::VideoEncoder* const encoder_;
webrtc::VideoDecoder* const decoder_;
std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
FrameReader* const frame_reader_;
FrameWriter* const frame_writer_;
PacketManipulator* const packet_manipulator_;
const TestConfig& config_;
Stats* stats_;
std::unique_ptr<EncodedImageCallback> encode_callback_;
std::unique_ptr<DecodedImageCallback> decode_callback_;
// Keep track of the last successful frame, since we need to write that
// when decoding fails:
std::unique_ptr<uint8_t[]> last_successful_frame_buffer_;
// To keep track of if we have excluded the first key frame from packet loss:
bool first_key_frame_has_been_excluded_;
// To tell the decoder previous frame have been dropped due to packet loss:
bool last_frame_missing_;
// If Init() has executed successfully.
bool initialized_;
size_t encoded_frame_size_;
FrameType encoded_frame_type_;
int prev_time_stamp_;
int num_dropped_frames_;
int num_spatial_resizes_;
int last_encoder_frame_width_;
int last_encoder_frame_height_;
// Statistics
double bit_rate_factor_; // multiply frame length with this to get bit rate
int64_t encode_start_ns_;
int64_t decode_start_ns_;
// Callback class required to implement according to the VideoEncoder API.
class VideoProcessorEncodeCompleteCallback
: public webrtc::EncodedImageCallback {
@ -232,7 +180,13 @@ class VideoProcessorImpl : public VideoProcessor {
Result OnEncodedImage(
const webrtc::EncodedImage& encoded_image,
const webrtc::CodecSpecificInfo* codec_specific_info,
const webrtc::RTPFragmentationHeader* fragmentation) override;
const webrtc::RTPFragmentationHeader* fragmentation) override {
// Forward to parent class.
RTC_CHECK(codec_specific_info);
video_processor_->FrameEncoded(codec_specific_info->codecType,
encoded_image, fragmentation);
return Result(Result::OK, 0);
}
private:
VideoProcessorImpl* const video_processor_;
@ -244,7 +198,11 @@ class VideoProcessorImpl : public VideoProcessor {
public:
explicit VideoProcessorDecodeCompleteCallback(VideoProcessorImpl* vp)
: video_processor_(vp) {}
int32_t Decoded(webrtc::VideoFrame& image) override;
int32_t Decoded(webrtc::VideoFrame& image) override {
// Forward to parent class.
video_processor_->FrameDecoded(image);
return 0;
}
int32_t Decoded(webrtc::VideoFrame& image,
int64_t decode_time_ms) override {
RTC_NOTREACHED();
@ -259,6 +217,67 @@ class VideoProcessorImpl : public VideoProcessor {
private:
VideoProcessorImpl* const video_processor_;
};
// Invoked by the callback when a frame has completed encoding.
void FrameEncoded(webrtc::VideoCodecType codec,
const webrtc::EncodedImage& encodedImage,
const webrtc::RTPFragmentationHeader* fragmentation);
// Invoked by the callback when a frame has completed decoding.
void FrameDecoded(const webrtc::VideoFrame& image);
// Used for getting a 32-bit integer representing time
// (checks the size is within signed 32-bit bounds before casting it)
int GetElapsedTimeMicroseconds(int64_t start, int64_t stop);
// Updates the encoder with the target bit rate and the frame rate.
void SetRates(int bit_rate, int frame_rate) override;
// Return the size of the encoded frame in bytes.
size_t EncodedFrameSize() override;
// Return the encoded frame type (key or delta).
FrameType EncodedFrameType() override;
// Return the number of dropped frames.
int NumberDroppedFrames() override;
// Return the number of spatial resizes.
int NumberSpatialResizes() override;
webrtc::VideoEncoder* const encoder_;
webrtc::VideoDecoder* const decoder_;
std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
FrameReader* const frame_reader_;
FrameWriter* const frame_writer_;
PacketManipulator* const packet_manipulator_;
const TestConfig& config_;
Stats* stats_;
std::unique_ptr<EncodedImageCallback> encode_callback_;
std::unique_ptr<DecodedImageCallback> decode_callback_;
// Keep track of the last successful frame, since we need to write that
// when decoding fails.
std::unique_ptr<uint8_t[]> last_successful_frame_buffer_;
// To keep track of if we have excluded the first key frame from packet loss.
bool first_key_frame_has_been_excluded_;
// To tell the decoder previous frame have been dropped due to packet loss.
bool last_frame_missing_;
// If Init() has executed successfully.
bool initialized_;
size_t encoded_frame_size_;
FrameType encoded_frame_type_;
int prev_time_stamp_;
int num_dropped_frames_;
int num_spatial_resizes_;
int last_encoder_frame_width_;
int last_encoder_frame_height_;
// Statistics.
double bit_rate_factor_; // Multiply frame length with this to get bit rate.
int64_t encode_start_ns_;
int64_t decode_start_ns_;
};
} // namespace test

View File

@ -24,8 +24,8 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecH264, 0.0f, -1, 1, false,
@ -55,8 +55,8 @@ TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
@ -77,8 +77,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.05f, -1, 1, false,
@ -103,8 +103,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) {
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
SetRateProfilePars(&rate_profile, 1, 700, 30, 100);
SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
@ -136,8 +136,8 @@ TEST_F(VideoProcessorIntegrationTest,
SetRateProfilePars(&rate_profile, 0, 100, 24, 0);
SetRateProfilePars(&rate_profile, 1, 100, 15, 100);
SetRateProfilePars(&rate_profile, 2, 100, 10, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
@ -159,8 +159,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessNoLossDenoiserOnVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
@ -184,8 +184,8 @@ TEST_F(VideoProcessorIntegrationTest,
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 50, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[1] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
@ -212,8 +212,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
@ -234,8 +234,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.05f, -1, 1, false,
@ -256,8 +256,8 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
rate_profile.frame_index_rate_update[1] = kNumFramesShort + 1;
rate_profile.num_frames = kNumFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.1f, -1, 1, false,
@ -300,8 +300,8 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossChangeBitRateVP8) {
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
@ -341,8 +341,8 @@ TEST_F(VideoProcessorIntegrationTest,
SetRateProfilePars(&rate_profile, 0, 80, 24, 0);
SetRateProfilePars(&rate_profile, 1, 80, 15, 100);
SetRateProfilePars(&rate_profile, 2, 80, 10, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[3] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
@ -377,8 +377,8 @@ TEST_F(VideoProcessorIntegrationTest, MAYBE_ProcessNoLossTemporalLayersVP8) {
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
SetRateProfilePars(&rate_profile, 1, 400, 30, 150);
rate_profile.frame_index_rate_update[2] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
rate_profile.frame_index_rate_update[2] = kNumFramesLong + 1;
rate_profile.num_frames = kNumFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 3, false,

View File

@ -16,6 +16,7 @@
#include <memory>
#include <string>
#include "webrtc/base/checks.h"
#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
#include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
#include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
@ -97,9 +98,9 @@ struct RateControlMetrics {
};
#if !defined(WEBRTC_IOS)
const int kNbrFramesShort = 100; // Some tests are run for shorter sequence.
const int kNumFramesShort = 100;
#endif
const int kNbrFramesLong = 299;
const int kNumFramesLong = 299;
// Parameters from VP8 wrapper, which control target size of key frames.
const float kInitialBufferSize = 0.5f;
@ -116,52 +117,6 @@ const float kScaleKeyFrameSize = 0.5f;
// happen when some significant regression or breakdown occurs.
class VideoProcessorIntegrationTest : public testing::Test {
protected:
std::unique_ptr<VideoEncoder> encoder_;
std::unique_ptr<VideoDecoder> decoder_;
std::unique_ptr<test::FrameReader> frame_reader_;
std::unique_ptr<test::FrameWriter> frame_writer_;
test::PacketReader packet_reader_;
std::unique_ptr<test::PacketManipulator> packet_manipulator_;
test::Stats stats_;
test::TestConfig config_;
VideoCodec codec_settings_;
std::unique_ptr<test::VideoProcessor> processor_;
TemporalLayersFactory tl_factory_;
// Quantities defined/updated for every encoder rate update.
// Some quantities defined per temporal layer (at most 3 layers in this test).
int num_frames_per_update_[3];
float sum_frame_size_mismatch_[3];
float sum_encoded_frame_size_[3];
float encoding_bitrate_[3];
float per_frame_bandwidth_[3];
float bit_rate_layer_[3];
float frame_rate_layer_[3];
int num_frames_total_;
float sum_encoded_frame_size_total_;
float encoding_bitrate_total_;
float perc_encoding_rate_mismatch_;
int num_frames_to_hit_target_;
bool encoding_rate_within_target_;
int bit_rate_;
int frame_rate_;
int layer_;
float target_size_key_frame_initial_;
float target_size_key_frame_;
float sum_key_frame_size_mismatch_;
int num_key_frames_;
float start_bitrate_;
// Codec and network settings.
VideoCodecType codec_type_;
float packet_loss_;
int num_temporal_layers_;
int key_frame_interval_;
bool error_concealment_on_;
bool denoising_on_;
bool frame_dropper_on_;
bool spatial_resize_on_;
VideoProcessorIntegrationTest() {}
virtual ~VideoProcessorIntegrationTest() {}
@ -230,7 +185,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
config_.codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval;
break;
default:
assert(false);
RTC_NOTREACHED();
break;
}
frame_reader_.reset(new test::FrameReaderImpl(
@ -238,15 +193,15 @@ class VideoProcessorIntegrationTest : public testing::Test {
config_.codec_settings->height));
frame_writer_.reset(new test::FrameWriterImpl(
config_.output_filename, config_.frame_length_in_bytes));
ASSERT_TRUE(frame_reader_->Init());
ASSERT_TRUE(frame_writer_->Init());
RTC_CHECK(frame_reader_->Init());
RTC_CHECK(frame_writer_->Init());
packet_manipulator_.reset(new test::PacketManipulatorImpl(
&packet_reader_, config_.networking_config, config_.verbose));
processor_.reset(new test::VideoProcessorImpl(
encoder_.get(), decoder_.get(), frame_reader_.get(),
frame_writer_.get(), packet_manipulator_.get(), config_, &stats_));
ASSERT_TRUE(processor_->Init());
RTC_CHECK(processor_->Init());
}
// Reset quantities after each encoder update, update the target
@ -401,13 +356,13 @@ class VideoProcessorIntegrationTest : public testing::Test {
layer_ = 2;
}
} else {
assert(false); // Only up to 3 layers.
RTC_NOTREACHED() << "Max 3 layers are supported.";
}
}
// Set the bitrate and frame rate per layer, for up to 3 layers.
void SetLayerRates() {
assert(num_temporal_layers_ <= 3);
RTC_DCHECK_LE(num_temporal_layers_, 3);
for (int i = 0; i < num_temporal_layers_; i++) {
float bit_rate_ratio =
kVp8LayerRateAlloction[num_temporal_layers_ - 1][i];
@ -452,6 +407,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
target_size_key_frame_initial_ =
0.5 * kInitialBufferSize * bit_rate_layer_[0];
processor_->SetRates(bit_rate_, frame_rate_);
// Process each frame, up to |num_frames|.
int num_frames = rate_profile.num_frames;
int update_index = 0;
@ -507,6 +463,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
// Release encoder and decoder to make sure they have finished processing:
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
// Close the files before we start using them for SSIM/PSNR calculations.
frame_reader_->Close();
frame_writer_->Close();
@ -616,6 +573,52 @@ class VideoProcessorIntegrationTest : public testing::Test {
rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes;
rc_metrics[update_index].num_key_frames = num_key_frames;
}
std::unique_ptr<VideoEncoder> encoder_;
std::unique_ptr<VideoDecoder> decoder_;
std::unique_ptr<test::FrameReader> frame_reader_;
std::unique_ptr<test::FrameWriter> frame_writer_;
test::PacketReader packet_reader_;
std::unique_ptr<test::PacketManipulator> packet_manipulator_;
test::Stats stats_;
test::TestConfig config_;
VideoCodec codec_settings_;
std::unique_ptr<test::VideoProcessor> processor_;
TemporalLayersFactory tl_factory_;
// Quantities defined/updated for every encoder rate update.
// Some quantities defined per temporal layer (at most 3 layers in this test).
int num_frames_per_update_[3];
float sum_frame_size_mismatch_[3];
float sum_encoded_frame_size_[3];
float encoding_bitrate_[3];
float per_frame_bandwidth_[3];
float bit_rate_layer_[3];
float frame_rate_layer_[3];
int num_frames_total_;
float sum_encoded_frame_size_total_;
float encoding_bitrate_total_;
float perc_encoding_rate_mismatch_;
int num_frames_to_hit_target_;
bool encoding_rate_within_target_;
int bit_rate_;
int frame_rate_;
int layer_;
float target_size_key_frame_initial_;
float target_size_key_frame_;
float sum_key_frame_size_mismatch_;
int num_key_frames_;
float start_bitrate_;
// Codec and network settings.
VideoCodecType codec_type_;
float packet_loss_;
int num_temporal_layers_;
int key_frame_interval_;
bool error_concealment_on_;
bool denoising_on_;
bool frame_dropper_on_;
bool spatial_resize_on_;
};
} // namespace test