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 &params) 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