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 <jamr...@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 <jamr...@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, ¤t->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, ¤t->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-requ...@ffmpeg.org with subject "unsubscribe".