diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 0ac3951c81..ed2507d03f 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -331,8 +331,8 @@ bool LibaomAv1Encoder::SetSvcParams( void LibaomAv1Encoder::SetSvcLayerId( const ScalableVideoController::LayerFrameConfig& layer_frame) { aom_svc_layer_id_t layer_id = {}; - layer_id.spatial_layer_id = layer_frame.spatial_id; - layer_id.temporal_layer_id = layer_frame.temporal_id; + layer_id.spatial_layer_id = layer_frame.SpatialId(); + layer_id.temporal_layer_id = layer_frame.TemporalId(); aom_codec_err_t ret = aom_codec_control(&ctx_, AV1E_SET_SVC_LAYER_ID, &layer_id); if (ret != AOM_CODEC_OK) { @@ -354,9 +354,9 @@ void LibaomAv1Encoder::SetSvcRefFrameConfig( static constexpr int kAv1NumBuffers = 8; aom_svc_ref_frame_config_t ref_frame_config = {}; - RTC_CHECK_LE(layer_frame.buffers.size(), ABSL_ARRAYSIZE(kPreferedSlotName)); - for (size_t i = 0; i < layer_frame.buffers.size(); ++i) { - const CodecBufferUsage& buffer = layer_frame.buffers[i]; + RTC_CHECK_LE(layer_frame.Buffers().size(), ABSL_ARRAYSIZE(kPreferedSlotName)); + for (size_t i = 0; i < layer_frame.Buffers().size(); ++i) { + const CodecBufferUsage& buffer = layer_frame.Buffers()[i]; int slot_name = kPreferedSlotName[i]; RTC_CHECK_GE(buffer.id, 0); RTC_CHECK_LT(buffer.id, kAv1NumBuffers); @@ -442,7 +442,7 @@ int32_t LibaomAv1Encoder::Encode( for (ScalableVideoController::LayerFrameConfig& layer_frame : layer_frames) { aom_enc_frame_flags_t flags = - layer_frame.is_keyframe ? AOM_EFLAG_FORCE_KF : 0; + layer_frame.IsKeyframe() ? AOM_EFLAG_FORCE_KF : 0; if (svc_enabled_) { SetSvcLayerId(layer_frame); @@ -486,9 +486,10 @@ int32_t LibaomAv1Encoder::Encode( } encoded_image.SetEncodedData(EncodedImageBuffer::Create(data, size)); - layer_frame.is_keyframe = - ((pkt->data.frame.flags & AOM_EFLAG_FORCE_KF) != 0); - encoded_image._frameType = layer_frame.is_keyframe + if ((pkt->data.frame.flags & AOM_EFLAG_FORCE_KF) != 0) { + layer_frame.Keyframe(); + } + encoded_image._frameType = layer_frame.IsKeyframe() ? VideoFrameType::kVideoFrameKey : VideoFrameType::kVideoFrameDelta; encoded_image.SetTimestamp(frame.timestamp()); @@ -517,7 +518,7 @@ int32_t LibaomAv1Encoder::Encode( if (encoded_image.size() > 0) { CodecSpecificInfo codec_specific_info; codec_specific_info.codecType = kVideoCodecAV1; - bool is_keyframe = layer_frame.is_keyframe; + bool is_keyframe = layer_frame.IsKeyframe(); codec_specific_info.generic_frame_info = svc_controller_->OnEncodeDone(std::move(layer_frame)); if (is_keyframe && codec_specific_info.generic_frame_info) { diff --git a/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc b/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc index 697c3cf69c..c8386efeed 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l1t2.cc @@ -65,28 +65,18 @@ ScalabilityStructureL1T2::NextFrameConfig(bool restart) { switch (next_pattern_) { case kKeyFrame: - result[0].id = 0; - result[0].temporal_id = 0; - result[0].is_keyframe = true; - result[0].buffers = {{/*id=*/0, /*references=*/false, /*updates=*/true}}; + result[0].Id(0).T(0).Keyframe().Update(0); next_pattern_ = kDeltaFrameT1; break; case kDeltaFrameT1: - result[0].id = 1; - result[0].temporal_id = 1; - result[0].is_keyframe = false; - result[0].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/false}}; + result[0].Id(1).T(1).Reference(0); next_pattern_ = kDeltaFrameT0; break; case kDeltaFrameT0: - result[0].id = 2; - result[0].temporal_id = 0; - result[0].is_keyframe = false; - result[0].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/true}}; + result[0].Id(2).T(0).ReferenceAndUpdate(0); next_pattern_ = kDeltaFrameT1; break; } - RTC_DCHECK(!result.empty()); return result; } @@ -94,21 +84,21 @@ absl::optional ScalabilityStructureL1T2::OnEncodeDone( LayerFrameConfig config) { // Encoder may have generated a keyframe even when not asked for it. Treat // such frame same as requested keyframe, in particular restart the sequence. - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = NextFrameConfig(/*restart=*/true).front(); } absl::optional frame_info; - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - frame_info->part_of_chain = {config.temporal_id == 0}; + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = config.Buffers(); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + frame_info->part_of_chain = {config.TemporalId() == 0}; return frame_info; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc b/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc index 2c97ef75aa..f3e7583195 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l2t1.cc @@ -60,40 +60,20 @@ FrameDependencyStructure ScalabilityStructureL2T1::DependencyStructure() const { ScalableVideoController::LayerFrameConfig ScalabilityStructureL2T1::KeyFrameConfig() const { - LayerFrameConfig result; - result.id = 0; - result.spatial_id = 0; - result.is_keyframe = true; - result.buffers = {{/*id=*/0, /*references=*/false, /*updates=*/true}}; - return result; + return LayerFrameConfig().Id(0).S(0).Keyframe().Update(0); } std::vector ScalabilityStructureL2T1::NextFrameConfig(bool restart) { std::vector result(2); - // Buffer0 keeps latest S0 frame, Buffer1 keeps latest S1 frame. if (restart || keyframe_) { result[0] = KeyFrameConfig(); - - result[1].id = 1; - result[1].spatial_id = 1; - result[1].is_keyframe = false; - result[1].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/false}, - {/*id=*/1, /*references=*/false, /*updates=*/true}}; - + result[1].Id(1).S(1).Reference(0).Update(1); keyframe_ = false; } else { - result[0].id = 2; - result[0].spatial_id = 0; - result[0].is_keyframe = false; - result[0].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/true}}; - - result[1].id = 3; - result[1].spatial_id = 1; - result[1].is_keyframe = false; - result[1].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/false}, - {/*id=*/1, /*references=*/true, /*updates=*/true}}; + result[0].Id(2).S(0).ReferenceAndUpdate(0); + result[1].Id(3).S(1).Reference(0).ReferenceAndUpdate(1); } return result; } @@ -101,21 +81,21 @@ ScalabilityStructureL2T1::NextFrameConfig(bool restart) { absl::optional ScalabilityStructureL2T1::OnEncodeDone( LayerFrameConfig config) { absl::optional frame_info; - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = KeyFrameConfig(); } - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - frame_info->part_of_chain = {config.spatial_id == 0, true}; + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = std::move(config.Buffers()); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + frame_info->part_of_chain = {config.SpatialId() == 0, true}; return frame_info; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc b/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc index fa2a943ffc..74761beb6a 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l2t1_key.cc @@ -59,12 +59,7 @@ FrameDependencyStructure ScalabilityStructureL2T1Key::DependencyStructure() ScalableVideoController::LayerFrameConfig ScalabilityStructureL2T1Key::KeyFrameConfig() const { - LayerFrameConfig result; - result.id = 0; - result.spatial_id = 0; - result.is_keyframe = true; - result.buffers = {{/*id=*/0, /*references=*/false, /*updates=*/true}}; - return result; + return LayerFrameConfig().Id(0).S(0).Keyframe().Update(0); } std::vector @@ -74,25 +69,11 @@ ScalabilityStructureL2T1Key::NextFrameConfig(bool restart) { // Buffer0 keeps latest S0T0 frame, Buffer1 keeps latest S1T0 frame. if (restart || keyframe_) { result[0] = KeyFrameConfig(); - - result[1].id = 2; - result[1].spatial_id = 1; - result[1].is_keyframe = false; - result[1].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/false}, - {/*id=*/1, /*references=*/false, /*updates=*/true}}; - + result[1].Id(2).S(1).Reference(0).Update(1); keyframe_ = false; } else { - result[0].id = 1; - result[0].spatial_id = 0; - result[0].is_keyframe = false; - result[0].buffers = {{/*id=*/0, /*references=*/true, /*updates=*/true}}; - - result[1].id = 2; - result[1].spatial_id = 1; - result[1].is_keyframe = false; - result[1].buffers = {{/*id=*/0, /*references=*/false, /*updates=*/false}, - {/*id=*/1, /*references=*/true, /*updates=*/true}}; + result[0].Id(1).S(0).ReferenceAndUpdate(0); + result[1].Id(2).S(1).ReferenceAndUpdate(1); } return result; } @@ -100,25 +81,25 @@ ScalabilityStructureL2T1Key::NextFrameConfig(bool restart) { absl::optional ScalabilityStructureL2T1Key::OnEncodeDone( LayerFrameConfig config) { absl::optional frame_info; - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = KeyFrameConfig(); } - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - if (config.is_keyframe) { + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = std::move(config.Buffers()); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + if (config.IsKeyframe()) { frame_info->part_of_chain = {true, true}; } else { - frame_info->part_of_chain = {config.spatial_id == 0, - config.spatial_id == 1}; + frame_info->part_of_chain = {config.SpatialId() == 0, + config.SpatialId() == 1}; } return frame_info; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc b/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc index 30874d44da..798e4d5f9c 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l2t2.cc @@ -78,13 +78,7 @@ FrameDependencyStructure ScalabilityStructureL2T2::DependencyStructure() const { ScalableVideoController::LayerFrameConfig ScalabilityStructureL2T2::KeyFrameConfig() const { - LayerFrameConfig result; - result.id = 0; - result.is_keyframe = true; - result.spatial_id = 0; - result.temporal_id = 0; - result.buffers = {{/*id=*/0, /*referenced=*/false, /*updated=*/true}}; - return result; + return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); } std::vector @@ -100,47 +94,17 @@ ScalabilityStructureL2T2::NextFrameConfig(bool restart) { switch (next_pattern_) { case kKey: result[0] = KeyFrameConfig(); - - result[1].id = 1; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}, - {/*id=*/1, /*referenced=*/false, /*updated=*/true}}; - + result[1].Id(1).S(1).T(0).Reference(0).Update(1); next_pattern_ = kDeltaT1; break; case kDeltaT1: - result[0].id = 2; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 1; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}, - {/*id=*/2, /*referenced=*/false, /*updated=*/true}}; - - result[1].id = 3; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 1; - result[1].buffers = {{/*id=*/2, /*referenced=*/true, /*updated=*/false}, - {/*id=*/1, /*referenced=*/true, /*updated=*/false}}; - + result[0].Id(2).S(0).T(1).Reference(0).Update(2); + result[1].Id(3).S(1).T(1).Reference(2).Reference(1); next_pattern_ = kDeltaT0; break; case kDeltaT0: - result[0].id = 4; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 0; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/true}}; - - result[1].id = 5; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}, - {/*id=*/1, /*referenced=*/true, /*updated=*/true}}; - + result[0].Id(4).S(0).T(0).ReferenceAndUpdate(0); + result[1].Id(5).S(1).T(0).Reference(0).ReferenceAndUpdate(1); next_pattern_ = kDeltaT1; break; } @@ -149,23 +113,23 @@ ScalabilityStructureL2T2::NextFrameConfig(bool restart) { absl::optional ScalabilityStructureL2T2::OnEncodeDone( LayerFrameConfig config) { - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = KeyFrameConfig(); } absl::optional frame_info; - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - if (config.temporal_id == 0) { - frame_info->part_of_chain = {config.spatial_id == 0, true}; + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = config.Buffers(); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + if (config.TemporalId() == 0) { + frame_info->part_of_chain = {config.SpatialId() == 0, true}; } else { frame_info->part_of_chain = {false, false}; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc b/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc index 02fd408c96..e42f8fcc7a 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l2t2_key.cc @@ -66,13 +66,7 @@ FrameDependencyStructure ScalabilityStructureL2T2Key::DependencyStructure() ScalableVideoController::LayerFrameConfig ScalabilityStructureL2T2Key::KeyFrameConfig() const { - LayerFrameConfig result; - result.id = 0; - result.is_keyframe = true; - result.spatial_id = 0; - result.temporal_id = 0; - result.buffers = {{/*id=*/0, /*referenced=*/false, /*updated=*/true}}; - return result; + return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); } std::vector @@ -87,44 +81,17 @@ ScalabilityStructureL2T2Key::NextFrameConfig(bool restart) { switch (next_pattern_) { case kKey: result[0] = KeyFrameConfig(); - - result[1].id = 1; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}, - {/*id=*/1, /*referenced=*/false, /*updated=*/true}}; - + result[1].Id(1).S(1).T(0).Reference(0).Update(1); next_pattern_ = kDeltaT1; break; case kDeltaT1: - result[0].id = 2; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 1; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}}; - - result[1].id = 3; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 1; - result[1].buffers = {{/*id=*/1, /*referenced=*/true, /*updated=*/false}}; - + result[0].Id(2).S(0).T(1).Reference(0); + result[1].Id(3).S(1).T(1).Reference(1); next_pattern_ = kDeltaT0; break; case kDeltaT0: - result[0].id = 4; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 0; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/true}}; - - result[1].id = 5; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/1, /*referenced=*/true, /*updated=*/true}}; - + result[0].Id(4).S(0).T(0).ReferenceAndUpdate(0); + result[1].Id(5).S(1).T(0).ReferenceAndUpdate(1); next_pattern_ = kDeltaT1; break; } @@ -133,26 +100,26 @@ ScalabilityStructureL2T2Key::NextFrameConfig(bool restart) { absl::optional ScalabilityStructureL2T2Key::OnEncodeDone( LayerFrameConfig config) { - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = KeyFrameConfig(); } absl::optional frame_info; - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - if (config.is_keyframe) { + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = config.Buffers(); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + if (config.IsKeyframe()) { frame_info->part_of_chain = {true, true}; - } else if (config.temporal_id == 0) { - frame_info->part_of_chain = {config.spatial_id == 0, - config.spatial_id == 1}; + } else if (config.TemporalId() == 0) { + frame_info->part_of_chain = {config.SpatialId() == 0, + config.SpatialId() == 1}; } else { frame_info->part_of_chain = {false, false}; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc b/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc index f268a157e9..6d19151461 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_l2t2_key_shift.cc @@ -67,13 +67,7 @@ FrameDependencyStructure ScalabilityStructureL2T2KeyShift::DependencyStructure() ScalableVideoController::LayerFrameConfig ScalabilityStructureL2T2KeyShift::KeyFrameConfig() const { - LayerFrameConfig result; - result.id = 0; - result.is_keyframe = true; - result.spatial_id = 0; - result.temporal_id = 0; - result.buffers = {{/*id=*/0, /*referenced=*/false, /*updated=*/true}}; - return result; + return LayerFrameConfig().Id(0).Keyframe().S(0).T(0).Update(0); } std::vector @@ -88,44 +82,17 @@ ScalabilityStructureL2T2KeyShift::NextFrameConfig(bool restart) { switch (next_pattern_) { case kKey: result[0] = KeyFrameConfig(); - - result[1].id = 1; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}, - {/*id=*/1, /*referenced=*/false, /*updated=*/true}}; - + result[1].Id(1).S(1).T(0).Reference(0).Update(1); next_pattern_ = kDelta0; break; case kDelta0: - result[0].id = 2; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 0; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/true}}; - - result[1].id = 3; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 1; - result[1].buffers = {{/*id=*/1, /*referenced=*/true, /*updated=*/false}}; - + result[0].Id(2).S(0).T(0).ReferenceAndUpdate(0); + result[1].Id(3).S(1).T(1).Reference(1); next_pattern_ = kDelta1; break; case kDelta1: - result[0].id = 4; - result[0].is_keyframe = false; - result[0].spatial_id = 0; - result[0].temporal_id = 1; - result[0].buffers = {{/*id=*/0, /*referenced=*/true, /*updated=*/false}}; - - result[1].id = 5; - result[1].is_keyframe = false; - result[1].spatial_id = 1; - result[1].temporal_id = 0; - result[1].buffers = {{/*id=*/1, /*referenced=*/true, /*updated=*/true}}; - + result[0].Id(4).S(0).T(1).Reference(0); + result[1].Id(5).S(1).T(0).ReferenceAndUpdate(1); next_pattern_ = kDelta0; break; } @@ -134,26 +101,26 @@ ScalabilityStructureL2T2KeyShift::NextFrameConfig(bool restart) { absl::optional ScalabilityStructureL2T2KeyShift::OnEncodeDone( LayerFrameConfig config) { - if (config.is_keyframe) { + if (config.IsKeyframe()) { config = KeyFrameConfig(); } absl::optional frame_info; - if (config.id < 0 || config.id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; + if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); - frame_info->decode_target_indications.assign(std::begin(kDtis[config.id]), - std::end(kDtis[config.id])); - if (config.is_keyframe) { + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = config.Buffers(); + frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]), + std::end(kDtis[config.Id()])); + if (config.IsKeyframe()) { frame_info->part_of_chain = {true, true}; - } else if (config.temporal_id == 0) { - frame_info->part_of_chain = {config.spatial_id == 0, - config.spatial_id == 1}; + } else if (config.TemporalId() == 0) { + frame_info->part_of_chain = {config.SpatialId() == 0, + config.SpatialId() == 1}; } else { frame_info->part_of_chain = {false, false}; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc b/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc index d1d257d586..067e3f3f86 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_s2t1.cc @@ -57,42 +57,36 @@ FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const { std::vector ScalabilityStructureS2T1::NextFrameConfig(bool restart) { - if (restart) { - keyframe_ = true; - } std::vector result(2); - // Buffer0 keeps latest S0T0 frame, Buffer1 keeps latest S1T0 frame. - result[0].spatial_id = 0; - result[0].is_keyframe = keyframe_; - result[0].buffers = {{/*id=*/0, /*references=*/!keyframe_, /*updates=*/true}}; - - result[1].spatial_id = 1; - result[1].is_keyframe = keyframe_; - result[1].buffers = {{/*id=*/1, /*references=*/!keyframe_, /*updates=*/true}}; - - keyframe_ = false; + if (restart || keyframe_) { + result[0].S(0).Keyframe().Update(0); + result[1].S(1).Keyframe().Update(1); + keyframe_ = false; + } else { + result[0].S(0).ReferenceAndUpdate(0); + result[1].S(1).ReferenceAndUpdate(1); + } return result; } absl::optional ScalabilityStructureS2T1::OnEncodeDone( LayerFrameConfig config) { absl::optional frame_info; - if (config.id != 0) { - RTC_LOG(LS_ERROR) << "Unexpected config id " << config.id; - } - if (config.spatial_id < 0 || - config.spatial_id >= int{ABSL_ARRAYSIZE(kDtis)}) { - RTC_LOG(LS_ERROR) << "Unexpected spatial id " << config.spatial_id; + if (config.SpatialId() < 0 || + config.SpatialId() >= int{ABSL_ARRAYSIZE(kDtis)}) { + RTC_LOG(LS_ERROR) << "Unexpected spatial id " << config.SpatialId(); return frame_info; } frame_info.emplace(); - frame_info->spatial_id = config.spatial_id; - frame_info->temporal_id = config.temporal_id; - frame_info->encoder_buffers = std::move(config.buffers); + frame_info->spatial_id = config.SpatialId(); + frame_info->temporal_id = config.TemporalId(); + frame_info->encoder_buffers = std::move(config.Buffers()); frame_info->decode_target_indications.assign( - std::begin(kDtis[config.spatial_id]), std::end(kDtis[config.spatial_id])); - frame_info->part_of_chain = {config.spatial_id == 0, config.spatial_id == 1}; + std::begin(kDtis[config.SpatialId()]), + std::end(kDtis[config.SpatialId()])); + frame_info->part_of_chain = {config.SpatialId() == 0, + config.SpatialId() == 1}; return frame_info; } diff --git a/modules/video_coding/codecs/av1/scalability_structure_unittest.cc b/modules/video_coding/codecs/av1/scalability_structure_unittest.cc index 29aac5dd2b..9b47cfa16a 100644 --- a/modules/video_coding/codecs/av1/scalability_structure_unittest.cc +++ b/modules/video_coding/codecs/av1/scalability_structure_unittest.cc @@ -72,7 +72,7 @@ class ScalabilityStructureTest : public TestWithParam { for (auto& layer_frame : structure_controller->NextFrameConfig(/*reset=*/false)) { int64_t frame_id = static_cast(frames.size()); - bool is_keyframe = layer_frame.is_keyframe; + bool is_keyframe = layer_frame.IsKeyframe(); absl::optional frame_info = structure_controller->OnEncodeDone(std::move(layer_frame)); EXPECT_TRUE(frame_info.has_value()); diff --git a/modules/video_coding/codecs/av1/scalable_video_controller.h b/modules/video_coding/codecs/av1/scalable_video_controller.h index dec985f282..6b2c00b346 100644 --- a/modules/video_coding/codecs/av1/scalable_video_controller.h +++ b/modules/video_coding/codecs/av1/scalable_video_controller.h @@ -28,23 +28,44 @@ class ScalableVideoController { int num_spatial_layers = 1; int num_temporal_layers = 1; }; - struct LayerFrameConfig { + class LayerFrameConfig { + public: + // Builders/setters. + LayerFrameConfig& Id(int value); + LayerFrameConfig& Keyframe(); + LayerFrameConfig& S(int value); + LayerFrameConfig& T(int value); + LayerFrameConfig& Reference(int buffer_id); + LayerFrameConfig& Update(int buffer_id); + LayerFrameConfig& ReferenceAndUpdate(int buffer_id); + + // Getters. + int Id() const { return id_; } + bool IsKeyframe() const { return is_keyframe_; } + int SpatialId() const { return spatial_id_; } + int TemporalId() const { return temporal_id_; } + const absl::InlinedVector& Buffers() + const { + return buffers_; + } + + private: // Id to match configuration returned by NextFrameConfig with // (possibly modified) configuration passed back via OnEncoderDone. // The meaning of the id is an implementation detail of // the ScalableVideoController. - int id = 0; + int id_ = 0; // Indication frame should be encoded as a key frame. In particular when // `is_keyframe=true` property `CodecBufferUsage::referenced` should be // ignored and treated as false. - bool is_keyframe = false; + bool is_keyframe_ = false; - int spatial_id = 0; - int temporal_id = 0; + int spatial_id_ = 0; + int temporal_id_ = 0; // Describes how encoder which buffers encoder allowed to reference and // which buffers encoder should update. - absl::InlinedVector buffers; + absl::InlinedVector buffers_; }; virtual ~ScalableVideoController() = default; @@ -66,6 +87,43 @@ class ScalableVideoController { LayerFrameConfig config) = 0; }; +// Below are implementation details. +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::Id(int value) { + id_ = value; + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::Keyframe() { + is_keyframe_ = true; + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::S(int value) { + spatial_id_ = value; + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::T(int value) { + temporal_id_ = value; + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::Reference(int buffer_id) { + buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/false); + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::Update(int buffer_id) { + buffers_.emplace_back(buffer_id, /*referenced=*/false, /*updated=*/true); + return *this; +} +inline ScalableVideoController::LayerFrameConfig& +ScalableVideoController::LayerFrameConfig::ReferenceAndUpdate(int buffer_id) { + buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/true); + return *this; +} + } // namespace webrtc #endif // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_ diff --git a/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc b/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc index 6b63ca4328..0d211fb911 100644 --- a/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc +++ b/modules/video_coding/codecs/av1/scalable_video_controller_no_layering.cc @@ -40,24 +40,22 @@ ScalableVideoControllerNoLayering::DependencyStructure() const { std::vector ScalableVideoControllerNoLayering::NextFrameConfig(bool restart) { - if (restart) { - start_ = true; - } std::vector result(1); - result[0].id = 0; - result[0].is_keyframe = start_; - result[0].buffers = {{/*id=*/0, /*references=*/!start_, /*updates=*/true}}; - + if (restart || start_) { + result[0].Id(0).Keyframe().Update(0); + } else { + result[0].Id(0).ReferenceAndUpdate(0); + } start_ = false; return result; } absl::optional ScalableVideoControllerNoLayering::OnEncodeDone(LayerFrameConfig config) { - RTC_DCHECK_EQ(config.id, 0); + RTC_DCHECK_EQ(config.Id(), 0); absl::optional frame_info(absl::in_place); - frame_info->encoder_buffers = std::move(config.buffers); - if (config.is_keyframe) { + frame_info->encoder_buffers = config.Buffers(); + if (config.IsKeyframe()) { for (auto& buffer : frame_info->encoder_buffers) { buffer.referenced = false; }