[FFmpeg-devel] [PATCH] avutil/hwcontext: add support to allow hardware to ref/unref frame
suji.velupillai at broadcom.com
suji.velupillai at broadcom.com
Thu Mar 4 08:19:09 EET 2021
From: Patrick Rault <patrick.rault at broadcom.com>
Add support to allow attached hardware to add/remove reference to the
frame buffer mirroring the ffmpeg.
Signed-off-by: Patrick Rault <patrick.rault at broadcom.com>
Signed-off-by: Suji Velupillai <suji.velupillai at broadcom.com>
---
libavutil/frame.c | 7 ++++++-
libavutil/hwcontext.c | 21 +++++++++++++++++++++
libavutil/hwcontext.h | 15 +++++++++++++++
libavutil/hwcontext_internal.h | 2 ++
4 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index eab51b6a32..6f8db14bf5 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -22,6 +22,7 @@
#include "common.h"
#include "dict.h"
#include "frame.h"
+#include "hwcontext.h"
#include "imgutils.h"
#include "mem.h"
#include "samplefmt.h"
@@ -492,7 +493,7 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
dst->nb_extended_buf = src->nb_extended_buf;
for (i = 0; i < src->nb_extended_buf; i++) {
- dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]);
+ dst->extended_buf[i] = av_buffer_ref(dst);
if (!dst->extended_buf[i]) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -530,6 +531,8 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
memcpy(dst->data, src->data, sizeof(src->data));
memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
+ av_hwframe_ref_buffer(dst);
+
return 0;
fail:
@@ -571,6 +574,8 @@ FF_DISABLE_DEPRECATION_WARNINGS
FF_ENABLE_DEPRECATION_WARNINGS
#endif
+ av_hwframe_unref_buffer(frame);
+
av_buffer_unref(&frame->hw_frames_ctx);
av_buffer_unref(&frame->opaque_ref);
diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index d13d0f7c9b..5e2209725e 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -562,6 +562,27 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
return 0;
}
+int av_hwframe_ref_buffer(AVFrame *frame)
+{
+ int ret = 0;
+
+ if (frame->hw_frames_ctx) {
+ AVHWFramesContext *ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
+ if (ctx->internal->hw_type->frames_ref_buffer)
+ ret = ctx->internal->hw_type->frames_ref_buffer(frame);
+ }
+ return ret;
+}
+
+void av_hwframe_unref_buffer(AVFrame *frame)
+{
+ if (frame->hw_frames_ctx) {
+ AVHWFramesContext *ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
+ if (ctx->internal->hw_type->frames_unref_buffer)
+ ctx->internal->hw_type->frames_unref_buffer(frame);
+ }
+}
+
void *av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
{
AVHWDeviceContext *ctx = (AVHWDeviceContext*)ref->data;
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index 04d19d89c2..9dc74b9e46 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -381,6 +381,21 @@ int av_hwframe_ctx_init(AVBufferRef *ref);
*/
int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags);
+/**
+ * Allow hardware to add a reference on a buffer
+ *
+ * @param frame Hardware to add reference to the frame
+ * @return 0 on success, a negative AVERROR code on failure
+ */
+int av_hwframe_ref_buffer(AVFrame *frame);
+
+/**
+ * Allow to release hardware specific attached to the frame
+ *
+ * @param frame Hardware to release reference on the frame
+ */
+void av_hwframe_unref_buffer(AVFrame *frame);
+
/**
* Copy data to or from a hw surface. At least one of dst/src must have an
* AVHWFramesContext attached.
diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h
index e6266494ac..fde34932c6 100644
--- a/libavutil/hwcontext_internal.h
+++ b/libavutil/hwcontext_internal.h
@@ -81,6 +81,8 @@ typedef struct HWContextType {
void (*frames_uninit)(AVHWFramesContext *ctx);
int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame);
+ int (*frames_ref_buffer)(AVFrame *frame);
+ void (*frames_unref_buffer)(AVFrame *frame);
int (*transfer_get_formats)(AVHWFramesContext *ctx,
enum AVHWFrameTransferDirection dir,
enum AVPixelFormat **formats);
--
2.17.1
More information about the ffmpeg-devel
mailing list