Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: bcheng <code@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Subject: [FFmpeg-devel] [PATCH] {cbs,vulkan}_vp9: Fix regression for vulkan_vp9 (PR #20209)
Date: Mon, 11 Aug 2025 04:18:45 +0300 (EEST)
Message-ID: <20250811011845.97AF968D2FD@ffbox0-bg.ffmpeg.org> (raw)

PR #20209 opened by bcheng
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20209
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20209.patch

The previous change 26a2a76346 broke Vulkan decoding because the `VP9RawFrameHeader`s can no longer be updated.

I reworked vulkan_vp9 to use the existing parsed header in `VP9BitstreamHeader` for the segmentation and loop filter deltas (the only "stateful" values we need). The follow-up commit drops the now unused fields from the `CodedBitstreamVP9Context`.



From 1f9750f3a74e40d14a87e68c95e0d7cfd648a592 Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <ben@bcheng.me>
Date: Sun, 10 Aug 2025 21:06:18 -0400
Subject: [PATCH 1/2] vulkan_vp9: Read values from VP9BitstreamHeader

The stateful values for loop filter and segmentation already exist, and
are parsed in VP9BitstreamHeader. This also preps for removal of the
previously added (in c0bf1382a) fields to CodedBitstreamVP9Context.

Fixes: 26a2a76346 ("cbs_vp9: Fix VP9 passthrough")
---
 libavcodec/vulkan_vp9.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/libavcodec/vulkan_vp9.c b/libavcodec/vulkan_vp9.c
index f8ce73dc90..0f7448ebb6 100644
--- a/libavcodec/vulkan_vp9.c
+++ b/libavcodec/vulkan_vp9.c
@@ -182,15 +182,14 @@ static int vk_vp9_start_frame(AVCodecContext          *avctx,
         .update_mode_delta = 0x0,
     };
 
-    for (int i = 0; i < 2; i++)
-        ap->loop_filter.update_mode_delta |= pic->frame_header->update_mode_delta[i];
-
     for (int i = 0; i < STD_VIDEO_VP9_MAX_REF_FRAMES; i++) {
-        ap->loop_filter.loop_filter_ref_deltas[i] = pic->frame_header->loop_filter_ref_deltas[i];
+        ap->loop_filter.loop_filter_ref_deltas[i] = s->h.lf_delta.ref[i]; /* Use stateful value */
         ap->loop_filter.update_ref_delta |= pic->frame_header->update_ref_delta[i];
     }
-    for (int i = 0; i < STD_VIDEO_VP9_LOOP_FILTER_ADJUSTMENTS; i++)
-        ap->loop_filter.loop_filter_mode_deltas[i] = pic->frame_header->loop_filter_mode_deltas[i];
+    for (int i = 0; i < STD_VIDEO_VP9_LOOP_FILTER_ADJUSTMENTS; i++) {
+        ap->loop_filter.loop_filter_mode_deltas[i] = s->h.lf_delta.mode[i]; /* Use stateful value */
+        ap->loop_filter.update_mode_delta |= pic->frame_header->update_mode_delta[i];
+    }
 
     ap->segmentation = (StdVideoVP9Segmentation) {
         .flags = (StdVideoVP9SegmentationFlags) {
@@ -201,18 +200,21 @@ static int vk_vp9_start_frame(AVCodecContext          *avctx,
         },
     };
 
+    /* Use the stateful value for segmentation also */
     for (int i = 0; i < STD_VIDEO_VP9_MAX_SEGMENTATION_TREE_PROBS; i++)
-        ap->segmentation.segmentation_tree_probs[i] = pic->frame_header->segmentation_tree_probs[i];
+        ap->segmentation.segmentation_tree_probs[i] = s->h.segmentation.prob[i];
     for (int i = 0; i < STD_VIDEO_VP9_MAX_SEGMENTATION_PRED_PROB; i++)
-        ap->segmentation.segmentation_pred_prob[i] = pic->frame_header->segmentation_pred_prob[i];
+        ap->segmentation.segmentation_pred_prob[i] = s->h.segmentation.pred_prob[i];
     for (int i = 0; i < STD_VIDEO_VP9_MAX_SEGMENTS; i++) {
-        ap->segmentation.FeatureEnabled[i] = 0x0;
-        for (int j = 0; j < STD_VIDEO_VP9_SEG_LVL_MAX; j++) {
-            ap->segmentation.FeatureEnabled[i] |= pic->frame_header->feature_enabled[i][j] << j;
-            ap->segmentation.FeatureData[i][j] = pic->frame_header->feature_sign[i][j] ?
-                                                 -pic->frame_header->feature_value[i][j] :
-                                                 +pic->frame_header->feature_value[i][j];
-        }
+        ap->segmentation.FeatureEnabled[i] =
+            (s->h.segmentation.feat[i].q_enabled    << 0) |
+            (s->h.segmentation.feat[i].lf_enabled   << 1) |
+            (s->h.segmentation.feat[i].ref_enabled  << 2) |
+            (s->h.segmentation.feat[i].skip_enabled << 3);
+        ap->segmentation.FeatureData[i][0] = s->h.segmentation.feat[i].q_val;
+        ap->segmentation.FeatureData[i][1] = s->h.segmentation.feat[i].lf_val;
+        ap->segmentation.FeatureData[i][2] = s->h.segmentation.feat[i].ref_val;
+        /* FeatureData[i][3] is for skip, which does not have a value */
     }
 
     ap->color_config = (StdVideoVP9ColorConfig) {
-- 
2.49.1


From 597ce26e0e51d861d3cb28f10a5288c497925f25 Mon Sep 17 00:00:00 2001
From: Benjamin Cheng <ben@bcheng.me>
Date: Sun, 10 Aug 2025 21:10:44 -0400
Subject: [PATCH 2/2] cbs_vp9: Drop unused fields from CBS context

These were previously added for vulkan_vp9 but are since no longer
required.

Fixes: 26a2a76346 ("cbs_vp9: Fix VP9 passthrough")
---
 libavcodec/cbs_vp9.h                 |  8 -----
 libavcodec/cbs_vp9_syntax_template.c | 54 ----------------------------
 2 files changed, 62 deletions(-)

diff --git a/libavcodec/cbs_vp9.h b/libavcodec/cbs_vp9.h
index 588765b873..af15eb4bac 100644
--- a/libavcodec/cbs_vp9.h
+++ b/libavcodec/cbs_vp9.h
@@ -206,14 +206,6 @@ typedef struct CodedBitstreamVP9Context {
     uint8_t subsampling_y;
     int bit_depth;
 
-    int8_t loop_filter_ref_deltas[VP9_MAX_REF_FRAMES];
-    int8_t loop_filter_mode_deltas[2];
-    uint8_t segmentation_tree_probs[7];
-    uint8_t segmentation_pred_prob[3];
-    uint8_t feature_enabled[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
-    uint8_t feature_value[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
-    uint8_t feature_sign[VP9_MAX_SEGMENTS][VP9_SEG_LVL_MAX];
-
     VP9ReferenceFrameState ref[VP9_NUM_REF_FRAMES];
 } CodedBitstreamVP9Context;
 
diff --git a/libavcodec/cbs_vp9_syntax_template.c b/libavcodec/cbs_vp9_syntax_template.c
index 9d01debb6d..2945165bcb 100644
--- a/libavcodec/cbs_vp9_syntax_template.c
+++ b/libavcodec/cbs_vp9_syntax_template.c
@@ -374,60 +374,6 @@ 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,
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

                 reply	other threads:[~2025-08-11  1:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250811011845.97AF968D2FD@ffbox0-bg.ffmpeg.org \
    --to=code@ffmpeg.org \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git