in Av1 encoder wrapper communicate end_of_picture flag similar to VP9

In particular move end_of_picture flag out of vp9 specific information
since VP9 is not the only codec that can use spatial scalability and
thus need to distinguish layer frame and picture (aka temporal unit).

Bug: webrtc:12167
Change-Id: I0d046d8785fbea55281209ad099738c03ea7db96
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/192542
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32588}
This commit is contained in:
Danil Chapovalov
2020-11-11 12:42:56 +01:00
committed by Commit Bot
parent f2a2fe84b8
commit 06bbeb3398
12 changed files with 45 additions and 26 deletions

View File

@ -462,7 +462,10 @@ int32_t LibaomAv1Encoder::Encode(
const uint32_t duration =
kRtpTicksPerSecond / static_cast<float>(encoder_settings_.maxFramerate);
for (ScalableVideoController::LayerFrameConfig& layer_frame : layer_frames) {
for (size_t i = 0; i < layer_frames.size(); ++i) {
ScalableVideoController::LayerFrameConfig& layer_frame = layer_frames[i];
const bool end_of_picture = i == layer_frames.size() - 1;
aom_enc_frame_flags_t flags =
layer_frame.IsKeyframe() ? AOM_EFLAG_FORCE_KF : 0;
@ -528,6 +531,7 @@ int32_t LibaomAv1Encoder::Encode(
if (encoded_image.size() > 0) {
CodecSpecificInfo codec_specific_info;
codec_specific_info.codecType = kVideoCodecAV1;
codec_specific_info.end_of_picture = end_of_picture;
bool is_keyframe = layer_frame.IsKeyframe();
codec_specific_info.generic_frame_info =
svc_controller_->OnEncodeDone(std::move(layer_frame));

View File

@ -83,5 +83,24 @@ TEST(LibaomAv1EncoderTest, NoBitrateOnTopLayerRefecltedInActiveDecodeTargets) {
0b01);
}
TEST(LibaomAv1EncoderTest, SetsEndOfPictureForLastFrameInTemporalUnit) {
std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
VideoCodec codec_settings = DefaultCodecSettings();
// Configure encoder with 3 spatial layers.
codec_settings.SetScalabilityMode("L3T1");
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
WEBRTC_VIDEO_CODEC_OK);
std::vector<EncodedVideoFrameProducer::EncodedFrame> encoded_frames =
EncodedVideoFrameProducer(*encoder).SetNumInputFrames(2).Encode();
ASSERT_THAT(encoded_frames, SizeIs(6));
EXPECT_FALSE(encoded_frames[0].codec_specific_info.end_of_picture);
EXPECT_FALSE(encoded_frames[1].codec_specific_info.end_of_picture);
EXPECT_TRUE(encoded_frames[2].codec_specific_info.end_of_picture);
EXPECT_FALSE(encoded_frames[3].codec_specific_info.end_of_picture);
EXPECT_FALSE(encoded_frames[4].codec_specific_info.end_of_picture);
EXPECT_TRUE(encoded_frames[5].codec_specific_info.end_of_picture);
}
} // namespace
} // namespace webrtc

View File

@ -373,13 +373,11 @@ void VideoProcessor::FrameEncoded(
frame_stat->max_nalu_size_bytes = GetMaxNaluSizeBytes(encoded_image, config_);
frame_stat->qp = encoded_image.qp_;
bool end_of_picture = false;
if (codec_type == kVideoCodecVP9) {
const CodecSpecificInfoVP9& vp9_info = codec_specific.codecSpecific.VP9;
frame_stat->inter_layer_predicted = vp9_info.inter_layer_predicted;
frame_stat->non_ref_for_inter_layer_pred =
vp9_info.non_ref_for_inter_layer_pred;
end_of_picture = vp9_info.end_of_picture;
} else {
frame_stat->inter_layer_predicted = false;
frame_stat->non_ref_for_inter_layer_pred = true;
@ -397,7 +395,7 @@ void VideoProcessor::FrameEncoded(
if (config_.decode) {
DecodeFrame(*encoded_image_for_decode, spatial_idx);
if (end_of_picture && num_spatial_layers > 1) {
if (codec_specific.end_of_picture && num_spatial_layers > 1) {
// If inter-layer prediction is enabled and upper layer was dropped then
// base layer should be passed to upper layer decoder. Otherwise decoder
// won't be able to decode next superframe.

View File

@ -919,8 +919,8 @@ TEST_F(TestVp9Impl, EndOfPicture) {
std::vector<EncodedImage> frames;
std::vector<CodecSpecificInfo> codec_specific;
ASSERT_TRUE(WaitForEncodedFrames(&frames, &codec_specific));
EXPECT_FALSE(codec_specific[0].codecSpecific.VP9.end_of_picture);
EXPECT_TRUE(codec_specific[1].codecSpecific.VP9.end_of_picture);
EXPECT_FALSE(codec_specific[0].end_of_picture);
EXPECT_TRUE(codec_specific[1].end_of_picture);
// Encode only base layer. Check that end-of-superframe flag is
// set on base layer frame.
@ -935,7 +935,7 @@ TEST_F(TestVp9Impl, EndOfPicture) {
ASSERT_TRUE(WaitForEncodedFrames(&frames, &codec_specific));
EXPECT_FALSE(frames[0].SpatialIndex());
EXPECT_TRUE(codec_specific[0].codecSpecific.VP9.end_of_picture);
EXPECT_TRUE(codec_specific[0].end_of_picture);
}
TEST_F(TestVp9Impl, InterLayerPred) {

View File

@ -1683,7 +1683,7 @@ void VP9EncoderImpl::DeliverBufferedFrame(bool end_of_picture) {
}
}
codec_specific_.codecSpecific.VP9.end_of_picture = end_of_picture;
codec_specific_.end_of_picture = end_of_picture;
encoded_complete_callback_->OnEncodedImage(encoded_image_,
&codec_specific_);