From e37330cf6a1f768c733ca6d0b23b9e5847a5fe4f Mon Sep 17 00:00:00 2001 From: Lynne Date: Thu, 10 Mar 2022 18:03:05 +0100 Subject: [PATCH 25/92] avcodec: add AVHWAccel.free_frame_priv callback --- libavcodec/av1dec.c | 4 ++-- libavcodec/avcodec.h | 8 ++++++++ libavcodec/decode.c | 19 +++++++++++++++++++ libavcodec/decode.h | 11 +++++++++++ libavcodec/h264_slice.c | 3 ++- libavcodec/hevc_refs.c | 3 ++- libavcodec/mpegpicture.c | 4 +++- libavcodec/vp8.c | 2 +- libavcodec/vp9.c | 2 +- 9 files changed, 49 insertions(+), 7 deletions(-) diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index 1956666cb8..fb558b4900 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -25,6 +25,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/opt.h" #include "avcodec.h" +#include "decode.h" #include "av1dec.h" #include "atsc_a53.h" #include "bytestream.h" @@ -871,8 +872,7 @@ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame *f) if (avctx->hwaccel) { const AVHWAccel *hwaccel = avctx->hwaccel; if (hwaccel->frame_priv_data_size) { - f->hwaccel_priv_buf = - av_buffer_allocz(hwaccel->frame_priv_data_size); + f->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(avctx, hwaccel); if (!f->hwaccel_priv_buf) { ret = AVERROR(ENOMEM); goto fail; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 30f1d312f4..b43e79a2a6 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2233,6 +2233,14 @@ typedef struct AVHWAccel { * that avctx->hwaccel_priv_data is invalid. */ int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); + + /** + * Callback to free the hwaccel-specific frame data. + * + * @param avctx the codec context + * @param data the per-frame hardware accelerator private data to be freed. + */ + void (*free_frame_priv)(AVCodecContext *avctx, void *data); } AVHWAccel; /** diff --git a/libavcodec/decode.c b/libavcodec/decode.c index d1ba7f167f..c4630ce275 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1685,3 +1685,22 @@ int ff_copy_palette(void *dst, const AVPacket *src, void *logctx) } return 0; } + +AVBufferRef *ff_alloc_hwaccel_frame_priv_data(AVCodecContext *avctx, + const AVHWAccel *hwaccel) +{ + AVBufferRef *ref; + uint8_t *data = av_mallocz(hwaccel->frame_priv_data_size); + if (!data) + return NULL; + + ref = av_buffer_create(data, hwaccel->frame_priv_data_size, + (void (*)(void *, uint8_t *))hwaccel->free_frame_priv, + avctx, 0); + if (!ref) { + av_free(data); + return NULL; + } + + return ref; +} diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 8430ffbd66..aa40baafc0 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -150,4 +150,15 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags); int ff_side_data_update_matrix_encoding(AVFrame *frame, enum AVMatrixEncoding matrix_encoding); +/** + * Allocate a hwaccel frame private data and create an AVBufferRef + * from it. + * + * @param avctx The codec context which to attach as an opaque value + * @param hwaccel The hwaccel for which to allocate + * @return The allocated buffer + */ +AVBufferRef *ff_alloc_hwaccel_frame_priv_data(AVCodecContext *avctx, + const AVHWAccel *hwaccel); + #endif /* AVCODEC_DECODE_H */ diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 7767e16cf1..579f074c42 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -33,6 +33,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/timecode.h" #include "internal.h" +#include "decode.h" #include "cabac.h" #include "cabac_functions.h" #include "decode.h" @@ -212,7 +213,7 @@ static int alloc_picture(H264Context *h, H264Picture *pic) const AVHWAccel *hwaccel = h->avctx->hwaccel; av_assert0(!pic->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { - pic->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + pic->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(h->avctx, hwaccel); if (!pic->hwaccel_priv_buf) return AVERROR(ENOMEM); pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 96153a2459..e68a7bc014 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -23,6 +23,7 @@ #include "libavutil/avassert.h" +#include "decode.h" #include "thread.h" #include "hevc.h" #include "hevcdec.h" @@ -118,7 +119,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s) const AVHWAccel *hwaccel = s->avctx->hwaccel; av_assert0(!frame->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { - frame->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + frame->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(s->avctx, hwaccel); if (!frame->hwaccel_priv_buf) goto fail; frame->hwaccel_picture_private = frame->hwaccel_priv_buf->data; diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c index 3204a70578..654e796e38 100644 --- a/libavcodec/mpegpicture.c +++ b/libavcodec/mpegpicture.c @@ -27,6 +27,8 @@ #include "avcodec.h" #include "encode.h" +#include "internal.h" +#include "decode.h" #include "motion_est.h" #include "mpegpicture.h" #include "mpegutils.h" @@ -172,7 +174,7 @@ static int alloc_frame_buffer(AVCodecContext *avctx, Picture *pic, if (avctx->hwaccel) { assert(!pic->hwaccel_picture_private); if (avctx->hwaccel->frame_priv_data_size) { - pic->hwaccel_priv_buf = av_buffer_allocz(avctx->hwaccel->frame_priv_data_size); + pic->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(avctx, avctx->hwaccel); if (!pic->hwaccel_priv_buf) { av_log(avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n"); return -1; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index db2419deaf..4c23eb5672 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -109,7 +109,7 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) if (s->avctx->hwaccel) { const AVHWAccel *hwaccel = s->avctx->hwaccel; if (hwaccel->frame_priv_data_size) { - f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + f->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(s->avctx, hwaccel); if (!f->hwaccel_priv_buf) goto fail; f->hwaccel_picture_private = f->hwaccel_priv_buf->data; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 7c0a246446..4f345f18db 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -136,7 +136,7 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame *f) const AVHWAccel *hwaccel = avctx->hwaccel; av_assert0(!f->hwaccel_picture_private); if (hwaccel->frame_priv_data_size) { - f->hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + f->hwaccel_priv_buf = ff_alloc_hwaccel_frame_priv_data(avctx, hwaccel); if (!f->hwaccel_priv_buf) goto fail; f->hwaccel_picture_private = f->hwaccel_priv_buf->data; -- 2.39.2