This repository has been archived by the owner on Feb 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
0021-lavc-decode-Add-internal-surface-re-allocate-method-.patch
84 lines (73 loc) · 2.67 KB
/
0021-lavc-decode-Add-internal-surface-re-allocate-method-.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
From 925d2ce3d8b57a70f8bf2de521e96e4b28996ecd Mon Sep 17 00:00:00 2001
From: Linjie Fu <[email protected]>
Date: Thu, 2 Jan 2020 11:12:15 +0800
Subject: [PATCH 21/28] lavc/decode: Add internal surface re-allocate method
for hwaccel
Add HWACCEL_CAP_INTERNAL_ALLOC flag to indicate hwaccels are able to
re-allocate surface internally through ff_decode_get_hw_frames_ctx.
Signed-off-by: Linjie Fu <[email protected]>
---
libavcodec/decode.c | 36 ++++++++++++++++++++++++++++++++++++
libavcodec/hwconfig.h | 1 +
2 files changed, 37 insertions(+)
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 3e74759..561d025 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1387,6 +1387,33 @@ static const AVCodecHWConfigInternal *get_hw_config(AVCodecContext *avctx, enum
return hw_config;
}
+static int hwaccel_realloc_surface(AVCodecContext *avctx)
+{
+ const AVCodecHWConfigInternal *hw_config;
+ int ret;
+
+ if (avctx->hw_frames_ctx)
+ av_buffer_unref(&avctx->hw_frames_ctx);
+
+ hw_config = get_hw_config(avctx, avctx->pix_fmt);
+ if (!hw_config)
+ return AV_PIX_FMT_NONE;
+
+ if (avctx->hw_device_ctx &&
+ hw_config->public.methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) {
+ const AVHWDeviceContext *device_ctx =
+ (AVHWDeviceContext*)avctx->hw_device_ctx->data;
+ ret = ff_decode_get_hw_frames_ctx(avctx, device_ctx->type);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_WARNING, "Failed to re-allocate hwaccel surface internally.\n");
+ return AV_PIX_FMT_NONE;
+ }
+ } else
+ return AV_PIX_FMT_NONE;
+
+ return hw_config->public.pix_fmt;
+}
+
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
{
const AVPixFmtDescriptor *desc;
@@ -1415,6 +1442,15 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
memcpy(choices, fmt, (n + 1) * sizeof(*choices));
for (;;) {
+ if (avctx->internal->hwaccel_priv_data &&
+ avctx->hwaccel->caps_internal & HWACCEL_CAP_INTERNAL_ALLOC) {
+ err = hwaccel_realloc_surface(avctx);
+ if (err < 0)
+ av_log(avctx, AV_LOG_WARNING, "Try to re-initialize all.\n");
+ else
+ return err;
+ }
+
// Remove the previous hwaccel, if there was one.
hwaccel_uninit(avctx);
diff --git a/libavcodec/hwconfig.h b/libavcodec/hwconfig.h
index 3aaa925..1605ad4 100644
--- a/libavcodec/hwconfig.h
+++ b/libavcodec/hwconfig.h
@@ -24,6 +24,7 @@
#define HWACCEL_CAP_ASYNC_SAFE (1 << 0)
+#define HWACCEL_CAP_INTERNAL_ALLOC (1 << 1)
typedef struct AVCodecHWConfigInternal {
--
2.7.4