diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index a183704caa..a5a87eeed2 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -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> 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; } diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc index 99ccea14fb..79275e1210 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc @@ -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 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 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);