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
/
0086-lavc-vaapi_encode_h265-set-low-delay-B-automatically.patch
134 lines (123 loc) · 6.08 KB
/
0086-lavc-vaapi_encode_h265-set-low-delay-B-automatically.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
From ef1a8fed12b297b968acdff46278813c2439f820 Mon Sep 17 00:00:00 2001
From: Fei Wang <[email protected]>
Date: Wed, 25 Nov 2020 13:48:35 -0500
Subject: [PATCH] lavc/vaapi_encode_h265: set low delay B automatically
When encode P frame, query driver if it support P. If not, convert
P frame to forward prediction B.
Signed-off-by: Fei Wang <[email protected]>
---
libavcodec/vaapi_encode.c | 28 ++++++++++++++++++++++++++--
libavcodec/vaapi_encode_h265.c | 25 +++++--------------------
2 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index f561feb38d..b91556b38a 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1907,6 +1907,30 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
ref_l1 = attr.value >> 16 & 0xffff;
}
+#if VA_CHECK_VERSION(1, 9, 0)
+ // if driver doesn't support P frame, convert P to forward-prediction B.
+ // if driver doesn't support future prediction type, convert B to forward-prediction B.
+ if (!ctx->b_frame_strategy) {
+ attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
+ vas = vaGetConfigAttributes(ctx->hwctx->display,
+ ctx->va_profile,
+ ctx->va_entrypoint,
+ &attr, 1);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query prediction direction "
+ "attribute: %d (%s).\n", vas, vaErrorStr(vas));
+ return AVERROR_EXTERNAL;
+ }
+
+ if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
+ if (attr.value & VA_PREDICTION_DIRECTION_FUTURE)
+ ctx->b_frame_strategy = 2;
+ else
+ ctx->b_frame_strategy = 1;
+ }
+ }
+#endif
+
if (ctx->codec->flags & FLAG_INTRA_ONLY ||
avctx->gop_size <= 1) {
av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
@@ -1918,7 +1942,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
} else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
ref_l1 < 1 || avctx->max_b_frames < 1 ||
ctx->b_frame_strategy == 1) {
- if (ctx->b_frame_strategy == 1)
+ if (ctx->b_frame_strategy)
av_log(avctx, AV_LOG_VERBOSE, "Using intra and low delay "
"B-frames (supported references: %d / %d).\n",
ref_l0, ref_l1);
@@ -1929,7 +1953,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
ctx->p_per_i = INT_MAX;
ctx->b_per_p = 0;
} else {
- if (ctx->b_frame_strategy == 2)
+ if (ctx->b_frame_strategy)
av_log(avctx, AV_LOG_VERBOSE, "Using intra, reference B- and "
"B-frames (supported references: %d / %d).\n",
ref_l0, ref_l1);
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 45f233cdea..aadc43e6ca 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -950,8 +950,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
sh->slice_type = hpic->slice_type;
- // driver requires low delay B frame in low power mode
- if (sh->slice_type == HEVC_SLICE_P && priv->b_frame_strategy)
+ if (sh->slice_type == HEVC_SLICE_P && ctx->b_frame_strategy)
sh->slice_type = HEVC_SLICE_B;
sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt &
@@ -1120,7 +1119,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
av_assert0(pic->type == PICTURE_TYPE_P ||
pic->type == PICTURE_TYPE_B);
vslice->ref_pic_list0[0] = vpic->reference_frames[0];
- if (priv->b_frame_strategy && pic->type == PICTURE_TYPE_P)
+ if (ctx->b_frame_strategy && pic->type == PICTURE_TYPE_P)
// Reference for low delay B-frame, L0 == L1
vslice->ref_pic_list1[0] = vpic->reference_frames[0];
}
@@ -1131,8 +1130,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
}
// Driver requires low delay B frame and matched ref_pic_list0/1[]
- // for low power mode
- if (pic->type == PICTURE_TYPE_P && ctx->low_power) {
+ if (pic->type == PICTURE_TYPE_P && ctx->b_frame_strategy) {
vslice->slice_type = HEVC_SLICE_B;
for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id;
@@ -1279,20 +1277,7 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
if (priv->qp > 0)
ctx->explicit_qp = priv->qp;
- // Low delay B-frames is required for low power encoding.
- if (ctx->low_power && priv->b_frame_strategy != 1) {
- priv->b_frame_strategy = 1;
- av_log(avctx, AV_LOG_WARNING, "Low delay B-frames required "
- "for low power encoding.\n");
- }
-
- if (priv->b_frame_strategy) {
- ctx->b_frame_strategy = priv->b_frame_strategy;
- if (ctx->b_frame_strategy == 1)
- av_log(avctx, AV_LOG_VERBOSE, "Low delay B-frames enabled.\n");
- else
- av_log(avctx, AV_LOG_VERBOSE, "Reference B-frames enabled.\n");
- }
+ ctx->b_frame_strategy = priv->b_frame_strategy;
return ff_vaapi_encode_init(avctx);
}
@@ -1372,7 +1357,7 @@ static const AVOption vaapi_encode_h265_options[] = {
INT_MIN, INT_MAX, FLAGS, "sei" },
{ "b_strategy", "Strategy to choose between I/P/B-frames",
OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FLAGS, "b_strategy" },
- { "normal", "Normal IB..BPB..B strategy",
+ { "auto", "Convert P/B to forward-prediction B automatically if driver doesn't support.",
0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "b_strategy" },
{ "low_delay_b", "Use low delay B-frames with forward-prediction only",
0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, FLAGS, "b_strategy" },
--
2.17.1