avcodec/prores: adapt hwaccel code for slice-based accelerators

In preparation for the Vulkan hwaccel.
The existing hwaccel code was designed around
videotoolbox, which ingests the whole frame
bitstream including picture headers.
This adapts the code to accomodate lower-level,
slice-based hwaccels.
This commit is contained in:
averne
2025-06-12 19:31:44 +02:00
committed by Lynne
parent 9195af77eb
commit 987368ef25
2 changed files with 30 additions and 20 deletions

View File

@@ -756,6 +756,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int frame_hdr_size, pic_size, ret;
int i;
if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
av_log(avctx, AV_LOG_ERROR, "invalid frame header\n");
@@ -786,20 +787,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
ff_thread_finish_setup(avctx);
if (HWACCEL_MAX && avctx->hwaccel) {
const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, avpkt->size);
if (ret < 0)
return ret;
ret = hwaccel->decode_slice(avctx, avpkt->data, avpkt->size);
if (ret < 0)
return ret;
ret = hwaccel->end_frame(avctx);
if (ret < 0)
return ret;
goto finish;
}
decode_picture:
pic_size = decode_picture_header(avctx, buf, buf_size);
if (pic_size < 0) {
@@ -807,7 +794,23 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
return pic_size;
}
if ((ret = decode_picture(avctx)) < 0) {
if (HWACCEL_MAX && avctx->hwaccel) {
const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel);
ret = hwaccel->start_frame(avctx, avpkt->buf, avpkt->data, avpkt->size);
if (ret < 0)
return ret;
for (i = 0; i < ctx->slice_count; ++i) {
ret = hwaccel->decode_slice(avctx, ctx->slices[i].data, ctx->slices[i].data_size);
if (ret < 0)
return ret;
}
ret = hwaccel->end_frame(avctx);
if (ret < 0)
return ret;
} else if ((ret = decode_picture(avctx)) < 0) {
av_log(avctx, AV_LOG_ERROR, "error decoding picture\n");
return ret;
}
@@ -820,7 +823,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
goto decode_picture;
}
finish:
av_refstruct_unref(&ctx->hwaccel_last_picture_private);
*got_frame = 1;

View File

@@ -1161,16 +1161,21 @@ static int videotoolbox_prores_start_frame(AVCodecContext *avctx,
const uint8_t *buffer,
uint32_t size)
{
return 0;
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
ProresContext *ctx = avctx->priv_data;
/* Videotoolbox decodes both fields simultaneously */
if (!ctx->first_field)
return 0;
return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
}
static int videotoolbox_prores_decode_slice(AVCodecContext *avctx,
const uint8_t *buffer,
uint32_t size)
{
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
return 0;
}
static int videotoolbox_prores_end_frame(AVCodecContext *avctx)
@@ -1178,6 +1183,9 @@ static int videotoolbox_prores_end_frame(AVCodecContext *avctx)
ProresContext *ctx = avctx->priv_data;
AVFrame *frame = ctx->frame;
if (!ctx->first_field)
return 0;
return ff_videotoolbox_common_end_frame(avctx, frame);
}