Fix AV1 encoder do't set end_of_picture when the top layer is dropped
Bug: webrtc:357721007 Change-Id: I4e318618192aa9d58a2ef6338f7b1e2ee5140254 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/366100 Reviewed-by: Åsa Persson <asapersson@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43437}
This commit is contained in:
parent
8da15c43dd
commit
253b8464ff
@ -645,6 +645,7 @@ int32_t LibaomAv1Encoder::Encode(
|
||||
const size_t num_spatial_layers =
|
||||
svc_params_ ? svc_params_->number_spatial_layers : 1;
|
||||
auto next_layer_frame = layer_frames.begin();
|
||||
std::vector<std::pair<EncodedImage, CodecSpecificInfo>> encoded_images;
|
||||
for (size_t i = 0; i < num_spatial_layers; ++i) {
|
||||
// The libaom AV1 encoder requires that `aom_codec_encode` is called for
|
||||
// every spatial layer, even if the configured bitrate for that layer is
|
||||
@ -763,10 +764,17 @@ int32_t LibaomAv1Encoder::Encode(
|
||||
resolutions = {RenderResolution(cfg_.g_w, cfg_.g_h)};
|
||||
}
|
||||
}
|
||||
encoded_image_callback_->OnEncodedImage(encoded_image,
|
||||
&codec_specific_info);
|
||||
encoded_images.emplace_back(std::move(encoded_image),
|
||||
std::move(codec_specific_info));
|
||||
}
|
||||
}
|
||||
if (!encoded_images.empty()) {
|
||||
encoded_images.back().second.end_of_picture = true;
|
||||
}
|
||||
for (auto& [encoded_image, codec_specific_info] : encoded_images) {
|
||||
encoded_image_callback_->OnEncodedImage(encoded_image,
|
||||
&codec_specific_info);
|
||||
}
|
||||
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
@ -177,6 +177,35 @@ TEST(LibaomAv1EncoderTest, SetsEndOfPictureForLastFrameInTemporalUnit) {
|
||||
EXPECT_TRUE(encoded_frames[5].codec_specific_info.end_of_picture);
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest,
|
||||
SetsEndOfPictureForLastFrameInTemporalUnitWhenLayerDrop) {
|
||||
VideoBitrateAllocation allocation;
|
||||
allocation.SetBitrate(0, 0, 30000);
|
||||
allocation.SetBitrate(1, 0, 40000);
|
||||
// Lower bitrate for the last spatial layer to provoke layer drop.
|
||||
allocation.SetBitrate(2, 0, 500);
|
||||
|
||||
std::unique_ptr<VideoEncoder> encoder =
|
||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||
VideoCodec codec_settings = DefaultCodecSettings();
|
||||
// Configure encoder with 3 spatial layers.
|
||||
codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1);
|
||||
codec_settings.startBitrate = allocation.get_sum_kbps();
|
||||
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||
WEBRTC_VIDEO_CODEC_OK);
|
||||
|
||||
encoder->SetRates(VideoEncoder::RateControlParameters(
|
||||
allocation, codec_settings.maxFramerate));
|
||||
|
||||
std::vector<EncodedVideoFrameProducer::EncodedFrame> encoded_frames =
|
||||
EncodedVideoFrameProducer(*encoder).SetNumInputFrames(2).Encode();
|
||||
ASSERT_THAT(encoded_frames, SizeIs(4));
|
||||
EXPECT_FALSE(encoded_frames[0].codec_specific_info.end_of_picture);
|
||||
EXPECT_TRUE(encoded_frames[1].codec_specific_info.end_of_picture);
|
||||
EXPECT_FALSE(encoded_frames[2].codec_specific_info.end_of_picture);
|
||||
EXPECT_TRUE(encoded_frames[3].codec_specific_info.end_of_picture);
|
||||
}
|
||||
|
||||
TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) {
|
||||
VideoBitrateAllocation allocation;
|
||||
allocation.SetBitrate(0, 0, 30000);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user