Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Unified Diff: webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h

Issue 2741953002: Step #4: Run VideoProcessor integration test batch mode on task queue. (Closed)
Patch Set: Fix gn again. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h
diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h
index 5c275aa949015bd3ef63aa340d2283f2258b4488..c784194e958bb530e93f324c9d050d55aec9325d 100644
--- a/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h
+++ b/webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h
@@ -28,8 +28,11 @@
#endif
#include "webrtc/base/checks.h"
+#include "webrtc/base/event.h"
#include "webrtc/base/file.h"
#include "webrtc/base/logging.h"
+#include "webrtc/base/task_queue.h"
+#include "webrtc/base/timeutils.h"
#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
@@ -41,6 +44,7 @@
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/include/video_coding.h"
#include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
+#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/test/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/frame_reader.h"
@@ -237,6 +241,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
}
void SetUpCodecConfig(const CodecParams& process,
+ const RateProfile& rate_profile,
const VisualizationParams* visualization_params) {
CreateEncoderAndDecoder(process.hw_codec, process.codec_type);
@@ -255,12 +260,13 @@ class VideoProcessorIntegrationTest : public testing::Test {
// Key frame interval and packet loss are set for each test.
config_.keyframe_interval = process.key_frame_interval;
config_.networking_config.packet_loss_probability =
- packet_loss_probability_;
+ process.packet_loss_probability;
// Configure codec settings.
VideoCodingModule::Codec(process.codec_type, &codec_settings_);
config_.codec_settings = &codec_settings_;
- config_.codec_settings->startBitrate = start_bitrate_;
+ float start_bitrate = rate_profile.target_bit_rate[0];
+ config_.codec_settings->startBitrate = start_bitrate;
config_.codec_settings->width = process.width;
config_.codec_settings->height = process.height;
@@ -318,13 +324,13 @@ class VideoProcessorIntegrationTest : public testing::Test {
test::OutputPath() + process.filename +
"_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") +
"_hw-" + std::to_string(process.hw_codec) +
- "_fr-" + std::to_string(start_frame_rate_) +
- "_br-" + std::to_string(static_cast<int>(start_bitrate_));
+ "_br-" + std::to_string(static_cast<int>(start_bitrate));
// clang-format on
+ int start_frame_rate = rate_profile.input_frame_rate[0];
if (visualization_params->save_source_y4m) {
source_frame_writer_.reset(new test::Y4mFrameWriterImpl(
output_filename_base + "_source.y4m", config_.codec_settings->width,
- config_.codec_settings->height, start_frame_rate_));
+ config_.codec_settings->height, start_frame_rate));
RTC_CHECK(source_frame_writer_->Init());
}
if (visualization_params->save_encoded_ivf) {
@@ -337,7 +343,7 @@ class VideoProcessorIntegrationTest : public testing::Test {
decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl(
output_filename_base + "_decoded.y4m",
config_.codec_settings->width, config_.codec_settings->height,
- start_frame_rate_));
+ start_frame_rate));
RTC_CHECK(decoded_frame_writer_->Init());
}
}
@@ -349,7 +355,6 @@ class VideoProcessorIntegrationTest : public testing::Test {
analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
&stats_, source_frame_writer_.get(), encoded_frame_writer_.get(),
decoded_frame_writer_.get()));
- processor_->Init();
}
// Reset quantities after each encoder update, update the target
@@ -383,12 +388,12 @@ class VideoProcessorIntegrationTest : public testing::Test {
}
// For every encoded frame, update the rate control metrics.
- void UpdateRateControlMetrics(int frame_number) {
+ void UpdateRateControlMetrics(int frame_number,
+ FrameType frame_type,
+ size_t encoded_frame_size) {
RTC_CHECK_GE(frame_number, 0);
int tl_idx = TemporalLayerIndexForFrame(frame_number);
- FrameType frame_type = processor_->EncodedFrameType(frame_number);
- float encoded_size_kbits =
- processor_->EncodedFrameSize(frame_number) * 8.0f / 1000.0f;
+ float encoded_size_kbits = encoded_frame_size * 8.0f / 1000.0f;
// Update layer data.
// Update rate mismatch relative to per-frame bandwidth for delta frames.
@@ -423,11 +428,36 @@ class VideoProcessorIntegrationTest : public testing::Test {
}
}
+ void UpdateRateControlMetrics(int frame_number, rtc::TaskQueue* task_queue) {
+ FrameType frame_type;
+ size_t encoded_frame_size;
+
+ if (task_queue) {
+ rtc::Event sync_event(false, false);
+ task_queue->PostTask([this, &frame_type, &encoded_frame_size,
+ frame_number, &sync_event]() {
+ frame_type = processor_->EncodedFrameType(frame_number);
+ encoded_frame_size = processor_->EncodedFrameSize(frame_number);
+ sync_event.Set();
+ });
+ ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever));
+ } else {
+ frame_type = processor_->EncodedFrameType(frame_number);
+ encoded_frame_size = processor_->EncodedFrameSize(frame_number);
+ }
+
+ UpdateRateControlMetrics(frame_number, frame_type, encoded_frame_size);
+ }
+
+ void UpdateRateControlMetrics(int frame_number) {
+ UpdateRateControlMetrics(frame_number, nullptr);
+ }
+
// Verify expected behavior of rate control and print out data.
void VerifyRateControlMetrics(int update_index,
- const RateControlThresholds& rc_expected) {
- int num_dropped_frames = processor_->NumberDroppedFrames();
- int num_resize_actions = processor_->NumberSpatialResizes();
+ const RateControlThresholds& rc_expected,
+ int num_dropped_frames,
+ int num_resize_actions) {
printf(
"For update #: %d,\n"
" Target Bitrate: %d,\n"
@@ -489,6 +519,35 @@ class VideoProcessorIntegrationTest : public testing::Test {
}
}
+ void VerifyRateControlMetrics(int update_index,
+ const RateControlThresholds& rc_expected,
+ rtc::TaskQueue* task_queue) {
+ int num_dropped_frames;
+ int num_resize_actions;
+
+ if (task_queue) {
+ rtc::Event sync_event(false, false);
+ task_queue->PostTask(
+ [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
+ num_dropped_frames = processor_->NumberDroppedFrames();
+ num_resize_actions = processor_->NumberSpatialResizes();
+ sync_event.Set();
+ });
+ ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever));
+ } else {
+ num_dropped_frames = processor_->NumberDroppedFrames();
+ num_resize_actions = processor_->NumberSpatialResizes();
+ }
+
+ VerifyRateControlMetrics(update_index, rc_expected, num_dropped_frames,
+ num_resize_actions);
+ }
+
+ void VerifyRateControlMetrics(int update_index,
+ const RateControlThresholds& rc_expected) {
+ VerifyRateControlMetrics(update_index, rc_expected, nullptr);
+ }
+
void VerifyQuality(const test::QualityMetricsResult& psnr_result,
const test::QualityMetricsResult& ssim_result,
const QualityThresholds& quality_thresholds) {
@@ -570,11 +629,9 @@ class VideoProcessorIntegrationTest : public testing::Test {
RateControlThresholds* rc_thresholds,
const VisualizationParams* visualization_params) {
// Codec/config settings.
- start_bitrate_ = rate_profile.target_bit_rate[0];
- start_frame_rate_ = rate_profile.input_frame_rate[0];
- packet_loss_probability_ = process.packet_loss_probability;
num_temporal_layers_ = process.num_temporal_layers;
- SetUpCodecConfig(process, visualization_params);
+ SetUpCodecConfig(process, rate_profile, visualization_params);
+
// Update the temporal layers and the codec with the initial rates.
bit_rate_ = rate_profile.target_bit_rate[0];
frame_rate_ = rate_profile.input_frame_rate[0];
@@ -582,7 +639,6 @@ class VideoProcessorIntegrationTest : public testing::Test {
// Set the initial target size for key frame.
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 frame_number = 0;
@@ -595,17 +651,54 @@ class VideoProcessorIntegrationTest : public testing::Test {
// In batch mode, we calculate the metrics for all frames after all frames
// have been sent for encoding.
+ // AndroidMediaEncoder must be called on a task queue, so during the batch
+ // run we will call |processor_| on a task queue.
+ rtc::TaskQueue task_queue("VidProc TQ");
+
+ // Initialize |processor_|, which initializes the encoder and decoder.
+ rtc::Event sync_event(false, false);
+ task_queue.PostTask([this, &sync_event]() {
+ processor_->Init();
+ processor_->SetRates(bit_rate_, frame_rate_);
+ sync_event.Set();
+ });
+ ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever));
+
+ // Post all frames (in order) to encoder.
+ int start_frame_rate = rate_profile.input_frame_rate[0];
// TODO(brandtr): Refactor "frame number accounting" so we don't have to
// call ProcessFrame num_frames+1 times here.
for (frame_number = 0; frame_number <= num_frames; ++frame_number) {
- EXPECT_TRUE(processor_->ProcessFrame(frame_number));
+ task_queue.PostTask([this, frame_number]() {
+ EXPECT_TRUE(processor_->ProcessFrame(frame_number));
+ });
+
+ // In order to not overwhelm the OpenMAX buffers in the Android
+ // MediaCodec API, we roughly pace the frames here. The downside
+ // is that the encode run will be done in realtime.
+ if (process.hw_codec) {
+ SleepMs(rtc::kNumMillisecsPerSec / start_frame_rate);
+ }
}
+ // Give the task queue some time to finish processing the posted frames,
+ // then shut down processing and synchronize with main thread.
+ SleepMs(rtc::kNumMillisecsPerSec);
+ sync_event.Reset();
+ task_queue.PostTask([this, &sync_event]() {
+ processor_->Release();
+ sync_event.Set();
+ });
+ ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever));
+
+ // Calculate and print rate control metrics.
for (frame_number = 0; frame_number < num_frames; ++frame_number) {
++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)];
++num_frames_total_;
- UpdateRateControlMetrics(frame_number);
+ UpdateRateControlMetrics(frame_number, &task_queue);
}
+
+ VerifyRateControlMetrics(update_index, rc_thresholds[0], &task_queue);
} else {
// In online mode, we calculate the metrics for a given frame right after
// it has been sent for encoding.
@@ -615,6 +708,10 @@ class VideoProcessorIntegrationTest : public testing::Test {
"since they may be pipelining.";
}
+ // Initialize |processor_| on main thread.
+ processor_->Init();
+ processor_->SetRates(bit_rate_, frame_rate_);
+
while (frame_number < num_frames) {
EXPECT_TRUE(processor_->ProcessFrame(frame_number));
VerifyQpParser(process, frame_number);
@@ -643,18 +740,16 @@ class VideoProcessorIntegrationTest : public testing::Test {
// TODO(brandtr): Refactor "frame number accounting" so we don't have to
// call ProcessFrame one extra time here.
EXPECT_TRUE(processor_->ProcessFrame(frame_number));
- }
- // Verify rate control metrics for all frames (if in batch mode), or for all
- // frames since the last rate update (if not in batch mode).
- VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
+ // Release codecs to make sure they have finished processing.
+ processor_->Release();
+
+ // Verify for final rate update.
+ VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
+ }
EXPECT_EQ(num_frames, frame_number);
EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size()));
- // 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 analysis files before we use them for SSIM/PSNR calculations.
analysis_frame_reader_->Close();
analysis_frame_writer_->Close();
@@ -829,11 +924,8 @@ class VideoProcessorIntegrationTest : public testing::Test {
float target_size_key_frame_;
float sum_key_frame_size_mismatch_;
int num_key_frames_;
- float start_bitrate_;
- int start_frame_rate_;
// Codec and network settings.
- float packet_loss_probability_;
int num_temporal_layers_;
};

Powered by Google App Engine
This is Rietveld 408576698