1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

avcodec: add AVHWAccel.free_frame_priv callback

This commit is contained in:
Lynne 2022-03-10 18:03:05 +01:00
parent 09dc9193ea
commit be07145109
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
9 changed files with 50 additions and 7 deletions

View File

@ -27,6 +27,7 @@
#include "libavutil/opt.h"
#include "avcodec.h"
#include "av1_parse.h"
#include "decode.h"
#include "av1dec.h"
#include "atsc_a53.h"
#include "bytestream.h"
@ -865,8 +866,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_hwaccel_frame_priv_alloc(avctx, hwaccel);
if (!f->hwaccel_priv_buf) {
ret = AVERROR(ENOMEM);
goto fail;

View File

@ -2259,6 +2259,14 @@ typedef struct AVHWAccel {
* For thread-safe hwaccels only.
*/
int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
/**
* Callback to free the hwaccel-specific frame data.
*
* @param hwctx a pointer to an AVHWDeviceContext.
* @param data the per-frame hardware accelerator private data to be freed.
*/
void (*free_frame_priv)(void *hwctx, uint8_t *data);
} AVHWAccel;
/**

View File

@ -1718,3 +1718,23 @@ int ff_copy_palette(void *dst, const AVPacket *src, void *logctx)
}
return 0;
}
AVBufferRef *ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx,
const AVHWAccel *hwaccel)
{
AVBufferRef *ref;
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
uint8_t *data = av_mallocz(hwaccel->frame_priv_data_size);
if (!data)
return NULL;
ref = av_buffer_create(data, hwaccel->frame_priv_data_size,
hwaccel->free_frame_priv,
frames_ctx->device_ctx, 0);
if (!ref) {
av_free(data);
return NULL;
}
return ref;
}

View File

@ -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_hwaccel_frame_priv_alloc(AVCodecContext *avctx,
const AVHWAccel *hwaccel);
#endif /* AVCODEC_DECODE_H */

View File

@ -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_hwaccel_frame_priv_alloc(h->avctx, hwaccel);
if (!pic->hwaccel_priv_buf)
return AVERROR(ENOMEM);
pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;

View File

@ -23,6 +23,7 @@
#include "libavutil/avassert.h"
#include "decode.h"
#include "thread.h"
#include "hevc.h"
#include "hevcdec.h"
@ -121,7 +122,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_hwaccel_frame_priv_alloc(s->avctx, hwaccel);
if (!frame->hwaccel_priv_buf)
goto fail;
frame->hwaccel_picture_private = frame->hwaccel_priv_buf->data;

View File

@ -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_hwaccel_frame_priv_alloc(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;

View File

@ -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_hwaccel_frame_priv_alloc(s->avctx, hwaccel);
if (!f->hwaccel_priv_buf)
goto fail;
f->hwaccel_picture_private = f->hwaccel_priv_buf->data;

View File

@ -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_hwaccel_frame_priv_alloc(avctx, hwaccel);
if (!f->hwaccel_priv_buf)
goto fail;
f->hwaccel_picture_private = f->hwaccel_priv_buf->data;