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 "decode.h"
#include "dpx.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) static unsigned int read16(const uint8_t **ptr, int is_big)
{ {
unsigned int temp; 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, static int decode_frame(AVCodecContext *avctx, AVFrame *p,
int *got_frame, AVPacket *avpkt) int *got_frame, AVPacket *avpkt)
{ {
DPXDecContext *dpx = avctx->priv_data; DPXDecContext *dpx = avctx->priv_data;
enum AVPixelFormat pix_fmt;
const uint8_t *buf = avpkt->data; const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size; int buf_size = avpkt->size;
uint32_t header_version, version = 0; uint32_t header_version, version = 0;
@ -631,96 +651,96 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p,
case 4080: case 4080:
case 6081: case 6081:
case 6080: case 6080:
avctx->pix_fmt = AV_PIX_FMT_GRAY8; pix_fmt = AV_PIX_FMT_GRAY8;
break; break;
case 6121: case 6121:
case 6120: case 6120:
avctx->pix_fmt = AV_PIX_FMT_GRAY12; pix_fmt = AV_PIX_FMT_GRAY12;
break; break;
case 1320: case 1320:
case 2320: case 2320:
case 3320: case 3320:
case 4320: case 4320:
case 6320: case 6320:
avctx->pix_fmt = AV_PIX_FMT_GRAYF32LE; pix_fmt = AV_PIX_FMT_GRAYF32LE;
break; break;
case 1321: case 1321:
case 2321: case 2321:
case 3321: case 3321:
case 4321: case 4321:
case 6321: case 6321:
avctx->pix_fmt = AV_PIX_FMT_GRAYF32BE; pix_fmt = AV_PIX_FMT_GRAYF32BE;
break; break;
case 50081: case 50081:
case 50080: case 50080:
avctx->pix_fmt = AV_PIX_FMT_RGB24; pix_fmt = AV_PIX_FMT_RGB24;
break; break;
case 52081: case 52081:
case 52080: case 52080:
avctx->pix_fmt = AV_PIX_FMT_ABGR; pix_fmt = AV_PIX_FMT_ABGR;
break; break;
case 51081: case 51081:
case 51080: case 51080:
avctx->pix_fmt = AV_PIX_FMT_RGBA; pix_fmt = AV_PIX_FMT_RGBA;
break; break;
case 50100: case 50100:
case 50101: case 50101:
avctx->pix_fmt = AV_PIX_FMT_GBRP10; pix_fmt = AV_PIX_FMT_GBRP10;
break; break;
case 51100: case 51100:
case 51101: case 51101:
avctx->pix_fmt = AV_PIX_FMT_GBRAP10; pix_fmt = AV_PIX_FMT_GBRAP10;
break; break;
case 50120: case 50120:
case 50121: case 50121:
avctx->pix_fmt = AV_PIX_FMT_GBRP12; pix_fmt = AV_PIX_FMT_GBRP12;
break; break;
case 51120: case 51120:
case 51121: case 51121:
avctx->pix_fmt = AV_PIX_FMT_GBRAP12; pix_fmt = AV_PIX_FMT_GBRAP12;
break; break;
case 6100: case 6100:
case 6101: case 6101:
avctx->pix_fmt = AV_PIX_FMT_GRAY10; pix_fmt = AV_PIX_FMT_GRAY10;
break; break;
case 6161: case 6161:
avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; pix_fmt = AV_PIX_FMT_GRAY16BE;
break; break;
case 6160: case 6160:
avctx->pix_fmt = AV_PIX_FMT_GRAY16LE; pix_fmt = AV_PIX_FMT_GRAY16LE;
break; break;
case 50161: case 50161:
avctx->pix_fmt = AV_PIX_FMT_RGB48BE; pix_fmt = AV_PIX_FMT_RGB48BE;
break; break;
case 50160: case 50160:
avctx->pix_fmt = AV_PIX_FMT_RGB48LE; pix_fmt = AV_PIX_FMT_RGB48LE;
break; break;
case 51161: case 51161:
avctx->pix_fmt = AV_PIX_FMT_RGBA64BE; pix_fmt = AV_PIX_FMT_RGBA64BE;
break; break;
case 51160: case 51160:
avctx->pix_fmt = AV_PIX_FMT_RGBA64LE; pix_fmt = AV_PIX_FMT_RGBA64LE;
break; break;
case 50320: case 50320:
avctx->pix_fmt = AV_PIX_FMT_GBRPF32LE; pix_fmt = AV_PIX_FMT_GBRPF32LE;
break; break;
case 50321: case 50321:
avctx->pix_fmt = AV_PIX_FMT_GBRPF32BE; pix_fmt = AV_PIX_FMT_GBRPF32BE;
break; break;
case 51320: case 51320:
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32LE; pix_fmt = AV_PIX_FMT_GBRAPF32LE;
break; break;
case 51321: case 51321:
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32BE; pix_fmt = AV_PIX_FMT_GBRAPF32BE;
break; break;
case 100081: case 100081:
avctx->pix_fmt = AV_PIX_FMT_UYVY422; pix_fmt = AV_PIX_FMT_UYVY422;
break; break;
case 102081: case 102081:
avctx->pix_fmt = AV_PIX_FMT_YUV444P; pix_fmt = AV_PIX_FMT_YUV444P;
break; break;
case 103081: case 103081:
avctx->pix_fmt = AV_PIX_FMT_YUVA444P; pix_fmt = AV_PIX_FMT_YUVA444P;
break; break;
default: default:
av_log(avctx, AV_LOG_ERROR, "Unsupported format %d\n", 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; 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); ff_set_sar(avctx, avctx->sample_aspect_ratio);
if ((ret = ff_get_buffer(avctx, p, 0)) < 0) 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; buf = avpkt->data + offset;
dpx->frame = p; 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; *got_frame = 1;
return buf_size; 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 = { const FFCodec ff_dpx_decoder = {
.p.name = "dpx", .p.name = "dpx",
CODEC_LONG_NAME("DPX (Digital Picture Exchange) image"), CODEC_LONG_NAME("DPX (Digital Picture Exchange) image"),
@ -751,5 +833,11 @@ const FFCodec ff_dpx_decoder = {
.p.type = AVMEDIA_TYPE_VIDEO, .p.type = AVMEDIA_TYPE_VIDEO,
.p.id = AV_CODEC_ID_DPX, .p.id = AV_CODEC_ID_DPX,
FF_CODEC_DECODE_CB(decode_frame), 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 #define AVCODEC_DPX_H
#include "libavutil/frame.h" #include "libavutil/frame.h"
#include "libavutil/pixfmt.h"
enum DPX_TRC { enum DPX_TRC {
DPX_TRC_USER_DEFINED = 0, DPX_TRC_USER_DEFINED = 0,
@ -58,6 +59,8 @@ enum DPX_COL_SPEC {
typedef struct DPXDecContext { typedef struct DPXDecContext {
AVFrame *frame; AVFrame *frame;
void *hwaccel_picture_private;
enum AVPixelFormat pix_fmt;
int packing; int packing;
int stride; int stride;