1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

cbs_vp9: Fix VP9 passthrough

Don't overwrite the bitstream values when updating the top-level loop
filter and segmentation state, instead do the update separately at the
end of the frame parsing.

This also reverts the change to the passthrough tests which made them
have output not matching the input.
This commit is contained in:
Mark Thompson
2025-08-09 09:06:13 +01:00
committed by Lynne
parent 19473362fc
commit 26a2a76346
15 changed files with 72 additions and 43 deletions

View File

@@ -152,7 +152,6 @@ static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw,
static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw,
VP9RawFrameHeader *current)
{
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
int err, i;
f(6, loop_filter_level);
@@ -160,8 +159,6 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw,
f(1, loop_filter_delta_enabled);
if (current->loop_filter_delta_enabled) {
memcpy(current->loop_filter_ref_deltas, vp9->loop_filter_ref_deltas, sizeof(vp9->loop_filter_ref_deltas));
memcpy(current->loop_filter_mode_deltas, vp9->loop_filter_mode_deltas, sizeof(vp9->loop_filter_mode_deltas));
f(1, loop_filter_delta_update);
if (current->loop_filter_delta_update) {
for (i = 0; i < VP9_MAX_REF_FRAMES; i++) {
@@ -174,9 +171,9 @@ static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw,
if (current->update_mode_delta[i])
ss(6, loop_filter_mode_deltas[i], 1, i);
}
memcpy(vp9->loop_filter_ref_deltas, current->loop_filter_ref_deltas, sizeof(vp9->loop_filter_ref_deltas));
memcpy(vp9->loop_filter_mode_deltas, current->loop_filter_mode_deltas, sizeof(vp9->loop_filter_mode_deltas));
}
} else {
infer(loop_filter_delta_update, 0);
}
return 0;
@@ -201,18 +198,11 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw,
{
static const uint8_t segmentation_feature_bits[VP9_SEG_LVL_MAX] = { 8, 6, 2, 0 };
static const uint8_t segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 };
CodedBitstreamVP9Context *vp9 = ctx->priv_data;
int err, i, j;
f(1, segmentation_enabled);
if (current->segmentation_enabled) {
memcpy(current->segmentation_tree_probs, vp9->segmentation_tree_probs, sizeof(vp9->segmentation_tree_probs));
memcpy(current->segmentation_pred_prob, vp9->segmentation_pred_prob, sizeof(vp9->segmentation_pred_prob));
memcpy(current->feature_enabled, vp9->feature_enabled, sizeof(vp9->feature_enabled));
memcpy(current->feature_value, vp9->feature_value, sizeof(vp9->feature_value));
memcpy(current->feature_sign, vp9->feature_sign, sizeof(vp9->feature_sign));
f(1, segmentation_update_map);
if (current->segmentation_update_map) {
for (i = 0; i < 7; i++)
@@ -224,8 +214,6 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw,
else
infer(segmentation_pred_prob[i], 255);
}
memcpy(vp9->segmentation_tree_probs, current->segmentation_tree_probs, sizeof(vp9->segmentation_tree_probs));
memcpy(vp9->segmentation_pred_prob, current->segmentation_pred_prob, sizeof(vp9->segmentation_pred_prob));
}
f(1, segmentation_update_data);
@@ -248,10 +236,9 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw,
}
}
}
memcpy(vp9->feature_enabled, current->feature_enabled, sizeof(vp9->feature_enabled));
memcpy(vp9->feature_value, current->feature_value, sizeof(vp9->feature_value));
memcpy(vp9->feature_sign, current->feature_sign, sizeof(vp9->feature_sign));
}
} else {
infer(segmentation_update_data, 0);
}
return 0;
@@ -368,18 +355,6 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
f(2, frame_context_idx);
if (current->frame_type == VP9_KEY_FRAME || current->error_resilient_mode || current->intra_only) {
infer(update_ref_delta[0], 1);
infer(update_ref_delta[1], 0);
infer(update_ref_delta[2], -1);
infer(update_ref_delta[3], -1);
infer(loop_filter_mode_deltas[0], 0);
infer(loop_filter_mode_deltas[1], 0);
memset(vp9->feature_enabled, 0, sizeof(current->feature_enabled));
memset(vp9->feature_value, 0, sizeof(current->feature_value));
memset(vp9->feature_sign, 0, sizeof(current->feature_sign));
}
CHECK(FUNC(loop_filter_params)(ctx, rw, current));
CHECK(FUNC(quantization_params)(ctx, rw, current));
CHECK(FUNC(segmentation_params)(ctx, rw, current));
@@ -399,6 +374,60 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw,
}
}
// Update top-level loop filter and segmentation state with changes
// from this frame.
if (current->frame_type == VP9_KEY_FRAME ||
current->intra_only ||
current->error_resilient_mode) {
// setup_past_independence() - fill with the initial values.
vp9->loop_filter_ref_deltas[VP9_INTRA_FRAME] = 1;
vp9->loop_filter_ref_deltas[VP9_LAST_FRAME] = 0;
vp9->loop_filter_ref_deltas[VP9_GOLDEN_FRAME] = -1;
vp9->loop_filter_ref_deltas[VP9_ALTREF_FRAME] = -1;
vp9->loop_filter_mode_deltas[0] = 0;
vp9->loop_filter_mode_deltas[1] = 0;
memset(vp9->feature_enabled, 0, sizeof(vp9->feature_enabled));
memset(vp9->feature_value, 0, sizeof(vp9->feature_value));
memset(vp9->feature_sign, 0, sizeof(vp9->feature_sign));
} else {
// Modify previous state based on updates in this frame.
if (current->loop_filter_delta_update) {
for (i = 0; i < 4; i++) {
if (current->update_ref_delta[i])
vp9->loop_filter_ref_deltas[i] =
current->loop_filter_ref_deltas[i];
}
for (i = 0; i < 2; i++) {
if (current->update_mode_delta[i])
vp9->loop_filter_mode_deltas[i] =
current->loop_filter_mode_deltas[i];
}
}
if (current->segmentation_update_data) {
memcpy(vp9->feature_enabled, current->feature_enabled,
sizeof(vp9->feature_enabled));
memcpy(vp9->feature_value, current->feature_value,
sizeof(vp9->feature_value));
memcpy(vp9->feature_sign, current->feature_sign,
sizeof(vp9->feature_sign));
if (current->segmentation_update_map) {
memcpy(vp9->segmentation_tree_probs,
current->segmentation_tree_probs,
sizeof(vp9->segmentation_tree_probs));
memcpy(vp9->segmentation_pred_prob,
current->segmentation_pred_prob,
sizeof(vp9->segmentation_pred_prob));
}
}
}
av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame: size %dx%d "
"subsample %dx%d bit_depth %d tiles %dx%d.\n",
vp9->frame_width, vp9->frame_height,

View File

@@ -1 +1 @@
0f43cdcbdc97ea6651c56540d97610e5
fe62460fe28202e0666e628afd8602ca

View File

@@ -1 +1 @@
af456bb18c4f5e6fb83c559769ce1b07
6838422ebb45df353a2bad62b9aff8e9

View File

@@ -1 +1 @@
af98321cd43a36f065f8c728e22f2c06
179e228004c396a301c89f34b6c72f68

View File

@@ -1 +1 @@
8b4ce818cde9621481b6bf7997b544b8
1d1f0768c547461ae2abef57f0aabc24

View File

@@ -1 +1 @@
ea65b698e86322709257caf9038da40a
13fa042ee1b4079c227a5c5c96e2db38

View File

@@ -1 +1 @@
c1047aeeb593f2f87818d9bd19cb12f2
2ab7c95e4637fb6a15efd8c0a8d6af98

View File

@@ -1 +1 @@
cb14fde4f0f99d6e962fb109d3db36ee
b5be66a6a8792f7aac090beb9f3b4555

View File

@@ -1 +1 @@
0f1cfba95edb2446689547fc012f741b
7bde6532fc682bfa3f5170cf9d607865

View File

@@ -1 +1 @@
db40458891febf9f007c98e735e02ab9
1e40e8b48e4682e8b8004b9e0e60a5b6

View File

@@ -1 +1 @@
855cffb78a063ad0dfc432ae593974a2
9bb416c0304a13c4f66c56aef8431cd4

View File

@@ -1 +1 @@
8f6c44c4098915261e7708ab270877ff
3a7ed001d30f96d4888f5ca16e6263ce

View File

@@ -1 +1 @@
0ed4ec02fd72c0b594d74c5cbd7e252f
7315bb7b55693a87c350b48cd2ee9811

View File

@@ -1 +1 @@
1e8d7e1bd62a04bf47270c72a1c55bb7
1a7b5bf86bf0bbef10c9a1b2c799b276

View File

@@ -1 +1 @@
c2ca28679265c1c86d4a7ef60cc061ff
9b7a0b7fc081542d9be1074b23054861