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:

committed by
Commit Bot

parent
3ae59d33a3
commit
44cec0b5bd
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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_;
|
||||||
|
Reference in New Issue
Block a user