mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-05 14:30:00 +01:00
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:
@@ -756,6 +756,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
int frame_hdr_size, pic_size, ret;
|
int frame_hdr_size, pic_size, ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
|
if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "invalid frame header\n");
|
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);
|
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:
|
decode_picture:
|
||||||
pic_size = decode_picture_header(avctx, buf, buf_size);
|
pic_size = decode_picture_header(avctx, buf, buf_size);
|
||||||
if (pic_size < 0) {
|
if (pic_size < 0) {
|
||||||
@@ -807,7 +794,23 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||||||
return pic_size;
|
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");
|
av_log(avctx, AV_LOG_ERROR, "error decoding picture\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -820,7 +823,6 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
|||||||
goto decode_picture;
|
goto decode_picture;
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
|
||||||
av_refstruct_unref(&ctx->hwaccel_last_picture_private);
|
av_refstruct_unref(&ctx->hwaccel_last_picture_private);
|
||||||
|
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
|
|||||||
@@ -1161,16 +1161,21 @@ static int videotoolbox_prores_start_frame(AVCodecContext *avctx,
|
|||||||
const uint8_t *buffer,
|
const uint8_t *buffer,
|
||||||
uint32_t size)
|
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,
|
static int videotoolbox_prores_decode_slice(AVCodecContext *avctx,
|
||||||
const uint8_t *buffer,
|
const uint8_t *buffer,
|
||||||
uint32_t size)
|
uint32_t size)
|
||||||
{
|
{
|
||||||
VTContext *vtctx = avctx->internal->hwaccel_priv_data;
|
return 0;
|
||||||
|
|
||||||
return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int videotoolbox_prores_end_frame(AVCodecContext *avctx)
|
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;
|
ProresContext *ctx = avctx->priv_data;
|
||||||
AVFrame *frame = ctx->frame;
|
AVFrame *frame = ctx->frame;
|
||||||
|
|
||||||
|
if (!ctx->first_field)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return ff_videotoolbox_common_end_frame(avctx, frame);
|
return ff_videotoolbox_common_end_frame(avctx, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user