Add builder setters for ScalableVideoStructure::LayerFrameConfig
Bug: None Change-Id: I19721f87b9f4641e093dc51f9c023b0493adcf97 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176702 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31473}
This commit is contained in:

committed by
Commit Bot

parent
c186e1498b
commit
a48dd43fe1
@ -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) {
|
||||
|
@ -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<GenericFrameInfo> 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<GenericFrameInfo> 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;
|
||||
}
|
||||
|
||||
|
@ -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<ScalableVideoController::LayerFrameConfig>
|
||||
ScalabilityStructureL2T1::NextFrameConfig(bool restart) {
|
||||
std::vector<LayerFrameConfig> 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<GenericFrameInfo> ScalabilityStructureL2T1::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
absl::optional<GenericFrameInfo> 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;
|
||||
}
|
||||
|
||||
|
@ -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<ScalableVideoController::LayerFrameConfig>
|
||||
@ -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<GenericFrameInfo> ScalabilityStructureL2T1Key::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
absl::optional<GenericFrameInfo> 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;
|
||||
}
|
||||
|
@ -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<ScalableVideoController::LayerFrameConfig>
|
||||
@ -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<GenericFrameInfo> ScalabilityStructureL2T2::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
if (config.is_keyframe) {
|
||||
if (config.IsKeyframe()) {
|
||||
config = KeyFrameConfig();
|
||||
}
|
||||
|
||||
absl::optional<GenericFrameInfo> 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};
|
||||
}
|
||||
|
@ -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<ScalableVideoController::LayerFrameConfig>
|
||||
@ -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<GenericFrameInfo> ScalabilityStructureL2T2Key::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
if (config.is_keyframe) {
|
||||
if (config.IsKeyframe()) {
|
||||
config = KeyFrameConfig();
|
||||
}
|
||||
|
||||
absl::optional<GenericFrameInfo> 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};
|
||||
}
|
||||
|
@ -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<ScalableVideoController::LayerFrameConfig>
|
||||
@ -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<GenericFrameInfo> ScalabilityStructureL2T2KeyShift::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
if (config.is_keyframe) {
|
||||
if (config.IsKeyframe()) {
|
||||
config = KeyFrameConfig();
|
||||
}
|
||||
|
||||
absl::optional<GenericFrameInfo> 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};
|
||||
}
|
||||
|
@ -57,42 +57,36 @@ FrameDependencyStructure ScalabilityStructureS2T1::DependencyStructure() const {
|
||||
|
||||
std::vector<ScalableVideoController::LayerFrameConfig>
|
||||
ScalabilityStructureS2T1::NextFrameConfig(bool restart) {
|
||||
if (restart) {
|
||||
keyframe_ = true;
|
||||
}
|
||||
std::vector<LayerFrameConfig> 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}};
|
||||
|
||||
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<GenericFrameInfo> ScalabilityStructureS2T1::OnEncodeDone(
|
||||
LayerFrameConfig config) {
|
||||
absl::optional<GenericFrameInfo> 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;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ class ScalabilityStructureTest : public TestWithParam<SvcTestParam> {
|
||||
for (auto& layer_frame :
|
||||
structure_controller->NextFrameConfig(/*reset=*/false)) {
|
||||
int64_t frame_id = static_cast<int64_t>(frames.size());
|
||||
bool is_keyframe = layer_frame.is_keyframe;
|
||||
bool is_keyframe = layer_frame.IsKeyframe();
|
||||
absl::optional<GenericFrameInfo> frame_info =
|
||||
structure_controller->OnEncodeDone(std::move(layer_frame));
|
||||
EXPECT_TRUE(frame_info.has_value());
|
||||
|
@ -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<CodecBufferUsage, kMaxEncoderBuffers>& 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<CodecBufferUsage, kMaxEncoderBuffers> buffers;
|
||||
absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers> 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_
|
||||
|
@ -40,24 +40,22 @@ ScalableVideoControllerNoLayering::DependencyStructure() const {
|
||||
|
||||
std::vector<ScalableVideoController::LayerFrameConfig>
|
||||
ScalableVideoControllerNoLayering::NextFrameConfig(bool restart) {
|
||||
if (restart) {
|
||||
start_ = true;
|
||||
}
|
||||
std::vector<LayerFrameConfig> 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<GenericFrameInfo>
|
||||
ScalableVideoControllerNoLayering::OnEncodeDone(LayerFrameConfig config) {
|
||||
RTC_DCHECK_EQ(config.id, 0);
|
||||
RTC_DCHECK_EQ(config.Id(), 0);
|
||||
absl::optional<GenericFrameInfo> 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user