Handle non-integer frame rates in video codec tests.

Encoder API accepts non-integer frame rate since
https://webrtc-review.googlesource.com/c/src/+/131949.

Bug: webrtc:10812
Change-Id: I5fc9c5dfac4b182b84a735218a2946a95cc2b93c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/143483
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28548}
This commit is contained in:
Sergey Silkin
2019-07-11 14:20:38 +02:00
committed by Commit Bot
parent 3ae59d33a3
commit 44cec0b5bd
7 changed files with 26 additions and 23 deletions

View File

@ -25,7 +25,7 @@ namespace test {
// Rates for the encoder and the frame number when to apply profile. // Rates for the encoder and the frame number when to apply profile.
struct RateProfile { struct RateProfile {
size_t target_kbps; size_t target_kbps;
size_t input_fps; double input_fps;
size_t frame_num; size_t frame_num;
}; };

View File

@ -43,6 +43,7 @@ std::string VideoCodecTestStats::FrameStatistics::ToString() const {
ss << " decode_time_us " << decode_time_us; ss << " decode_time_us " << decode_time_us;
ss << " rtp_timestamp " << rtp_timestamp; ss << " rtp_timestamp " << rtp_timestamp;
ss << " target_bitrate_kbps " << target_bitrate_kbps; ss << " target_bitrate_kbps " << target_bitrate_kbps;
ss << " target_framerate_fps " << target_framerate_fps;
return ss.Release(); return ss.Release();
} }

View File

@ -42,6 +42,7 @@ class VideoCodecTestStats {
bool encoding_successful = false; bool encoding_successful = false;
size_t encode_time_us = 0; size_t encode_time_us = 0;
size_t target_bitrate_kbps = 0; size_t target_bitrate_kbps = 0;
double target_framerate_fps = 0.0;
size_t length_bytes = 0; size_t length_bytes = 0;
VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta; VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta;

View File

@ -405,9 +405,8 @@ void VideoCodecTestFixtureImpl::RunTest(
// codecs on a task queue. // codecs on a task queue.
TaskQueueForTest task_queue("VidProc TQ"); TaskQueueForTest task_queue("VidProc TQ");
SetUpAndInitObjects(&task_queue, SetUpAndInitObjects(&task_queue, rate_profiles[0].target_kbps,
static_cast<const int>(rate_profiles[0].target_kbps), rate_profiles[0].input_fps);
static_cast<const int>(rate_profiles[0].input_fps));
PrintSettings(&task_queue); PrintSettings(&task_queue);
ProcessAllFrames(&task_queue, rate_profiles); ProcessAllFrames(&task_queue, rate_profiles);
ReleaseAndCloseObjects(&task_queue); ReleaseAndCloseObjects(&task_queue);
@ -442,9 +441,9 @@ void VideoCodecTestFixtureImpl::ProcessAllFrames(
if (RunEncodeInRealTime(config_)) { if (RunEncodeInRealTime(config_)) {
// Roughly pace the frames. // Roughly pace the frames.
const size_t frame_duration_ms = const int frame_duration_ms =
rtc::kNumMillisecsPerSec / rate_profile->input_fps; std::ceil(rtc::kNumMillisecsPerSec / rate_profile->input_fps);
SleepMs(static_cast<int>(frame_duration_ms)); SleepMs(frame_duration_ms);
} }
} }
@ -552,7 +551,7 @@ void VideoCodecTestFixtureImpl::VerifyVideoStatistic(
const QualityThresholds* quality_thresholds, const QualityThresholds* quality_thresholds,
const BitstreamThresholds* bs_thresholds, const BitstreamThresholds* bs_thresholds,
size_t target_bitrate_kbps, size_t target_bitrate_kbps,
float input_framerate_fps) { double input_framerate_fps) {
if (rc_thresholds) { if (rc_thresholds) {
const float bitrate_mismatch_percent = const float bitrate_mismatch_percent =
100 * std::fabs(1.0f * video_stat.bitrate_kbps - target_bitrate_kbps) / 100 * std::fabs(1.0f * video_stat.bitrate_kbps - target_bitrate_kbps) /
@ -638,11 +637,11 @@ VideoCodecTestStats& VideoCodecTestFixtureImpl::GetStats() {
void VideoCodecTestFixtureImpl::SetUpAndInitObjects( void VideoCodecTestFixtureImpl::SetUpAndInitObjects(
TaskQueueForTest* task_queue, TaskQueueForTest* task_queue,
int initial_bitrate_kbps, size_t initial_bitrate_kbps,
int initial_framerate_fps) { double initial_framerate_fps) {
config_.codec_settings.minBitrate = 0; config_.codec_settings.minBitrate = 0;
config_.codec_settings.startBitrate = initial_bitrate_kbps; config_.codec_settings.startBitrate = static_cast<int>(initial_bitrate_kbps);
config_.codec_settings.maxFramerate = initial_framerate_fps; config_.codec_settings.maxFramerate = std::ceil(initial_framerate_fps);
// Create file objects for quality analysis. // Create file objects for quality analysis.
source_frame_reader_.reset( source_frame_reader_.reset(
@ -679,7 +678,7 @@ void VideoCodecTestFixtureImpl::SetUpAndInitObjects(
if (config_.visualization_params.save_decoded_y4m) { if (config_.visualization_params.save_decoded_y4m) {
FrameWriter* decoded_frame_writer = new Y4mFrameWriterImpl( FrameWriter* decoded_frame_writer = new Y4mFrameWriterImpl(
output_filename_base + ".y4m", config_.codec_settings.width, output_filename_base + ".y4m", config_.codec_settings.width,
config_.codec_settings.height, initial_framerate_fps); config_.codec_settings.height, config_.codec_settings.maxFramerate);
EXPECT_TRUE(decoded_frame_writer->Init()); EXPECT_TRUE(decoded_frame_writer->Init());
decoded_frame_writers_.push_back( decoded_frame_writers_.push_back(
std::unique_ptr<FrameWriter>(decoded_frame_writer)); std::unique_ptr<FrameWriter>(decoded_frame_writer));

View File

@ -62,8 +62,8 @@ class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
void CreateEncoderAndDecoder(); void CreateEncoderAndDecoder();
void DestroyEncoderAndDecoder(); void DestroyEncoderAndDecoder();
void SetUpAndInitObjects(TaskQueueForTest* task_queue, void SetUpAndInitObjects(TaskQueueForTest* task_queue,
int initial_bitrate_kbps, size_t initial_bitrate_kbps,
int initial_framerate_fps); double initial_framerate_fps);
void ReleaseAndCloseObjects(TaskQueueForTest* task_queue); void ReleaseAndCloseObjects(TaskQueueForTest* task_queue);
void ProcessAllFrames(TaskQueueForTest* task_queue, void ProcessAllFrames(TaskQueueForTest* task_queue,
@ -80,7 +80,7 @@ class VideoCodecTestFixtureImpl : public VideoCodecTestFixture {
const QualityThresholds* quality_thresholds, const QualityThresholds* quality_thresholds,
const BitstreamThresholds* bs_thresholds, const BitstreamThresholds* bs_thresholds,
size_t target_bitrate_kbps, size_t target_bitrate_kbps,
float input_framerate_fps); double input_framerate_fps);
void PrintSettings(TaskQueueForTest* task_queue) const; void PrintSettings(TaskQueueForTest* task_queue) const;

View File

@ -256,7 +256,8 @@ void VideoProcessor::ProcessFrame() {
input_frame_reader_->ReadFrame(); input_frame_reader_->ReadFrame();
RTC_CHECK(buffer) << "Tried to read too many frames from the file."; RTC_CHECK(buffer) << "Tried to read too many frames from the file.";
const size_t timestamp = const size_t timestamp =
last_inputed_timestamp_ + kVideoPayloadTypeFrequency / framerate_fps_; last_inputed_timestamp_ +
static_cast<size_t>(kVideoPayloadTypeFrequency / framerate_fps_);
VideoFrame input_frame = VideoFrame input_frame =
VideoFrame::Builder() VideoFrame::Builder()
.set_video_frame_buffer(buffer) .set_video_frame_buffer(buffer)
@ -301,13 +302,13 @@ void VideoProcessor::ProcessFrame() {
} }
} }
void VideoProcessor::SetRates(size_t bitrate_kbps, size_t framerate_fps) { void VideoProcessor::SetRates(size_t bitrate_kbps, double framerate_fps) {
RTC_DCHECK_RUN_ON(&sequence_checker_); RTC_DCHECK_RUN_ON(&sequence_checker_);
framerate_fps_ = static_cast<uint32_t>(framerate_fps); framerate_fps_ = framerate_fps;
bitrate_allocation_ = bitrate_allocator_->GetAllocation( bitrate_allocation_ = bitrate_allocator_->GetAllocation(
static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_); static_cast<uint32_t>(bitrate_kbps * 1000), framerate_fps_);
encoder_->SetRates(VideoEncoder::RateControlParameters( encoder_->SetRates(
bitrate_allocation_, static_cast<double>(framerate_fps_))); VideoEncoder::RateControlParameters(bitrate_allocation_, framerate_fps_));
} }
int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded( int32_t VideoProcessor::VideoProcessorDecodeCompleteCallback::Decoded(
@ -381,6 +382,7 @@ void VideoProcessor::FrameEncoded(
frame_stat->encode_start_ns, encode_stop_ns - post_encode_time_ns_); frame_stat->encode_start_ns, encode_stop_ns - post_encode_time_ns_);
frame_stat->target_bitrate_kbps = frame_stat->target_bitrate_kbps =
bitrate_allocation_.GetTemporalLayerSum(spatial_idx, temporal_idx) / 1000; bitrate_allocation_.GetTemporalLayerSum(spatial_idx, temporal_idx) / 1000;
frame_stat->target_framerate_fps = framerate_fps_;
frame_stat->length_bytes = encoded_image.size(); frame_stat->length_bytes = encoded_image.size();
frame_stat->frame_type = encoded_image._frameType; frame_stat->frame_type = encoded_image._frameType;
frame_stat->temporal_idx = temporal_idx; frame_stat->temporal_idx = temporal_idx;

View File

@ -76,7 +76,7 @@ class VideoProcessor {
void ProcessFrame(); void ProcessFrame();
// Updates the encoder with target rates. Must be called at least once. // Updates the encoder with target rates. Must be called at least once.
void SetRates(size_t bitrate_kbps, size_t framerate_fps); void SetRates(size_t bitrate_kbps, double framerate_fps);
private: private:
class VideoProcessorEncodeCompleteCallback class VideoProcessorEncodeCompleteCallback
@ -194,7 +194,7 @@ class VideoProcessor {
VideoDecoderList* const decoders_; VideoDecoderList* const decoders_;
const std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_; const std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
VideoBitrateAllocation bitrate_allocation_ RTC_GUARDED_BY(sequence_checker_); VideoBitrateAllocation bitrate_allocation_ RTC_GUARDED_BY(sequence_checker_);
uint32_t framerate_fps_ RTC_GUARDED_BY(sequence_checker_); double framerate_fps_ RTC_GUARDED_BY(sequence_checker_);
// Adapters for the codec callbacks. // Adapters for the codec callbacks.
VideoProcessorEncodeCompleteCallback encode_callback_; VideoProcessorEncodeCompleteCallback encode_callback_;