1 /*
2 * Copyright (c) 2019-2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_vp9_brc.cpp
24 //! \brief Defines the common interface for vp9 brc features
25 //!
26
27 #include "encode_vp9_brc.h"
28 #include "encode_utils.h"
29 #include "encode_vp9_vdenc_feature_manager.h"
30 #include "encode_vp9_vdenc_const_settings.h"
31 #include "encode_vp9_segmentation.h"
32
33 namespace encode
34 {
35 constexpr int8_t Vp9EncodeBrc::m_instRateThresholdI[Vp9EncodeBrc::m_numInstRateThresholds];
36 constexpr int8_t Vp9EncodeBrc::m_instRateThresholdP[Vp9EncodeBrc::m_numInstRateThresholds];
37 constexpr double Vp9EncodeBrc::m_devThresholdFpNegI[Vp9EncodeBrc::m_numDevThresholds / 2];
38 constexpr double Vp9EncodeBrc::m_devThresholdFpPosI[Vp9EncodeBrc::m_numDevThresholds / 2];
39 constexpr double Vp9EncodeBrc::m_devThresholdFpNegPB[Vp9EncodeBrc::m_numDevThresholds / 2];
40 constexpr double Vp9EncodeBrc::m_devThresholdFpPosPB[Vp9EncodeBrc::m_numDevThresholds / 2];
41 constexpr double Vp9EncodeBrc::m_devThresholdVbrNeg[Vp9EncodeBrc::m_numDevThresholds / 2];
42 constexpr double Vp9EncodeBrc::m_devThresholdVbrPos[Vp9EncodeBrc::m_numDevThresholds / 2];
43
44 const uint32_t Vp9EncodeBrc::m_brcConstData[2][416] =
45 {
46 // I Frame
47 {
48 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
49 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
50 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
51 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
52 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
53 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
54 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
55 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
56 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
57 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
58 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
59 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
60 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
61 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
62 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
63 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
64 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
65 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
67 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
68 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
69 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
70 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
71 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
72 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
73 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
74 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
75 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
76 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
77 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
78 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
79 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
80 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
81 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
82 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
83 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
84 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
85 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
86 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
87 0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000,
88 0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000,
89 0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A,
90 0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600,
91 0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000,
92 0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A,
93 0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600,
94 0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA,
95 0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000,
96 0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000,
97 0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802,
98 0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000,
99 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
100 },
101 // P Frame
102 {
103 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
104 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
105 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
106 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
107 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
108 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
109 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
110 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
111 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
112 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
113 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
114 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
115 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
116 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
117 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
118 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
119 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
120 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
121 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
122 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
123 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
124 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
125 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
126 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
127 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
128 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
129 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
130 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
131 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
132 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
133 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
134 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
135 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
136 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
137 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
138 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
139 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
140 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
141 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
142 0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000,
143 0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000,
144 0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A,
145 0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600,
146 0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000,
147 0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A,
148 0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600,
149 0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA,
150 0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000,
151 0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000,
152 0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802,
153 0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000,
154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
155 }
156 };
157
Vp9EncodeBrc(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)158 Vp9EncodeBrc::Vp9EncodeBrc(
159 MediaFeatureManager *featureManager,
160 EncodeAllocator * allocator,
161 CodechalHwInterfaceNext *hwInterface,
162 void * constSettings) : MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr),
163 m_hwInterface(hwInterface),
164 m_allocator(allocator)
165 {
166 ENCODE_FUNC_CALL();
167 ENCODE_CHK_NULL_NO_STATUS_RETURN(featureManager);
168
169 m_featureManager = featureManager;
170 auto encFeatureManager = dynamic_cast<EncodeVp9VdencFeatureManager *>(featureManager);
171 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
172
173 m_basicFeature = dynamic_cast<Vp9BasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
174 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
175
176 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface);
177
178 m_vdencInterfaceNew = std::static_pointer_cast<mhw::vdbox::vdenc::Itf>(m_hwInterface->GetVdencInterfaceNext());
179 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_vdencInterfaceNew);
180
181 m_hcpInterfaceNew = std::static_pointer_cast<mhw::vdbox::hcp::Itf>(m_hwInterface->GetHcpInterfaceNext());
182 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hcpInterfaceNew);
183 }
184
~Vp9EncodeBrc()185 Vp9EncodeBrc::~Vp9EncodeBrc()
186 {
187 FreeResources();
188 }
189
Init(void * settings)190 MOS_STATUS Vp9EncodeBrc::Init(void *settings)
191 {
192 ENCODE_FUNC_CALL();
193 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface());
194
195 m_vdencEnabled = true;
196
197 // VDENC BRC related buffer size
198 m_brcHistoryBufferSize = m_brcHistoryBufSize;
199 // VDENC BRC related buffer size
200 m_vdencBrcStatsBufferSize = m_brcStatsBufSize;
201 m_vdencBrcPakStatsBufferSize = m_brcPakStatsBufSize;
202
203 #if (_DEBUG || _RELEASE_INTERNAL)
204 MediaUserSetting::Value outValue;
205 ReadUserSettingForDebug(
206 m_userSettingPtr,
207 outValue,
208 "VP9 Encode Multipass BRC Enable",
209 MediaUserSetting::Group::Sequence);
210 m_multipassBrcSupported = outValue.Get<bool>();
211 #endif
212
213 ENCODE_CHK_STATUS_RETURN(AllocateResources());
214
215 return MOS_STATUS_SUCCESS;
216 }
217
Update(void * params)218 MOS_STATUS Vp9EncodeBrc::Update(void *params)
219 {
220 ENCODE_FUNC_CALL();
221 ENCODE_CHK_NULL_RETURN(params);
222
223 EncoderParams *encodeParams = (EncoderParams *)params;
224 auto vp9PicParams = m_basicFeature->m_vp9PicParams;
225 auto vp9SeqParams = m_basicFeature->m_vp9SeqParams;
226
227 if (m_basicFeature->m_newSeq)
228 {
229 ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
230 }
231
232 auto featureManager = dynamic_cast<EncodeVp9VdencFeatureManager *>(m_featureManager);
233 ENCODE_CHK_NULL_RETURN(featureManager);
234 auto numPasses = featureManager->GetNumPass();
235
236 auto dysRefFrameFlags = m_basicFeature->m_ref.DysRefFrameFlags();
237 auto dysVdencMultiPassEnabled = m_basicFeature->m_dysVdencMultiPassEnabled;
238
239 if (dysRefFrameFlags != DYS_REF_NONE && dysVdencMultiPassEnabled)
240 {
241 if (m_vdencBrcEnabled)
242 {
243 m_basicFeature->m_dysBrc = true;
244 // Reduce passes by 1, as m_numPasses == 1 becomes m_numPasses = 0 for Huc to run
245 numPasses = (numPasses > 0) ? (numPasses - 1) : numPasses;
246 featureManager->SetNumPass(numPasses);
247 }
248 else
249 {
250 m_basicFeature->m_dysCqp = true;
251 }
252 }
253
254 // This is BRC SinglePass case
255 // Actually, repak is disabled
256 if (m_vdencBrcEnabled && (dysRefFrameFlags != DYS_REF_NONE) && !dysVdencMultiPassEnabled)
257 {
258 m_basicFeature->m_dysBrc = true;
259 // Reduce passes by 1, as m_numPasses == 1 becomes m_numPasses = 0 for Huc to run
260 numPasses = (numPasses > 0) ? (numPasses - 1) : numPasses;
261 featureManager->SetNumPass(numPasses);
262 }
263
264 if (!m_vdencBrcEnabled && (dysRefFrameFlags != DYS_REF_NONE))
265 {
266 m_basicFeature->m_dysCqp = true;
267 }
268
269 return MOS_STATUS_SUCCESS;
270 }
271
SetRegionsForBrcUpdate(mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR & params) const272 MOS_STATUS Vp9EncodeBrc::SetRegionsForBrcUpdate(mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR ¶ms) const
273 {
274 ENCODE_FUNC_CALL();
275
276 // Initialize BRC constant data buffer
277 ENCODE_CHK_STATUS_RETURN(InitConstantDataBuffer());
278
279 // History Buffer - IN/OUT
280 params.regionParams[0].presRegion = const_cast<PMOS_RESOURCE>(& m_brcBuffers.resBrcHistoryBuffer);
281 params.regionParams[0].isWritable = true;
282 // VDENC Stats Buffer - IN
283 params.regionParams[1].presRegion = m_basicFeature->m_recycleBuf->GetBuffer(VdencStatsBuffer, 0);
284 params.regionParams[1].dwOffset = 0;
285 // Frame (not PAK) Stats Buffer - IN
286 params.regionParams[2].presRegion = const_cast<PMOS_RESOURCE>(&m_resFrameStatStreamOutBuffer);
287 params.regionParams[2].dwOffset = 0;
288 // BRC Data - OUT
289 params.regionParams[4].presRegion = const_cast<PMOS_RESOURCE>(&m_brcBuffers.resBrcHucDataBuffer);
290 params.regionParams[4].isWritable = true;
291 // Const Data - IN
292 params.regionParams[5].presRegion = const_cast<PMOS_RESOURCE>(GetBrcConstantBuffer());
293 // PAK MMIO - IN
294 params.regionParams[7].presRegion = const_cast<PMOS_RESOURCE>(&m_brcBuffers.resBrcBitstreamSizeBuffer);
295
296 return MOS_STATUS_SUCCESS;
297 }
298
SetDmemForUpdate(void * params,bool isFirstPass) const299 MOS_STATUS Vp9EncodeBrc::SetDmemForUpdate(void *params, bool isFirstPass) const
300 {
301 ENCODE_FUNC_CALL();
302 ENCODE_CHK_NULL_RETURN(params);
303
304 auto dmem = (HucBrcUpdateDmem *)params;
305
306 const CODEC_VP9_ENCODE_SEQUENCE_PARAMS *vp9SeqParams = m_basicFeature->m_vp9SeqParams;
307 const CODEC_VP9_ENCODE_PIC_PARAMS * vp9PicParams = m_basicFeature->m_vp9PicParams;
308
309 // BRC update setting
310 if (m_curTargetFullness > vp9SeqParams->VBVBufferSizeInBit)
311 {
312 dmem->UPD_OVERFLOW_FLAG_U8 = 0x1;
313 m_curTargetFullness -= vp9SeqParams->VBVBufferSizeInBit;
314 }
315 // We only set target fullness on first BRC pass
316 if (isFirstPass)
317 {
318 dmem->UPD_TARGET_BUF_FULLNESS_U32 = (int32_t)m_curTargetFullness;
319 }
320
321 dmem->UPD_FRAMENUM_U32 = m_basicFeature->m_frameNum;
322 dmem->UPD_Temporal_Level_U8 = vp9PicParams->temporal_id;
323 dmem->UPD_HRD_BUFF_FULLNESS_UPPER_I32 = vp9SeqParams->UpperVBVBufferLevelThresholdInBit;
324 dmem->UPD_HRD_BUFF_FULLNESS_LOWER_I32 = vp9SeqParams->LowerVBVBufferLevelThresholdInBit;
325
326 // Frame info.
327 dmem->UPD_CurWidth_U16 = (uint16_t)m_basicFeature->m_frameWidth;
328 dmem->UPD_CurHeight_U16 = (uint16_t)m_basicFeature->m_frameHeight;
329 dmem->UPD_CurrFrameType_U8 = (m_basicFeature->m_pictureCodingType == I_TYPE) ? 2 : 0;
330
331 // Offsets
332 dmem->UPD_VDEncImgStateOffset = m_basicFeature->m_slbbImgStateOffset;
333 dmem->UPD_SLBBSize = m_basicFeature->m_hucSlbbSize;
334 dmem->UPD_PicStateOffset = m_basicFeature->m_hucPicStateOffset;
335
336 // Thresholds not programmed by driver currently
337
338 // Global adjust settings not programmed by driver currently.
339
340 // QP's
341 dmem->UPD_ACQQp_U8 = vp9PicParams->LumaACQIndex;
342
343 // We increment by the average frame value once for each frame
344 if (isFirstPass)
345 {
346 m_curTargetFullness += m_inputBitsPerFrame;
347 }
348
349 return MOS_STATUS_SUCCESS;
350 }
351
SetDmemForInit(void * params) const352 MOS_STATUS Vp9EncodeBrc::SetDmemForInit(void *params) const
353 {
354 ENCODE_FUNC_CALL();
355 ENCODE_CHK_NULL_RETURN(params);
356
357 auto dmem = (HucBrcInitDmem *)params;
358
359 const CODEC_VP9_ENCODE_SEQUENCE_PARAMS *vp9SeqParams = m_basicFeature->m_vp9SeqParams;
360
361 dmem->BRCFunc = IsBrcInit() ? 0 : 2; // 0 for init, 2 for reset
362 dmem->ProfileLevelMaxFrame = m_basicFeature->GetProfileLevelMaxFrameSize();
363 dmem->InitBufFullness = vp9SeqParams->InitVBVBufferFullnessInBit;
364 dmem->BufSize = vp9SeqParams->VBVBufferSizeInBit;
365
366 dmem->TargetBitrate = vp9SeqParams->TargetBitRate[vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS;
367 dmem->MaxRate = vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS;
368
369 ENCODE_CHK_STATUS_RETURN(SetBrcSettings(dmem));
370
371 m_inputBitsPerFrame = ((vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS) * 100.) / ((vp9SeqParams->FrameRate[vp9SeqParams->NumTemporalLayersMinus1].uiNumerator * 100.) / vp9SeqParams->FrameRate[vp9SeqParams->NumTemporalLayersMinus1].uiDenominator);
372 m_curTargetFullness = vp9SeqParams->TargetBitRate[vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS;
373
374 // lets allow huc to calculate it
375 dmem->GoldenFrameInterval = 0;
376
377 return MOS_STATUS_SUCCESS;
378 }
379
GetHucBrcBuffers(HucBrcBuffers * & buffers)380 MOS_STATUS Vp9EncodeBrc::GetHucBrcBuffers(HucBrcBuffers *&buffers)
381 {
382 ENCODE_FUNC_CALL();
383
384 buffers = &m_brcBuffers;
385
386 return MOS_STATUS_SUCCESS;
387 }
388
GetBrcHistoryBufferSize(uint32_t & size)389 MOS_STATUS Vp9EncodeBrc::GetBrcHistoryBufferSize(uint32_t &size)
390 {
391 ENCODE_FUNC_CALL();
392
393 size = m_brcHistoryBufferSize;
394
395 return MOS_STATUS_SUCCESS;
396 }
397
GetVdencBrcStatsBufferSize(uint32_t & size)398 MOS_STATUS Vp9EncodeBrc::GetVdencBrcStatsBufferSize(uint32_t &size)
399 {
400 ENCODE_FUNC_CALL();
401
402 size = m_vdencBrcStatsBufferSize;
403
404 return MOS_STATUS_SUCCESS;
405 }
406
GetVdencBrcPakStatsBufferSize(uint32_t & size)407 MOS_STATUS Vp9EncodeBrc::GetVdencBrcPakStatsBufferSize(uint32_t &size)
408 {
409 ENCODE_FUNC_CALL();
410
411 size = m_vdencBrcPakStatsBufferSize;
412
413 return MOS_STATUS_SUCCESS;
414 }
415
AllocateResources()416 MOS_STATUS Vp9EncodeBrc::AllocateResources()
417 {
418 ENCODE_FUNC_CALL();
419 MOS_RESOURCE *allocatedBuffer = nullptr;
420
421 ENCODE_CHK_NULL_RETURN(m_allocator);
422 ENCODE_CHK_NULL_RETURN(m_basicFeature);
423 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_recycleBuf);
424 ENCODE_CHK_NULL_RETURN(m_hwInterface);
425 ENCODE_CHK_NULL_RETURN(m_hwInterface->GetOsInterface());
426
427 // Initiate allocation parameters
428 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
429 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
430 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
431 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
432 allocParamsForBufferLinear.Format = Format_Buffer;
433
434 // VDENC BRC statistics buffer
435 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_basicFeature->m_maxTileNumber * m_vdencBrcStatsBufferSize, CODECHAL_PAGE_SIZE);
436 allocParamsForBufferLinear.pBufName = "VDENC BRC Statistics Buffer";
437 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
438 m_basicFeature->m_recycleBuf->RegisterResource(VdencStatsBuffer, allocParamsForBufferLinear, 1);
439
440 // Allocate frame statistics stream out data destination buffer
441 uint32_t size = MOS_ALIGN_CEIL(m_vdencBrcPakStatsBufferSize, CODECHAL_PAGE_SIZE); // Align to page is HuC requirement
442 allocParamsForBufferLinear.dwBytes = size * m_basicFeature->m_maxTileNumber;
443 allocParamsForBufferLinear.pBufName = "FrameStatStreamOutBuffer";
444 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
445 m_basicFeature->m_recycleBuf->RegisterResource(FrameStatStreamOutBuffer, allocParamsForBufferLinear, 1);
446 allocatedBuffer = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0);
447 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
448 m_resFrameStatStreamOutBuffer = *allocatedBuffer;
449
450 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(&m_resFrameStatStreamOutBuffer);
451 ENCODE_CHK_NULL_RETURN(data);
452 MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes);
453 m_allocator->UnLock(&m_resFrameStatStreamOutBuffer);
454
455 // BRC history buffer
456 allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(m_brcHistoryBufferSize, CODECHAL_PAGE_SIZE) : m_brcHistoryBufferSize;
457 allocParamsForBufferLinear.pBufName = "BRC History Buffer";
458 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
459 m_basicFeature->m_recycleBuf->RegisterResource(VdencBRCHistoryBuffer, allocParamsForBufferLinear, 1);
460 allocatedBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencBRCHistoryBuffer, 0);
461 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
462 m_brcBuffers.resBrcHistoryBuffer = *allocatedBuffer;
463
464 // BRC constant data buffer of I/P frame
465 allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(m_brcConstantSurfaceSize, CODECHAL_PAGE_SIZE) : CODECHAL_ENCODE_VP9_BRC_CONSTANTSURFACE_SIZE;
466 allocParamsForBufferLinear.pBufName = "BRC Constant Data Buffer";
467 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_WRITE;
468
469 for (auto i = 0; i < 2; ++i)
470 {
471 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
472 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
473 m_brcBuffers.resBrcConstantDataBuffer[i] = *allocatedBuffer;
474 }
475
476 // PicState BRC read buffer
477 size = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * m_brcMaxNumPasses;
478 allocParamsForBufferLinear.dwBytes = size;
479 allocParamsForBufferLinear.pBufName = "BRC Pic State Read Buffer";
480 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
481 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
482 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
483 m_brcBuffers.resPicStateBrcReadBuffer = *allocatedBuffer;
484
485 data = (uint8_t *)m_allocator->LockResourceForWrite(&m_brcBuffers.resPicStateBrcReadBuffer);
486 ENCODE_CHK_NULL_RETURN(data);
487 MOS_ZeroMemory(data, size);
488 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(&m_brcBuffers.resPicStateBrcReadBuffer));
489
490 // PicState BRC write and HuC read buffers
491 allocParamsForBufferLinear.dwBytes = size;
492 allocParamsForBufferLinear.pBufName = "BRC Pic State Write Buffer";
493 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
494 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
495 m_brcBuffers.resPicStateBrcWriteHucReadBuffer = *allocatedBuffer;
496
497 data = (uint8_t *)m_allocator->LockResourceForWrite(&m_brcBuffers.resPicStateBrcWriteHucReadBuffer);
498 ENCODE_CHK_NULL_RETURN(data);
499 MOS_ZeroMemory(data, size);
500 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(&m_brcBuffers.resPicStateBrcWriteHucReadBuffer));
501
502 // PicState HuC write buffer
503 allocParamsForBufferLinear.dwBytes = size;
504 allocParamsForBufferLinear.pBufName = "BRC Huc Pic State Write Buffer";
505 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
506 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
507 m_brcBuffers.resPicStateHucWriteBuffer = *allocatedBuffer;
508
509 // SegmentState BRC read buffer
510 allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE;
511 allocParamsForBufferLinear.pBufName = "BRC Segment State Read Buffer";
512 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
513 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
514 m_brcBuffers.resSegmentStateBrcReadBuffer = *allocatedBuffer;
515
516 // SegmentState BRC write buffer
517 allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE;
518 allocParamsForBufferLinear.pBufName = "BRC Segment State Write Buffer";
519 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
520 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
521 m_brcBuffers.resSegmentStateBrcWriteBuffer = *allocatedBuffer;
522
523 // BRC bitstream size data buffer
524 allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE, CODECHAL_PAGE_SIZE) : CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE;
525 allocParamsForBufferLinear.pBufName = "BRC Bitstream Size Data buffer";
526 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
527 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
528 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
529 m_brcBuffers.resBrcBitstreamSizeBuffer = *allocatedBuffer;
530
531 // BRC HuC data buffer
532 allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE, CODECHAL_PAGE_SIZE) : CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE;
533 allocParamsForBufferLinear.pBufName = "BRC HuC Data Buffer";
534 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
535 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
536 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
537 m_brcBuffers.resBrcHucDataBuffer = *allocatedBuffer;
538
539 // BRC MSDK buffer
540 allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_BRC_MSDK_PAK_BUFFER_SIZE;
541 allocParamsForBufferLinear.pBufName = "BRC MSDK Buffer";
542 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
543 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
544 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
545 m_brcBuffers.resBrcMsdkPakBuffer = *allocatedBuffer;
546
547 // Huc debug output buffer
548 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(1024 * sizeof(uint32_t), CODECHAL_PAGE_SIZE);
549 allocParamsForBufferLinear.pBufName = "HucDebugOutputBuffer";
550 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
551 m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcDebugBuffer, allocParamsForBufferLinear, 1);
552
553 // Huc VP9 pak mmio buffer
554 allocParamsForBufferLinear.dwBytes = 4 * sizeof(uint32_t);
555 allocParamsForBufferLinear.pBufName = "HucPakMmioBuffer";
556 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
557 m_basicFeature->m_recycleBuf->RegisterResource(VdencBrcPakMmioBuffer, allocParamsForBufferLinear, 1);
558
559 return MOS_STATUS_SUCCESS;
560 }
561
FreeResources()562 MOS_STATUS Vp9EncodeBrc::FreeResources()
563 {
564 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
565
566 ENCODE_FUNC_CALL();
567 ENCODE_CHK_NULL_RETURN(m_hwInterface);
568
569 return eStatus;
570 }
571
GetBrcConstantBuffer() const572 const MOS_RESOURCE* Vp9EncodeBrc::GetBrcConstantBuffer() const
573 {
574 ENCODE_FUNC_CALL();
575
576 uint16_t pictureCodingType = m_basicFeature->m_pictureCodingType;
577 ENCODE_ASSERT(pictureCodingType == I_TYPE || pictureCodingType == P_TYPE);
578
579 return &(m_brcBuffers.resBrcConstantDataBuffer[pictureCodingType - 1]);
580 }
581
InitConstantDataBuffer() const582 MOS_STATUS Vp9EncodeBrc::InitConstantDataBuffer() const
583 {
584 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
585
586 ENCODE_FUNC_CALL();
587 ENCODE_CHK_NULL_RETURN(m_basicFeature);
588
589 if (m_initBrcConstantDataBuffer)
590 return eStatus;
591
592 uint16_t pictureCodingType = m_basicFeature->m_pictureCodingType;
593 ENCODE_ASSERT(pictureCodingType == I_TYPE || pictureCodingType == P_TYPE);
594
595 // I/P frame const data
596 for (auto i = 0; i < 2; ++i)
597 {
598 const PMOS_RESOURCE brcConstDataBuffer = const_cast<PMOS_RESOURCE>(&m_brcBuffers.resBrcConstantDataBuffer[i]);
599 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(brcConstDataBuffer);
600 ENCODE_CHK_NULL_RETURN(data);
601
602 eStatus = MOS_SecureMemcpy(data,
603 sizeof(m_brcConstData[i]),
604 m_brcConstData[i],
605 sizeof(m_brcConstData[i]));
606 if (eStatus != MOS_STATUS_SUCCESS)
607 {
608 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(brcConstDataBuffer));
609 ENCODE_ASSERTMESSAGE("Failed to initialize constant memory buffer.");
610 return eStatus;
611 }
612
613 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(brcConstDataBuffer));
614 }
615
616 const_cast<Vp9EncodeBrc *>(this)->m_initBrcConstantDataBuffer = true;
617
618 return eStatus;
619 }
620
SetBrcSettings(void * params) const621 MOS_STATUS Vp9EncodeBrc::SetBrcSettings(void *params) const
622 {
623 ENCODE_FUNC_CALL();
624 ENCODE_CHK_NULL_RETURN(params);
625 auto dmem = (HucBrcInitDmem *)params;
626
627 const CODEC_VP9_ENCODE_SEQUENCE_PARAMS *vp9SeqParams = m_basicFeature->m_vp9SeqParams;
628
629 FRAME_RATE targetFR = vp9SeqParams->FrameRate[vp9SeqParams->NumTemporalLayersMinus1];
630 dmem->FrameRateM = targetFR.uiNumerator;
631 dmem->FrameRateD = targetFR.uiDenominator;
632
633 switch (vp9SeqParams->RateControlMethod)
634 {
635 case RATECONTROL_CBR:
636 dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISCBR;
637 dmem->MaxRate = dmem->TargetBitrate;
638 break;
639 case RATECONTROL_VBR:
640 dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISVBR;
641 break;
642 case RATECONTROL_AVBR:
643 dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISAVBR;
644 break;
645 case RATECONTROL_CQL:
646 dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISCQL;
647 dmem->LevelQP = vp9SeqParams->ICQQualityFactor;
648 break;
649 default:
650 ENCODE_ASSERTMESSAGE("BRCInit: Invalid rate control provided (%d)", vp9SeqParams->RateControlMethod);
651 return MOS_STATUS_INVALID_PARAMETER;
652 }
653
654 if (dmem->MaxRate < dmem->TargetBitrate)
655 {
656 dmem->MaxRate = 2 * dmem->TargetBitrate;
657 }
658
659 dmem->GopP = vp9SeqParams->GopPicSize - 1;
660 dmem->FrameWidth = (uint16_t)m_basicFeature->m_frameWidth;
661 dmem->FrameHeight = (uint16_t)m_basicFeature->m_frameHeight;
662
663 // Limit 1-255 as the QP range
664 dmem->MinQP = 1;
665 dmem->MaxQP = CODEC_VP9_MAX_QP;
666
667 dmem->EnableScaling = vp9SeqParams->SeqFlags.fields.EnableDynamicScaling;
668
669 for (auto i = 0; i < m_numInstRateThresholds; ++i)
670 {
671 dmem->InstRateThreshI0[i] = m_instRateThresholdI[i];
672 dmem->InstRateThreshP0[i] = m_instRateThresholdP[i];
673 }
674
675 double inputBitsPerFrame = ((double)dmem->MaxRate * (double)dmem->FrameRateD) / (double)dmem->FrameRateM;
676 // Make sure the buffer size can contain at least 4 frames in average
677 if (dmem->BufSize < (uint32_t)(inputBitsPerFrame * 4))
678 {
679 dmem->BufSize = (uint32_t)(inputBitsPerFrame * 4);
680 }
681 // Make sure the initial buffer size is larger than 2 average frames and smaller than the max buffer size.
682 if (dmem->InitBufFullness == 0)
683 {
684 dmem->InitBufFullness = 7 * dmem->BufSize / 8;
685 }
686 if (dmem->InitBufFullness < (uint32_t)(inputBitsPerFrame * 2))
687 {
688 dmem->InitBufFullness = (uint32_t)(inputBitsPerFrame * 2);
689 }
690 if (dmem->InitBufFullness > dmem->BufSize)
691 {
692 dmem->InitBufFullness = dmem->BufSize;
693 }
694
695 double bpsRatio = inputBitsPerFrame / ((double)dmem->BufSize / m_devStdFps);
696 bpsRatio = MOS_CLAMP_MIN_MAX(bpsRatio, m_bpsRatioLow, m_bpsRatioHigh);
697 for (auto i = 0; i < m_numDevThresholds / 2; i++)
698 {
699 dmem->DevThreshPB0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegPB[i], bpsRatio));
700 dmem->DevThreshPB0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosPB[i], bpsRatio));
701
702 dmem->DevThreshI0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegI[i], bpsRatio));
703 dmem->DevThreshI0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosI[i], bpsRatio));
704
705 dmem->DevThreshVBR0[i] = (int8_t)(m_negMultVbr * pow(m_devThresholdVbrNeg[i], bpsRatio));
706 dmem->DevThreshVBR0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultVbr * pow(m_devThresholdVbrPos[i], bpsRatio));
707 }
708
709 int32_t qpI = 0, qpP = 0;
710 ENCODE_CHK_STATUS_RETURN(ComputeVDEncInitQP(qpI, qpP));
711
712 dmem->InitQPI = (uint8_t)qpI;
713 dmem->InitQPP = (uint8_t)qpP;
714
715 dmem->Total_Level = vp9SeqParams->NumTemporalLayersMinus1 + 1;
716 if (dmem->Total_Level > 1)
717 {
718 ENCODE_CHK_STATUS_RETURN(CalculateTemporalRatios(
719 dmem->Total_Level, dmem->TargetBitrate, targetFR, dmem->MaxLevel_Ratio));
720 }
721
722 return MOS_STATUS_SUCCESS;
723 }
724
ComputeVDEncInitQP(int32_t & initQpI,int32_t & initQpP) const725 MOS_STATUS Vp9EncodeBrc::ComputeVDEncInitQP(int32_t &initQpI, int32_t &initQpP) const
726 {
727 ENCODE_FUNC_CALL();
728
729 uint32_t frameSize = ((m_basicFeature->m_frameWidth * m_basicFeature->m_frameHeight * 3) >> 1);
730
731 const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f;
732
733 int32_t qpP = (uint32_t)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)m_basicFeature->m_vp9SeqParams->FrameRate[0].uiNumerator) / ((float)m_basicFeature->m_vp9SeqParams->TargetBitRate[0] * CODECHAL_ENCODE_BRC_KBPS * m_basicFeature->m_vp9SeqParams->FrameRate[0].uiDenominator)) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5);
734 qpP = (int32_t)((float)qpP * (5.0));
735 qpP -= 20;
736 qpP = MOS_CLAMP_MIN_MAX(qpP, 1, 200);
737
738 int32_t qpI = (qpP > 4) ? (qpP - 4) : qpP;
739 uint16_t numP = m_basicFeature->m_vp9SeqParams->GopPicSize - 1;
740 int16_t qiboost = numP / 30 - 1;
741 qiboost = MOS_CLAMP_MIN_MAX(qiboost, 0, 20);
742
743 qpI -= qiboost;
744 qpI = MOS_CLAMP_MIN_MAX(qpI, 1, 200);
745
746 qpP = qpI + 20;
747
748 initQpI = qpI;
749 initQpP = qpP;
750
751 return MOS_STATUS_SUCCESS;
752 }
753
CalculateTemporalRatios(uint16_t numberOfLayers,uint32_t maxTemporalBitrate,FRAME_RATE maxTemporalFrameRate,uint8_t * maxLevelRatios) const754 MOS_STATUS Vp9EncodeBrc::CalculateTemporalRatios(uint16_t numberOfLayers, uint32_t maxTemporalBitrate, FRAME_RATE maxTemporalFrameRate, uint8_t *maxLevelRatios) const
755 {
756 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
757
758 ENCODE_FUNC_CALL();
759
760 ENCODE_CHK_NULL_RETURN(maxLevelRatios);
761
762 CODEC_VP9_ENCODE_SEQUENCE_PARAMS *vp9SeqParams = m_basicFeature->m_vp9SeqParams;
763
764 if (numberOfLayers <= 1)
765 {
766 ENCODE_ASSERTMESSAGE("Need to have multiple temporal layers to calculate ratios");
767 return MOS_STATUS_INVALID_PARAMETER;
768 }
769
770 if (numberOfLayers > CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS)
771 {
772 ENCODE_ASSERTMESSAGE("VP9 VDEnc supports only %d temporal layers (%d provided)",
773 CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS,
774 numberOfLayers);
775 return MOS_STATUS_INVALID_PARAMETER;
776 }
777
778 if (!maxTemporalBitrate || !maxTemporalFrameRate.uiDenominator)
779 {
780 ENCODE_ASSERTMESSAGE("Invalid bitrate or framerate provided to calculate ratios");
781 return MOS_STATUS_INVALID_PARAMETER;
782 }
783
784 // Calculate normalized denominator as least common multiplier of all layers denominators
785 uint32_t normalizedDenominator = 1;
786 normalizedDenominator = CalculateNormalizedDenominator(vp9SeqParams->FrameRate, numberOfLayers, normalizedDenominator);
787
788 // Calculate 0 layer framerate multiplier and apply it
789 FRAME_RATE currentLayerFrameRate = vp9SeqParams->FrameRate[0];
790 uint32_t frameRateMultiplier = normalizedDenominator / currentLayerFrameRate.uiDenominator;
791 currentLayerFrameRate.uiNumerator *= frameRateMultiplier;
792 currentLayerFrameRate.uiDenominator *= frameRateMultiplier;
793
794 uint32_t currentLayerBitrate = vp9SeqParams->TargetBitRate[0] * CODECHAL_ENCODE_BRC_KBPS;
795
796 maxLevelRatios[0] = (currentLayerBitrate << 6) / maxTemporalBitrate *
797 currentLayerFrameRate.uiDenominator / maxTemporalFrameRate.uiDenominator *
798 maxTemporalFrameRate.uiNumerator / currentLayerFrameRate.uiNumerator;
799
800 for (auto i = 1; i < numberOfLayers; ++i)
801 {
802 // From ddi
803 // framerate and bitrate are provided on asceding order
804 // 0 indexed is base player properties (bitrate and framerate)
805 // 1 indexed is first layer properties including layer below (which is base)
806 // so on, every current layer properties values include current and all previous layers properties values
807
808 // Extract actual layer bitrate
809 currentLayerBitrate = vp9SeqParams->TargetBitRate[i] * CODECHAL_ENCODE_BRC_KBPS -
810 vp9SeqParams->TargetBitRate[i - 1] * CODECHAL_ENCODE_BRC_KBPS;
811
812 // Extract actual layer framerate
813 currentLayerFrameRate.uiNumerator = vp9SeqParams->FrameRate[i].uiNumerator * (normalizedDenominator / vp9SeqParams->FrameRate[i].uiDenominator) -
814 vp9SeqParams->FrameRate[i - 1].uiNumerator * (normalizedDenominator / vp9SeqParams->FrameRate[i - 1].uiDenominator);
815 currentLayerFrameRate.uiDenominator = normalizedDenominator;
816
817 // Based on hardware behavior to calculate ratio
818 // current layer bitrate is in unit of 1 / 64
819 // 64 is just a number to represent a range or temporal bitrate for different layers
820 // For ex: 22,22,20 means each layer splits in the ratio of 22/64, 22/64 and 20/64 in terms of bitrate that needs to be achieved
821 maxLevelRatios[i] = (currentLayerBitrate << 6) /
822 maxTemporalBitrate * currentLayerFrameRate.uiDenominator /
823 maxTemporalFrameRate.uiDenominator * maxTemporalFrameRate.uiNumerator /
824 currentLayerFrameRate.uiNumerator;
825 }
826
827 return eStatus;
828 }
829
CalculateNormalizedDenominator(FRAME_RATE * frameRates,uint16_t numberOfLayers,uint32_t normalizedDenominator) const830 uint32_t Vp9EncodeBrc::CalculateNormalizedDenominator(FRAME_RATE *frameRates, uint16_t numberOfLayers, uint32_t normalizedDenominator) const
831 {
832 ENCODE_FUNC_CALL();
833
834 // If pointer to the list of FrameRates is null, return the current Normalized Denominator.
835 if (!frameRates)
836 {
837 return normalizedDenominator;
838 }
839
840 if (numberOfLayers == 0)
841 {
842 return normalizedDenominator;
843 }
844
845 normalizedDenominator = normalizedDenominator * frameRates[numberOfLayers - 1].uiDenominator / MosUtilities::MosGCD(normalizedDenominator, frameRates[numberOfLayers - 1].uiDenominator);
846
847 return CalculateNormalizedDenominator(frameRates, numberOfLayers - 1, normalizedDenominator);
848 }
849
SetSequenceStructs()850 MOS_STATUS Vp9EncodeBrc::SetSequenceStructs()
851 {
852 ENCODE_FUNC_CALL();
853
854 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
855
856 CODEC_VP9_ENCODE_SEQUENCE_PARAMS *vp9SeqParams = m_basicFeature->m_vp9SeqParams;
857 ENCODE_CHK_NULL_RETURN(vp9SeqParams);
858
859 m_brcEnabled = CodecHalIsRateControlBrc(vp9SeqParams->RateControlMethod, CODECHAL_VP9);
860 if (m_brcEnabled)
861 {
862 m_brcReset = vp9SeqParams->SeqFlags.fields.bResetBRC;
863 m_vdencBrcEnabled = true;
864 }
865
866 m_basicFeature->m_tsEnabled = (vp9SeqParams->NumTemporalLayersMinus1 > 0) ? true : false;
867
868 if (m_basicFeature->m_tsEnabled && m_brcEnabled)
869 {
870 // Check base layer properties
871 ENCODE_ASSERT(vp9SeqParams->FrameRate[0].uiNumerator > 0 && vp9SeqParams->FrameRate[0].uiDenominator > 0);
872 ENCODE_ASSERT(vp9SeqParams->TargetBitRate[0] > 0);
873
874 for (auto i = 1; i < (vp9SeqParams->NumTemporalLayersMinus1 + 1); ++i)
875 {
876 // Check current layer properties
877 ENCODE_ASSERT(vp9SeqParams->FrameRate[i].uiNumerator > 0 && vp9SeqParams->FrameRate[i].uiDenominator > 0);
878 ENCODE_ASSERT(vp9SeqParams->TargetBitRate[i] > 0);
879
880 // Check current layer properties are bigger than previous layer (since current includes previous layer properties)
881 ENCODE_ASSERT(vp9SeqParams->FrameRate[i].uiNumerator / vp9SeqParams->FrameRate[i].uiDenominator >
882 vp9SeqParams->FrameRate[i - 1].uiNumerator / vp9SeqParams->FrameRate[i - 1].uiDenominator);
883 ENCODE_ASSERT(vp9SeqParams->TargetBitRate[i] > vp9SeqParams->TargetBitRate[i - 1]);
884 }
885 }
886
887 return eStatus;
888 }
889
MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE,Vp9EncodeBrc)890 MHW_SETPAR_DECL_SRC(HCP_VP9_PIC_STATE, Vp9EncodeBrc)
891 {
892 ENCODE_FUNC_CALL();
893
894 params.sseEnable = m_vdencBrcEnabled;
895
896 return MOS_STATUS_SUCCESS;
897 }
898
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,Vp9EncodeBrc)899 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, Vp9EncodeBrc)
900 {
901 ENCODE_FUNC_CALL();
902
903 ENCODE_CHK_NULL_RETURN(m_basicFeature);
904
905 params.presStreamOutBuffer = nullptr;
906
907 if (!m_basicFeature->m_scalableMode)
908 {
909 params.presVdencStreamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencStatsBuffer, 0);
910 params.dwVdencStatsStreamOutOffset = 0;
911 params.presFrameStatStreamOutBuffer = const_cast<PMOS_RESOURCE>(&m_resFrameStatStreamOutBuffer);
912 params.dwFrameStatStreamOutOffset = 0;
913 }
914
915 return MOS_STATUS_SUCCESS;
916 }
917
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Vp9EncodeBrc)918 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Vp9EncodeBrc)
919 {
920 ENCODE_FUNC_CALL();
921
922 ENCODE_CHK_NULL_RETURN(m_basicFeature);
923
924 if (!m_basicFeature->m_scalableMode)
925 {
926 params.streamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(VdencStatsBuffer, 0);
927 params.streamOutOffset = 0;
928 }
929
930 return MOS_STATUS_SUCCESS;
931 }
932
933 } // namespace encode
934