media/gpu: Enable default variable bitrate allocation
This CL modifies AllocateDefaultBitrateForEncoding and similar in
media/gpu/gpu_video_encode_accelerator_helpers.*, enabling request for a
variable bitrate instead of a constant bitrate. For now, the testing
version of the function will set the peak of the constructed default
bitrate to be the same as the target, and callers may adjust the peak
if they wish.
This CL is one of a series of CLs to enable VBR support in encoding. A
design doc for the VA-API-specific changes is available at
https://docs.google.com/document/d/16kp6nfgMOvQWZRhB_4rzzVTIl6YhpSn46CvJ-jf628k/edit?usp=sharing
And an overall design doc for VBR encoding is available at
https://docs.google.com/document/d/1kofC1bNUgfJQ3DAlYuTlEkXhe86my0UrKzAXGHvnvgw/edit?usp=sharing
Bug: b:181797390
Change-Id: I85d161663b2b95856744b8e6e619f6ee581fd89a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3688417
Commit-Queue: Clarissa Garvey <clarissagarvey@chromium.org>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1011248}
diff --git a/media/gpu/gpu_video_encode_accelerator_helpers.cc b/media/gpu/gpu_video_encode_accelerator_helpers.cc
index c731dff8..2f057cf 100644
--- a/media/gpu/gpu_video_encode_accelerator_helpers.cc
+++ b/media/gpu/gpu_video_encode_accelerator_helpers.cc
@@ -58,9 +58,12 @@
return kMaxBitstreamBufferSizeInBytes;
}
+// This function sets the peak equal to the target. The peak can then be
+// updated by callers.
VideoBitrateAllocation AllocateBitrateForDefaultEncodingWithBitrates(
const std::vector<uint32_t>& sl_bitrates,
- const size_t num_temporal_layers) {
+ const size_t num_temporal_layers,
+ const bool uses_vbr) {
CHECK(!sl_bitrates.empty());
CHECK_LE(sl_bitrates.size(), kMaxSpatialLayers);
@@ -77,6 +80,8 @@
DCHECK_EQ(std::size(kTemporalLayersBitrateScaleFactors), kMaxTemporalLayers);
VideoBitrateAllocation bitrate_allocation;
+ bitrate_allocation = VideoBitrateAllocation(
+ uses_vbr ? Bitrate::Mode::kVariable : Bitrate::Mode::kConstant);
for (size_t spatial_id = 0; spatial_id < sl_bitrates.size(); ++spatial_id) {
const uint32_t bitrate_bps = sl_bitrates[spatial_id];
for (size_t temporal_id = 0; temporal_id < num_temporal_layers;
@@ -156,10 +161,16 @@
VideoBitrateAllocation AllocateBitrateForDefaultEncoding(
const VideoEncodeAccelerator::Config& config) {
+ VideoBitrateAllocation allocation;
+ const bool use_vbr = config.bitrate.mode() == Bitrate::Mode::kVariable;
if (config.spatial_layers.empty()) {
- return AllocateBitrateForDefaultEncodingWithBitrates(
+ allocation = AllocateBitrateForDefaultEncodingWithBitrates(
{config.bitrate.target_bps()},
- /*num_temporal_layers=*/1u);
+ /*num_temporal_layers=*/1u, use_vbr);
+ if (use_vbr) {
+ allocation.SetPeakBps(config.bitrate.peak_bps());
+ }
+ return allocation;
}
const size_t num_temporal_layers =
@@ -171,14 +182,19 @@
bitrates.push_back(spatial_layer.bitrate_bps);
}
- return AllocateBitrateForDefaultEncodingWithBitrates(bitrates,
- num_temporal_layers);
+ allocation = AllocateBitrateForDefaultEncodingWithBitrates(
+ bitrates, num_temporal_layers, use_vbr);
+ if (use_vbr) {
+ allocation.SetPeakBps(config.bitrate.peak_bps());
+ }
+ return allocation;
}
VideoBitrateAllocation AllocateDefaultBitrateForTesting(
const size_t num_spatial_layers,
const size_t num_temporal_layers,
- const uint32_t bitrate) {
+ const uint32_t bitrate,
+ const bool uses_vbr) {
// Higher spatial layers (those to the right) get more bitrate.
constexpr double kSpatialLayersBitrateScaleFactors[][kMaxSpatialLayers] = {
{1.00, 0.00, 0.00}, // For one spatial layer.
@@ -197,8 +213,8 @@
bitrates[sid] = bitrate * bitrate_factor;
}
- return AllocateBitrateForDefaultEncodingWithBitrates(bitrates,
- num_temporal_layers);
+ return AllocateBitrateForDefaultEncodingWithBitrates(
+ bitrates, num_temporal_layers, uses_vbr);
}
} // namespace media
diff --git a/media/gpu/gpu_video_encode_accelerator_helpers.h b/media/gpu/gpu_video_encode_accelerator_helpers.h
index 79f9b8c..66d1b95 100644
--- a/media/gpu/gpu_video_encode_accelerator_helpers.h
+++ b/media/gpu/gpu_video_encode_accelerator_helpers.h
@@ -43,17 +43,21 @@
AllocateBitrateForDefaultEncoding(const VideoEncodeAccelerator::Config& config);
// Create VideoBitrateAllocation with |num_spatial_layers|,
-// |num_temporal_layers| and |bitrate|. |bitrate| is the bitrate of the entire
+// |num_temporal_layers| and |bitrate|, additionally indicating if the
+// constructed bitrate should |use_vbr|. |bitrate| is the bitrate of the entire
// stream. |num_temporal_layers| is the number of temporal layers in each
-// spatial layer.
+// spatial layer. |use_vbr| indicates whether the bitrate should have
+// |Bitrate::Mode::kVariable.|
// First, |bitrate| is distributed to spatial layers based on libwebrtc bitrate
// division. Then the bitrate of each spatial layer is distributed to temporal
// layers in the spatial layer based on the same bitrate division ratio as a
-// software encoder.
+// software encoder. If a variable bitrate is requested, the peak will be set
+// equal to the target.
MEDIA_GPU_EXPORT VideoBitrateAllocation
AllocateDefaultBitrateForTesting(const size_t num_spatial_layers,
const size_t num_temporal_layers,
- const uint32_t bitrate);
+ const uint32_t bitrate,
+ const bool uses_vbr);
} // namespace media
#endif // MEDIA_GPU_GPU_VIDEO_ENCODE_ACCELERATOR_HELPERS_H_
diff --git a/media/gpu/test/video_encoder/video_encoder_test_environment.cc b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
index 57a44e7..41e1a62 100644
--- a/media/gpu/test/video_encoder/video_encoder_test_environment.cc
+++ b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
@@ -204,7 +204,8 @@
num_spatial_layers_(num_spatial_layers),
bitrate_(AllocateDefaultBitrateForTesting(num_spatial_layers_,
num_temporal_layers_,
- bitrate)),
+ bitrate,
+ false)),
spatial_layers_(GetDefaultSpatialLayers(bitrate_,
video_.get(),
num_spatial_layers_,
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
index e4fc807b..8f07a9f1 100644
--- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
+++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
@@ -344,7 +344,7 @@
auto initial_bitrate_allocation = AllocateDefaultBitrateForTesting(
num_spatial_layers, num_temporal_layers,
- kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps());
+ kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps(), false);
std::vector<gfx::Size> svc_layer_size =
GetDefaultSpatialLayerResolutions(num_spatial_layers);
if (num_spatial_layers > 1u || num_temporal_layers > 1u) {
@@ -368,7 +368,7 @@
EXPECT_CALL(*mock_rate_ctrl_, UpdateRateControl(MatchRtcConfigWithRates(
AllocateDefaultBitrateForTesting(
num_spatial_layers, num_temporal_layers,
- config.bitrate.target_bps()),
+ config.bitrate.target_bps(), false),
VideoEncodeAccelerator::kDefaultFramerate,
num_temporal_layers, svc_layer_size)))
.Times(1)
@@ -496,7 +496,7 @@
uint8_t expected_temporal_layer_id,
uint32_t bitrate, uint32_t framerate) {
auto bitrate_allocation = AllocateDefaultBitrateForTesting(
- num_spatial_layers, num_temporal_layers, bitrate);
+ num_spatial_layers, num_temporal_layers, bitrate, false);
UpdateRatesAndEncode(bitrate_allocation, framerate,
/*valid_rates_request=*/true, is_key_pic,
spatial_layer_resolutions, num_temporal_layers,
@@ -627,7 +627,7 @@
const VideoBitrateAllocation kDefaultBitrateAllocation =
AllocateDefaultBitrateForTesting(
num_spatial_layers, num_temporal_layers,
- kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps());
+ kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps(), false);
const std::vector<gfx::Size> kDefaultSpatialLayers =
GetDefaultSpatialLayerResolutions(num_spatial_layers);
const uint32_t kFramerate =
@@ -657,7 +657,7 @@
const VideoBitrateAllocation kDefaultBitrateAllocation =
AllocateDefaultBitrateForTesting(
num_spatial_layers, num_temporal_layers,
- kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps());
+ kDefaultVideoEncodeAcceleratorConfig.bitrate.target_bps(), false);
std::vector<VideoBitrateAllocation> invalid_bitrate_allocations;
constexpr uint32_t kBitrate = 1234u;
auto bitrate_allocation = kDefaultBitrateAllocation;
diff --git a/media/gpu/video_encode_accelerator_tests.cc b/media/gpu/video_encode_accelerator_tests.cc
index 137d728..d4c87a91 100644
--- a/media/gpu/video_encode_accelerator_tests.cc
+++ b/media/gpu/video_encode_accelerator_tests.cc
@@ -536,7 +536,7 @@
encoder->ResetStats();
encoder->UpdateBitrate(AllocateDefaultBitrateForTesting(
config.num_spatial_layers,
- config.num_temporal_layers, second_bitrate),
+ config.num_temporal_layers, second_bitrate, false),
config.framerate);
encoder->Encode();
EXPECT_TRUE(encoder->WaitForFlushDone());
@@ -643,7 +643,7 @@
VideoEncoderClientConfig config(
nv12_video, g_env->Profile(), spatial_layers,
AllocateDefaultBitrateForTesting(/*num_spatial_layers=*/1u,
- num_temporal_layers, new_bitrate),
+ num_temporal_layers, new_bitrate, false),
g_env->Reverse());
config.output_resolution = output_resolution;
config.input_storage_type =