Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: James Almer <code@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Subject: [FFmpeg-devel] [PATCH] avcodec/cbs_apv: store derived tile information in a per frame basis (PR #20216)
Date: Mon, 11 Aug 2025 16:50:11 +0300 (EEST)
Message-ID: <20250811135011.DFF5668CBF0@ffbox0-bg.ffmpeg.org> (raw)

PR #20216 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20216
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20216.patch

If a single fragment contains more than one frame unit, the tile information stored in the private context will only correspond to one of them.


From 8723939d140da3f7b06e55d3e7b63389ca9a1338 Mon Sep 17 00:00:00 2001
From: James Almer <jamrial@gmail.com>
Date: Sun, 10 Aug 2025 13:44:31 -0300
Subject: [PATCH] avcodec/cbs_apv: store derived tile information in a per
 frame basis

If a single fragment contains more than one frame unit, the tile information stored
in the private context will only correspond to one of them.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/apv_decode.c              | 42 ++++++++++++++++++++++++++--
 libavcodec/cbs_apv.c                 | 27 ++++--------------
 libavcodec/cbs_apv.h                 | 12 +-------
 libavcodec/cbs_apv_syntax_template.c |  6 ++--
 4 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/libavcodec/apv_decode.c b/libavcodec/apv_decode.c
index 330d4980c0..6fbb19a5bc 100644
--- a/libavcodec/apv_decode.c
+++ b/libavcodec/apv_decode.c
@@ -35,6 +35,16 @@
 #include "thread.h"
 
 
+typedef struct APVDerivedTileInfo {
+    uint8_t  tile_cols;
+    uint8_t  tile_rows;
+    uint16_t num_tiles;
+    // The spec uses an extra element on the end of these arrays
+    // not corresponding to any tile.
+    uint16_t col_starts[APV_MAX_TILE_COLS + 1];
+    uint16_t row_starts[APV_MAX_TILE_ROWS + 1];
+} APVDerivedTileInfo;
+
 typedef struct APVDecodeContext {
     CodedBitstreamContext *cbc;
     APVDSPContext dsp;
@@ -184,7 +194,7 @@ static int apv_decode_tile_component(AVCodecContext *avctx, void *data,
     APVRawFrame                      *input = data;
     APVDecodeContext                   *apv = avctx->priv_data;
     const CodedBitstreamAPVContext *apv_cbc = apv->cbc->priv_data;
-    const APVDerivedTileInfo     *tile_info = &apv_cbc->tile_info;
+    const APVDerivedTileInfo     *tile_info = &apv->tile_info;
 
     int tile_index = job / apv_cbc->num_comp;
     int comp_index = job % apv_cbc->num_comp;
@@ -297,12 +307,38 @@ fail:
     return err;
 }
 
+static void apv_derive_tile_info(APVDerivedTileInfo *ti,
+                                 const APVRawFrameHeader *fh)
+{
+    int frame_width_in_mbs  = (fh->frame_info.frame_width  + 15) / 16;
+    int frame_height_in_mbs = (fh->frame_info.frame_height + 15) / 16;
+    int start_mb, i;
+
+    start_mb = 0;
+    for (i = 0; start_mb < frame_width_in_mbs; i++) {
+        ti->col_starts[i] = start_mb * APV_MB_WIDTH;
+        start_mb += fh->tile_info.tile_width_in_mbs;
+    }
+    ti->col_starts[i] = frame_width_in_mbs * APV_MB_WIDTH;
+    ti->tile_cols = i;
+
+    start_mb = 0;
+    for (i = 0; start_mb < frame_height_in_mbs; i++) {
+        ti->row_starts[i] = start_mb * APV_MB_HEIGHT;
+        start_mb += fh->tile_info.tile_height_in_mbs;
+    }
+    ti->row_starts[i] = frame_height_in_mbs * APV_MB_HEIGHT;
+    ti->tile_rows = i;
+
+    ti->num_tiles = ti->tile_cols * ti->tile_rows;
+}
+
 static int apv_decode(AVCodecContext *avctx, AVFrame *output,
                       APVRawFrame *input)
 {
     APVDecodeContext                   *apv = avctx->priv_data;
     const CodedBitstreamAPVContext *apv_cbc = apv->cbc->priv_data;
-    const APVDerivedTileInfo     *tile_info = &apv_cbc->tile_info;
+    APVDerivedTileInfo           *tile_info = &apv->tile_info;
     int err, job_count;
 
     err = apv_decode_check_format(avctx, &input->frame_header);
@@ -318,6 +354,8 @@ static int apv_decode(AVCodecContext *avctx, AVFrame *output,
     apv->output_frame = output;
     atomic_store_explicit(&apv->tile_errors, 0, memory_order_relaxed);
 
+    apv_derive_tile_info(tile_info, &input->frame_header);
+
     // Each component within a tile is independent of every other,
     // so we can decode all in parallel.
     job_count = tile_info->num_tiles * apv_cbc->num_comp;
diff --git a/libavcodec/cbs_apv.c b/libavcodec/cbs_apv.c
index 5239cd1269..fdc9042939 100644
--- a/libavcodec/cbs_apv.c
+++ b/libavcodec/cbs_apv.c
@@ -37,33 +37,18 @@ static int cbs_apv_get_num_comp(const APVRawFrameHeader *fh)
     }
 }
 
-static void cbs_apv_derive_tile_info(APVDerivedTileInfo *ti,
+static void cbs_apv_derive_tile_info(CodedBitstreamContext *ctx,
                                      const APVRawFrameHeader *fh)
 {
+    CodedBitstreamAPVContext *priv = ctx->priv_data;
     int frame_width_in_mbs   = (fh->frame_info.frame_width  + 15) / 16;
     int frame_height_in_mbs  = (fh->frame_info.frame_height + 15) / 16;
-    int start_mb, i;
+    int tile_cols = (frame_width_in_mbs  + fh->tile_info.tile_width_in_mbs - 1)  / fh->tile_info.tile_width_in_mbs;
+    int tile_rows = (frame_height_in_mbs + fh->tile_info.tile_height_in_mbs - 1) / fh->tile_info.tile_height_in_mbs;
 
-    start_mb = 0;
-    for (i = 0; start_mb < frame_width_in_mbs; i++) {
-        ti->col_starts[i] = start_mb * APV_MB_WIDTH;
-        start_mb += fh->tile_info.tile_width_in_mbs;
-    }
-    av_assert0(i <= APV_MAX_TILE_COLS);
-    ti->col_starts[i] = frame_width_in_mbs * APV_MB_WIDTH;
-    ti->tile_cols = i;
+    av_assert0(tile_cols <= APV_MAX_TILE_COLS && tile_rows <= APV_MAX_TILE_ROWS);
 
-    start_mb = 0;
-    for (i = 0; start_mb < frame_height_in_mbs; i++) {
-        av_assert0(i < APV_MAX_TILE_ROWS);
-        ti->row_starts[i] = start_mb * APV_MB_HEIGHT;
-        start_mb += fh->tile_info.tile_height_in_mbs;
-    }
-    av_assert0(i <= APV_MAX_TILE_ROWS);
-    ti->row_starts[i] = frame_height_in_mbs * APV_MB_HEIGHT;
-    ti->tile_rows = i;
-
-    ti->num_tiles = ti->tile_cols * ti->tile_rows;
+    priv->num_tiles = tile_cols * tile_rows;
 }
 
 
diff --git a/libavcodec/cbs_apv.h b/libavcodec/cbs_apv.h
index cbaeb45acb..d91372e644 100644
--- a/libavcodec/cbs_apv.h
+++ b/libavcodec/cbs_apv.h
@@ -187,21 +187,11 @@ typedef struct APVRawMetadata {
 } APVRawMetadata;
 
 
-typedef struct APVDerivedTileInfo {
-    uint8_t  tile_cols;
-    uint8_t  tile_rows;
-    uint16_t num_tiles;
-    // The spec uses an extra element on the end of these arrays
-    // not corresponding to any tile.
-    uint16_t col_starts[APV_MAX_TILE_COLS + 1];
-    uint16_t row_starts[APV_MAX_TILE_ROWS + 1];
-} APVDerivedTileInfo;
-
 typedef struct CodedBitstreamAPVContext {
     int bit_depth;
     int num_comp;
 
-    APVDerivedTileInfo tile_info;
+    uint16_t num_tiles;
 } CodedBitstreamAPVContext;
 
 #endif /* AVCODEC_CBS_APV_H */
diff --git a/libavcodec/cbs_apv_syntax_template.c b/libavcodec/cbs_apv_syntax_template.c
index b84565b107..621595ffbf 100644
--- a/libavcodec/cbs_apv_syntax_template.c
+++ b/libavcodec/cbs_apv_syntax_template.c
@@ -128,10 +128,10 @@ static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw,
 
     ub(1, tile_size_present_in_fh_flag);
 
-    cbs_apv_derive_tile_info(&priv->tile_info, fh);
+    cbs_apv_derive_tile_info(ctx, fh);
 
     if (current->tile_size_present_in_fh_flag) {
-        for (int t = 0; t < priv->tile_info.num_tiles; t++) {
+        for (int t = 0; t < priv->num_tiles; t++) {
             us(32, tile_size_in_fh[t], 10, MAX_UINT_BITS(32), 1, t);
         }
     }
@@ -262,7 +262,7 @@ static int FUNC(frame)(CodedBitstreamContext *ctx, RWContext *rw,
 
     CHECK(FUNC(frame_header)(ctx, rw, &current->frame_header));
 
-    for (int t = 0; t < priv->tile_info.num_tiles; t++) {
+    for (int t = 0; t < priv->num_tiles; t++) {
         us(32, tile_size[t], 10, MAX_UINT_BITS(32), 1, t);
 
         CHECK(FUNC(tile)(ctx, rw, &current->tile[t],
-- 
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 13:50 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=20250811135011.DFF5668CBF0@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