[FFmpeg-devel] [PATCH 23/42] avcodec/vaapi_encode: Use RefStruct pool API, stop abusing AVBuffer API
Andreas Rheinhardt
andreas.rheinhardt at outlook.com
Tue Sep 19 22:57:15 EEST 2023
Up until now, the VAAPI encoder uses fake data with the
AVBuffer-API: The data pointer does not point to real memory,
but is instead just a VABufferID converted to a pointer.
This has probably been copied from the VAAPI-hwcontext-API
(which presumably does it to avoid allocations).
This commit changes this without causing additional allocations
by switching to the RefStruct-pool API.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
libavcodec/vaapi_encode.c | 60 ++++++++++++++++-----------------------
libavcodec/vaapi_encode.h | 5 ++--
2 files changed, 28 insertions(+), 37 deletions(-)
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 0316fe5c18..3f06d7f21e 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -16,11 +16,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config_components.h"
-
#include <inttypes.h>
#include <string.h>
+#include "config.h"
+
#include "libavutil/avassert.h"
#include "libavutil/common.h"
#include "libavutil/internal.h"
@@ -30,6 +30,7 @@
#include "vaapi_encode.h"
#include "encode.h"
#include "avcodec.h"
+#include "refstruct.h"
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[] = {
HW_CONFIG_ENCODER_FRAMES(VAAPI, VAAPI),
@@ -309,12 +310,12 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface);
- pic->output_buffer_ref = av_buffer_pool_get(ctx->output_buffer_pool);
+ pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);
if (!pic->output_buffer_ref) {
err = AVERROR(ENOMEM);
goto fail;
}
- pic->output_buffer = (VABufferID)(uintptr_t)pic->output_buffer_ref->data;
+ pic->output_buffer = *pic->output_buffer_ref;
av_log(avctx, AV_LOG_DEBUG, "Output buffer is %#x.\n",
pic->output_buffer);
@@ -645,7 +646,7 @@ fail_at_end:
av_freep(&pic->slices);
av_freep(&pic->roi);
av_frame_free(&pic->recon_image);
- av_buffer_unref(&pic->output_buffer_ref);
+ ff_refstruct_unref(&pic->output_buffer_ref);
pic->output_buffer = VA_INVALID_ID;
return err;
}
@@ -713,7 +714,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
pic->opaque_ref = NULL;
}
- av_buffer_unref(&pic->output_buffer_ref);
+ ff_refstruct_unref(&pic->output_buffer_ref);
pic->output_buffer = VA_INVALID_ID;
av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
@@ -723,7 +724,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
fail_mapped:
vaUnmapBuffer(ctx->hwctx->display, pic->output_buffer);
fail:
- av_buffer_unref(&pic->output_buffer_ref);
+ ff_refstruct_unref(&pic->output_buffer_ref);
pic->output_buffer = VA_INVALID_ID;
return err;
}
@@ -738,7 +739,7 @@ static int vaapi_encode_discard(AVCodecContext *avctx,
"%"PRId64"/%"PRId64".\n",
pic->display_order, pic->encode_order);
- av_buffer_unref(&pic->output_buffer_ref);
+ ff_refstruct_unref(&pic->output_buffer_ref);
pic->output_buffer = VA_INVALID_ID;
}
@@ -2420,28 +2421,25 @@ static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
return 0;
}
-static void vaapi_encode_free_output_buffer(void *opaque,
- uint8_t *data)
+static void vaapi_encode_free_output_buffer(FFRefStructOpaque opaque,
+ void *obj)
{
- AVCodecContext *avctx = opaque;
+ AVCodecContext *avctx = opaque.nc;
VAAPIEncodeContext *ctx = avctx->priv_data;
- VABufferID buffer_id;
-
- buffer_id = (VABufferID)(uintptr_t)data;
+ VABufferID *buffer_id_ref = obj;
+ VABufferID buffer_id = *buffer_id_ref;
vaDestroyBuffer(ctx->hwctx->display, buffer_id);
av_log(avctx, AV_LOG_DEBUG, "Freed output buffer %#x\n", buffer_id);
}
-static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
- size_t size)
+static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
{
- AVCodecContext *avctx = opaque;
+ AVCodecContext *avctx = opaque.nc;
VAAPIEncodeContext *ctx = avctx->priv_data;
- VABufferID buffer_id;
+ VABufferID *buffer_id = obj;
VAStatus vas;
- AVBufferRef *ref;
// The output buffer size is fixed, so it needs to be large enough
// to hold the largest possible compressed frame. We assume here
@@ -2450,25 +2448,16 @@ static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VAEncCodedBufferType,
3 * ctx->surface_width * ctx->surface_height +
- (1 << 16), 1, 0, &buffer_id);
+ (1 << 16), 1, 0, buffer_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
"output buffer: %d (%s).\n", vas, vaErrorStr(vas));
- return NULL;
+ return AVERROR(ENOMEM);
}
- av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", buffer_id);
+ av_log(avctx, AV_LOG_DEBUG, "Allocated output buffer %#x\n", *buffer_id);
- ref = av_buffer_create((uint8_t*)(uintptr_t)buffer_id,
- sizeof(buffer_id),
- &vaapi_encode_free_output_buffer,
- avctx, AV_BUFFER_FLAG_READONLY);
- if (!ref) {
- vaDestroyBuffer(ctx->hwctx->display, buffer_id);
- return NULL;
- }
-
- return ref;
+ return 0;
}
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
@@ -2677,8 +2666,9 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
}
ctx->output_buffer_pool =
- av_buffer_pool_init2(sizeof(VABufferID), avctx,
- &vaapi_encode_alloc_output_buffer, NULL);
+ ff_refstruct_pool_alloc_ext(sizeof(VABufferID), 0, avctx,
+ &vaapi_encode_alloc_output_buffer, NULL,
+ vaapi_encode_free_output_buffer, NULL);
if (!ctx->output_buffer_pool) {
err = AVERROR(ENOMEM);
goto fail;
@@ -2776,7 +2766,7 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
vaapi_encode_free(avctx, pic);
}
- av_buffer_pool_uninit(&ctx->output_buffer_pool);
+ ff_refstruct_pool_uninit(&ctx->output_buffer_pool);
if (ctx->va_context != VA_INVALID_ID) {
vaDestroyContext(ctx->hwctx->display, ctx->va_context);
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index bd25cd5c95..741f6c6a77 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -102,7 +102,8 @@ typedef struct VAAPIEncodePicture {
int nb_param_buffers;
VABufferID *param_buffers;
- AVBufferRef *output_buffer_ref;
+ /* Refcounted via the refstruct-API */
+ VABufferID *output_buffer_ref;
VABufferID output_buffer;
void *priv_data;
@@ -262,7 +263,7 @@ typedef struct VAAPIEncodeContext {
AVHWFramesContext *recon_frames;
// Pool of (reusable) bitstream output buffers.
- AVBufferPool *output_buffer_pool;
+ struct FFRefStructPool *output_buffer_pool;
// Global parameters which will be applied at the start of the
// sequence (includes rate control parameters below).
--
2.34.1
More information about the ffmpeg-devel
mailing list