dpxdec: add hardware decoding hooks

This commit is contained in:
Lynne 2025-10-29 14:24:10 +01:00
parent 61ae1ec85f
commit a9acae202a
No known key found for this signature in database
GPG key ID: A2FEA5F03F034464
2 changed files with 118 additions and 27 deletions

View file

@ -29,6 +29,11 @@
#include "decode.h"
#include "dpx.h"
#include "thread.h"
#include "hwconfig.h"
#include "hwaccel_internal.h"
#include "config_components.h"
static unsigned int read16(const uint8_t **ptr, int is_big)
{
unsigned int temp;
@ -257,11 +262,26 @@ static void unpack_frame(AVCodecContext *avctx, AVFrame *p, const uint8_t *buf,
}
}
static enum AVPixelFormat get_pixel_format(AVCodecContext *avctx,
enum AVPixelFormat pix_fmt)
{
enum AVPixelFormat pix_fmts[] = {
#if CONFIG_DPX_VULKAN_HWACCEL
AV_PIX_FMT_VULKAN,
#endif
pix_fmt,
AV_PIX_FMT_NONE,
};
return ff_get_format(avctx, pix_fmts);
}
static int decode_frame(AVCodecContext *avctx, AVFrame *p,
int *got_frame, AVPacket *avpkt)
{
DPXDecContext *dpx = avctx->priv_data;
enum AVPixelFormat pix_fmt;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
uint32_t header_version, version = 0;
@ -631,96 +651,96 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
case 4080:
case 6081:
case 6080:
avctx->pix_fmt = AV_PIX_FMT_GRAY8;
pix_fmt = AV_PIX_FMT_GRAY8;
break;
case 6121:
case 6120:
avctx->pix_fmt = AV_PIX_FMT_GRAY12;
pix_fmt = AV_PIX_FMT_GRAY12;
break;
case 1320:
case 2320:
case 3320:
case 4320:
case 6320:
avctx->pix_fmt = AV_PIX_FMT_GRAYF32LE;
pix_fmt = AV_PIX_FMT_GRAYF32LE;
break;
case 1321:
case 2321:
case 3321:
case 4321:
case 6321:
avctx->pix_fmt = AV_PIX_FMT_GRAYF32BE;
pix_fmt = AV_PIX_FMT_GRAYF32BE;
break;
case 50081:
case 50080:
avctx->pix_fmt = AV_PIX_FMT_RGB24;
pix_fmt = AV_PIX_FMT_RGB24;
break;
case 52081:
case 52080:
avctx->pix_fmt = AV_PIX_FMT_ABGR;
pix_fmt = AV_PIX_FMT_ABGR;
break;
case 51081:
case 51080:
avctx->pix_fmt = AV_PIX_FMT_RGBA;
pix_fmt = AV_PIX_FMT_RGBA;
break;
case 50100:
case 50101:
avctx->pix_fmt = AV_PIX_FMT_GBRP10;
pix_fmt = AV_PIX_FMT_GBRP10;
break;
case 51100:
case 51101:
avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
pix_fmt = AV_PIX_FMT_GBRAP10;
break;
case 50120:
case 50121:
avctx->pix_fmt = AV_PIX_FMT_GBRP12;
pix_fmt = AV_PIX_FMT_GBRP12;
break;
case 51120:
case 51121:
avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
pix_fmt = AV_PIX_FMT_GBRAP12;
break;
case 6100:
case 6101:
avctx->pix_fmt = AV_PIX_FMT_GRAY10;
pix_fmt = AV_PIX_FMT_GRAY10;
break;
case 6161:
avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
pix_fmt = AV_PIX_FMT_GRAY16BE;
break;
case 6160:
avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
pix_fmt = AV_PIX_FMT_GRAY16LE;
break;
case 50161:
avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
pix_fmt = AV_PIX_FMT_RGB48BE;
break;
case 50160:
avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
pix_fmt = AV_PIX_FMT_RGB48LE;
break;
case 51161:
avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
pix_fmt = AV_PIX_FMT_RGBA64BE;
break;
case 51160:
avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
pix_fmt = AV_PIX_FMT_RGBA64LE;
break;
case 50320:
avctx->pix_fmt = AV_PIX_FMT_GBRPF32LE;
pix_fmt = AV_PIX_FMT_GBRPF32LE;
break;
case 50321:
avctx->pix_fmt = AV_PIX_FMT_GBRPF32BE;
pix_fmt = AV_PIX_FMT_GBRPF32BE;
break;
case 51320:
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32LE;
pix_fmt = AV_PIX_FMT_GBRAPF32LE;
break;
case 51321:
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32BE;
pix_fmt = AV_PIX_FMT_GBRAPF32BE;
break;
case 100081:
avctx->pix_fmt = AV_PIX_FMT_UYVY422;
pix_fmt = AV_PIX_FMT_UYVY422;
break;
case 102081:
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
pix_fmt = AV_PIX_FMT_YUV444P;
break;
case 103081:
avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
pix_fmt = AV_PIX_FMT_YUVA444P;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported format %d\n",
@ -728,6 +748,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
return AVERROR_PATCHWELCOME;
}
if (pix_fmt != dpx->pix_fmt) {
dpx->pix_fmt = pix_fmt;
ret = get_pixel_format(avctx, pix_fmt);
if (ret < 0)
return ret;
avctx->pix_fmt = ret;
}
ff_set_sar(avctx, avctx->sample_aspect_ratio);
if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
@ -737,13 +767,65 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
buf = avpkt->data + offset;
dpx->frame = p;
unpack_frame(avctx, p, buf, dpx->components, dpx->endian);
/* Start */
if (avctx->hwaccel) {
const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
ret = ff_hwaccel_frame_priv_alloc(avctx, &dpx->hwaccel_picture_private);
if (ret < 0)
return ret;
ret = hwaccel->start_frame(avctx, avpkt->buf, buf, avpkt->size - offset);
if (ret < 0)
return ret;
ret = hwaccel->decode_slice(avctx, buf, avpkt->size - offset);
if (ret < 0)
return ret;
ret = hwaccel->end_frame(avctx);
if (ret < 0)
return ret;
av_refstruct_unref(&dpx->hwaccel_picture_private);
} else {
unpack_frame(avctx, p, buf, dpx->components, dpx->endian);
}
p->pict_type = AV_PICTURE_TYPE_I;
p->flags |= AV_FRAME_FLAG_KEY;
*got_frame = 1;
return buf_size;
}
#if HAVE_THREADS
static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
{
DPXDecContext *ssrc = src->priv_data;
DPXDecContext *sdst = dst->priv_data;
sdst->pix_fmt = ssrc->pix_fmt;
return 0;
}
#endif
static av_cold int decode_end(AVCodecContext *avctx)
{
DPXDecContext *dpx = avctx->priv_data;
av_refstruct_unref(&dpx->hwaccel_picture_private);
return 0;
}
static av_cold int decode_init(AVCodecContext *avctx)
{
DPXDecContext *dpx = avctx->priv_data;
dpx->pix_fmt = AV_PIX_FMT_NONE;
return 0;
}
const FFCodec ff_dpx_decoder = {
.p.name = "dpx",
CODEC_LONG_NAME("DPX (Digital Picture Exchange) image"),
@ -751,5 +833,11 @@ const FFCodec ff_dpx_decoder = {
.p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DPX,
FF_CODEC_DECODE_CB(decode_frame),
.p.capabilities = AV_CODEC_CAP_DR1,
.init = decode_init,
.close = decode_end,
UPDATE_THREAD_CONTEXT(update_thread_context),
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.hw_configs = (const AVCodecHWConfigInternal *const []) {
NULL
},
};

View file

@ -23,6 +23,7 @@
#define AVCODEC_DPX_H
#include "libavutil/frame.h"
#include "libavutil/pixfmt.h"
enum DPX_TRC {
DPX_TRC_USER_DEFINED = 0,
@ -58,6 +59,8 @@ enum DPX_COL_SPEC {
typedef struct DPXDecContext {
AVFrame *frame;
void *hwaccel_picture_private;
enum AVPixelFormat pix_fmt;
int packing;
int stride;