This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit feb8a37767549f3b1316698d435b31134b0609dc
Author:     Lynne <[email protected]>
AuthorDate: Sun Nov 2 14:38:10 2025 +0000
Commit:     Lynne <[email protected]>
CommitDate: Tue May 19 17:43:52 2026 +0900

    apv_decode: add hardware decoding hooks
---
 libavcodec/apv_decode.c | 147 +++++++++++++++++++++++++++++-------------------
 libavcodec/apv_decode.h |  35 +++++++++++-
 2 files changed, 123 insertions(+), 59 deletions(-)

diff --git a/libavcodec/apv_decode.c b/libavcodec/apv_decode.c
index 4c0fd78cb0..a9dcd4ce7d 100644
--- a/libavcodec/apv_decode.c
+++ b/libavcodec/apv_decode.c
@@ -27,42 +27,15 @@
 
 #include "apv.h"
 #include "apv_decode.h"
-#include "apv_dsp.h"
 #include "avcodec.h"
-#include "cbs.h"
 #include "cbs_apv.h"
 #include "codec_internal.h"
 #include "decode.h"
 #include "internal.h"
 #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;
-
-    CodedBitstreamFragment au;
-    APVDerivedTileInfo tile_info;
-
-    AVPacket *pkt;
-    AVFrame *output_frame;
-    atomic_int tile_errors;
-
-    int nb_unit;
-
-    uint8_t warned_additional_frames;
-    uint8_t warned_unknown_pbu_types;
-} APVDecodeContext;
+#include "hwconfig.h"
+#include "hwaccel_internal.h"
+#include "config_components.h"
 
 static const enum AVPixelFormat apv_format_table[5][4] = {
     { AV_PIX_FMT_GRAY10,     AV_PIX_FMT_GRAY12,     AV_PIX_FMT_GRAY14,    
AV_PIX_FMT_GRAY16     },
@@ -74,10 +47,25 @@ static const enum AVPixelFormat apv_format_table[5][4] = {
 
 static APVVLCLUT decode_lut;
 
+static enum AVPixelFormat get_pixel_format(AVCodecContext *avctx,
+                                           enum AVPixelFormat pix_fmt)
+{
+    enum AVPixelFormat pix_fmts[] = {
+        pix_fmt,
+        AV_PIX_FMT_NONE,
+    };
+
+    return ff_get_format(avctx, pix_fmts);
+}
+
 static int apv_decode_check_format(AVCodecContext *avctx,
                                    const APVRawFrameHeader *header)
 {
     int err, bit_depth;
+    enum AVPixelFormat pix_fmt;
+    int coded_width = FFALIGN(header->frame_info.frame_width, 16);
+    int coded_height = FFALIGN(header->frame_info.frame_height, 16);
+    APVDecodeContext *apv = avctx->priv_data;
 
     avctx->profile = header->frame_info.profile_idc;
     avctx->level   = header->frame_info.level_idc;
@@ -88,24 +76,35 @@ static int apv_decode_check_format(AVCodecContext *avctx,
         avpriv_request_sample(avctx, "Bit depth %d", bit_depth);
         return AVERROR_PATCHWELCOME;
     }
-    avctx->pix_fmt =
-        apv_format_table[header->frame_info.chroma_format_idc][(bit_depth - 
10) >> 1];
 
-    if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
+    pix_fmt = 
apv_format_table[header->frame_info.chroma_format_idc][(bit_depth - 10) >> 1];
+    if (pix_fmt == AV_PIX_FMT_NONE) {
         avpriv_request_sample(avctx, "YUVA444P14");
         return AVERROR_PATCHWELCOME;
     }
 
-    err = ff_set_dimensions(avctx,
-                            FFALIGN(header->frame_info.frame_width,  16),
-                            FFALIGN(header->frame_info.frame_height, 16));
-    if (err < 0) {
-        // Unsupported frame size.
-        return err;
+    if (avctx->coded_width != coded_width ||
+        avctx->coded_height != coded_height) {
+        err = ff_set_dimensions(avctx, coded_width, coded_height);
+        if (err < 0) {
+            // Unsupported frame size.
+            return err;
+        }
     }
+
     avctx->width  = header->frame_info.frame_width;
     avctx->height = header->frame_info.frame_height;
 
+    if (pix_fmt != apv->pix_fmt) {
+        apv->pix_fmt = pix_fmt;
+
+        err = get_pixel_format(avctx, pix_fmt);
+        if (err < 0)
+            return err;
+
+        avctx->pix_fmt = err;
+    }
+
     avctx->sample_aspect_ratio = (AVRational){ 1, 1 };
 
     avctx->color_primaries = header->color_primaries;
@@ -138,6 +137,8 @@ static av_cold int apv_decode_init(AVCodecContext *avctx)
     APVDecodeContext *apv = avctx->priv_data;
     int err;
 
+    apv->pix_fmt = AV_PIX_FMT_NONE;
+
     ff_thread_once(&apv_entropy_once, apv_entropy_build_decode_lut);
 
     err = ff_cbs_init(&apv->cbc, AV_CODEC_ID_APV, avctx);
@@ -217,7 +218,7 @@ static int apv_decode_tile_component(AVCodecContext *avctx, 
void *data,
     int comp_index = job % apv_cbc->num_comp;
 
     const AVPixFmtDescriptor *pix_fmt_desc =
-        av_pix_fmt_desc_get(avctx->pix_fmt);
+        av_pix_fmt_desc_get(apv->pix_fmt);
 
     int sub_w_shift = comp_index == 0 ? 0 : pix_fmt_desc->log2_chroma_w;
     int sub_h_shift = comp_index == 0 ? 0 : pix_fmt_desc->log2_chroma_h;
@@ -367,7 +368,7 @@ static int apv_decode(AVCodecContext *avctx, AVFrame 
*output,
     if (avctx->skip_frame == AVDISCARD_ALL)
         return 0;
 
-    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    desc = av_pix_fmt_desc_get(apv->pix_fmt);
     av_assert0(desc);
 
     err = ff_thread_get_buffer(avctx, output, 0);
@@ -379,22 +380,51 @@ static int apv_decode(AVCodecContext *avctx, AVFrame 
*output,
 
     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 * desc->nb_components;
-
-    avctx->execute2(avctx, apv_decode_tile_component,
-                    input, NULL, job_count);
-
-    err = atomic_load_explicit(&apv->tile_errors, memory_order_relaxed);
-    if (err > 0) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Decode errors in %d tile components.\n", err);
-        if (avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) {
-            // Output the frame anyway.
-            output->flags |= AV_FRAME_FLAG_CORRUPT;
-        } else {
-            return AVERROR_INVALIDDATA;
+    if (avctx->hwaccel) {
+        const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
+
+        err = ff_hwaccel_frame_priv_alloc(avctx, 
&apv->hwaccel_picture_private);
+        if (err < 0)
+            return err;
+
+        err = hwaccel->start_frame(avctx, apv->pkt->buf,
+                                   apv->pkt->data, apv->pkt->size);
+        if (err < 0)
+            return err;
+
+        for (int j = 0; j < desc->nb_components; j++) {
+            for (int i = 0; i < tile_info->num_tiles; i++) {
+                APVRawTile *tile = &input->tile[i];
+                err = hwaccel->decode_slice(avctx, tile->tile_data[j],
+                                            
tile->tile_header.tile_data_size[j]);
+                if (err < 0)
+                    return err;
+            }
+        }
+
+        err = hwaccel->end_frame(avctx);
+        if (err < 0)
+            return err;
+
+        av_refstruct_unref(&apv->hwaccel_picture_private);
+    } else {
+        // Each component within a tile is independent of every other,
+        // so we can decode all in parallel.
+        job_count = tile_info->num_tiles * desc->nb_components;
+
+        avctx->execute2(avctx, apv_decode_tile_component,
+                        input, NULL, job_count);
+
+        err = atomic_load_explicit(&apv->tile_errors, memory_order_relaxed);
+        if (err > 0) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Decode errors in %d tile components.\n", err);
+            if (avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) {
+                // Output the frame anyway.
+                output->flags |= AV_FRAME_FLAG_CORRUPT;
+            } else {
+                return AVERROR_INVALIDDATA;
+            }
         }
     }
 
@@ -571,4 +601,7 @@ const FFCodec ff_apv_decoder = {
                              AV_CODEC_CAP_SLICE_THREADS |
                              AV_CODEC_CAP_FRAME_THREADS,
     .caps_internal         = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM,
+    .hw_configs     = (const AVCodecHWConfigInternal *const []) {
+        NULL
+    },
 };
diff --git a/libavcodec/apv_decode.h b/libavcodec/apv_decode.h
index 5671d89552..60259e1b5e 100644
--- a/libavcodec/apv_decode.h
+++ b/libavcodec/apv_decode.h
@@ -20,11 +20,14 @@
 #define AVCODEC_APV_DECODE_H
 
 #include <stdint.h>
+#include <stdatomic.h>
 
 #include "apv.h"
-#include "avcodec.h"
-#include "get_bits.h"
+#include "apv_dsp.h"
 
+#include "cbs.h"
+#include "get_bits.h"
+#include "libavutil/frame.h"
 
 // Number of bits in the entropy look-up tables.
 // It may be desirable to tune this per-architecture, as a larger LUT
@@ -81,6 +84,34 @@ typedef struct APVEntropyState {
     uint8_t prev_k_level;
 } APVEntropyState;
 
+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;
+
+    CodedBitstreamFragment au;
+    APVDerivedTileInfo tile_info;
+
+    AVPacket *pkt;
+    AVFrame *output_frame;
+    void *hwaccel_picture_private;
+    atomic_int tile_errors;
+
+    enum AVPixelFormat pix_fmt;
+    int nb_unit;
+
+    uint8_t warned_additional_frames;
+    uint8_t warned_unknown_pbu_types;
+} APVDecodeContext;
 
 /**
  * Build the decoder VLC look-up tables.

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to