1 /*
2 * Copyright (c) 2017-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 /*
24 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
25 *
26 *  Use of this source code is governed by a BSD-style license
27 *  that can be found in the LICENSE file in the root of the source
28 *  tree. An additional intellectual property rights grant can be found
29 *  in the file PATENTS.  All contributing project authors may
30 *  be found in the AUTHORS file in the root of the source tree.
31 */
32 
33 //!
34 //! \file     codechal_vdenc_vp9_base.cpp
35 //! \brief    Defines base class for VP9 VDENC encoder.
36 //!
37 
38 #include "codechal_vdenc_vp9_base.h"
39 #include "codechal_mmc_encode_vp9.h"
40 #include "codec_def_vp9_probs.h"
41 #include "BRCIF.h"
42 #include "mos_os_cp_interface_specific.h"
43 
44 extern const uint8_t Keyframe_Default_Probs[2048] = {
45     0x64, 0x42, 0x14, 0x98, 0x0f, 0x65, 0x03, 0x88, 0x25, 0x05, 0x34, 0x0d, 0x00, 0x00, 0x00, 0x00,
46     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49     0xc3, 0x1d, 0xb7, 0x54, 0x31, 0x88, 0x08, 0x2a, 0x47, 0x1f, 0x6b, 0xa9, 0x23, 0x63, 0x9f, 0x11,
50     0x52, 0x8c, 0x08, 0x42, 0x72, 0x02, 0x2c, 0x4c, 0x01, 0x13, 0x20, 0x28, 0x84, 0xc9, 0x1d, 0x72,
51     0xbb, 0x0d, 0x5b, 0x9d, 0x07, 0x4b, 0x7f, 0x03, 0x3a, 0x5f, 0x01, 0x1c, 0x2f, 0x45, 0x8e, 0xdd,
52     0x2a, 0x7a, 0xc9, 0x0f, 0x5b, 0x9f, 0x06, 0x43, 0x79, 0x01, 0x2a, 0x4d, 0x01, 0x11, 0x1f, 0x66,
53     0x94, 0xe4, 0x43, 0x75, 0xcc, 0x11, 0x52, 0x9a, 0x06, 0x3b, 0x72, 0x02, 0x27, 0x4b, 0x01, 0x0f,
54     0x1d, 0x9c, 0x39, 0xe9, 0x77, 0x39, 0xd4, 0x3a, 0x30, 0xa3, 0x1d, 0x28, 0x7c, 0x0c, 0x1e, 0x51,
55     0x03, 0x0c, 0x1f, 0xbf, 0x6b, 0xe2, 0x7c, 0x75, 0xcc, 0x19, 0x63, 0x9b, 0x1d, 0x94, 0xd2, 0x25,
56     0x7e, 0xc2, 0x08, 0x5d, 0x9d, 0x02, 0x44, 0x76, 0x01, 0x27, 0x45, 0x01, 0x11, 0x21, 0x29, 0x97,
57     0xd5, 0x1b, 0x7b, 0xc1, 0x03, 0x52, 0x90, 0x01, 0x3a, 0x69, 0x01, 0x20, 0x3c, 0x01, 0x0d, 0x1a,
58     0x3b, 0x9f, 0xdc, 0x17, 0x7e, 0xc6, 0x04, 0x58, 0x97, 0x01, 0x42, 0x72, 0x01, 0x26, 0x47, 0x01,
59     0x12, 0x22, 0x72, 0x88, 0xe8, 0x33, 0x72, 0xcf, 0x0b, 0x53, 0x9b, 0x03, 0x38, 0x69, 0x01, 0x21,
60     0x41, 0x01, 0x11, 0x22, 0x95, 0x41, 0xea, 0x79, 0x39, 0xd7, 0x3d, 0x31, 0xa6, 0x1c, 0x24, 0x72,
61     0x0c, 0x19, 0x4c, 0x03, 0x10, 0x2a, 0xd6, 0x31, 0xdc, 0x84, 0x3f, 0xbc, 0x2a, 0x41, 0x89, 0x55,
62     0x89, 0xdd, 0x68, 0x83, 0xd8, 0x31, 0x6f, 0xc0, 0x15, 0x57, 0x9b, 0x02, 0x31, 0x57, 0x01, 0x10,
63     0x1c, 0x59, 0xa3, 0xe6, 0x5a, 0x89, 0xdc, 0x1d, 0x64, 0xb7, 0x0a, 0x46, 0x87, 0x02, 0x2a, 0x51,
64     0x01, 0x11, 0x21, 0x6c, 0xa7, 0xed, 0x37, 0x85, 0xde, 0x0f, 0x61, 0xb3, 0x04, 0x48, 0x87, 0x01,
65     0x2d, 0x55, 0x01, 0x13, 0x26, 0x7c, 0x92, 0xf0, 0x42, 0x7c, 0xe0, 0x11, 0x58, 0xaf, 0x04, 0x3a,
66     0x7a, 0x01, 0x24, 0x4b, 0x01, 0x12, 0x25, 0x8d, 0x4f, 0xf1, 0x7e, 0x46, 0xe3, 0x42, 0x3a, 0xb6,
67     0x1e, 0x2c, 0x88, 0x0c, 0x22, 0x60, 0x02, 0x14, 0x2f, 0xe5, 0x63, 0xf9, 0x8f, 0x6f, 0xeb, 0x2e,
68     0x6d, 0xc0, 0x52, 0x9e, 0xec, 0x5e, 0x92, 0xe0, 0x19, 0x75, 0xbf, 0x09, 0x57, 0x95, 0x03, 0x38,
69     0x63, 0x01, 0x21, 0x39, 0x53, 0xa7, 0xed, 0x44, 0x91, 0xde, 0x0a, 0x67, 0xb1, 0x02, 0x48, 0x83,
70     0x01, 0x29, 0x4f, 0x01, 0x14, 0x27, 0x63, 0xa7, 0xef, 0x2f, 0x8d, 0xe0, 0x0a, 0x68, 0xb2, 0x02,
71     0x49, 0x85, 0x01, 0x2c, 0x55, 0x01, 0x16, 0x2f, 0x7f, 0x91, 0xf3, 0x47, 0x81, 0xe4, 0x11, 0x5d,
72     0xb1, 0x03, 0x3d, 0x7c, 0x01, 0x29, 0x54, 0x01, 0x15, 0x34, 0x9d, 0x4e, 0xf4, 0x8c, 0x48, 0xe7,
73     0x45, 0x3a, 0xb8, 0x1f, 0x2c, 0x89, 0x0e, 0x26, 0x69, 0x08, 0x17, 0x3d, 0x7d, 0x22, 0xbb, 0x34,
74     0x29, 0x85, 0x06, 0x1f, 0x38, 0x25, 0x6d, 0x99, 0x33, 0x66, 0x93, 0x17, 0x57, 0x80, 0x08, 0x43,
75     0x65, 0x01, 0x29, 0x3f, 0x01, 0x13, 0x1d, 0x1f, 0x9a, 0xb9, 0x11, 0x7f, 0xaf, 0x06, 0x60, 0x91,
76     0x02, 0x49, 0x72, 0x01, 0x33, 0x52, 0x01, 0x1c, 0x2d, 0x17, 0xa3, 0xc8, 0x0a, 0x83, 0xb9, 0x02,
77     0x5d, 0x94, 0x01, 0x43, 0x6f, 0x01, 0x29, 0x45, 0x01, 0x0e, 0x18, 0x1d, 0xb0, 0xd9, 0x0c, 0x91,
78     0xc9, 0x03, 0x65, 0x9c, 0x01, 0x45, 0x6f, 0x01, 0x27, 0x3f, 0x01, 0x0e, 0x17, 0x39, 0xc0, 0xe9,
79     0x19, 0x9a, 0xd7, 0x06, 0x6d, 0xa7, 0x03, 0x4e, 0x76, 0x01, 0x30, 0x45, 0x01, 0x15, 0x1d, 0xca,
80     0x69, 0xf5, 0x6c, 0x6a, 0xd8, 0x12, 0x5a, 0x90, 0x21, 0xac, 0xdb, 0x40, 0x95, 0xce, 0x0e, 0x75,
81     0xb1, 0x05, 0x5a, 0x8d, 0x02, 0x3d, 0x5f, 0x01, 0x25, 0x39, 0x21, 0xb3, 0xdc, 0x0b, 0x8c, 0xc6,
82     0x01, 0x59, 0x94, 0x01, 0x3c, 0x68, 0x01, 0x21, 0x39, 0x01, 0x0c, 0x15, 0x1e, 0xb5, 0xdd, 0x08,
83     0x8d, 0xc6, 0x01, 0x57, 0x91, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x14, 0x20, 0xba,
84     0xe0, 0x07, 0x8e, 0xc6, 0x01, 0x56, 0x8f, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x16,
85     0x39, 0xc0, 0xe3, 0x14, 0x8f, 0xcc, 0x03, 0x60, 0x9a, 0x01, 0x44, 0x70, 0x01, 0x2a, 0x45, 0x01,
86     0x13, 0x20, 0xd4, 0x23, 0xd7, 0x71, 0x2f, 0xa9, 0x1d, 0x30, 0x69, 0x4a, 0x81, 0xcb, 0x6a, 0x78,
87     0xcb, 0x31, 0x6b, 0xb2, 0x13, 0x54, 0x90, 0x04, 0x32, 0x54, 0x01, 0x0f, 0x19, 0x47, 0xac, 0xd9,
88     0x2c, 0x8d, 0xd1, 0x0f, 0x66, 0xad, 0x06, 0x4c, 0x85, 0x02, 0x33, 0x59, 0x01, 0x18, 0x2a, 0x40,
89     0xb9, 0xe7, 0x1f, 0x94, 0xd8, 0x08, 0x67, 0xaf, 0x03, 0x4a, 0x83, 0x01, 0x2e, 0x51, 0x01, 0x12,
90     0x1e, 0x41, 0xc4, 0xeb, 0x19, 0x9d, 0xdd, 0x05, 0x69, 0xae, 0x01, 0x43, 0x78, 0x01, 0x26, 0x45,
91     0x01, 0x0f, 0x1e, 0x41, 0xcc, 0xee, 0x1e, 0x9c, 0xe0, 0x07, 0x6b, 0xb1, 0x02, 0x46, 0x7c, 0x01,
92     0x2a, 0x49, 0x01, 0x12, 0x22, 0xe1, 0x56, 0xfb, 0x90, 0x68, 0xeb, 0x2a, 0x63, 0xb5, 0x55, 0xaf,
93     0xef, 0x70, 0xa5, 0xe5, 0x1d, 0x88, 0xc8, 0x0c, 0x67, 0xa2, 0x06, 0x4d, 0x7b, 0x02, 0x35, 0x54,
94     0x4b, 0xb7, 0xef, 0x1e, 0x9b, 0xdd, 0x03, 0x6a, 0xab, 0x01, 0x4a, 0x80, 0x01, 0x2c, 0x4c, 0x01,
95     0x11, 0x1c, 0x49, 0xb9, 0xf0, 0x1b, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x4b, 0x7f, 0x01, 0x2a,
96     0x49, 0x01, 0x11, 0x1d, 0x3e, 0xbe, 0xee, 0x15, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x48, 0x7a,
97     0x01, 0x28, 0x47, 0x01, 0x12, 0x20, 0x3d, 0xc7, 0xf0, 0x1b, 0xa1, 0xe2, 0x04, 0x71, 0xb4, 0x01,
98     0x4c, 0x81, 0x01, 0x2e, 0x50, 0x01, 0x17, 0x29, 0x07, 0x1b, 0x99, 0x05, 0x1e, 0x5f, 0x01, 0x10,
99     0x1e, 0x32, 0x4b, 0x7f, 0x39, 0x4b, 0x7c, 0x1b, 0x43, 0x6c, 0x0a, 0x36, 0x56, 0x01, 0x21, 0x34,
100     0x01, 0x0c, 0x12, 0x2b, 0x7d, 0x97, 0x1a, 0x6c, 0x94, 0x07, 0x53, 0x7a, 0x02, 0x3b, 0x59, 0x01,
101     0x26, 0x3c, 0x01, 0x11, 0x1b, 0x17, 0x90, 0xa3, 0x0d, 0x70, 0x9a, 0x02, 0x4b, 0x75, 0x01, 0x32,
102     0x51, 0x01, 0x1f, 0x33, 0x01, 0x0e, 0x17, 0x12, 0xa2, 0xb9, 0x06, 0x7b, 0xab, 0x01, 0x4e, 0x7d,
103     0x01, 0x33, 0x56, 0x01, 0x1f, 0x36, 0x01, 0x0e, 0x17, 0x0f, 0xc7, 0xe3, 0x03, 0x96, 0xcc, 0x01,
104     0x5b, 0x92, 0x01, 0x37, 0x5f, 0x01, 0x1e, 0x35, 0x01, 0x0b, 0x14, 0x13, 0x37, 0xf0, 0x13, 0x3b,
105     0xc4, 0x03, 0x34, 0x69, 0x29, 0xa6, 0xcf, 0x68, 0x99, 0xc7, 0x1f, 0x7b, 0xb5, 0x0e, 0x65, 0x98,
106     0x05, 0x48, 0x6a, 0x01, 0x24, 0x34, 0x23, 0xb0, 0xd3, 0x0c, 0x83, 0xbe, 0x02, 0x58, 0x90, 0x01,
107     0x3c, 0x65, 0x01, 0x24, 0x3c, 0x01, 0x10, 0x1c, 0x1c, 0xb7, 0xd5, 0x08, 0x86, 0xbf, 0x01, 0x56,
108     0x8e, 0x01, 0x38, 0x60, 0x01, 0x1e, 0x35, 0x01, 0x0c, 0x14, 0x14, 0xbe, 0xd7, 0x04, 0x87, 0xc0,
109     0x01, 0x54, 0x8b, 0x01, 0x35, 0x5b, 0x01, 0x1c, 0x31, 0x01, 0x0b, 0x14, 0x0d, 0xc4, 0xd8, 0x02,
110     0x89, 0xc0, 0x01, 0x56, 0x8f, 0x01, 0x39, 0x63, 0x01, 0x20, 0x38, 0x01, 0x0d, 0x18, 0xd3, 0x1d,
111     0xd9, 0x60, 0x2f, 0x9c, 0x16, 0x2b, 0x57, 0x4e, 0x78, 0xc1, 0x6f, 0x74, 0xba, 0x2e, 0x66, 0xa4,
112     0x0f, 0x50, 0x80, 0x02, 0x31, 0x4c, 0x01, 0x12, 0x1c, 0x47, 0xa1, 0xcb, 0x2a, 0x84, 0xc0, 0x0a,
113     0x62, 0x96, 0x03, 0x45, 0x6d, 0x01, 0x2c, 0x46, 0x01, 0x12, 0x1d, 0x39, 0xba, 0xd3, 0x1e, 0x8c,
114     0xc4, 0x04, 0x5d, 0x92, 0x01, 0x3e, 0x66, 0x01, 0x26, 0x41, 0x01, 0x10, 0x1b, 0x2f, 0xc7, 0xd9,
115     0x0e, 0x91, 0xc4, 0x01, 0x58, 0x8e, 0x01, 0x39, 0x62, 0x01, 0x24, 0x3e, 0x01, 0x0f, 0x1a, 0x1a,
116     0xdb, 0xe5, 0x05, 0x9b, 0xcf, 0x01, 0x5e, 0x97, 0x01, 0x3c, 0x68, 0x01, 0x24, 0x3e, 0x01, 0x10,
117     0x1c, 0xe9, 0x1d, 0xf8, 0x92, 0x2f, 0xdc, 0x2b, 0x34, 0x8c, 0x64, 0xa3, 0xe8, 0xb3, 0xa1, 0xde,
118     0x3f, 0x8e, 0xcc, 0x25, 0x71, 0xae, 0x1a, 0x59, 0x89, 0x12, 0x44, 0x61, 0x55, 0xb5, 0xe6, 0x20,
119     0x92, 0xd1, 0x07, 0x64, 0xa4, 0x03, 0x47, 0x79, 0x01, 0x2d, 0x4d, 0x01, 0x12, 0x1e, 0x41, 0xbb,
120     0xe6, 0x14, 0x94, 0xcf, 0x02, 0x61, 0x9f, 0x01, 0x44, 0x74, 0x01, 0x28, 0x46, 0x01, 0x0e, 0x1d,
121     0x28, 0xc2, 0xe3, 0x08, 0x93, 0xcc, 0x01, 0x5e, 0x9b, 0x01, 0x41, 0x70, 0x01, 0x27, 0x42, 0x01,
122     0x0e, 0x1a, 0x10, 0xd0, 0xe4, 0x03, 0x97, 0xcf, 0x01, 0x62, 0xa0, 0x01, 0x43, 0x75, 0x01, 0x29,
123     0x4a, 0x01, 0x11, 0x1f, 0x11, 0x26, 0x8c, 0x07, 0x22, 0x50, 0x01, 0x11, 0x1d, 0x25, 0x4b, 0x80,
124     0x29, 0x4c, 0x80, 0x1a, 0x42, 0x74, 0x0c, 0x34, 0x5e, 0x02, 0x20, 0x37, 0x01, 0x0a, 0x10, 0x32,
125     0x7f, 0x9a, 0x25, 0x6d, 0x98, 0x10, 0x52, 0x79, 0x05, 0x3b, 0x55, 0x01, 0x23, 0x36, 0x01, 0x0d,
126     0x14, 0x28, 0x8e, 0xa7, 0x11, 0x6e, 0x9d, 0x02, 0x47, 0x70, 0x01, 0x2c, 0x48, 0x01, 0x1b, 0x2d,
127     0x01, 0x0b, 0x11, 0x1e, 0xaf, 0xbc, 0x09, 0x7c, 0xa9, 0x01, 0x4a, 0x74, 0x01, 0x30, 0x4e, 0x01,
128     0x1e, 0x31, 0x01, 0x0b, 0x12, 0x0a, 0xde, 0xdf, 0x02, 0x96, 0xc2, 0x01, 0x53, 0x80, 0x01, 0x30,
129     0x4f, 0x01, 0x1b, 0x2d, 0x01, 0x0b, 0x11, 0x24, 0x29, 0xeb, 0x1d, 0x24, 0xc1, 0x0a, 0x1b, 0x6f,
130     0x55, 0xa5, 0xde, 0xb1, 0xa2, 0xd7, 0x6e, 0x87, 0xc3, 0x39, 0x71, 0xa8, 0x17, 0x53, 0x78, 0x0a,
131     0x31, 0x3d, 0x55, 0xbe, 0xdf, 0x24, 0x8b, 0xc8, 0x05, 0x5a, 0x92, 0x01, 0x3c, 0x67, 0x01, 0x26,
132     0x41, 0x01, 0x12, 0x1e, 0x48, 0xca, 0xdf, 0x17, 0x8d, 0xc7, 0x02, 0x56, 0x8c, 0x01, 0x38, 0x61,
133     0x01, 0x24, 0x3d, 0x01, 0x10, 0x1b, 0x37, 0xda, 0xe1, 0x0d, 0x91, 0xc8, 0x01, 0x56, 0x8d, 0x01,
134     0x39, 0x63, 0x01, 0x23, 0x3d, 0x01, 0x0d, 0x16, 0x0f, 0xeb, 0xd4, 0x01, 0x84, 0xb8, 0x01, 0x54,
135     0x8b, 0x01, 0x39, 0x61, 0x01, 0x22, 0x38, 0x01, 0x0e, 0x17, 0xb5, 0x15, 0xc9, 0x3d, 0x25, 0x7b,
136     0x0a, 0x26, 0x47, 0x2f, 0x6a, 0xac, 0x5f, 0x68, 0xad, 0x2a, 0x5d, 0x9f, 0x12, 0x4d, 0x83, 0x04,
137     0x32, 0x51, 0x01, 0x11, 0x17, 0x3e, 0x93, 0xc7, 0x2c, 0x82, 0xbd, 0x1c, 0x66, 0x9a, 0x12, 0x4b,
138     0x73, 0x02, 0x2c, 0x41, 0x01, 0x0c, 0x13, 0x37, 0x99, 0xd2, 0x18, 0x82, 0xc2, 0x03, 0x5d, 0x92,
139     0x01, 0x3d, 0x61, 0x01, 0x1f, 0x32, 0x01, 0x0a, 0x10, 0x31, 0xba, 0xdf, 0x11, 0x94, 0xcc, 0x01,
140     0x60, 0x8e, 0x01, 0x35, 0x53, 0x01, 0x1a, 0x2c, 0x01, 0x0b, 0x11, 0x0d, 0xd9, 0xd4, 0x02, 0x88,
141     0xb4, 0x01, 0x4e, 0x7c, 0x01, 0x32, 0x53, 0x01, 0x1d, 0x31, 0x01, 0x0e, 0x17, 0xc5, 0x0d, 0xf7,
142     0x52, 0x11, 0xde, 0x19, 0x11, 0xa2, 0x7e, 0xba, 0xf7, 0xea, 0xbf, 0xf3, 0xb0, 0xb1, 0xea, 0x68,
143     0x9e, 0xdc, 0x42, 0x80, 0xba, 0x37, 0x5a, 0x89, 0x6f, 0xc5, 0xf2, 0x2e, 0x9e, 0xdb, 0x09, 0x68,
144     0xab, 0x02, 0x41, 0x7d, 0x01, 0x2c, 0x50, 0x01, 0x11, 0x5b, 0x68, 0xd0, 0xf5, 0x27, 0xa8, 0xe0,
145     0x03, 0x6d, 0xa2, 0x01, 0x4f, 0x7c, 0x01, 0x32, 0x66, 0x01, 0x2b, 0x66, 0x54, 0xdc, 0xf6, 0x1f,
146     0xb1, 0xe7, 0x02, 0x73, 0xb4, 0x01, 0x4f, 0x86, 0x01, 0x37, 0x4d, 0x01, 0x3c, 0x4f, 0x2b, 0xf3,
147     0xf0, 0x08, 0xb4, 0xd9, 0x01, 0x73, 0xa6, 0x01, 0x54, 0x79, 0x01, 0x33, 0x43, 0x01, 0x10, 0x06,
148     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149     0xc0, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x61, 0x5e, 0x5d,
155     0x18, 0x63, 0x55, 0x77, 0x2c, 0x3e, 0x3b, 0x43, 0x95, 0x35, 0x35, 0x5e, 0x14, 0x30, 0x53, 0x35,
156     0x18, 0x34, 0x12, 0x12, 0x96, 0x28, 0x27, 0x4e, 0x0c, 0x1a, 0x43, 0x21, 0x0b, 0x18, 0x07, 0x05,
157     0xae, 0x23, 0x31, 0x44, 0x0b, 0x1b, 0x39, 0x0f, 0x09, 0x0c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
158     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165     0x90, 0x0b, 0x36, 0x9d, 0xc3, 0x82, 0x2e, 0x3a, 0x6c, 0x76, 0x0f, 0x7b, 0x94, 0x83, 0x65, 0x2c,
166     0x5d, 0x83, 0x71, 0x0c, 0x17, 0xbc, 0xe2, 0x8e, 0x1a, 0x20, 0x7d, 0x78, 0x0b, 0x32, 0x7b, 0xa3,
167     0x87, 0x40, 0x4d, 0x67, 0x71, 0x09, 0x24, 0x9b, 0x6f, 0x9d, 0x20, 0x2c, 0xa1, 0x74, 0x09, 0x37,
168     0xb0, 0x4c, 0x60, 0x25, 0x3d, 0x95, 0x73, 0x09, 0x1c, 0x8d, 0xa1, 0xa7, 0x15, 0x19, 0xc1, 0x78,
169     0x0c, 0x20, 0x91, 0xc3, 0x8e, 0x20, 0x26, 0x56, 0x74, 0x0c, 0x40, 0x78, 0x8c, 0x7d, 0x31, 0x73,
170     0x79, 0x66, 0x13, 0x42, 0xa2, 0xb6, 0x7a, 0x23, 0x3b, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
171     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
173 };
174 
175 extern const uint8_t Inter_Default_Probs[2048] = {
176     0x64, 0x42, 0x14, 0x98, 0x0f, 0x65, 0x03, 0x88, 0x25, 0x05, 0x34, 0x0d, 0x00, 0x00, 0x00, 0x00,
177     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180     0xc3, 0x1d, 0xb7, 0x54, 0x31, 0x88, 0x08, 0x2a, 0x47, 0x1f, 0x6b, 0xa9, 0x23, 0x63, 0x9f, 0x11,
181     0x52, 0x8c, 0x08, 0x42, 0x72, 0x02, 0x2c, 0x4c, 0x01, 0x13, 0x20, 0x28, 0x84, 0xc9, 0x1d, 0x72,
182     0xbb, 0x0d, 0x5b, 0x9d, 0x07, 0x4b, 0x7f, 0x03, 0x3a, 0x5f, 0x01, 0x1c, 0x2f, 0x45, 0x8e, 0xdd,
183     0x2a, 0x7a, 0xc9, 0x0f, 0x5b, 0x9f, 0x06, 0x43, 0x79, 0x01, 0x2a, 0x4d, 0x01, 0x11, 0x1f, 0x66,
184     0x94, 0xe4, 0x43, 0x75, 0xcc, 0x11, 0x52, 0x9a, 0x06, 0x3b, 0x72, 0x02, 0x27, 0x4b, 0x01, 0x0f,
185     0x1d, 0x9c, 0x39, 0xe9, 0x77, 0x39, 0xd4, 0x3a, 0x30, 0xa3, 0x1d, 0x28, 0x7c, 0x0c, 0x1e, 0x51,
186     0x03, 0x0c, 0x1f, 0xbf, 0x6b, 0xe2, 0x7c, 0x75, 0xcc, 0x19, 0x63, 0x9b, 0x1d, 0x94, 0xd2, 0x25,
187     0x7e, 0xc2, 0x08, 0x5d, 0x9d, 0x02, 0x44, 0x76, 0x01, 0x27, 0x45, 0x01, 0x11, 0x21, 0x29, 0x97,
188     0xd5, 0x1b, 0x7b, 0xc1, 0x03, 0x52, 0x90, 0x01, 0x3a, 0x69, 0x01, 0x20, 0x3c, 0x01, 0x0d, 0x1a,
189     0x3b, 0x9f, 0xdc, 0x17, 0x7e, 0xc6, 0x04, 0x58, 0x97, 0x01, 0x42, 0x72, 0x01, 0x26, 0x47, 0x01,
190     0x12, 0x22, 0x72, 0x88, 0xe8, 0x33, 0x72, 0xcf, 0x0b, 0x53, 0x9b, 0x03, 0x38, 0x69, 0x01, 0x21,
191     0x41, 0x01, 0x11, 0x22, 0x95, 0x41, 0xea, 0x79, 0x39, 0xd7, 0x3d, 0x31, 0xa6, 0x1c, 0x24, 0x72,
192     0x0c, 0x19, 0x4c, 0x03, 0x10, 0x2a, 0xd6, 0x31, 0xdc, 0x84, 0x3f, 0xbc, 0x2a, 0x41, 0x89, 0x55,
193     0x89, 0xdd, 0x68, 0x83, 0xd8, 0x31, 0x6f, 0xc0, 0x15, 0x57, 0x9b, 0x02, 0x31, 0x57, 0x01, 0x10,
194     0x1c, 0x59, 0xa3, 0xe6, 0x5a, 0x89, 0xdc, 0x1d, 0x64, 0xb7, 0x0a, 0x46, 0x87, 0x02, 0x2a, 0x51,
195     0x01, 0x11, 0x21, 0x6c, 0xa7, 0xed, 0x37, 0x85, 0xde, 0x0f, 0x61, 0xb3, 0x04, 0x48, 0x87, 0x01,
196     0x2d, 0x55, 0x01, 0x13, 0x26, 0x7c, 0x92, 0xf0, 0x42, 0x7c, 0xe0, 0x11, 0x58, 0xaf, 0x04, 0x3a,
197     0x7a, 0x01, 0x24, 0x4b, 0x01, 0x12, 0x25, 0x8d, 0x4f, 0xf1, 0x7e, 0x46, 0xe3, 0x42, 0x3a, 0xb6,
198     0x1e, 0x2c, 0x88, 0x0c, 0x22, 0x60, 0x02, 0x14, 0x2f, 0xe5, 0x63, 0xf9, 0x8f, 0x6f, 0xeb, 0x2e,
199     0x6d, 0xc0, 0x52, 0x9e, 0xec, 0x5e, 0x92, 0xe0, 0x19, 0x75, 0xbf, 0x09, 0x57, 0x95, 0x03, 0x38,
200     0x63, 0x01, 0x21, 0x39, 0x53, 0xa7, 0xed, 0x44, 0x91, 0xde, 0x0a, 0x67, 0xb1, 0x02, 0x48, 0x83,
201     0x01, 0x29, 0x4f, 0x01, 0x14, 0x27, 0x63, 0xa7, 0xef, 0x2f, 0x8d, 0xe0, 0x0a, 0x68, 0xb2, 0x02,
202     0x49, 0x85, 0x01, 0x2c, 0x55, 0x01, 0x16, 0x2f, 0x7f, 0x91, 0xf3, 0x47, 0x81, 0xe4, 0x11, 0x5d,
203     0xb1, 0x03, 0x3d, 0x7c, 0x01, 0x29, 0x54, 0x01, 0x15, 0x34, 0x9d, 0x4e, 0xf4, 0x8c, 0x48, 0xe7,
204     0x45, 0x3a, 0xb8, 0x1f, 0x2c, 0x89, 0x0e, 0x26, 0x69, 0x08, 0x17, 0x3d, 0x7d, 0x22, 0xbb, 0x34,
205     0x29, 0x85, 0x06, 0x1f, 0x38, 0x25, 0x6d, 0x99, 0x33, 0x66, 0x93, 0x17, 0x57, 0x80, 0x08, 0x43,
206     0x65, 0x01, 0x29, 0x3f, 0x01, 0x13, 0x1d, 0x1f, 0x9a, 0xb9, 0x11, 0x7f, 0xaf, 0x06, 0x60, 0x91,
207     0x02, 0x49, 0x72, 0x01, 0x33, 0x52, 0x01, 0x1c, 0x2d, 0x17, 0xa3, 0xc8, 0x0a, 0x83, 0xb9, 0x02,
208     0x5d, 0x94, 0x01, 0x43, 0x6f, 0x01, 0x29, 0x45, 0x01, 0x0e, 0x18, 0x1d, 0xb0, 0xd9, 0x0c, 0x91,
209     0xc9, 0x03, 0x65, 0x9c, 0x01, 0x45, 0x6f, 0x01, 0x27, 0x3f, 0x01, 0x0e, 0x17, 0x39, 0xc0, 0xe9,
210     0x19, 0x9a, 0xd7, 0x06, 0x6d, 0xa7, 0x03, 0x4e, 0x76, 0x01, 0x30, 0x45, 0x01, 0x15, 0x1d, 0xca,
211     0x69, 0xf5, 0x6c, 0x6a, 0xd8, 0x12, 0x5a, 0x90, 0x21, 0xac, 0xdb, 0x40, 0x95, 0xce, 0x0e, 0x75,
212     0xb1, 0x05, 0x5a, 0x8d, 0x02, 0x3d, 0x5f, 0x01, 0x25, 0x39, 0x21, 0xb3, 0xdc, 0x0b, 0x8c, 0xc6,
213     0x01, 0x59, 0x94, 0x01, 0x3c, 0x68, 0x01, 0x21, 0x39, 0x01, 0x0c, 0x15, 0x1e, 0xb5, 0xdd, 0x08,
214     0x8d, 0xc6, 0x01, 0x57, 0x91, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x14, 0x20, 0xba,
215     0xe0, 0x07, 0x8e, 0xc6, 0x01, 0x56, 0x8f, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x16,
216     0x39, 0xc0, 0xe3, 0x14, 0x8f, 0xcc, 0x03, 0x60, 0x9a, 0x01, 0x44, 0x70, 0x01, 0x2a, 0x45, 0x01,
217     0x13, 0x20, 0xd4, 0x23, 0xd7, 0x71, 0x2f, 0xa9, 0x1d, 0x30, 0x69, 0x4a, 0x81, 0xcb, 0x6a, 0x78,
218     0xcb, 0x31, 0x6b, 0xb2, 0x13, 0x54, 0x90, 0x04, 0x32, 0x54, 0x01, 0x0f, 0x19, 0x47, 0xac, 0xd9,
219     0x2c, 0x8d, 0xd1, 0x0f, 0x66, 0xad, 0x06, 0x4c, 0x85, 0x02, 0x33, 0x59, 0x01, 0x18, 0x2a, 0x40,
220     0xb9, 0xe7, 0x1f, 0x94, 0xd8, 0x08, 0x67, 0xaf, 0x03, 0x4a, 0x83, 0x01, 0x2e, 0x51, 0x01, 0x12,
221     0x1e, 0x41, 0xc4, 0xeb, 0x19, 0x9d, 0xdd, 0x05, 0x69, 0xae, 0x01, 0x43, 0x78, 0x01, 0x26, 0x45,
222     0x01, 0x0f, 0x1e, 0x41, 0xcc, 0xee, 0x1e, 0x9c, 0xe0, 0x07, 0x6b, 0xb1, 0x02, 0x46, 0x7c, 0x01,
223     0x2a, 0x49, 0x01, 0x12, 0x22, 0xe1, 0x56, 0xfb, 0x90, 0x68, 0xeb, 0x2a, 0x63, 0xb5, 0x55, 0xaf,
224     0xef, 0x70, 0xa5, 0xe5, 0x1d, 0x88, 0xc8, 0x0c, 0x67, 0xa2, 0x06, 0x4d, 0x7b, 0x02, 0x35, 0x54,
225     0x4b, 0xb7, 0xef, 0x1e, 0x9b, 0xdd, 0x03, 0x6a, 0xab, 0x01, 0x4a, 0x80, 0x01, 0x2c, 0x4c, 0x01,
226     0x11, 0x1c, 0x49, 0xb9, 0xf0, 0x1b, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x4b, 0x7f, 0x01, 0x2a,
227     0x49, 0x01, 0x11, 0x1d, 0x3e, 0xbe, 0xee, 0x15, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x48, 0x7a,
228     0x01, 0x28, 0x47, 0x01, 0x12, 0x20, 0x3d, 0xc7, 0xf0, 0x1b, 0xa1, 0xe2, 0x04, 0x71, 0xb4, 0x01,
229     0x4c, 0x81, 0x01, 0x2e, 0x50, 0x01, 0x17, 0x29, 0x07, 0x1b, 0x99, 0x05, 0x1e, 0x5f, 0x01, 0x10,
230     0x1e, 0x32, 0x4b, 0x7f, 0x39, 0x4b, 0x7c, 0x1b, 0x43, 0x6c, 0x0a, 0x36, 0x56, 0x01, 0x21, 0x34,
231     0x01, 0x0c, 0x12, 0x2b, 0x7d, 0x97, 0x1a, 0x6c, 0x94, 0x07, 0x53, 0x7a, 0x02, 0x3b, 0x59, 0x01,
232     0x26, 0x3c, 0x01, 0x11, 0x1b, 0x17, 0x90, 0xa3, 0x0d, 0x70, 0x9a, 0x02, 0x4b, 0x75, 0x01, 0x32,
233     0x51, 0x01, 0x1f, 0x33, 0x01, 0x0e, 0x17, 0x12, 0xa2, 0xb9, 0x06, 0x7b, 0xab, 0x01, 0x4e, 0x7d,
234     0x01, 0x33, 0x56, 0x01, 0x1f, 0x36, 0x01, 0x0e, 0x17, 0x0f, 0xc7, 0xe3, 0x03, 0x96, 0xcc, 0x01,
235     0x5b, 0x92, 0x01, 0x37, 0x5f, 0x01, 0x1e, 0x35, 0x01, 0x0b, 0x14, 0x13, 0x37, 0xf0, 0x13, 0x3b,
236     0xc4, 0x03, 0x34, 0x69, 0x29, 0xa6, 0xcf, 0x68, 0x99, 0xc7, 0x1f, 0x7b, 0xb5, 0x0e, 0x65, 0x98,
237     0x05, 0x48, 0x6a, 0x01, 0x24, 0x34, 0x23, 0xb0, 0xd3, 0x0c, 0x83, 0xbe, 0x02, 0x58, 0x90, 0x01,
238     0x3c, 0x65, 0x01, 0x24, 0x3c, 0x01, 0x10, 0x1c, 0x1c, 0xb7, 0xd5, 0x08, 0x86, 0xbf, 0x01, 0x56,
239     0x8e, 0x01, 0x38, 0x60, 0x01, 0x1e, 0x35, 0x01, 0x0c, 0x14, 0x14, 0xbe, 0xd7, 0x04, 0x87, 0xc0,
240     0x01, 0x54, 0x8b, 0x01, 0x35, 0x5b, 0x01, 0x1c, 0x31, 0x01, 0x0b, 0x14, 0x0d, 0xc4, 0xd8, 0x02,
241     0x89, 0xc0, 0x01, 0x56, 0x8f, 0x01, 0x39, 0x63, 0x01, 0x20, 0x38, 0x01, 0x0d, 0x18, 0xd3, 0x1d,
242     0xd9, 0x60, 0x2f, 0x9c, 0x16, 0x2b, 0x57, 0x4e, 0x78, 0xc1, 0x6f, 0x74, 0xba, 0x2e, 0x66, 0xa4,
243     0x0f, 0x50, 0x80, 0x02, 0x31, 0x4c, 0x01, 0x12, 0x1c, 0x47, 0xa1, 0xcb, 0x2a, 0x84, 0xc0, 0x0a,
244     0x62, 0x96, 0x03, 0x45, 0x6d, 0x01, 0x2c, 0x46, 0x01, 0x12, 0x1d, 0x39, 0xba, 0xd3, 0x1e, 0x8c,
245     0xc4, 0x04, 0x5d, 0x92, 0x01, 0x3e, 0x66, 0x01, 0x26, 0x41, 0x01, 0x10, 0x1b, 0x2f, 0xc7, 0xd9,
246     0x0e, 0x91, 0xc4, 0x01, 0x58, 0x8e, 0x01, 0x39, 0x62, 0x01, 0x24, 0x3e, 0x01, 0x0f, 0x1a, 0x1a,
247     0xdb, 0xe5, 0x05, 0x9b, 0xcf, 0x01, 0x5e, 0x97, 0x01, 0x3c, 0x68, 0x01, 0x24, 0x3e, 0x01, 0x10,
248     0x1c, 0xe9, 0x1d, 0xf8, 0x92, 0x2f, 0xdc, 0x2b, 0x34, 0x8c, 0x64, 0xa3, 0xe8, 0xb3, 0xa1, 0xde,
249     0x3f, 0x8e, 0xcc, 0x25, 0x71, 0xae, 0x1a, 0x59, 0x89, 0x12, 0x44, 0x61, 0x55, 0xb5, 0xe6, 0x20,
250     0x92, 0xd1, 0x07, 0x64, 0xa4, 0x03, 0x47, 0x79, 0x01, 0x2d, 0x4d, 0x01, 0x12, 0x1e, 0x41, 0xbb,
251     0xe6, 0x14, 0x94, 0xcf, 0x02, 0x61, 0x9f, 0x01, 0x44, 0x74, 0x01, 0x28, 0x46, 0x01, 0x0e, 0x1d,
252     0x28, 0xc2, 0xe3, 0x08, 0x93, 0xcc, 0x01, 0x5e, 0x9b, 0x01, 0x41, 0x70, 0x01, 0x27, 0x42, 0x01,
253     0x0e, 0x1a, 0x10, 0xd0, 0xe4, 0x03, 0x97, 0xcf, 0x01, 0x62, 0xa0, 0x01, 0x43, 0x75, 0x01, 0x29,
254     0x4a, 0x01, 0x11, 0x1f, 0x11, 0x26, 0x8c, 0x07, 0x22, 0x50, 0x01, 0x11, 0x1d, 0x25, 0x4b, 0x80,
255     0x29, 0x4c, 0x80, 0x1a, 0x42, 0x74, 0x0c, 0x34, 0x5e, 0x02, 0x20, 0x37, 0x01, 0x0a, 0x10, 0x32,
256     0x7f, 0x9a, 0x25, 0x6d, 0x98, 0x10, 0x52, 0x79, 0x05, 0x3b, 0x55, 0x01, 0x23, 0x36, 0x01, 0x0d,
257     0x14, 0x28, 0x8e, 0xa7, 0x11, 0x6e, 0x9d, 0x02, 0x47, 0x70, 0x01, 0x2c, 0x48, 0x01, 0x1b, 0x2d,
258     0x01, 0x0b, 0x11, 0x1e, 0xaf, 0xbc, 0x09, 0x7c, 0xa9, 0x01, 0x4a, 0x74, 0x01, 0x30, 0x4e, 0x01,
259     0x1e, 0x31, 0x01, 0x0b, 0x12, 0x0a, 0xde, 0xdf, 0x02, 0x96, 0xc2, 0x01, 0x53, 0x80, 0x01, 0x30,
260     0x4f, 0x01, 0x1b, 0x2d, 0x01, 0x0b, 0x11, 0x24, 0x29, 0xeb, 0x1d, 0x24, 0xc1, 0x0a, 0x1b, 0x6f,
261     0x55, 0xa5, 0xde, 0xb1, 0xa2, 0xd7, 0x6e, 0x87, 0xc3, 0x39, 0x71, 0xa8, 0x17, 0x53, 0x78, 0x0a,
262     0x31, 0x3d, 0x55, 0xbe, 0xdf, 0x24, 0x8b, 0xc8, 0x05, 0x5a, 0x92, 0x01, 0x3c, 0x67, 0x01, 0x26,
263     0x41, 0x01, 0x12, 0x1e, 0x48, 0xca, 0xdf, 0x17, 0x8d, 0xc7, 0x02, 0x56, 0x8c, 0x01, 0x38, 0x61,
264     0x01, 0x24, 0x3d, 0x01, 0x10, 0x1b, 0x37, 0xda, 0xe1, 0x0d, 0x91, 0xc8, 0x01, 0x56, 0x8d, 0x01,
265     0x39, 0x63, 0x01, 0x23, 0x3d, 0x01, 0x0d, 0x16, 0x0f, 0xeb, 0xd4, 0x01, 0x84, 0xb8, 0x01, 0x54,
266     0x8b, 0x01, 0x39, 0x61, 0x01, 0x22, 0x38, 0x01, 0x0e, 0x17, 0xb5, 0x15, 0xc9, 0x3d, 0x25, 0x7b,
267     0x0a, 0x26, 0x47, 0x2f, 0x6a, 0xac, 0x5f, 0x68, 0xad, 0x2a, 0x5d, 0x9f, 0x12, 0x4d, 0x83, 0x04,
268     0x32, 0x51, 0x01, 0x11, 0x17, 0x3e, 0x93, 0xc7, 0x2c, 0x82, 0xbd, 0x1c, 0x66, 0x9a, 0x12, 0x4b,
269     0x73, 0x02, 0x2c, 0x41, 0x01, 0x0c, 0x13, 0x37, 0x99, 0xd2, 0x18, 0x82, 0xc2, 0x03, 0x5d, 0x92,
270     0x01, 0x3d, 0x61, 0x01, 0x1f, 0x32, 0x01, 0x0a, 0x10, 0x31, 0xba, 0xdf, 0x11, 0x94, 0xcc, 0x01,
271     0x60, 0x8e, 0x01, 0x35, 0x53, 0x01, 0x1a, 0x2c, 0x01, 0x0b, 0x11, 0x0d, 0xd9, 0xd4, 0x02, 0x88,
272     0xb4, 0x01, 0x4e, 0x7c, 0x01, 0x32, 0x53, 0x01, 0x1d, 0x31, 0x01, 0x0e, 0x17, 0xc5, 0x0d, 0xf7,
273     0x52, 0x11, 0xde, 0x19, 0x11, 0xa2, 0x7e, 0xba, 0xf7, 0xea, 0xbf, 0xf3, 0xb0, 0xb1, 0xea, 0x68,
274     0x9e, 0xdc, 0x42, 0x80, 0xba, 0x37, 0x5a, 0x89, 0x6f, 0xc5, 0xf2, 0x2e, 0x9e, 0xdb, 0x09, 0x68,
275     0xab, 0x02, 0x41, 0x7d, 0x01, 0x2c, 0x50, 0x01, 0x11, 0x5b, 0x68, 0xd0, 0xf5, 0x27, 0xa8, 0xe0,
276     0x03, 0x6d, 0xa2, 0x01, 0x4f, 0x7c, 0x01, 0x32, 0x66, 0x01, 0x2b, 0x66, 0x54, 0xdc, 0xf6, 0x1f,
277     0xb1, 0xe7, 0x02, 0x73, 0xb4, 0x01, 0x4f, 0x86, 0x01, 0x37, 0x4d, 0x01, 0x3c, 0x4f, 0x2b, 0xf3,
278     0xf0, 0x08, 0xb4, 0xd9, 0x01, 0x73, 0xa6, 0x01, 0x54, 0x79, 0x01, 0x33, 0x43, 0x01, 0x10, 0x06,
279     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280     0xc0, 0x80, 0x40, 0x02, 0xad, 0x22, 0x07, 0x91, 0x55, 0x07, 0xa6, 0x3f, 0x07, 0x5e, 0x42, 0x08,
281     0x40, 0x2e, 0x11, 0x51, 0x1f, 0x19, 0x1d, 0x1e, 0xeb, 0xa2, 0x24, 0xff, 0x22, 0x03, 0x95, 0x90,
282     0x09, 0x66, 0xbb, 0xe1, 0xef, 0xb7, 0x77, 0x60, 0x29, 0x21, 0x10, 0x4d, 0x4a, 0x8e, 0x8e, 0xac,
283     0xaa, 0xee, 0xf7, 0x32, 0x7e, 0x7b, 0xdd, 0xe2, 0x41, 0x20, 0x12, 0x90, 0xa2, 0xc2, 0x29, 0x33,
284     0x62, 0x84, 0x44, 0x12, 0xa5, 0xd9, 0xc4, 0x2d, 0x28, 0x4e, 0xad, 0x50, 0x13, 0xb0, 0xf0, 0xc1,
285     0x40, 0x23, 0x2e, 0xdd, 0x87, 0x26, 0xc2, 0xf8, 0x79, 0x60, 0x55, 0x1d, 0xc7, 0x7a, 0x8d, 0x93,
286     0x3f, 0x9f, 0x94, 0x85, 0x76, 0x79, 0x68, 0x72, 0xae, 0x49, 0x57, 0x5c, 0x29, 0x53, 0x52, 0x63,
287     0x32, 0x35, 0x27, 0x27, 0xb1, 0x3a, 0x3b, 0x44, 0x1a, 0x3f, 0x34, 0x4f, 0x19, 0x11, 0x0e, 0x0c,
288     0xde, 0x22, 0x1e, 0x48, 0x10, 0x2c, 0x3a, 0x20, 0x0c, 0x0a, 0x07, 0x06, 0x20, 0x40, 0x60, 0x80,
289     0xe0, 0x90, 0xc0, 0xa8, 0xc0, 0xb0, 0xc0, 0xc6, 0xc6, 0xf5, 0xd8, 0x88, 0x8c, 0x94, 0xa0, 0xb0,
290     0xc0, 0xe0, 0xea, 0xea, 0xf0, 0x80, 0xd8, 0x80, 0xb0, 0xa0, 0xb0, 0xb0, 0xc0, 0xc6, 0xc6, 0xd0,
291     0xd0, 0x88, 0x8c, 0x94, 0xa0, 0xb0, 0xc0, 0xe0, 0xea, 0xea, 0xf0, 0x80, 0x80, 0x40, 0x60, 0x70,
292     0x40, 0x40, 0x60, 0x40, 0x80, 0x80, 0x40, 0x60, 0x70, 0x40, 0x40, 0x60, 0x40, 0xa0, 0x80, 0xa0,
293     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296     0x78, 0x07, 0x4c, 0xb0, 0xd0, 0x7e, 0x1c, 0x36, 0x67, 0x30, 0x0c, 0x9a, 0x9b, 0x8b, 0x5a, 0x22,
297     0x75, 0x77, 0x43, 0x06, 0x19, 0xcc, 0xf3, 0x9e, 0x0d, 0x15, 0x60, 0x61, 0x05, 0x2c, 0x83, 0xb0,
298     0x8b, 0x30, 0x44, 0x61, 0x53, 0x05, 0x2a, 0x9c, 0x6f, 0x98, 0x1a, 0x31, 0x98, 0x50, 0x05, 0x3a,
299     0xb2, 0x4a, 0x53, 0x21, 0x3e, 0x91, 0x56, 0x05, 0x20, 0x9a, 0xc0, 0xa8, 0x0e, 0x16, 0xa3, 0x55,
300     0x05, 0x20, 0x9c, 0xd8, 0x94, 0x13, 0x1d, 0x49, 0x4d, 0x07, 0x40, 0x74, 0x84, 0x7a, 0x25, 0x7e,
301     0x78, 0x65, 0x15, 0x6b, 0xb5, 0xc0, 0x67, 0x13, 0x43, 0x7d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
302     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
304 };
305 
306 // loop filter value based on qp index look up table
307 extern const uint8_t LF_VALUE_QP_LOOKUP[CODEC_VP9_QINDEX_RANGE] = {
308     0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
309     0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
310     0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
311     0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a,
312     0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e,
313     0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13,
314     0x13, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19,
315     0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1f,
316     0x1f, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25,
317     0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c,
318     0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x32, 0x32,
319     0x32, 0x33, 0x33, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38,
320     0x38, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d,
321     0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
322     0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
323     0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
324 };
325 
326 constexpr int8_t CodechalVdencVp9State::m_instRateThresholdI[CodechalVdencVp9State::m_numInstRateThresholds];
327 constexpr int8_t CodechalVdencVp9State::m_instRateThresholdP[CodechalVdencVp9State::m_numInstRateThresholds];
328 constexpr double CodechalVdencVp9State::m_devThresholdFpNegI[CodechalVdencVp9State::m_numDevThresholds / 2];
329 constexpr double CodechalVdencVp9State::m_devThresholdFpPosI[CodechalVdencVp9State::m_numDevThresholds / 2];
330 constexpr double CodechalVdencVp9State::m_devThresholdFpNegPB[CodechalVdencVp9State::m_numDevThresholds / 2];
331 constexpr double CodechalVdencVp9State::m_devThresholdFpPosPB[CodechalVdencVp9State::m_numDevThresholds / 2];
332 constexpr double CodechalVdencVp9State::m_devThresholdVbrNeg[CodechalVdencVp9State::m_numDevThresholds / 2];
333 constexpr double CodechalVdencVp9State::m_devThresholdVbrPos[CodechalVdencVp9State::m_numDevThresholds / 2];
334 
335 const uint32_t CodechalVdencVp9State::m_vdencMeCurbeInit[48] =
336 {
337     0x00000000, 0x00200010, 0x00003939, 0x77a43000, 0x00000000, 0x28300000, 0x00000000, 0x00000000,
338     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
339     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
340     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
341     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
342     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
343 };
344 
345 const uint32_t CodechalVdencVp9State::m_brcInitDmem[48] =
346 {
347     0x00000000, 0x00038400, 0x00030D40, 0x000C3500, 0x00061A80, 0x00061A80, 0x00000000, 0x0000001E,
348     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x270F0020, 0x02800000, 0x00010168,
349     0x000000FF, 0x0000000E, 0x00000073, 0x00000000, 0x00000000, 0x7846321E, 0x7846321E, 0x735A321E,
350     0xE5DFD8D1, 0x2F29211B, 0xE5DDD7D1, 0x5E56463F, 0xEAE3DAD4, 0x2F281F16, 0x01007488, 0x00000000,
351     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
352     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
353 };
354 
355 const uint32_t CodechalVdencVp9State::m_brcUpdateDmem[64] =
356 {
357     0x00061A80, 0x00000000, 0x0007A120, 0x000493E0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
358     0x00000000, 0x00000000, 0x00000000, 0x0032000A, 0x00960064, 0x01680280, 0x02200000, 0x007802B8,
359     0x00000000, 0x00000000, 0x00000000, 0x02032000, 0xB4785028, 0x67614B28, 0x0101A07D, 0x28010203,
360     0x01030505, 0x00FEFCFA, 0x04060402, 0x78503C1E, 0x00FFC88C, 0x503C1E04, 0xFFC88C78, 0x28140200,
361     0xC8A08246, 0x090800FF, 0x040C0B0A, 0x07060605, 0x06060504, 0xFB650007, 0xFB0501FF, 0x000501FE,
362     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
363     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
364     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
365 };
366 
367 const uint32_t CodechalVdencVp9State::m_probDmem[320] =
368 {
369     0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
370     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
371     0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
372     0x00000004, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
373     0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x0000FF00, 0x00000000, 0x00000000, 0x00000000,
374     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
375     0x00540049, 0x00000060, 0x00000072, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
376     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
377     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
378     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
379     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
380     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
381     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
382     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
383     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
384     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
385     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
386     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
387     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
388     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
389     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
390     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
391     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
392     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
393     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
394     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
395     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
396     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
397     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
398     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
399     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
400     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
401     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
402     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
403     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
404     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
405     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
406     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
407     0x00000000, 0x00000000, 0x00000000, 0x02B80078, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
408     0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
409 };
410 
411 const uint32_t CodechalVdencVp9State::m_brcConstData[2][416] =
412 {
413     // I Frame
414     {
415         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
416         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
417         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
418         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
419         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
420         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
421         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
422         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
423         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
424         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
425         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
426         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
427         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
428         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
429         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
430         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
431         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
432         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
433         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
434         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
435         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
436         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
437         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
438         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
439         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
440         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
441         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
442         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
443         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
444         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
445         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
446         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
447         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
448         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
449         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
450         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
451         0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B,
452         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000,
453         0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
454         0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000,
455         0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000,
456         0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A,
457         0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600,
458         0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000,
459         0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A,
460         0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600,
461         0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA,
462         0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000,
463         0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000,
464         0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802,
465         0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000,
466         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
467     },
468     // P Frame
469     {
470         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
471         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
472         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
473         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
474         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
475         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
476         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
477         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
478         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
479         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
480         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
481         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
482         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
483         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
484         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
485         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
486         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
487         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
488         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
489         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
490         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
491         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
492         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
493         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
494         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
495         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
496         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
497         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
498         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
499         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
500         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
501         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
502         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
503         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
504         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
505         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
506         0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626,
507         0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904,
508         0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B,
509         0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000,
510         0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000,
511         0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A,
512         0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600,
513         0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000,
514         0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A,
515         0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600,
516         0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA,
517         0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000,
518         0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000,
519         0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802,
520         0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000,
521         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
522     }
523 };
524 
525 const uint32_t CodechalVdencVp9State::m_samplerFilterCoeffs[32][6] = {
526     {0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x00004000, 0x00004000},
527     {0x40fe01ff, 0x0001ff02, 0x40fe01ff, 0x0001ff02, 0x000140ff, 0x000140ff},
528     {0x41fc02ff, 0xff01fe04, 0x41fc02ff, 0xff01fe04, 0x00033ffe, 0x00033ffe},
529     {0x3ffb03ff, 0xff02fd06, 0x3ffb03ff, 0xff02fd06, 0x00053efd, 0x00053efd},
530     {0x40f903fe, 0xff02fc09, 0x40f903fe, 0xff02fc09, 0x00063efc, 0x00063efc},
531     {0x3ff804fe, 0xfe03fb0b, 0x3ff804fe, 0xfe03fb0b, 0x00083cfc, 0x00083cfc},
532     {0x3ef705fd, 0xfe03fa0e, 0x3ef705fd, 0xfe03fa0e, 0xff0a3cfb, 0xff0a3cfb},
533     {0x3df505fd, 0xfe04f911, 0x3df505fd, 0xfe04f911, 0xff0d39fb, 0xff0d39fb},
534     {0x3bf506fd, 0xfd04f814, 0x3bf506fd, 0xfd04f814, 0xff0f37fb, 0xff0f37fb},
535     {0x3bf406fc, 0xfd05f716, 0x3bf406fc, 0xfd05f716, 0xff1135fb, 0xff1135fb},
536     {0x39f307fc, 0xfd05f619, 0x39f307fc, 0xfd05f619, 0xfe1433fb, 0xfe1433fb},
537     {0x37f307fc, 0xfc06f51c, 0x37f307fc, 0xfc06f51c, 0xfe1631fb, 0xfe1631fb},
538     {0x35f207fc, 0xfc06f51f, 0x35f207fc, 0xfc06f51f, 0xfe192efb, 0xfe192efb},
539     {0x32f207fc, 0xfc07f422, 0x32f207fc, 0xfc07f422, 0xfd1c2cfb, 0xfd1c2cfb},
540     {0x30f207fc, 0xfc07f325, 0x30f207fc, 0xfc07f325, 0xfd1f29fb, 0xfd1f29fb},
541     {0x2df207fc, 0xfc07f328, 0x2df207fc, 0xfc07f328, 0xfc2127fc, 0xfc2127fc},
542     {0x29f307fc, 0xfc07f32b, 0x29f307fc, 0xfc07f32b, 0xfc2424fc, 0xfc2424fc},
543     {0x28f307fc, 0xfc07f22d, 0x28f307fc, 0xfc07f22d, 0xfc2721fc, 0xfc2721fc},
544     {0x25f307fc, 0xfc07f230, 0x25f307fc, 0xfc07f230, 0xfb291ffd, 0xfb291ffd},
545     {0x22f407fc, 0xfc07f232, 0x22f407fc, 0xfc07f232, 0xfb2c1cfd, 0xfb2c1cfd},
546     {0x1ff506fc, 0xfc07f235, 0x1ff506fc, 0xfc07f235, 0xfb2e19fe, 0xfb2e19fe},
547     {0x1cf506fc, 0xfc07f337, 0x1cf506fc, 0xfc07f337, 0xfb3116fe, 0xfb3116fe},
548     {0x19f605fd, 0xfc07f339, 0x19f605fd, 0xfc07f339, 0xfb3314fe, 0xfb3314fe},
549     {0x16f705fd, 0xfc06f43b, 0x16f705fd, 0xfc06f43b, 0xfb3511ff, 0xfb3511ff},
550     {0x14f804fd, 0xfd06f53b, 0x14f804fd, 0xfd06f53b, 0xfb370fff, 0xfb370fff},
551     {0x11f904fe, 0xfd05f53d, 0x11f904fe, 0xfd05f53d, 0xfb390dff, 0xfb390dff},
552     {0x0efa03fe, 0xfd05f73e, 0x0efa03fe, 0xfd05f73e, 0xfb3c0aff, 0xfb3c0aff},
553     {0x0bfb03fe, 0xfe04f83f, 0x0bfb03fe, 0xfe04f83f, 0xfc3c0800, 0xfc3c0800},
554     {0x09fc02ff, 0xfe03f940, 0x09fc02ff, 0xfe03f940, 0xfc3e0600, 0xfc3e0600},
555     {0x06fd02ff, 0xff03fb3f, 0x06fd02ff, 0xff03fb3f, 0xfd3e0500, 0xfd3e0500},
556     {0x04fe01ff, 0xff02fc41, 0x04fe01ff, 0xff02fc41, 0xfe3f0300, 0xfe3f0300},
557     {0x02ff0100, 0xff01fe40, 0x02ff0100, 0xff01fe40, 0xff400100, 0xff400100}
558 };
559 
CalculateRePakThresholds()560 MOS_STATUS CodechalVdencVp9State::CalculateRePakThresholds()
561 {
562     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
563 
564     CODECHAL_ENCODE_FUNCTION_ENTER;
565 
566     int32_t repakSavingThreshold = 0;
567     if (m_prevFrameInfo.FrameWidth != m_oriFrameWidth ||
568         m_prevFrameInfo.FrameHeight != m_oriFrameHeight)
569     {
570         switch (m_vp9SeqParams->TargetUsage)
571         {
572         case TU_QUALITY:
573         case 2:
574             repakSavingThreshold = 2;
575             break;
576         case TU_PERFORMANCE:
577             repakSavingThreshold = 80;
578             break;
579         default:  // normal settings
580             repakSavingThreshold = 10;
581             break;
582         }
583 
584         int32_t scale = (m_oriFrameWidth * m_oriFrameHeight) / (176 * 144);
585         if (!scale)
586         {
587             scale = 1;
588         }
589 
590         for (auto i = 0; i < CODEC_VP9_QINDEX_RANGE; i += 1)
591         {
592             double tempQp = i - 144.0;
593 
594             int32_t b = (int32_t)(92.5 * i);
595             int32_t c = (int32_t)(1.6 * tempQp * tempQp);
596             int32_t d = (int32_t)(0.01 * tempQp * tempQp * tempQp);
597             int32_t threshold = (int32_t)((18630 - b + c - d) / 10);
598             int32_t calculatedRepakSavingThreshold = repakSavingThreshold * scale;
599 
600             // To avoid overflow of the integer threshold, it must be (RepakSavingThreshold * scale) <= CODEC_VP9_MAX_REPAK_THRESHOLD
601             if (calculatedRepakSavingThreshold > CODEC_VP9_MAX_REPAK_THRESHOLD)
602             {
603                 calculatedRepakSavingThreshold = CODEC_VP9_MAX_REPAK_THRESHOLD;
604             }
605             m_rePakThreshold[i] = calculatedRepakSavingThreshold * threshold;
606         }
607     }
608 
609     return eStatus;
610 }
611 
612 //------------------------------------------------------------------------------
613 //| Purpose:    Calculate Normalized Denominator for VP9 BRC Curbe Setup
614 //|             based on LCM of provided framerates denominators
615 //| Return:     uint32_t
616 //------------------------------------------------------------------------------
CalculateNormalizedDenominator(FRAME_RATE * frameRates,uint16_t numberOfLayers,uint32_t normalizedDenominator)617 uint32_t CodechalVdencVp9State::CalculateNormalizedDenominator(
618     FRAME_RATE* frameRates,
619     uint16_t numberOfLayers,
620     uint32_t normalizedDenominator)
621 {
622     CODECHAL_ENCODE_FUNCTION_ENTER;
623 
624     // If pointer to the list of FrameRates is null, return the current Normalized Denominator.
625     if (!frameRates)
626     {
627         return normalizedDenominator;
628     }
629 
630     if (numberOfLayers == 0)
631     {
632         return normalizedDenominator;
633     }
634 
635     normalizedDenominator = normalizedDenominator * frameRates[numberOfLayers - 1].uiDenominator / MosUtilities::MosGCD(normalizedDenominator, frameRates[numberOfLayers - 1].uiDenominator);
636 
637     return CalculateNormalizedDenominator(frameRates, numberOfLayers - 1, normalizedDenominator);
638 }
639 
640 //------------------------------------------------------------------------------
641 //| Purpose:    Calculate the max level ratios for temporal scalability
642 //| Return:     STATUS via return & max level ratios inside of maxLevelRatios
643 //------------------------------------------------------------------------------
CalculateTemporalRatios(uint16_t numberOfLayers,uint32_t maxTemporalBitrate,FRAME_RATE maxTemporalFrameRate,uint8_t * maxLevelRatios)644 MOS_STATUS CodechalVdencVp9State::CalculateTemporalRatios(
645     uint16_t numberOfLayers,
646     uint32_t maxTemporalBitrate,
647     FRAME_RATE maxTemporalFrameRate,
648     uint8_t* maxLevelRatios)
649 {
650     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
651 
652     CODECHAL_ENCODE_FUNCTION_ENTER;
653 
654     CODECHAL_ENCODE_CHK_NULL_RETURN(maxLevelRatios);
655 
656     if (numberOfLayers <= 1)
657     {
658         CODECHAL_ENCODE_ASSERTMESSAGE("Need to have multiple temporal layers to calculate ratios");
659         return MOS_STATUS_INVALID_PARAMETER;
660     }
661 
662     if (numberOfLayers > CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS)
663     {
664         CODECHAL_ENCODE_ASSERTMESSAGE("VP9 VDEnc supports only %d temporal layers (%d provided)",
665             CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS, numberOfLayers);
666         return MOS_STATUS_INVALID_PARAMETER;
667     }
668 
669     if (!maxTemporalBitrate || !maxTemporalFrameRate.uiDenominator)
670     {
671         CODECHAL_ENCODE_ASSERTMESSAGE("Invalid bitrate or framerate provided to calculate ratios");
672         return MOS_STATUS_INVALID_PARAMETER;
673     }
674 
675     // calculate normalized denominator as least common multiplier of all layers denominators
676     uint32_t normalizedDenominator = 1;
677     normalizedDenominator          = CalculateNormalizedDenominator(m_vp9SeqParams->FrameRate, numberOfLayers, normalizedDenominator);
678 
679     // calculate 0 layer framerate multiplier and apply it
680     FRAME_RATE currentLayerFrameRate = m_vp9SeqParams->FrameRate[0];
681     uint32_t frameRateMultiplier = normalizedDenominator / currentLayerFrameRate.uiDenominator;
682     currentLayerFrameRate.uiNumerator *= frameRateMultiplier;
683     currentLayerFrameRate.uiDenominator *= frameRateMultiplier;
684 
685     uint32_t currentLayerBitrate = m_vp9SeqParams->TargetBitRate[0] * CODECHAL_ENCODE_BRC_KBPS;
686     maxLevelRatios[0] = (currentLayerBitrate << 6) / maxTemporalBitrate * currentLayerFrameRate.uiDenominator / maxTemporalFrameRate.uiDenominator *
687         maxTemporalFrameRate.uiNumerator / currentLayerFrameRate.uiNumerator;
688 
689     for (auto i = 1; i < numberOfLayers; ++i)
690     {
691         // per ddi
692         // framerate and bitrate are provided on asceding order
693         // 0 indexed is base player properties (bitrate and framerate)
694         // 1 indexed is first layer properties including layer below (which is base)
695         // so on, every current layer properties values include current and all previous layers properties values
696 
697         // extract actual layer bitrate
698         currentLayerBitrate = m_vp9SeqParams->TargetBitRate[i] * CODECHAL_ENCODE_BRC_KBPS - m_vp9SeqParams->TargetBitRate[i - 1] * CODECHAL_ENCODE_BRC_KBPS;
699 
700         // extract actual layer framerate
701         currentLayerFrameRate.uiNumerator   = m_vp9SeqParams->FrameRate[i].uiNumerator * (normalizedDenominator / m_vp9SeqParams->FrameRate[i].uiDenominator) - m_vp9SeqParams->FrameRate[i - 1].uiNumerator * (normalizedDenominator / m_vp9SeqParams->FrameRate[i - 1].uiDenominator);
702         currentLayerFrameRate.uiDenominator = normalizedDenominator;
703 
704         // based on hardware behavior calculate ratio
705         // current layer bitrate is in unit of 1 / 64
706         // 64 is just a number to represent a range or temporal bitrate for different layers
707         // 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
708         maxLevelRatios[i] = (currentLayerBitrate << 6) / maxTemporalBitrate * currentLayerFrameRate.uiDenominator / maxTemporalFrameRate.uiDenominator *
709             maxTemporalFrameRate.uiNumerator / currentLayerFrameRate.uiNumerator;
710     }
711 
712     return eStatus;
713 }
714 
ConstructPicStateBatchBuf(PMOS_RESOURCE picStateBuffer)715 MOS_STATUS CodechalVdencVp9State::ConstructPicStateBatchBuf(
716     PMOS_RESOURCE picStateBuffer)
717 {
718     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
719 
720     CODECHAL_ENCODE_FUNCTION_ENTER;
721 
722     CODECHAL_ENCODE_CHK_NULL_RETURN(picStateBuffer);
723 
724     CODECHAL_ENCODE_CHK_NULL_RETURN(m_hucCmdInitializer);
725 
726     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucCmdInitializer->CommandInitializerSetVp9Params(this));
727 
728     MOS_COMMAND_BUFFER cmdBuffer;
729     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
730 
731     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
732     {
733         // Send command buffer header at the beginning (OS dependent)
734         bool requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : 0;
735         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
736         m_firstTaskInPhase = false;
737     }
738 
739     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucCmdInitializer->CmdInitializerVp9Execute(&cmdBuffer, picStateBuffer));
740 
741     MOS_LOCK_PARAMS lockFlagsWriteOnly;
742     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
743     lockFlagsWriteOnly.WriteOnly = 1;
744     uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, picStateBuffer, &lockFlagsWriteOnly);
745     CODECHAL_ENCODE_CHK_NULL_RETURN(data);
746 
747     MOS_COMMAND_BUFFER constructedCmdBuf;
748     MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf));
749     constructedCmdBuf.pCmdBase  = (uint32_t *)data;
750     constructedCmdBuf.pCmdPtr   = (uint32_t *)data;
751     constructedCmdBuf.iOffset   = 0;
752     constructedCmdBuf.iRemaining = m_vdencPicStateSecondLevelBatchBufferSize;
753 
754     // HCP_VP9_PIC_STATE
755     MHW_VDBOX_VP9_ENCODE_PIC_STATE picState;
756     MOS_ZeroMemory(&picState, sizeof(picState));
757     picState.pVp9PicParams                    = m_vp9PicParams;
758     picState.pVp9SeqParams                    = m_vp9SeqParams;
759     picState.ppVp9RefList                     = &(m_refList[0]);
760     picState.PrevFrameParams.fields.KeyFrame  = m_prevFrameInfo.KeyFrame;
761     picState.PrevFrameParams.fields.IntraOnly = m_prevFrameInfo.IntraOnly;
762     picState.PrevFrameParams.fields.Display   = m_prevFrameInfo.ShowFrame;
763     picState.dwPrevFrmWidth                   = m_prevFrameInfo.FrameWidth;
764     picState.dwPrevFrmHeight                  = m_prevFrameInfo.FrameHeight;
765     picState.ucTxMode                        = m_txMode;
766     picState.bSSEEnable                      = m_vdencBrcEnabled;
767     picState.bUseDysRefSurface               = (m_dysRefFrameFlags != DYS_REF_NONE) && m_dysVdencMultiPassEnabled;
768     picState.bVdencPakOnlyPassFlag           = m_vdencPakonlyMultipassEnabled;
769     picState.uiMaxBitRate                     = m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS;
770     picState.uiMinBitRate                     = m_vp9SeqParams->MinBitRate * CODECHAL_ENCODE_BRC_KBPS;
771     constructedCmdBuf.iOffset += m_cmd1Size;
772     m_hucPicStateOffset = (uint16_t)constructedCmdBuf.iOffset;
773     constructedCmdBuf.pCmdPtr += constructedCmdBuf.iOffset/sizeof(uint32_t);
774     eStatus = m_hcpInterface->AddHcpVp9PicStateEncCmd(&constructedCmdBuf, nullptr, &picState);
775     if (eStatus != MOS_STATUS_SUCCESS)
776     {
777         m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer);
778         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add HCP_VP9_PIC_STATE command.");
779         return eStatus;
780     }
781 
782     // HCP_VP9_SEGMENT_STATE
783     MHW_VDBOX_VP9_SEGMENT_STATE segmentState;
784     MOS_ZeroMemory(&segmentState, sizeof(segmentState));
785     segmentState.Mode                    = m_mode;
786     segmentState.pVp9EncodeSegmentParams = m_vp9SegmentParams;
787     uint8_t segmentCount                 = (m_vp9PicParams->PicFlags.fields.segmentation_enabled) ? CODEC_VP9_MAX_SEGMENTS : 1;
788 
789     for (uint8_t i = 0; i < segmentCount; i++)
790     {
791         segmentState.ucCurrentSegmentId = i;
792         eStatus = m_hcpInterface->AddHcpVp9SegmentStateCmd(&constructedCmdBuf, nullptr, &segmentState);
793         if (eStatus != MOS_STATUS_SUCCESS)
794         {
795             m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer);
796             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add MHW_VDBOX_VP9_SEGMENT_STATE command.");
797             return eStatus;
798         }
799     }
800 
801     // Adjust cmd buffer offset to have 8 segment state blocks
802     if (segmentCount < CODEC_VP9_MAX_SEGMENTS)
803     {
804         // Max 7 segments, 32 bytes each
805         uint8_t zeroBlock[m_segmentStateBlockSize * (CODEC_VP9_MAX_SEGMENTS - 1)];
806         MOS_ZeroMemory(zeroBlock, sizeof(zeroBlock));
807         Mhw_AddCommandCmdOrBB(m_osInterface, &constructedCmdBuf, nullptr, zeroBlock, (CODEC_VP9_MAX_SEGMENTS - segmentCount) * m_segmentStateBlockSize);
808     }
809     m_slbbImgStateOffset = (uint16_t)constructedCmdBuf.iOffset;
810     constructedCmdBuf.iOffset += m_cmd2Size;
811     constructedCmdBuf.pCmdPtr += m_cmd2Size/ sizeof(uint32_t);
812 
813     // BB_END
814     eStatus = m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr);
815     if (eStatus != MOS_STATUS_SUCCESS)
816     {
817         m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer);
818         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add MI Batch Buffer End command.");
819         return eStatus;
820     }
821     m_hucSlbbSize = (uint16_t)constructedCmdBuf.iOffset;
822 
823     m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer);
824 
825     return eStatus;
826 }
827 
GetReferenceBufferSlotIndex(uint8_t refreshFlags)828 uint8_t CodechalVdencVp9State::GetReferenceBufferSlotIndex(uint8_t refreshFlags)
829 {
830     // even if there could be multiple reference frames in the buffer
831     // but here we only retrieve the one which has the smallest index
832 
833     if (refreshFlags == 0)
834     {
835         return 0;
836     }
837 
838     refreshFlags = ~refreshFlags;
839 
840     uint8_t refSlotIndex = 0;
841     while (refreshFlags & 1)
842     {
843         refreshFlags >>= 1;
844         refSlotIndex++;
845     }
846 
847     return refSlotIndex;
848 }
849 
SetDmemHuCVp9Prob()850 MOS_STATUS CodechalVdencVp9State::SetDmemHuCVp9Prob()
851 {
852     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
853 
854     CODECHAL_ENCODE_FUNCTION_ENTER;
855 
856     MOS_LOCK_PARAMS lockFlagsWriteOnly;
857     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
858     lockFlagsWriteOnly.WriteOnly = 1;
859 
860     HucProbDmem* dmem = nullptr;
861     HucProbDmem* dmemTemp = nullptr;
862     int currPass = GetCurrentPass();
863     if (IsFirstPass())
864     {
865         for (auto i = 0; i < 3; i++)
866         {
867             dmem = (HucProbDmem *)m_osInterface->pfnLockResource(
868                 m_osInterface, &m_resHucProbDmemBuffer[i][m_currRecycledBufIdx], &lockFlagsWriteOnly);
869             CODECHAL_ENCODE_CHK_NULL_RETURN(dmem);
870 
871             if (i == 0)
872             {
873                 dmemTemp = dmem;
874             }
875 
876             MOS_SecureMemcpy(dmem, sizeof(HucProbDmem),
877                 m_probDmem, sizeof(HucProbDmem));
878 
879             if (i != 0)
880             {
881                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucProbDmemBuffer[i][m_currRecycledBufIdx]));
882                 dmem = dmemTemp;
883             }
884         }
885     }
886     else
887     {
888         dmem = (HucProbDmem *)m_osInterface->pfnLockResource(
889             m_osInterface, &m_resHucProbDmemBuffer[currPass][m_currRecycledBufIdx], &lockFlagsWriteOnly);
890         CODECHAL_ENCODE_CHK_NULL_RETURN(dmem);
891     }
892 
893     // for BRC cases, HuC needs to be called on Pass 1
894     if (m_superFrameHucPass)
895     {
896         dmem->HuCPassNum = CODECHAL_ENCODE_VP9_HUC_SUPERFRAME_PASS;
897     }
898     else
899     {
900         if (m_dysBrc)
901         {
902             //For BRC+Dynamic Scaling, we need to run as HUC pass 1 in the last pass since the curr_pass was changed to 0.
903             dmem->HuCPassNum = currPass != 0;
904         }
905         else
906         {
907             //For Non-dynamic scaling BRC cases, HuC needs to run as HuC pass one only in last pass.
908             dmem->HuCPassNum = ((m_vdencBrcEnabled && currPass == 1) ? 0 : (currPass != 0));
909         }
910     }
911 
912     dmem->FrameWidth  = m_oriFrameWidth;
913     dmem->FrameHeight = m_oriFrameHeight;
914 
915     for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
916     {
917         dmem->SegmentRef[i]  = (m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled == true) ? m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentReference : CODECHAL_ENCODE_VP9_REF_SEGMENT_DISABLED;
918         dmem->SegmentSkip[i] = m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped;
919     }
920 
921     if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME && m_currPass == 0)
922     {
923         for (auto i = 1; i < CODEC_VP9_NUM_CONTEXTS; i++)
924         {
925             uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
926                 m_osInterface,
927                 &m_resProbBuffer[i],
928                 &lockFlagsWriteOnly);
929 
930             CODECHAL_ENCODE_CHK_NULL_RETURN(data);
931 
932             ContextBufferInit(data, 0);
933             CtxBufDiffInit(data, 0);
934 
935             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
936                 m_osInterface,
937                 &m_resProbBuffer[i]));
938         }
939     }
940 
941     // in multipasses, only delta seg qp (SegCodeAbs = 0) is supported, confirmed by the arch team
942     dmem->SegCodeAbs                     = 0;
943     dmem->SegTemporalUpdate              = m_vp9PicParams->PicFlags.fields.segmentation_temporal_update;
944     dmem->LastRefIndex                   = m_vp9PicParams->RefFlags.fields.LastRefIdx;
945     dmem->GoldenRefIndex                 = m_vp9PicParams->RefFlags.fields.GoldenRefIdx;
946     dmem->AltRefIndex                    = m_vp9PicParams->RefFlags.fields.AltRefIdx;
947     dmem->RefreshFrameFlags              = m_vp9PicParams->RefFlags.fields.refresh_frame_flags;
948     dmem->RefFrameFlags                  = m_refFrameFlags;
949     dmem->ContextFrameTypes              = m_contextFrameTypes[m_vp9PicParams->PicFlags.fields.frame_context_idx];
950     dmem->FrameToShow                    = GetReferenceBufferSlotIndex(dmem->RefreshFrameFlags);
951 
952     dmem->FrameCtrl.FrameType            = m_vp9PicParams->PicFlags.fields.frame_type;
953     dmem->FrameCtrl.ShowFrame            = m_vp9PicParams->PicFlags.fields.show_frame;
954     dmem->FrameCtrl.ErrorResilientMode   = m_vp9PicParams->PicFlags.fields.error_resilient_mode;
955     dmem->FrameCtrl.IntraOnly            = m_vp9PicParams->PicFlags.fields.intra_only;
956     dmem->FrameCtrl.ContextReset         = m_vp9PicParams->PicFlags.fields.reset_frame_context;
957     dmem->FrameCtrl.LastRefFrameBias     = m_vp9PicParams->RefFlags.fields.LastRefSignBias;
958     dmem->FrameCtrl.GoldenRefFrameBias   = m_vp9PicParams->RefFlags.fields.GoldenRefSignBias;
959     dmem->FrameCtrl.AltRefFrameBias      = m_vp9PicParams->RefFlags.fields.AltRefSignBias;
960     dmem->FrameCtrl.AllowHighPrecisionMv = m_vp9PicParams->PicFlags.fields.allow_high_precision_mv;
961     dmem->FrameCtrl.McompFilterMode      = m_vp9PicParams->PicFlags.fields.mcomp_filter_type;
962     dmem->FrameCtrl.TxMode               = m_txMode;
963     dmem->FrameCtrl.RefreshFrameContext  = m_vp9PicParams->PicFlags.fields.refresh_frame_context;
964     dmem->FrameCtrl.FrameParallelDecode  = m_vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode;
965     dmem->FrameCtrl.CompPredMode         = m_vp9PicParams->PicFlags.fields.comp_prediction_mode;
966     dmem->FrameCtrl.FrameContextIdx      = m_vp9PicParams->PicFlags.fields.frame_context_idx;
967     dmem->FrameCtrl.SharpnessLevel       = m_vp9PicParams->sharpness_level;
968     dmem->FrameCtrl.SegOn                = m_vp9PicParams->PicFlags.fields.segmentation_enabled;
969     dmem->FrameCtrl.SegMapUpdate         = m_vp9PicParams->PicFlags.fields.segmentation_update_map;
970     dmem->FrameCtrl.SegUpdateData        = m_vp9PicParams->PicFlags.fields.seg_update_data;
971     dmem->StreamInSegEnable              = (uint8_t)m_segmentMapProvided;
972     dmem->StreamInEnable                 = (uint8_t)m_segmentMapProvided; // Currently unused, if used may || with HME enabled
973 
974     dmem->FrameCtrl.log2TileRows = m_vp9PicParams->log2_tile_rows;
975     dmem->FrameCtrl.log2TileCols = m_vp9PicParams->log2_tile_columns;
976 
977     dmem->PrevFrameInfo = m_prevFrameInfo;
978     // For DyS CQP or BRC case there is no Repak on last pass. So disable the Repak flag here
979     // We also disable repak pass in TU7 speed mode usage for performance reasons.
980     if (m_dysVdencMultiPassEnabled)
981     {
982         dmem->RePak = (m_numPasses > 0 && IsLastPass() && !(m_dysCqp || m_dysBrc) && (m_vp9SeqParams->TargetUsage != TU_PERFORMANCE));
983     }
984     else
985     {
986         dmem->RePak = (m_numPasses > 0 && IsLastPass() && (m_vp9SeqParams->TargetUsage != TU_PERFORMANCE));
987     }
988     if (dmem->RePak && m_adaptiveRepakSupported)
989     {
990         MOS_SecureMemcpy(dmem->RePakThreshold, sizeof(uint32_t) * CODEC_VP9_QINDEX_RANGE, m_rePakThreshold, sizeof(uint32_t) * CODEC_VP9_QINDEX_RANGE);
991     }
992 
993     dmem->LFLevelBitOffset           = m_vp9PicParams->BitOffsetForLFLevel;
994     dmem->QIndexBitOffset            = m_vp9PicParams->BitOffsetForQIndex;
995     dmem->SegBitOffset               = m_vp9PicParams->BitOffsetForSegmentation + 1;  // exclude segment_enable bit
996     dmem->SegLengthInBits            = m_vp9PicParams->BitSizeForSegmentation - 1;    // exclude segment_enable bit
997     dmem->UnCompHdrTotalLengthInBits = m_vp9PicParams->BitOffsetForFirstPartitionSize + 16;
998     dmem->PicStateOffset = m_hucPicStateOffset;
999     dmem->SLBBSize = m_hucSlbbSize;
1000     dmem->IVFHeaderSize = (m_frameNum == 0) ? 44 : 12;
1001 
1002     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucProbDmemBuffer[currPass][m_currRecycledBufIdx]));
1003 
1004     return eStatus;
1005 }
1006 
1007 /*----------------------------------------------------------------------------
1008 | Name      : StoreHuCStatus2Register
1009 | Purpose   : Store HUC_STATUS2 register bit 6 before HUC_Start command
1010 |             BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload
1011 |
1012 | Returns   : MOS_STATUS
1013 \---------------------------------------------------------------------------*/
StoreHuCStatus2Register(PMOS_COMMAND_BUFFER cmdBuffer)1014 MOS_STATUS CodechalVdencVp9State::StoreHuCStatus2Register(
1015     PMOS_COMMAND_BUFFER cmdBuffer)
1016 {
1017     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1018 
1019     CODECHAL_ENCODE_FUNCTION_ENTER;
1020 
1021     // Write HUC_STATUS2 mask - bit 6 - valid IMEM loaded
1022     MHW_MI_STORE_DATA_PARAMS storeDataParams;
1023     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1024     storeDataParams.pOsResource = &m_resHucStatus2Buffer;
1025     storeDataParams.dwResourceOffset = 0;
1026     storeDataParams.dwValue = m_hucInterface->GetHucStatus2ImemLoadedMask();
1027     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
1028 
1029     // Store HUC_STATUS2 register
1030     MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
1031     MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
1032     storeRegParams.presStoreBuffer = &m_resHucStatus2Buffer;
1033     storeRegParams.dwOffset = sizeof(uint32_t);
1034     storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(m_vdboxIndex)->hucStatus2RegOffset;
1035     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegParams));
1036 
1037     return eStatus;
1038 }
1039 
StoreHucErrorStatus(MmioRegistersHuc * mmioRegisters,PMOS_COMMAND_BUFFER cmdBuffer,bool addToEncodeStatus)1040 MOS_STATUS CodechalVdencVp9State::StoreHucErrorStatus(MmioRegistersHuc *mmioRegisters, PMOS_COMMAND_BUFFER cmdBuffer, bool addToEncodeStatus)
1041 {
1042     // Write Huc Error Flag mask: DW1 (mask value)
1043     MHW_MI_STORE_DATA_PARAMS storeDataParams;
1044     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1045     storeDataParams.pOsResource      = &m_resHucErrorStatusBuffer;
1046     storeDataParams.dwResourceOffset = sizeof(uint32_t);
1047     storeDataParams.dwValue          = CODECHAL_VDENC_VP9_BRC_HUC_STATUS_MEMORY_ACCESS_ERROR_MASK;
1048     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
1049 
1050     // store HUC_STATUS register: DW0 (actual value)
1051     MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
1052     MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
1053     storeRegParams.presStoreBuffer = &m_resHucErrorStatusBuffer;
1054     storeRegParams.dwOffset        = 0;
1055     storeRegParams.dwRegister      = mmioRegisters->hucStatusRegOffset;
1056     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegParams));
1057 
1058     if (addToEncodeStatus)
1059     {
1060         EncodeStatusBuffer encodeStatusBuf = m_encodeStatusBuf;
1061 
1062         uint32_t baseOffset =
1063             (encodeStatusBuf.wCurrIndex * encodeStatusBuf.dwReportSize) + sizeof(uint32_t) * 2;  // pEncodeStatus is offset by 2 DWs in the resource
1064 
1065         // store HUC_STATUS register
1066         MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
1067         MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
1068         storeRegParams.presStoreBuffer = &encodeStatusBuf.resStatusBuffer;
1069         storeRegParams.dwOffset        = baseOffset + encodeStatusBuf.dwHuCStatusRegOffset;
1070         storeRegParams.dwRegister      = mmioRegisters->hucStatusRegOffset;
1071         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1072             cmdBuffer,
1073             &storeRegParams));
1074     }
1075 
1076     return MOS_STATUS_SUCCESS;
1077 }
1078 
HuCVp9Prob()1079 MOS_STATUS CodechalVdencVp9State::HuCVp9Prob()
1080 {
1081     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1082 
1083     CODECHAL_ENCODE_FUNCTION_ENTER;
1084 
1085     CODECHAL_DEBUG_TOOL(
1086         uint32_t hucRegionSize[16] = { 0 };
1087         const char* hucRegionName[16] = {"\0"};
1088 
1089         hucRegionName[0] = "_UpdatedProbBuffer";   // hucRegionName[0] is used to dump region 0 after HuC is run, which has updated probabilities. Input Region 0 is dumped separetely before HuC.
1090         hucRegionSize[0] = 32 * CODECHAL_CACHELINE_SIZE;
1091         hucRegionName[1] = "_CountersBuffer";
1092         hucRegionSize[1] = 193 * CODECHAL_CACHELINE_SIZE;
1093         hucRegionName[2] = "_ProbBuffer";
1094         hucRegionSize[2] = 32 * CODECHAL_CACHELINE_SIZE;
1095         hucRegionName[3] = "_ProbDeltaBuffer";
1096         hucRegionSize[3] = 29 * CODECHAL_CACHELINE_SIZE;
1097         hucRegionName[4] = "_UncompressedHdr";
1098         hucRegionSize[4] = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER;
1099         hucRegionName[5] = "_CompressedHdr";
1100         hucRegionSize[5] = 32 * CODECHAL_CACHELINE_SIZE;
1101         hucRegionName[6] = "_SecondLevelBatchBuffer";
1102         hucRegionSize[6] = m_vdencPicStateSecondLevelBatchBufferSize;
1103         hucRegionName[7] = "_SecondLevelBatchBuffer";
1104         hucRegionSize[7] = m_vdencPicStateSecondLevelBatchBufferSize;
1105         hucRegionName[8] = "_UncompressedHdr";
1106         hucRegionSize[8] = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER;
1107         hucRegionName[9] = "_DefaultProbs";
1108         hucRegionSize[9] = sizeof(Keyframe_Default_Probs)+sizeof(Inter_Default_Probs);
1109         hucRegionName[10] = "_SuperFrameBuffer";
1110         hucRegionSize[10] = CODECHAL_ENCODE_VP9_BRC_SUPER_FRAME_BUFFER_SIZE;
1111         hucRegionName[11] = "_DataExtension";
1112         hucRegionSize[11] = CODECHAL_ENCODE_VP9_VDENC_DATA_EXTENSION_SIZE;
1113     )
1114 
1115     MOS_COMMAND_BUFFER cmdBuffer;
1116     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1117 
1118     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
1119     {
1120         bool requestFrameTracking = false;
1121 
1122         // Send command buffer header at the beginning (OS dependent)
1123         // frame tracking tag is only added in the last command buffer header
1124         requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
1125         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
1126 
1127         m_firstTaskInPhase = false;
1128     }
1129 
1130     // load kernel from WOPCM into L2 storage RAM
1131     MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
1132     MOS_ZeroMemory(&imemParams, sizeof(imemParams));
1133     imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencProbKernelDescriptor;
1134     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams));
1135 
1136     // pipe mode select
1137     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
1138     pipeModeSelectParams.Mode = m_mode;
1139     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
1140 
1141     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCVp9Prob());
1142     int currPass = GetCurrentPass();
1143     MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
1144     MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
1145     dmemParams.presHucDataSource = &m_resHucProbDmemBuffer[m_currPass][m_currRecycledBufIdx];
1146     dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucProbDmem), CODECHAL_CACHELINE_SIZE);
1147     dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
1148     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams));
1149 
1150     // Add Virtual addr
1151     MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
1152     MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
1153     // Input regions
1154     virtualAddrParams.regionParams[0].presRegion = &m_resProbBuffer[m_vp9PicParams->PicFlags.fields.frame_context_idx];
1155     virtualAddrParams.regionParams[0].isWritable = true;        // Region 0 is both read and write for HuC. Has input probabilities before running HuC and updated probabilities after running HuC, which will then be input to next pass
1156     virtualAddrParams.regionParams[1].presRegion = &m_resProbabilityCounterBuffer;
1157     virtualAddrParams.regionParams[7].presRegion = m_vdencBrcEnabled ? &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex] : &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex];
1158     virtualAddrParams.regionParams[8].presRegion = &m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx];
1159     virtualAddrParams.regionParams[9].presRegion = &m_resHucDefaultProbBuffer;
1160 
1161     // Output regions
1162     virtualAddrParams.regionParams[2].presRegion  = &m_resHucProbOutputBuffer;  // Final probability output from HuC after each pass
1163     virtualAddrParams.regionParams[2].isWritable = true;
1164     virtualAddrParams.regionParams[3].presRegion  = &m_resProbabilityDeltaBuffer;
1165     virtualAddrParams.regionParams[3].isWritable = true;
1166     virtualAddrParams.regionParams[4].presRegion  = &m_resHucPakInsertUncompressedHeaderWriteBuffer;
1167     virtualAddrParams.regionParams[4].isWritable = true;
1168     virtualAddrParams.regionParams[5].presRegion  = &m_resCompressedHeaderBuffer;
1169     virtualAddrParams.regionParams[5].isWritable = true;
1170     virtualAddrParams.regionParams[6].presRegion  = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex];
1171     virtualAddrParams.regionParams[6].isWritable = true;
1172     virtualAddrParams.regionParams[10].presRegion = &m_resBitstreamBuffer;
1173     virtualAddrParams.regionParams[10].isWritable = true;
1174     virtualAddrParams.regionParams[11].presRegion = &m_resVdencDataExtensionBuffer;
1175     virtualAddrParams.regionParams[11].isWritable = true;
1176 
1177     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams));
1178     // Store HUC_STATUS2 register bit 6 before HUC_Start command
1179     // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload
1180     // (HUC_Start command with last start bit set).
1181     CODECHAL_DEBUG_TOOL(
1182         CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer));
1183     )
1184 
1185     CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Report(&cmdBuffer));
1186 
1187     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true));
1188 
1189     // wait Huc completion (use HEVC bit for now)
1190     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
1191     MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
1192     vdPipeFlushParams.Flags.bFlushHEVC = 1;
1193     vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
1194     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams));
1195 
1196     // Flush the engine to ensure memory written out
1197     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1198     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1199     flushDwParams.bVideoPipelineCacheInvalidate = true;
1200     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1201 
1202     // Write HUC_STATUS mask: DW1 (mask value)
1203     MHW_MI_STORE_DATA_PARAMS storeDataParams;
1204     MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
1205     storeDataParams.pOsResource      = &m_resHucPakMmioBuffer;
1206     storeDataParams.dwResourceOffset = sizeof(uint32_t);
1207     storeDataParams.dwValue = 1 << 31; //Repak bit for HUC is bit 31
1208     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams) );
1209 
1210     // store HUC_STATUS register
1211     MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
1212     MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
1213     storeRegParams.presStoreBuffer = &m_resHucPakMmioBuffer;
1214     storeRegParams.dwOffset = 0;
1215     storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatusRegOffset;
1216     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &storeRegParams));
1217 
1218     // For superframe pass, after HuC executes, write the updated size (combined frame size) to status report
1219     // So app knows total size instead of just the showframe size
1220     if (m_superFrameHucPass)
1221     {
1222         EncodeStatusBuffer* encodeStatusBuf = &m_encodeStatusBuf;
1223         uint32_t baseOffset =
1224             (encodeStatusBuf->wCurrIndex * m_encodeStatusBuf.dwReportSize) +
1225             sizeof(uint32_t) * 2;  // encodeStatus is offset by 2 DWs in the resource
1226 
1227         MHW_MI_COPY_MEM_MEM_PARAMS copyMemMemParams;
1228         MOS_ZeroMemory(&copyMemMemParams, sizeof(copyMemMemParams));
1229 
1230         copyMemMemParams.presSrc = virtualAddrParams.regionParams[11].presRegion;
1231         copyMemMemParams.dwSrcOffset = 0; // Updated framesize is 1st DW in buffer
1232         copyMemMemParams.presDst = &encodeStatusBuf->resStatusBuffer;
1233         copyMemMemParams.dwDstOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset;
1234 
1235         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd(
1236             &cmdBuffer,
1237             &copyMemMemParams));
1238     }
1239 
1240     if (!m_singleTaskPhaseSupported || m_superFrameHucPass)
1241     {
1242         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1243     }
1244 
1245     // Dump input probabilites before running HuC
1246         CODECHAL_DEBUG_TOOL(m_debugInterface->DumpHucRegion(
1247             virtualAddrParams.regionParams[0].presRegion,
1248             virtualAddrParams.regionParams[0].dwOffset,
1249             hucRegionSize[0],
1250             0,
1251             "_ProbBuffer",
1252             (virtualAddrParams.regionParams[0].isWritable ? true : false),
1253             m_currPass,
1254             CodechalHucRegionDumpType::hucRegionDumpDefault);
1255     )
1256 
1257     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1258 
1259     // For Temporal scaling, super frame pass is initiated after the command buffer submission in ExecuteSliceLevel.
1260     // So if Single Task Phase is enabled, then we need to explicitly submit the command buffer here to call HuC
1261     if (!m_singleTaskPhaseSupported || m_superFrameHucPass)
1262     {
1263         bool renderFlags = m_videoContextUsesNullHw;
1264 
1265         CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
1266             &cmdBuffer,
1267             CODECHAL_NUM_MEDIA_STATES,
1268             "_ENC")));
1269 
1270         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags));
1271 
1272         CODECHAL_DEBUG_TOOL(
1273             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
1274                 &m_resHucProbDmemBuffer[m_currPass][m_currRecycledBufIdx],
1275                 sizeof(HucProbDmem),
1276                 currPass,
1277                 CodechalHucRegionDumpType::hucRegionDumpDefault));
1278 
1279             for (auto i = 0; i < 16; i++) {
1280                 if (virtualAddrParams.regionParams[i].presRegion)
1281                 {
1282                     m_debugInterface->DumpHucRegion(
1283                         virtualAddrParams.regionParams[i].presRegion,
1284                         virtualAddrParams.regionParams[i].dwOffset,
1285                         hucRegionSize[i],
1286                         i,
1287                         hucRegionName[i],
1288                         !virtualAddrParams.regionParams[i].isWritable,
1289                         m_currPass,
1290                         CodechalHucRegionDumpType::hucRegionDumpDefault);
1291                 }
1292             })
1293     }
1294 
1295     return eStatus;
1296 }
1297 
GetBrcConstantBuffer(PMOS_RESOURCE brcConstResource,uint16_t pictureCodingType)1298 PMOS_RESOURCE CodechalVdencVp9State::GetBrcConstantBuffer(
1299     PMOS_RESOURCE brcConstResource,
1300     uint16_t pictureCodingType)
1301 {
1302     CODECHAL_ENCODE_FUNCTION_ENTER;
1303 
1304     CODECHAL_ENCODE_ASSERT(brcConstResource != nullptr);
1305     CODECHAL_ENCODE_ASSERT(pictureCodingType == I_TYPE || pictureCodingType == P_TYPE);
1306 
1307     return brcConstResource + (pictureCodingType - 1);
1308 }
1309 
1310 
InitBrcConstantBuffer(PMOS_RESOURCE brcConstResource,uint16_t pictureCodingType)1311 MOS_STATUS CodechalVdencVp9State::InitBrcConstantBuffer(
1312     PMOS_RESOURCE brcConstResource,
1313     uint16_t pictureCodingType)
1314 {
1315     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1316 
1317     CODECHAL_ENCODE_FUNCTION_ENTER;
1318 
1319     if (m_initBrcConstantDataBuffer)
1320         return eStatus;
1321 
1322     CODECHAL_ENCODE_CHK_NULL_RETURN(brcConstResource);
1323     CODECHAL_ENCODE_ASSERT(pictureCodingType == I_TYPE || pictureCodingType == P_TYPE);
1324 
1325     PMOS_RESOURCE brcConstResourceI = brcConstResource;
1326     PMOS_RESOURCE brcConstResourceP = brcConstResource + 1;
1327 
1328     // I - frame const data
1329     {
1330         MOS_LOCK_PARAMS lockFlags;
1331         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
1332         lockFlags.WriteOnly = 1;
1333         uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
1334             m_osInterface,
1335             brcConstResourceI,
1336             &lockFlags);
1337         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1338 
1339         // Fill surface with BRC const data corresponding to I/P frame
1340         // -1 converts from frame type to index
1341         eStatus = MOS_SecureMemcpy(
1342             data,
1343             sizeof(m_brcConstData[0]),
1344             m_brcConstData[0],
1345             sizeof(m_brcConstData[0]));
1346 
1347         if (eStatus != MOS_STATUS_SUCCESS)
1348         {
1349             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to initialize constant memory buffer.");
1350             return eStatus;
1351         }
1352 
1353         m_osInterface->pfnUnlockResource(
1354             m_osInterface,
1355             brcConstResourceI);
1356     }
1357 
1358     // P - frame const data
1359     {
1360         MOS_LOCK_PARAMS lockFlags;
1361         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
1362         lockFlags.WriteOnly = 1;
1363         uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
1364             m_osInterface,
1365             brcConstResourceP,
1366             &lockFlags);
1367         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
1368 
1369         // Fill surface with BRC const data corresponding to I/P frame
1370         // -1 converts from frame type to index
1371         eStatus = MOS_SecureMemcpy(
1372             data,
1373             sizeof(m_brcConstData[1]),
1374             m_brcConstData[1],
1375             sizeof(m_brcConstData[1]));
1376 
1377         if (eStatus != MOS_STATUS_SUCCESS)
1378         {
1379             CODECHAL_ENCODE_ASSERTMESSAGE("Failed to initialize constant memory buffer.");
1380             return eStatus;
1381         }
1382 
1383         m_osInterface->pfnUnlockResource(
1384             m_osInterface,
1385             brcConstResourceP);
1386     }
1387 
1388     m_initBrcConstantDataBuffer = true;
1389 
1390     return eStatus;
1391 }
1392 
1393 /*----------------------------------------------------------------------------
1394 | Name      : ComputeVDEncBRCInitQP
1395 | Purpose   : Calculate VP9 BRC init QP value
1396 |
1397 | Returns   : MOS_STATUS
1398 \---------------------------------------------------------------------------*/
ComputeVDEncBRCInitQP(int32_t * initQpI,int32_t * initQpP)1399 MOS_STATUS CodechalVdencVp9State::ComputeVDEncBRCInitQP(
1400     int32_t* initQpI,
1401     int32_t* initQpP)
1402 {
1403     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1404 
1405     CODECHAL_ENCODE_CHK_NULL_RETURN(initQpI);
1406     CODECHAL_ENCODE_CHK_NULL_RETURN(initQpP);
1407 
1408     uint32_t frameSize = ((m_frameWidth * m_frameHeight * 3) >> 1);
1409 
1410     const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f;
1411     int32_t     qpP = (int32_t)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)m_vp9SeqParams->FrameRate[0].uiNumerator) / ((float)m_vp9SeqParams->TargetBitRate[0] * CODECHAL_ENCODE_BRC_KBPS * m_vp9SeqParams->FrameRate[0].uiDenominator)) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5);
1412     qpP = (int32_t)((float)qpP * (5.0));
1413     qpP -= 20;
1414     qpP = MOS_CLAMP_MIN_MAX(qpP, 1, 200);
1415 
1416     int32_t qpI = (qpP > 4) ? (qpP - 4) : qpP;
1417     uint16_t numP    = m_vp9SeqParams->GopPicSize - 1;
1418     int16_t qiboost = numP / 30 - 1;
1419     qiboost = MOS_CLAMP_MIN_MAX(qiboost, 0, 20);
1420 
1421     qpI -= qiboost;
1422     qpI = MOS_CLAMP_MIN_MAX(qpI, 1, 200);
1423 
1424     qpP = qpI + 20;
1425 
1426     *initQpI = qpI;
1427     *initQpP = qpP;
1428 
1429     return eStatus;
1430 }
1431 
1432 /*----------------------------------------------------------------------------
1433 | Name      : SetDmemHuCBrcUpdate
1434 | Purpose   : Setup DMEM for VP9 BrcUpdate HuC kernel
1435 |
1436 | Returns   : MOS_STATUS
1437 \---------------------------------------------------------------------------*/
SetDmemHuCBrcUpdate()1438 MOS_STATUS CodechalVdencVp9State::SetDmemHuCBrcUpdate()
1439 {
1440     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1441 
1442     CODECHAL_ENCODE_FUNCTION_ENTER;
1443 
1444     MOS_LOCK_PARAMS lockFlagsWriteOnly;
1445     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
1446     lockFlagsWriteOnly.WriteOnly = 1;
1447 
1448     // Setup BRC DMEM
1449     int currPass = GetCurrentPass();
1450     HucBrcUpdateDmem *dmem     = (HucBrcUpdateDmem *)m_osInterface->pfnLockResource(
1451         m_osInterface, &m_resVdencBrcUpdateDmemBuffer[currPass][m_currRecycledBufIdx], &lockFlagsWriteOnly);
1452     CODECHAL_ENCODE_CHK_NULL_RETURN(dmem);
1453 
1454     MOS_SecureMemcpy(dmem, sizeof(HucBrcUpdateDmem),
1455         m_brcUpdateDmem, sizeof(m_brcUpdateDmem));
1456 
1457     // BRC Settings
1458     if (m_curTargetFullness > m_vp9SeqParams->VBVBufferSizeInBit)
1459     {
1460         dmem->UPD_OVERFLOW_FLAG_U8    = 0x1;
1461         m_curTargetFullness -= m_vp9SeqParams->VBVBufferSizeInBit;
1462     }
1463     if (IsFirstPass()) // we only set target fullness on first BRC pass
1464     {
1465         dmem->UPD_TARGET_BUF_FULLNESS_U32     = (int32_t)m_curTargetFullness;
1466     }
1467     dmem->UPD_FRAMENUM_U32                    = m_frameNum;
1468     dmem->UPD_Temporal_Level_U8               = m_vp9PicParams->temporal_id;
1469     dmem->UPD_HRD_BUFF_FULLNESS_UPPER_I32     = m_vp9SeqParams->UpperVBVBufferLevelThresholdInBit;
1470     dmem->UPD_HRD_BUFF_FULLNESS_LOWER_I32     = m_vp9SeqParams->LowerVBVBufferLevelThresholdInBit;
1471 
1472     // Frame info
1473     dmem->UPD_CurWidth_U16                = (uint16_t)m_frameWidth;
1474     dmem->UPD_CurHeight_U16               = (uint16_t)m_frameHeight;
1475     dmem->UPD_CurrFrameType_U8            = (m_pictureCodingType == I_TYPE) ? 2 : 0;
1476 
1477     // PAK info
1478     dmem->UPD_MaxNumPAKs_U8               = (uint8_t)GetNumPasses();        // do not add 1 because we do not run update for RePAK
1479     dmem->UPD_PAKPassNum_U8               = (uint8_t)currPass;
1480 
1481     // Offsets
1482     dmem->UPD_VDEncImgStateOffset         = m_slbbImgStateOffset;
1483     dmem->UPD_SLBBSize                    = m_hucSlbbSize;
1484     dmem->UPD_PicStateOffset              = m_hucPicStateOffset;
1485 
1486     // Thresholds not programmed by driver.currently
1487 
1488     // Global adjust settings not programmed by driver currently
1489 
1490     // QP's
1491     dmem->UPD_ACQQp_U8 = m_vp9PicParams->LumaACQIndex;
1492     // If app gives segment map, we honor the QP deltas provided, if not, and segmentation is enabled,
1493     // BRC generates the QP deltas and patches them into the segment states
1494     dmem->UPD_SegMapGenerating_U8 = m_vp9PicParams->PicFlags.fields.segmentation_enabled && !m_segmentMapProvided;
1495 
1496     m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[currPass][m_currRecycledBufIdx]);
1497 
1498     return eStatus;
1499 }
1500 
1501 /*----------------------------------------------------------------------------
1502 | Name      : SetDmemHuCBrcInitReset
1503 | Purpose   : Setup DMEM for VP9 BrcInit HuC kernel
1504 |
1505 | Returns   : MOS_STATUS
1506 \---------------------------------------------------------------------------*/
SetDmemHuCBrcInitReset()1507 MOS_STATUS CodechalVdencVp9State::SetDmemHuCBrcInitReset()
1508 {
1509     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1510 
1511     CODECHAL_ENCODE_FUNCTION_ENTER;
1512 
1513     CODECHAL_ENCODE_ASSERT(m_brcInit || m_brcReset);
1514 
1515     MOS_LOCK_PARAMS lockFlagsWriteOnly;
1516     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
1517     lockFlagsWriteOnly.WriteOnly = 1;
1518 
1519     // Setup BRC DMEM
1520     HucBrcInitDmem *dmem = (HucBrcInitDmem *)m_osInterface->pfnLockResource(
1521         m_osInterface, &m_resVdencBrcInitDmemBuffer, &lockFlagsWriteOnly);
1522     CODECHAL_ENCODE_CHK_NULL_RETURN(dmem);
1523 
1524     MOS_SecureMemcpy(dmem, sizeof(HucBrcInitDmem),
1525         m_brcInitDmem, sizeof(m_brcInitDmem));
1526 
1527     dmem->BRCFunc               = m_brcInit ? 0 : 2; // 0 for init, 2 for reset
1528     dmem->ProfileLevelMaxFrame  = m_frameWidth * m_frameHeight;
1529     if (m_vp9SeqParams->UserMaxFrameSize > 0)
1530     {
1531         dmem->ProfileLevelMaxFrame = MOS_MIN(dmem->ProfileLevelMaxFrame, m_vp9SeqParams->UserMaxFrameSize);
1532     }
1533     dmem->InitBufFullness = m_vp9SeqParams->InitVBVBufferFullnessInBit;
1534     dmem->BufSize         = m_vp9SeqParams->VBVBufferSizeInBit;
1535 
1536     dmem->TargetBitrate = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS;
1537     dmem->MaxRate       = m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS;
1538 
1539     FRAME_RATE targetFR         = m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1];
1540     dmem->FrameRateM            = targetFR.uiNumerator;
1541     dmem->FrameRateD            = targetFR.uiDenominator;
1542 
1543     switch (m_vp9SeqParams->RateControlMethod)
1544     {
1545     case RATECONTROL_CBR:
1546         dmem->BRCFlag           = CODECHAL_ENCODE_BRCINIT_ISCBR;
1547         dmem->MaxRate           = dmem->TargetBitrate;
1548         break;
1549     case RATECONTROL_VBR:
1550         dmem->BRCFlag           = CODECHAL_ENCODE_BRCINIT_ISVBR;
1551         break;
1552     case RATECONTROL_AVBR:
1553         dmem->BRCFlag           = CODECHAL_ENCODE_BRCINIT_ISAVBR;
1554         break;
1555     case RATECONTROL_CQL:
1556         dmem->BRCFlag           = CODECHAL_ENCODE_BRCINIT_ISCQL;
1557         dmem->LevelQP           = m_vp9SeqParams->ICQQualityFactor;
1558         break;
1559     default:
1560         CODECHAL_ENCODE_ASSERTMESSAGE("BRCInit: Invalid rate control provided (%d)", m_vp9SeqParams->RateControlMethod);
1561         return MOS_STATUS_INVALID_PARAMETER;
1562     }
1563 
1564     if (dmem->MaxRate < dmem->TargetBitrate)
1565     {
1566         dmem->MaxRate = 2 * dmem->TargetBitrate;
1567     }
1568 
1569     dmem->GopP                  = m_vp9SeqParams->GopPicSize - 1;
1570     dmem->FrameWidth            = (uint16_t)m_frameWidth;
1571     dmem->FrameHeight           = (uint16_t)m_frameHeight;
1572 
1573     /* Limit 1-255 as the QP range */
1574     dmem->MinQP                 = 1;
1575     dmem->MaxQP                 = CODEC_VP9_MAX_QP;
1576 
1577     dmem->EnableScaling = m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling;
1578 
1579     for (auto i = 0; i < m_numInstRateThresholds; i++)
1580     {
1581         dmem->InstRateThreshI0[i] = m_instRateThresholdI[i];
1582         dmem->InstRateThreshP0[i] = m_instRateThresholdP[i];
1583     }
1584 
1585     double m_inputBitsPerFrame = ((double)dmem->MaxRate * (double)dmem->FrameRateD) / (double)dmem->FrameRateM;
1586 
1587     //make sure the buffer size can contain at least 4 frames in average
1588     if (dmem->BufSize < (uint32_t)(m_inputBitsPerFrame * 4))
1589     {
1590         dmem->BufSize = (uint32_t)(m_inputBitsPerFrame * 4);
1591     }
1592 
1593     //make sure the initial buffer size is larger than 2 average frames and smaller than the max buffer size.
1594     if (dmem->InitBufFullness == 0)
1595     {
1596         dmem->InitBufFullness = 7 * dmem->BufSize / 8;
1597     }
1598     if (dmem->InitBufFullness < (uint32_t)(m_inputBitsPerFrame * 2))
1599     {
1600         dmem->InitBufFullness = (uint32_t)(m_inputBitsPerFrame * 2);
1601     }
1602     if (dmem->InitBufFullness > dmem->BufSize)
1603     {
1604         dmem->InitBufFullness = dmem->BufSize;
1605     }
1606 
1607     double bpsRatio = m_inputBitsPerFrame / ((double)dmem->BufSize / m_devStdFps);
1608     bpsRatio = MOS_CLAMP_MIN_MAX(bpsRatio, m_bpsRatioLow, m_bpsRatioHigh);
1609 
1610     for (auto i = 0; i < m_numDevThresholds / 2; i++)
1611     {
1612         dmem->DevThreshPB0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegPB[i], bpsRatio));
1613         dmem->DevThreshPB0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosPB[i], bpsRatio));
1614 
1615         dmem->DevThreshI0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegI[i], bpsRatio));
1616         dmem->DevThreshI0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosI[i], bpsRatio));
1617 
1618         dmem->DevThreshVBR0[i] = (int8_t)(m_negMultVbr * pow(m_devThresholdVbrNeg[i], bpsRatio));
1619         dmem->DevThreshVBR0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultVbr * pow(m_devThresholdVbrPos[i], bpsRatio));
1620     }
1621 
1622     int32_t qpI = 0, qpP = 0;
1623     CODECHAL_ENCODE_CHK_STATUS_RETURN(ComputeVDEncBRCInitQP(&qpI, &qpP));
1624 
1625     dmem->InitQPI = (uint8_t)qpI;
1626     dmem->InitQPP = (uint8_t)qpP;
1627 
1628     dmem->Total_Level = m_vp9SeqParams->NumTemporalLayersMinus1 + 1;
1629     if (dmem->Total_Level > 1)
1630     {
1631         CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateTemporalRatios(
1632             dmem->Total_Level, dmem->TargetBitrate, targetFR, dmem->MaxLevel_Ratio));
1633     }
1634 
1635     // lets allow huc to calculate it
1636     dmem->GoldenFrameInterval = 0;
1637 
1638     m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcInitDmemBuffer);
1639 
1640     return eStatus;
1641 }
1642 
1643 /*----------------------------------------------------------------------------
1644 | Name      : HuCBrcUpdate
1645 | Purpose   : Start/Submit VP9 HuC BrcUpdate kernel to HW
1646 |
1647 | Returns   : MOS_STATUS
1648 \---------------------------------------------------------------------------*/
HuCBrcUpdate()1649 MOS_STATUS CodechalVdencVp9State::HuCBrcUpdate()
1650 {
1651     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1652 
1653     CODECHAL_ENCODE_FUNCTION_ENTER;
1654 
1655     CODECHAL_DEBUG_TOOL(
1656         uint32_t hucRegionSize[16];
1657         const char* hucRegionName[16];
1658 
1659         hucRegionName[0]  = "_BrcHistory";
1660         hucRegionSize[0]  = m_brcHistoryBufferSize;
1661         hucRegionName[1]  = "_VDEncStats";
1662         hucRegionSize[1]  = m_vdencBrcStatsBufferSize;
1663         hucRegionName[2]  = "_PAKStats";
1664         hucRegionSize[2]  = m_vdencBrcPakStatsBufferSize;
1665         hucRegionName[3]  = "_InputSLBB";
1666         hucRegionSize[3]  = m_vdencPicStateSecondLevelBatchBufferSize;
1667         hucRegionName[4]  = "_BRCData";
1668         hucRegionSize[4]  = CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE;
1669         hucRegionName[5]  = "_ConstData";
1670         hucRegionSize[5]  = m_brcConstantSurfaceSize;
1671         hucRegionName[6]  = "_OutputSLBB";
1672         hucRegionSize[6]  = m_vdencPicStateSecondLevelBatchBufferSize;
1673         hucRegionName[7]  = "_PAKMMIO";
1674         hucRegionSize[7]  = CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE;
1675     )
1676 
1677     MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
1678 #if (_DEBUG || _RELEASE_INTERNAL)
1679     if (m_swBrcMode)
1680     {
1681         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcUpdate());
1682         CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer[0], m_pictureCodingType));
1683         // Set region params for dumping only
1684         MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
1685         virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer;
1686         virtualAddrParams.regionParams[0].isWritable = true;
1687         virtualAddrParams.regionParams[1].presRegion = &m_resVdencBrcStatsBuffer;
1688         virtualAddrParams.regionParams[2].presRegion = &m_resFrameStatStreamOutBuffer;
1689         virtualAddrParams.regionParams[3].presRegion = &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex];
1690         virtualAddrParams.regionParams[4].presRegion = &m_brcBuffers.resBrcHucDataBuffer;
1691         virtualAddrParams.regionParams[4].isWritable = true;
1692         virtualAddrParams.regionParams[5].presRegion = GetBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer[0], m_pictureCodingType);
1693         virtualAddrParams.regionParams[6].presRegion = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex];
1694         virtualAddrParams.regionParams[6].isWritable = true;
1695         virtualAddrParams.regionParams[7].presRegion = &m_brcBuffers.resBrcBitstreamSizeBuffer;
1696         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(// Dump history IN since it's both IN/OUT, OUT will dump at end of function, rest of buffers are IN XOR OUT (not both)
1697             virtualAddrParams.regionParams[0].presRegion,
1698             virtualAddrParams.regionParams[0].dwOffset,
1699             hucRegionSize[0],
1700             0,
1701             hucRegionName[0],
1702             true,
1703             m_currPass,
1704             CodechalHucRegionDumpType::hucRegionDumpUpdate));
1705         CODECHAL_ENCODE_CHK_STATUS_RETURN(SoftwareBRC(true));
1706 
1707         CODECHAL_DEBUG_TOOL(
1708             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
1709 
1710                 &m_resVdencBrcUpdateDmemBuffer[m_currPass][m_currRecycledBufIdx],
1711                 sizeof(HucBrcUpdateDmem),  // Change buffer and size to update dmem
1712                 m_currPass,
1713                 CodechalHucRegionDumpType::hucRegionDumpUpdate));
1714 
1715             for (auto i = 0; i < 16; i++) {
1716                 if (virtualAddrParams.regionParams[i].presRegion)
1717                 {
1718                     m_debugInterface->DumpHucRegion(
1719                         virtualAddrParams.regionParams[i].presRegion,
1720                         virtualAddrParams.regionParams[i].dwOffset,
1721                         hucRegionSize[i],
1722                         i,
1723                         hucRegionName[i],
1724                         !virtualAddrParams.regionParams[i].isWritable,
1725                         m_currPass,
1726                         CodechalHucRegionDumpType::hucRegionDumpUpdate);
1727                 }
1728             })
1729         // We increment by the average frame value once for each frame
1730         if (m_currPass == 0)
1731         {
1732             m_curTargetFullness += m_inputBitsPerFrame;
1733         }
1734 
1735     return eStatus;
1736     }
1737 #endif
1738 
1739     MOS_COMMAND_BUFFER cmdBuffer;
1740     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1741 
1742     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
1743     {
1744         bool requestFrameTracking = false;
1745 
1746         // Send command buffer header at the beginning (OS dependent)
1747         requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
1748         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
1749 
1750         m_firstTaskInPhase = false;
1751     }
1752 
1753     CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer[0], m_pictureCodingType));
1754 
1755     // load kernel from WOPCM into L2 storage RAM
1756     MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
1757     MOS_ZeroMemory(&imemParams, sizeof(imemParams));
1758     imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencBrcUpdateKernelDescriptor;
1759     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams));
1760 
1761     // pipe mode select
1762     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
1763     pipeModeSelectParams.Mode = m_mode;
1764     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
1765 
1766     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcUpdate());
1767 
1768     // set HuC DMEM param
1769     MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
1770     MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
1771     dmemParams.presHucDataSource = &m_resVdencBrcUpdateDmemBuffer[m_currPass][m_currRecycledBufIdx];
1772     dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucBrcUpdateDmem), CODECHAL_CACHELINE_SIZE);
1773     dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; // how to set?
1774     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams));
1775 
1776     // Set surfaces to HuC regions
1777     MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
1778 
1779     // History Buffer - IN/OUT
1780     virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer;
1781     virtualAddrParams.regionParams[0].isWritable = true;
1782 
1783     // VDEnc Stats Buffer - IN
1784     virtualAddrParams.regionParams[1].presRegion = &m_resVdencBrcStatsBuffer;
1785 
1786     // Frame (not PAK) Stats Buffer - IN
1787     virtualAddrParams.regionParams[2].presRegion = &m_resFrameStatStreamOutBuffer;
1788 
1789     // Input SLBB (second level batch buffer) - IN
1790     //For Dys + BRC Pass 0, use the resVdencDysPictureState2ndLevelBatchBuffer as input buffer
1791     virtualAddrParams.regionParams[3].presRegion = (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled) ? &m_resVdencDysPictureState2NdLevelBatchBuffer : &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex];
1792 
1793     // BRC Data - OUT
1794     virtualAddrParams.regionParams[4].presRegion = &m_brcBuffers.resBrcHucDataBuffer;
1795     virtualAddrParams.regionParams[4].isWritable = true;
1796 
1797     // Const Data - IN
1798     virtualAddrParams.regionParams[5].presRegion = GetBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer[0], m_pictureCodingType);
1799 
1800     // Output SLBB - OUT
1801     virtualAddrParams.regionParams[6].presRegion = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex];
1802     virtualAddrParams.regionParams[6].isWritable = true;
1803 
1804     // PAK MMIO - IN
1805     virtualAddrParams.regionParams[7].presRegion = &m_brcBuffers.resBrcBitstreamSizeBuffer;
1806 
1807     // Load HuC Regions into Cmd Buf
1808     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams));
1809 
1810     // Store HUC_STATUS2 register bit 6 before HUC_Start command
1811     // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload
1812     // (HUC_Start command with last start bit set).
1813     CODECHAL_DEBUG_TOOL(
1814         CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer));
1815     )
1816 
1817     CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Report(&cmdBuffer));
1818 
1819     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true));
1820 
1821     // wait Huc completion (use HEVC bit for now)
1822     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
1823     MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
1824     vdPipeFlushParams.Flags.bFlushHEVC = 1;
1825     vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
1826     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams));
1827 
1828     // Flush the engine to ensure memory written out
1829     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1830     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1831     flushDwParams.bVideoPipelineCacheInvalidate = true;
1832     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
1833 
1834     if (!m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd))
1835     {
1836         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
1837     }
1838 
1839     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1840 
1841     if (!m_singleTaskPhaseSupported)
1842     {
1843         bool renderingFlags = m_videoContextUsesNullHw;
1844 
1845         // Dump history input before HuC runs
1846         CODECHAL_DEBUG_TOOL(
1847             m_debugInterface->DumpHucRegion(
1848                 virtualAddrParams.regionParams[0].presRegion,
1849                 virtualAddrParams.regionParams[0].dwOffset,
1850                 hucRegionSize[0],
1851                 0,
1852                 hucRegionName[0],
1853                 true,
1854                 m_currPass,
1855                 CodechalHucRegionDumpType::hucRegionDumpUpdate);
1856         );
1857 
1858         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags));
1859 
1860         CODECHAL_DEBUG_TOOL(
1861             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
1862                 &m_resVdencBrcUpdateDmemBuffer[m_currPass][m_currRecycledBufIdx],
1863                 sizeof(HucBrcUpdateDmem),  // Change buffer and size to update dmem
1864                 m_currPass,
1865                 CodechalHucRegionDumpType::hucRegionDumpUpdate));
1866 
1867             for (auto i = 0; i < 16; i++) {
1868                 if (virtualAddrParams.regionParams[i].presRegion)
1869                 {
1870                     m_debugInterface->DumpHucRegion(
1871                         virtualAddrParams.regionParams[i].presRegion,
1872                         virtualAddrParams.regionParams[i].dwOffset,
1873                         hucRegionSize[i],
1874                         i,
1875                         hucRegionName[i],
1876                         !virtualAddrParams.regionParams[i].isWritable,
1877                         m_currPass,
1878                         CodechalHucRegionDumpType::hucRegionDumpUpdate);
1879                 }
1880             })
1881     }
1882 
1883     // We increment by the average frame value once for each frame
1884     if (m_currPass == 0)
1885     {
1886         m_curTargetFullness += m_inputBitsPerFrame;
1887     }
1888 
1889     return eStatus;
1890 }
1891 
1892 /*----------------------------------------------------------------------------
1893 | Name      : ConstructSuperFrame
1894 | Purpose   : Enable VP9 third HUC phase to construct super frame in case of temporal scalability.
1895 \---------------------------------------------------------------------------*/
ConstructSuperFrame()1896 MOS_STATUS CodechalVdencVp9State::ConstructSuperFrame()
1897 {
1898     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1899 
1900     // enable super frame state
1901     m_superFrameHucPass = true;
1902 
1903     CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCVp9Prob());
1904 
1905     // disable super frame state
1906     m_superFrameHucPass = false;
1907 
1908     return eStatus;
1909 }
1910 
1911 /*----------------------------------------------------------------------------
1912 | Name      : HuCBrcInitReset
1913 | Purpose   : Start/Submit VP9 HuC BrcInit kernel to HW
1914 |
1915 | Returns   : MOS_STATUS
1916 \---------------------------------------------------------------------------*/
HuCBrcInitReset()1917 MOS_STATUS CodechalVdencVp9State::HuCBrcInitReset()
1918 {
1919     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1920 
1921     CODECHAL_ENCODE_FUNCTION_ENTER;
1922 
1923     CODECHAL_DEBUG_TOOL(
1924         uint32_t hucRegionSize[16];
1925         const char* hucRegionName[16];
1926 
1927         hucRegionName[0] = "_BrcHistoryBuffer";
1928         hucRegionSize[0] = m_brcHistoryBufferSize;
1929     )
1930 
1931     MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
1932 #if (_DEBUG || _RELEASE_INTERNAL)
1933     if (m_swBrcMode)
1934     {
1935         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcInitReset());
1936         CODECHAL_ENCODE_CHK_STATUS_RETURN(SoftwareBRC(false));
1937         // Set region params for dumping only
1938         MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
1939         virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer;
1940         virtualAddrParams.regionParams[0].isWritable = true;
1941         m_inputBitsPerFrame                          = ((m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS) * 100.) / ((m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1].uiNumerator * 100.) / m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1].uiDenominator);
1942         m_curTargetFullness                          = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS;
1943 
1944         CODECHAL_DEBUG_TOOL(
1945             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
1946                 &m_resVdencBrcInitDmemBuffer,
1947                 sizeof(HucBrcInitDmem),
1948                 0,
1949                 CodechalHucRegionDumpType::hucRegionDumpInit));
1950 
1951             for (auto i = 0; i < 16; i++) {
1952                 if (virtualAddrParams.regionParams[i].presRegion)
1953                 {
1954                     m_debugInterface->DumpHucRegion(
1955                         virtualAddrParams.regionParams[i].presRegion,
1956                         virtualAddrParams.regionParams[i].dwOffset,
1957                         hucRegionSize[i],
1958                         i,
1959                         hucRegionName[i],
1960                         !virtualAddrParams.regionParams[i].isWritable,
1961                         0,
1962                         CodechalHucRegionDumpType::hucRegionDumpInit);
1963                 }
1964             })
1965         return eStatus;
1966     }
1967 #endif
1968     MOS_COMMAND_BUFFER cmdBuffer;
1969     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1970 
1971     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
1972     {
1973         bool requestFrameTracking = false;
1974 
1975         // Send command buffer header at the beginning (OS dependent)
1976         requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
1977         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
1978 
1979         m_firstTaskInPhase = false;
1980     }
1981 
1982     // load kernel from WOPCM into L2 storage RAM
1983     MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
1984     MOS_ZeroMemory(&imemParams, sizeof(imemParams));
1985     imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencBrcInitKernelDescriptor;
1986     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams));
1987 
1988     // pipe mode select
1989     MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams;
1990     pipeModeSelectParams.Mode = m_mode;
1991     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams));
1992 
1993     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcInitReset());
1994 
1995     m_inputBitsPerFrame = ((m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS) * 100.) / ((m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1].uiNumerator * 100.) / m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1].uiDenominator);
1996     m_curTargetFullness = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS;
1997 
1998     // set HuC DMEM param
1999     MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
2000     MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
2001     dmemParams.presHucDataSource = &m_resVdencBrcInitDmemBuffer;
2002     dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE);
2003     dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
2004     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams));
2005 
2006     MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
2007     virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer;
2008     virtualAddrParams.regionParams[0].isWritable = true;
2009     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams));
2010 
2011     // Store HUC_STATUS2 register bit 6 before HUC_Start command
2012     // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload
2013     // (HUC_Start command with last start bit set).
2014     CODECHAL_DEBUG_TOOL(
2015         CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer));
2016     )
2017 
2018     CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Report(&cmdBuffer));
2019 
2020     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true));
2021 
2022     // wait Huc completion (use HEVC bit for now)
2023     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams;
2024     MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams));
2025     vdPipeFlushParams.Flags.bFlushHEVC = 1;
2026     vdPipeFlushParams.Flags.bWaitDoneHEVC = 1;
2027     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams));
2028 
2029     // Flush the engine to ensure memory written out
2030     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
2031     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
2032     flushDwParams.bVideoPipelineCacheInvalidate = true;
2033     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
2034 
2035     if (!m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd))
2036     {
2037         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
2038     }
2039 
2040     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
2041 
2042     if (!m_singleTaskPhaseSupported)
2043     {
2044         bool renderingFlags = m_videoContextUsesNullHw;
2045 
2046         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags));
2047 
2048         CODECHAL_DEBUG_TOOL(
2049             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
2050                 &m_resVdencBrcInitDmemBuffer,
2051                 sizeof(HucBrcInitDmem),
2052                 0,
2053                 CodechalHucRegionDumpType::hucRegionDumpInit));
2054 
2055             for (auto i = 0; i < 16; i++) {
2056                 if (virtualAddrParams.regionParams[i].presRegion)
2057                 {
2058                     m_debugInterface->DumpHucRegion(
2059                         virtualAddrParams.regionParams[i].presRegion,
2060                         virtualAddrParams.regionParams[i].dwOffset,
2061                         hucRegionSize[i],
2062                         i,
2063                         hucRegionName[i],
2064                         !virtualAddrParams.regionParams[i].isWritable,
2065                         0,
2066                         CodechalHucRegionDumpType::hucRegionDumpInit);
2067                 }
2068             })
2069     }
2070 
2071     return eStatus;
2072 }
2073 
2074 #if (_DEBUG || _RELEASE_INTERNAL)
SoftwareBRC(bool update)2075 MOS_STATUS CodechalVdencVp9State::SoftwareBRC(bool update)
2076 {
2077     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2078 
2079     typedef void*   (*BrcCreateInstance)();
2080     typedef void(*BrcReleaseInstance)(void*);
2081     typedef int(*BrcProcess)(void*, ProcessType);
2082     typedef int(*BrcSetBuff)(uint8_t*, VP9BufferType, void*);
2083 
2084     CODECHAL_DEBUG_FUNCTION_ENTER;
2085 
2086     CODECHAL_ENCODE_CHK_NULL_RETURN(m_swBrcMode);
2087 
2088     MOS_LOCK_PARAMS lpReadOnly;
2089     MOS_ZeroMemory(&lpReadOnly, sizeof(lpReadOnly));
2090     lpReadOnly.ReadOnly = 1;
2091 
2092     MOS_LOCK_PARAMS lpWriteOnly;
2093     MOS_ZeroMemory(&lpWriteOnly, sizeof(lpWriteOnly));
2094     lpWriteOnly.WriteOnly = 1;
2095 
2096     MOS_LOCK_PARAMS lpReadWrite;
2097     MOS_ZeroMemory(&lpReadWrite, sizeof(lpReadWrite));
2098     lpReadWrite.ReadOnly = lpReadWrite.WriteOnly = 1;
2099 
2100     BrcCreateInstance pfnCreateInstance = (BrcCreateInstance)MosUtilities::MosGetProcAddress(m_swBrcMode, "VP9BRC_CreateInstance");
2101     CODECHAL_ENCODE_CHK_NULL_RETURN(pfnCreateInstance);
2102     BrcReleaseInstance pfnReleaseInstance = (BrcReleaseInstance)MosUtilities::MosGetProcAddress(m_swBrcMode, "VP9BRC_ReleaseInstance");
2103     CODECHAL_ENCODE_CHK_NULL_RETURN(pfnReleaseInstance);
2104     BrcProcess pfnProcess = (BrcProcess)MosUtilities::MosGetProcAddress(m_swBrcMode, "VP9BRC_Process");
2105     CODECHAL_ENCODE_CHK_NULL_RETURN(pfnProcess);
2106     BrcSetBuff pfnSetBuffer = (BrcSetBuff)MosUtilities::MosGetProcAddress(m_swBrcMode, "VP9BRC_SetBuff");
2107     CODECHAL_ENCODE_CHK_NULL_RETURN(pfnSetBuffer);
2108 
2109     void* pvBrcIfHandle = pfnCreateInstance();
2110     CODECHAL_ENCODE_CHK_NULL_RETURN(pvBrcIfHandle);
2111 
2112     if (!update) // BRC INIT / RESET
2113     {
2114         // Set DMEM
2115         uint8_t* data_dmem = NULL;
2116         data_dmem          = (uint8_t *)m_osInterface->pfnLockResource(
2117             m_osInterface, &m_resVdencBrcInitDmemBuffer, &lpReadOnly);
2118         CODECHAL_ENCODE_CHK_NULL_RETURN(data_dmem);
2119         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_dmem, eVp9INLINE_DMEM, pvBrcIfHandle));
2120 
2121         // Set History OUT Buffer
2122         uint8_t* data_history_out = (uint8_t *)m_osInterface->pfnLockResource(
2123             m_osInterface, &m_brcBuffers.resBrcHistoryBuffer, &lpWriteOnly);
2124         CODECHAL_ENCODE_CHK_NULL_RETURN(data_history_out);
2125         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_history_out, eVp9HISTORY_BUFF, pvBrcIfHandle));
2126 
2127         // Execute init/reset firmware
2128         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnProcess(pvBrcIfHandle, m_brcInit ? BRCInit : BRCReset));
2129 
2130         m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcInitDmemBuffer);
2131         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHistoryBuffer);
2132     }
2133     else // BRC UPDATE
2134     {
2135         // Set DMEM
2136         uint8_t *data_dmem = (uint8_t *)m_osInterface->pfnLockResource(
2137             m_osInterface, &m_resVdencBrcUpdateDmemBuffer[m_currPass][m_currRecycledBufIdx], &lpReadOnly);
2138         CODECHAL_ENCODE_CHK_NULL_RETURN(data_dmem);
2139         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_dmem, eVp9INLINE_DMEM, pvBrcIfHandle));
2140 
2141         // Set History IN/OUT Buffer
2142         uint8_t *data_history_in_out = (uint8_t *)m_osInterface->pfnLockResource(
2143             m_osInterface, &m_brcBuffers.resBrcHistoryBuffer, &lpReadWrite);
2144         CODECHAL_ENCODE_CHK_NULL_RETURN(data_history_in_out);
2145         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_history_in_out, eVp9HISTORY_BUFF, pvBrcIfHandle));
2146 
2147         // Set VDEnc Stats IN
2148         uint8_t *data_vdenc_stat = (uint8_t *)m_osInterface->pfnLockResource(
2149             m_osInterface, &m_resVdencBrcStatsBuffer, &lpReadOnly);
2150         CODECHAL_ENCODE_CHK_NULL_RETURN(data_vdenc_stat);
2151         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_vdenc_stat, eVp9VDENC_STATISTICS_BUFF, pvBrcIfHandle));
2152 
2153         // Set Frame Stats IN
2154         uint8_t *data_frame_stat = (uint8_t *)m_osInterface->pfnLockResource(
2155             m_osInterface, &m_resFrameStatStreamOutBuffer, &lpReadOnly);
2156         CODECHAL_ENCODE_CHK_NULL_RETURN(data_frame_stat);
2157         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_frame_stat, eVp9PAK_STATISTICS_BUFF, pvBrcIfHandle));
2158 
2159         // Set SLBB IN
2160         uint8_t *data_slbb_in = (uint8_t *)m_osInterface->pfnLockResource(
2161             m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex], &lpReadOnly);
2162         CODECHAL_ENCODE_CHK_NULL_RETURN(data_slbb_in);
2163         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_slbb_in, eVp9INPUT_SLBB_BUFF, pvBrcIfHandle));
2164 
2165         // Set BRC data OUT
2166         uint8_t *data_brc_out = (uint8_t *)m_osInterface->pfnLockResource(
2167             m_osInterface, &m_brcBuffers.resBrcHucDataBuffer, &lpWriteOnly);
2168         CODECHAL_ENCODE_CHK_NULL_RETURN(data_brc_out);
2169         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_brc_out, eVp9BRC_DATA_BUFF, pvBrcIfHandle));
2170 
2171         // Set Const Data IN
2172         uint8_t *data_const_in = (uint8_t *)m_osInterface->pfnLockResource(
2173             m_osInterface, &m_brcBuffers.resBrcConstantDataBuffer[0], &lpReadOnly);
2174         CODECHAL_ENCODE_CHK_NULL_RETURN(data_const_in);
2175         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_const_in, eVp9CONSTANT_DATA_BUFF, pvBrcIfHandle));
2176 
2177         // Set SLBB OUT
2178         uint8_t *data_slbb_out = (uint8_t *)m_osInterface->pfnLockResource(
2179             m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex], &lpWriteOnly);
2180         CODECHAL_ENCODE_CHK_NULL_RETURN(data_slbb_out);
2181         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_slbb_out, eVp9OUTPUT_SLBB_BUFF, pvBrcIfHandle));
2182 
2183         // PAK MMIO IN
2184         uint8_t *data_mmio_in = (uint8_t *)m_osInterface->pfnLockResource(
2185             m_osInterface, &m_brcBuffers.resBrcBitstreamSizeBuffer, &lpReadOnly);
2186         CODECHAL_ENCODE_CHK_NULL_RETURN(data_mmio_in);
2187         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data_mmio_in, eVp9PAKMMIO_BUFF, pvBrcIfHandle));
2188 
2189         // AUX Buffer IN/OUT (DLL extension buffer)
2190         HUC_AUX_BUFFER auxBuffer = { 0 };
2191         CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer((uint8_t *)&auxBuffer, eVp9AUX_BUFF, pvBrcIfHandle));
2192 
2193         // Execute update firmware
2194         pfnProcess(pvBrcIfHandle, BRCUpdate);
2195 
2196         m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[m_currPass][m_currRecycledBufIdx]);
2197         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHistoryBuffer);
2198         m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcStatsBuffer);
2199         m_osInterface->pfnUnlockResource(m_osInterface, &m_resFrameStatStreamOutBuffer);
2200         m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]);
2201         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer);
2202         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcConstantDataBuffer[0]);
2203         m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]);
2204         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcBitstreamSizeBuffer);
2205     }
2206 
2207     pfnReleaseInstance(pvBrcIfHandle);
2208 
2209     return eStatus;
2210 }
2211 #endif
2212 
CalculateBufferOffset(uint32_t idx,uint32_t width,uint32_t blockSize,uint32_t bufferPitch)2213 uint32_t CodechalVdencVp9State::CalculateBufferOffset(
2214     uint32_t idx,
2215     uint32_t width,
2216     uint32_t blockSize,
2217     uint32_t bufferPitch)
2218 {
2219     uint32_t y = idx / (MOS_ALIGN_CEIL(width, CODEC_VP9_SUPER_BLOCK_WIDTH) / 32);
2220     uint32_t x = idx % (MOS_ALIGN_CEIL(width, CODEC_VP9_SUPER_BLOCK_WIDTH)/ 32);
2221 
2222     switch (blockSize)
2223     {
2224         case 0: // 16x16
2225             x *= 2;
2226             y *= 2;
2227             break;
2228         case 1: // 32x32 (no multiplier since streamin chunks are for 32x32)
2229             break;
2230         case 2: // 64x64
2231             x /= 2;
2232             y /= 2;
2233             break;
2234         case 3: // 8x8
2235             x *= 4;
2236             y *= 4;
2237             break;
2238     }
2239 
2240     uint32_t addr = y * bufferPitch;
2241     addr += x;
2242 
2243     return addr;
2244 }
2245 
IsToBeCompressed(bool isDownScaledSurface)2246 bool CodechalVdencVp9State::IsToBeCompressed(bool isDownScaledSurface)
2247 {
2248     CODECHAL_ENCODE_FUNCTION_ENTER;
2249     // For regular encoding, we always compress this surface regardless of downscaling
2250     return m_mmcState ? m_mmcState->IsMmcEnabled() : false;
2251 }
2252 
DysRefFrames()2253 MOS_STATUS CodechalVdencVp9State::DysRefFrames()
2254 {
2255     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2256 
2257     CODECHAL_ENCODE_FUNCTION_ENTER;
2258 
2259     if (m_dysRefFrameFlags == DYS_REF_NONE)
2260     {
2261         return eStatus;
2262     }
2263 
2264     // allocate dynamic scaled surfaces if needed
2265     uint8_t idx = 0, refIdx = 0, numDysRefFrames = 0;
2266     if (m_dysRefFrameFlags & DYS_REF_LAST)
2267     {
2268         idx    = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx;
2269         refIdx = 1;
2270         numDysRefFrames++;
2271     }
2272 
2273     if (m_dysRefFrameFlags & DYS_REF_GOLDEN)
2274     {
2275         idx    = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx;
2276         refIdx = 2;
2277         numDysRefFrames++;
2278     }
2279 
2280     if (m_dysRefFrameFlags & DYS_REF_ALT)
2281     {
2282         idx    = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx;
2283         refIdx = 3;
2284         numDysRefFrames++;
2285     }
2286 
2287     if (numDysRefFrames > 1)
2288     {
2289         // for performance reason, we can only support single reference for dynamic scaling
2290         CODECHAL_ENCODE_ASSERTMESSAGE("Only single reference is supported for dynamic scaling!");
2291         return MOS_STATUS_INVALID_PARAMETER;
2292     }
2293 
2294     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer;
2295     MOS_ZeroMemory(&allocParamsForBuffer, sizeof(MOS_ALLOC_GFXRES_PARAMS));
2296     allocParamsForBuffer.Type = MOS_GFXRES_2D;
2297     allocParamsForBuffer.TileType = MOS_TILE_Y;
2298     allocParamsForBuffer.Format = m_reconSurface.Format;
2299     allocParamsForBuffer.bIsCompressible = IsToBeCompressed(true);
2300 
2301     PCODEC_REF_LIST *refList = &m_refList[0];
2302     if (Mos_ResourceIsNull(&refList[idx]->sDysSurface.OsResource) ||
2303         (refList[idx]->sDysSurface.dwWidth != m_reconSurface.dwWidth) || (refList[idx]->sDysSurface.dwHeight != m_reconSurface.dwHeight))
2304     {
2305         // free existing resource first if resolution changes
2306         if (!Mos_ResourceIsNull(&refList[idx]->sDysSurface.OsResource))
2307         {
2308             m_osInterface->pfnFreeResource(
2309                 m_osInterface,
2310                 &refList[idx]->sDysSurface.OsResource);
2311         }
2312 
2313         allocParamsForBuffer.dwWidth = MOS_ALIGN_CEIL(m_reconSurface.dwWidth, CODEC_VP9_SUPER_BLOCK_WIDTH);
2314         allocParamsForBuffer.dwHeight = MOS_ALIGN_CEIL(m_reconSurface.dwHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
2315         allocParamsForBuffer.pBufName = "Dynamic Scaled Surface for VP9";
2316 
2317         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
2318             m_osInterface,
2319             &allocParamsForBuffer,
2320             &refList[idx]->sDysSurface.OsResource));
2321 
2322         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
2323             m_osInterface,
2324             &refList[idx]->sDysSurface));
2325     }
2326 
2327     refList[idx]->sDysSurface.dwWidth = m_oriFrameWidth;
2328     refList[idx]->sDysSurface.dwHeight = m_oriFrameHeight;
2329 
2330     // We use PAK to perform dynamic scaling for reference frame, basically if every CU is inter and skipped, the reconstructed picture will be
2331     // the down scaled copy of reference frame.
2332     // Here driver needs to prepare pak obj and cu record, since PAK has a limitation that input picture needs to be CU boundary aligned,
2333     // and to simplify handling the boundary condition, we set each CU with size 8x8, inter and zero MV.
2334     // Segment skip needs to be turned on also.
2335 
2336     auto oriFrameHeight = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_HEIGHT);
2337     auto oriFrameWidth  = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH);
2338 
2339     uint32_t numCuLastSbCol = (oriFrameWidth / CODEC_VP9_MIN_BLOCK_WIDTH) - (m_picWidthInSb - 1) * (CODEC_VP9_SUPER_BLOCK_WIDTH / CODEC_VP9_MIN_BLOCK_WIDTH);
2340     uint32_t numCuLastSbRow = (oriFrameHeight / CODEC_VP9_MIN_BLOCK_HEIGHT) - (m_picHeightInSb - 1) * (CODEC_VP9_SUPER_BLOCK_HEIGHT / CODEC_VP9_MIN_BLOCK_HEIGHT);
2341 
2342     MOS_LOCK_PARAMS lockFlags;
2343     MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
2344     lockFlags.WriteOnly = 1;
2345     uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
2346         m_osInterface, &m_resMbCodeSurface, &lockFlags);
2347     CODECHAL_ENCODE_CHK_NULL_RETURN(data);
2348 
2349     HcpPakObject* pakObjData = (HcpPakObject*)data;
2350     CU_DATA* cuDataPtr = (CU_DATA*)(data + m_mvOffset);
2351 
2352     // fill pak object
2353     HcpPakObject pakObj;
2354     MOS_ZeroMemory(&pakObj, sizeof(pakObj));
2355     pakObj.DW0.Type         = 0x03;
2356     pakObj.DW0.Opcode       = 0x27;
2357     pakObj.DW0.SubOp        = 0x35;
2358     pakObj.DW0.DwordLength  = 1;   //Total 4 DW. But only 3 DW are actual fields //DW 0,1 excluded from this field as per Spec definition
2359 
2360     pakObj.DW1.Split_flag_level0 = 1;
2361     pakObj.DW1.Split_flag_level1 = 0xF;
2362     pakObj.DW1.Split_flag_level2_level1part0 = 0xF;
2363     pakObj.DW1.Split_flag_level2_level1part1 = 0xF;
2364     pakObj.DW1.Split_flag_level2_level1part2 = 0xF;
2365     pakObj.DW1.Split_flag_level2_level1part3 = 0xF;
2366 
2367     // fill cu data
2368     CU_DATA cuData;
2369     MOS_ZeroMemory(&cuData, sizeof(cuData));
2370     cuData.cu_size = 0;  // 8x8
2371     cuData.cu_pred_mode0 = cuData.cu_pred_mode1 = 1;  // Inter
2372     cuData.refframe_part0_l0 = cuData.refframe_part1_l0 = refIdx;
2373 
2374     for (uint32_t j = 0; j < m_picHeightInSb; j++)
2375     {
2376         for (uint32_t  i = 0; i < m_picWidthInSb; i++)
2377         {
2378             if ((j == m_picHeightInSb - 1) && (i == m_picWidthInSb - 1))
2379             {
2380                 pakObj.DW1.CU_count_minus1 = numCuLastSbCol * numCuLastSbRow - 1;
2381                 pakObj.DW1.IsLastSBFrameflag = pakObj.DW1.IsLastSBTileflag = 1;
2382                 pakObj.Reserved_DW03 = 0x05000000; // add batch buffer end flag
2383             }
2384             else if (i == m_picWidthInSb - 1)
2385             {
2386                 pakObj.DW1.CU_count_minus1 = numCuLastSbCol * 8 - 1;
2387             }
2388             else if (j == m_picHeightInSb - 1)
2389             {
2390                 pakObj.DW1.CU_count_minus1 = numCuLastSbRow * 8 - 1;
2391             }
2392             else
2393             {
2394                 pakObj.DW1.CU_count_minus1 = 63;
2395             }
2396 
2397             pakObj.DW2.Current_SB_X_Addr = i;
2398             pakObj.DW2.Current_SB_Y_Addr = j;
2399 
2400             *pakObjData++ = pakObj;
2401 
2402             for (unsigned int cuIdx = 0; cuIdx < 64; cuIdx++)
2403             {
2404                 *cuDataPtr++ = cuData;
2405             }
2406         }
2407     }
2408 
2409     m_osInterface->pfnUnlockResource(m_osInterface, &m_resMbCodeSurface);
2410 
2411     // save current state
2412     // we only need to run PAK to get the recon picture, so disable HuC and VDENC here
2413     m_vdencEnabled = false;
2414     m_dysHucEnabled = m_hucEnabled;
2415     m_hucEnabled = false;
2416     bool origWaitForENC = m_waitForEnc;
2417     m_waitForEnc = false;
2418     MOS_SURFACE origReconSurface = m_reconSurface;
2419     // Set the downscaled surface as the recon output surface
2420     m_reconSurface = refList[idx]->sDysSurface;
2421     // save the ucNumPasses and set the ucNumPasses = ucCurrPass + 1. otherwise SliceLevel will mistakenly treat current pass as last pass
2422     uint8_t origNumPasses = m_numPasses;
2423     m_numPasses = m_currPass + 1;
2424 
2425     bool origSegmentSkip[CODEC_VP9_MAX_SEGMENTS] = {false};
2426     for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
2427     {
2428         origSegmentSkip[i]                                                = m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped;
2429         m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped = true;
2430     }
2431 
2432     CODECHAL_ENCODE_CHK_STATUS_RETURN(ExecuteDysPictureLevel());
2433     CODECHAL_ENCODE_CHK_STATUS_RETURN(ExecuteDysSliceLevel());
2434 
2435     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
2436         &refList[idx]->sDysSurface,
2437         CodechalDbgAttr::attrReferenceSurfaces,
2438         (refIdx == 1) ? "DysLastScaledSurf" : (refIdx == 2) ? "DysGoldenScaledSurf" : "DysAltScaledSurf")));
2439     // recover state
2440     m_vdencEnabled = true;
2441     m_waitForEnc = origWaitForENC;
2442     m_reconSurface = origReconSurface;
2443     m_numPasses = origNumPasses;
2444     m_hucEnabled = (m_dysHucEnabled && !m_dysVdencMultiPassEnabled);
2445     for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
2446     {
2447         m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped = origSegmentSkip[i];
2448     }
2449 
2450     return eStatus;
2451 }
2452 
2453 //------------------------------------------------------------------------------
2454 //| Purpose:    Setup Sampler State for VP9 DYS Kernels
2455 //| Return:     N/A
2456 //------------------------------------------------------------------------------
SetSamplerStateDys(DysSamplerStateParams * params)2457 MOS_STATUS CodechalVdencVp9State::SetSamplerStateDys(
2458     DysSamplerStateParams* params)
2459 {
2460     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2461 
2462     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2463     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
2464 
2465     MHW_SAMPLER_STATE_PARAM samplerParams;
2466     MOS_ZeroMemory(&samplerParams, sizeof(samplerParams));
2467 
2468     samplerParams.bInUse = true;
2469     samplerParams.SamplerType = MHW_SAMPLER_TYPE_AVS;
2470     samplerParams.Avs.bEnableAVS = true;
2471     samplerParams.Avs.wR3cCoefficient = 15;
2472     samplerParams.Avs.wR3xCoefficient = 6;
2473     samplerParams.Avs.StrongEdgeThr = 8;
2474     samplerParams.Avs.WeakEdgeThr = 1;
2475     samplerParams.Avs.GainFactor = 32;
2476     samplerParams.Avs.bHdcDwEnable = 1;
2477 
2478     samplerParams.Avs.wR5cCoefficient = 3;
2479     samplerParams.Avs.wR5cxCoefficient = 8;
2480     samplerParams.Avs.wR5xCoefficient = 9;
2481     samplerParams.Avs.StrongEdgeWght = 6;
2482     samplerParams.Avs.RegularWght = 3;
2483     samplerParams.Avs.NonEdgeWght = 2;
2484     samplerParams.Avs.GlobalNoiseEstm = 255;
2485 
2486     samplerParams.Avs.AdditionalOverridesUsed = 1;
2487     samplerParams.Avs.YSlope2 = 24;
2488     samplerParams.Avs.S0L = 1792;
2489     samplerParams.Avs.YSlope1 = 24;
2490     samplerParams.Avs.S2U = 1792;
2491     samplerParams.Avs.S1U = 0;
2492 
2493     MHW_SAMPLER_AVS_TABLE_PARAM samplerTableParams;
2494     MOS_ZeroMemory(&samplerTableParams, sizeof(samplerTableParams));
2495     samplerParams.Avs.pMhwSamplerAvsTableParam = &samplerTableParams;
2496 
2497     MOS_SecureMemcpy(samplerTableParams.paMhwAvsCoeffParam,
2498         sizeof(samplerTableParams.paMhwAvsCoeffParam),
2499         m_samplerFilterCoeffs,
2500         MHW_NUM_HW_POLYPHASE_TABLES * 6 * sizeof(uint32_t));
2501 
2502     MOS_SecureMemcpy(samplerTableParams.paMhwAvsCoeffParamExtra,
2503         sizeof(samplerTableParams.paMhwAvsCoeffParamExtra),
2504         &m_samplerFilterCoeffs[MHW_NUM_HW_POLYPHASE_TABLES][0],
2505         MHW_NUM_HW_POLYPHASE_EXTRA_TABLES_G9 * 6 * sizeof(uint32_t));
2506 
2507     samplerTableParams.byteDefaultSharpnessLevel = 255;
2508     samplerTableParams.byteMaxDerivative4Pixels = 7;
2509     samplerTableParams.byteMaxDerivative8Pixels = 20;
2510     samplerTableParams.byteTransitionArea4Pixels = 4;
2511     samplerTableParams.byteTransitionArea8Pixels = 5;
2512 
2513     samplerTableParams.bBypassXAdaptiveFiltering = 1;
2514     samplerTableParams.bBypassYAdaptiveFiltering = 1;
2515     samplerTableParams.bAdaptiveFilterAllChannels = 0;
2516 
2517     MHW_RENDER_STATE_SIZES* hwSizes = m_stateHeapInterface->pStateHeapInterface->GetHwSizesPointer();
2518     CODECHAL_ENCODE_CHK_NULL_RETURN(hwSizes);
2519     uint8_t* sampler = (uint8_t*)MOS_AllocAndZeroMemory(hwSizes->dwSizeSamplerStateAvs);
2520     CODECHAL_ENCODE_CHK_NULL_RETURN(sampler);
2521 
2522     eStatus = m_stateHeapInterface->pfnSetSamplerState(m_stateHeapInterface, sampler, &samplerParams);
2523     if (eStatus != MOS_STATUS_SUCCESS)
2524     {
2525         MOS_FreeMemory(sampler);
2526         return eStatus;
2527     }
2528 
2529     eStatus = params->pKernelState->m_dshRegion.AddData(
2530         sampler,
2531         params->pKernelState->dwSamplerOffset,
2532         hwSizes->dwSizeSamplerStateAvs);
2533 
2534         MOS_FreeMemory(sampler);
2535         return eStatus;
2536 }
2537 
2538 //------------------------------------------------------------------------------
2539 //| Purpose:    Setup Curbe for VP9 DYS Kernels
2540 //| Return:     N/A
2541 //------------------------------------------------------------------------------
SetCurbeDys(DysCurbeParams * params)2542 MOS_STATUS CodechalVdencVp9State::SetCurbeDys(
2543     DysCurbeParams* params)
2544 {
2545     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2546 
2547     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2548     CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
2549 
2550     DysStaticData cmd;
2551     MOS_ZeroMemory(&cmd, sizeof(DysStaticData));
2552 
2553     cmd.DW0.InputFrameWidth         = params->dwInputWidth;;
2554     cmd.DW0.InputFrameHeight        = params->dwInputHeight;
2555 
2556     cmd.DW1.OutputFrameWidth        = params->dwOutputWidth;
2557     cmd.DW1.OutputFrameHeight       = params->dwOutputHeight;
2558 
2559     cmd.DW2.DeltaU                  = 1.0f / params->dwOutputWidth;
2560     cmd.DW3.DeltaV                  = 1.0f / params->dwOutputHeight;
2561 
2562     cmd.DW16.InputFrameNV12SurfBTI  = 0; //Surface 0
2563     cmd.DW17.OutputFrameYSurfBTI    = 1; //surface 1
2564     cmd.DW18.AVSSampleIdx           = 0;
2565 
2566     CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
2567         &cmd,
2568         params->pKernelState->dwCurbeOffset,
2569         sizeof(cmd)));
2570 
2571     return eStatus;
2572 }
2573 
2574 // ------------------------------------------------------------------------------
2575 // Send surfaces for the VP9 DYS kernel
2576 //------------------------------------------------------------------------------------
SendDysSurfaces(PMOS_COMMAND_BUFFER cmdBuffer,DysSurfaceParams * params)2577 MOS_STATUS CodechalVdencVp9State::SendDysSurfaces(
2578     PMOS_COMMAND_BUFFER cmdBuffer,
2579     DysSurfaceParams* params)
2580 {
2581     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2582 
2583     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
2584     CODECHAL_ENCODE_CHK_NULL_RETURN(params);
2585     CODECHAL_ENCODE_CHK_NULL_RETURN(params->kernelState);
2586     CODECHAL_ENCODE_CHK_NULL_RETURN(params->dysBindingTable);
2587 
2588     DysBindingTable* dysBindingTable = (DysBindingTable*)params->dysBindingTable;
2589 
2590     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
2591     MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
2592     surfaceCodecParams.bUseAdvState         = true;
2593     surfaceCodecParams.psSurface            = params->inputFrameSurface;
2594     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
2595     surfaceCodecParams.ucVDirection         = g_cMhw_VDirection[MHW_FRAME];
2596     surfaceCodecParams.dwBindingTableOffset = dysBindingTable->dysInputFrameNv12;
2597     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
2598         m_hwInterface,
2599         cmdBuffer,
2600         &surfaceCodecParams,
2601         params->kernelState));
2602 
2603     MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
2604     surfaceCodecParams.bIs2DSurface                 = true;
2605     surfaceCodecParams.bMediaBlockRW                = true;
2606     surfaceCodecParams.bUseUVPlane                  = true;
2607     surfaceCodecParams.psSurface                    = params->outputFrameSurface;
2608     surfaceCodecParams.dwCacheabilityControl        = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
2609     surfaceCodecParams.dwBindingTableOffset         = dysBindingTable->dysOutputFrameY;
2610     surfaceCodecParams.dwUVBindingTableOffset       = dysBindingTable->dysOutputFrameUV;
2611     surfaceCodecParams.dwVerticalLineStride         = params->verticalLineStride;
2612     surfaceCodecParams.dwVerticalLineStrideOffset   = params->verticalLineStrideOffset;
2613     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
2614         m_hwInterface,
2615         cmdBuffer,
2616         &surfaceCodecParams,
2617         params->kernelState));
2618 
2619     return eStatus;
2620 }
2621 
DysKernel(DysKernelParams * dysKernelParams)2622 MOS_STATUS CodechalVdencVp9State::DysKernel(
2623     DysKernelParams* dysKernelParams)
2624 {
2625     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2626 
2627     CODECHAL_ENCODE_FUNCTION_ENTER;
2628 
2629     CODECHAL_ENCODE_CHK_NULL_RETURN(dysKernelParams);
2630 
2631     PerfTagSetting perfTag;
2632     CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL);
2633 
2634     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12;
2635     MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS));
2636     allocParamsForBufferNV12.Type = MOS_GFXRES_2D;
2637     allocParamsForBufferNV12.TileType = MOS_TILE_Y;
2638     allocParamsForBufferNV12.Format = Format_NV12;
2639 
2640     PMHW_KERNEL_STATE kernelState = &m_dysKernelState;
2641     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
2642         m_stateHeapInterface,
2643         kernelState->KernelParams.iBTCount));
2644 
2645     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
2646         m_stateHeapInterface,
2647         kernelState,
2648         false,
2649         m_dysDshSize,
2650         false,
2651         m_storeData));
2652 
2653     DysSamplerStateParams dysSamplerStateParams;
2654     MOS_ZeroMemory(&dysSamplerStateParams, sizeof(dysSamplerStateParams));
2655     dysSamplerStateParams.pKernelState = kernelState;
2656     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSamplerStateDys(&dysSamplerStateParams));
2657 
2658     DysCurbeParams dysCurbeParams;
2659     MOS_ZeroMemory(&dysCurbeParams, sizeof(dysCurbeParams));
2660     dysCurbeParams.dwInputWidth = dysKernelParams->dwInputWidth;
2661     dysCurbeParams.dwInputHeight = dysKernelParams->dwInputHeight;
2662     dysCurbeParams.dwOutputWidth = dysKernelParams->dwOutputWidth;
2663     dysCurbeParams.dwOutputHeight = dysKernelParams->dwOutputHeight;
2664     dysCurbeParams.pKernelState = kernelState;
2665     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeDys(&dysCurbeParams));
2666 
2667     MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
2668     MOS_ZeroMemory(&idParams, sizeof(idParams));
2669     idParams.pKernelState = kernelState;
2670     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
2671         m_stateHeapInterface,
2672         1,
2673         &idParams));
2674 
2675     CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_VP9_DYS;
2676     CODECHAL_DEBUG_TOOL(
2677         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2678             encFunctionType,
2679             MHW_DSH_TYPE,
2680             kernelState));
2681     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
2682         encFunctionType,
2683         kernelState));
2684     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2685         encFunctionType,
2686         MHW_ISH_TYPE,
2687         kernelState));
2688     )
2689 
2690     m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(kernelState->KernelParams.iBTCount);
2691     CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifyCommandBufferSize());
2692 
2693     MOS_COMMAND_BUFFER cmdBuffer;
2694     CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer));
2695 
2696     SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
2697     sendKernelCmdsParams.EncFunctionType = encFunctionType;
2698     sendKernelCmdsParams.pKernelState = kernelState;
2699     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
2700 
2701     // Add binding table
2702     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
2703         m_stateHeapInterface,
2704         kernelState));
2705 
2706     // allocate dynamic scaled surfaces if needed
2707     if (Mos_ResourceIsNull(&dysKernelParams->psOutputSurface->OsResource) ||
2708         (dysKernelParams->psOutputSurface->dwWidth != dysKernelParams->dwOutputWidth) || (dysKernelParams->psOutputSurface->dwHeight != dysKernelParams->dwOutputHeight))
2709     {
2710         // free existing resource first if resolution changes
2711         if (!Mos_ResourceIsNull(&dysKernelParams->psOutputSurface->OsResource))
2712         {
2713             m_osInterface->pfnFreeResource(
2714                 m_osInterface,
2715                 &dysKernelParams->psOutputSurface->OsResource);
2716         }
2717 
2718         allocParamsForBufferNV12.dwWidth = MOS_ALIGN_CEIL(dysKernelParams->dwOutputWidth, 64);
2719         allocParamsForBufferNV12.dwHeight = MOS_ALIGN_CEIL(dysKernelParams->dwOutputHeight, 64);
2720         allocParamsForBufferNV12.pBufName = "Dynamic Scaled Surface for VP9";
2721 
2722         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
2723             m_osInterface,
2724             &allocParamsForBufferNV12,
2725             &dysKernelParams->psOutputSurface->OsResource));
2726 
2727         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
2728             m_osInterface,
2729             dysKernelParams->psOutputSurface));
2730 
2731         dysKernelParams->psOutputSurface->dwWidth = dysKernelParams->dwOutputWidth;
2732         dysKernelParams->psOutputSurface->dwHeight = dysKernelParams->dwOutputHeight;
2733     }
2734 
2735     // Add surface states
2736     DysSurfaceParams dysSurfaceParams;
2737     MOS_ZeroMemory(&dysSurfaceParams, sizeof(DysSurfaceParams));
2738     dysSurfaceParams.inputFrameSurface = dysKernelParams->psInputSurface;
2739     dysSurfaceParams.outputFrameSurface = dysKernelParams->psOutputSurface;
2740     dysSurfaceParams.verticalLineStride = m_verticalLineStride;
2741     dysSurfaceParams.verticalLineStrideOffset = m_verticalLineStrideOffset;
2742     dysSurfaceParams.kernelState = kernelState;
2743     dysSurfaceParams.dysBindingTable = &m_dysBindingTable;
2744     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendDysSurfaces(&cmdBuffer, &dysSurfaceParams));
2745 
2746     CODECHAL_DEBUG_TOOL(
2747         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
2748             encFunctionType,
2749             MHW_SSH_TYPE,
2750             kernelState))
2751     );
2752 
2753     if (m_hwWalker)
2754     {
2755         uint32_t resolutionX = (uint32_t)m_picWidthInMb;
2756         uint32_t resolutionY = (uint32_t)m_frameFieldHeightInMb;
2757 
2758         CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
2759         MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
2760         walkerCodecParams.WalkerMode = m_walkerMode;
2761         walkerCodecParams.dwResolutionX = resolutionX;
2762         walkerCodecParams.dwResolutionY = resolutionY;
2763         walkerCodecParams.bNoDependency = true;
2764 
2765         MHW_WALKER_PARAMS walkerParams;
2766         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
2767             m_hwInterface,
2768             &walkerParams,
2769             &walkerCodecParams));
2770 
2771         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObjectWalkerCmd(
2772             &cmdBuffer,
2773             &walkerParams));
2774     }
2775 
2776     CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
2777 
2778     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
2779         m_stateHeapInterface));
2780 
2781     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(
2782         &cmdBuffer,
2783         nullptr));
2784 
2785     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
2786         &cmdBuffer,
2787         encFunctionType,
2788         nullptr)));
2789 
2790     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
2791 
2792     CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer));
2793 
2794     CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, m_renderContextUsesNullHw));
2795 
2796     return eStatus;
2797 }
2798 
InitMEState(VdencVmeState * state)2799 MOS_STATUS CodechalVdencVp9State::InitMEState(
2800     VdencVmeState* state)
2801 {
2802     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2803 
2804     CODECHAL_ENCODE_FUNCTION_ENTER;
2805 
2806     CODECHAL_ENCODE_CHK_NULL_RETURN(state);
2807     MOS_ZeroMemory(state, sizeof(VdencVmeState));
2808     // Frame settings
2809     state->QpY                          = m_vp9PicParams->LumaACQIndex;
2810     state->CurrOriginalPic              = m_vp9PicParams->CurrOriginalPic;
2811     state->TargetUsage                  = m_vp9SeqParams->TargetUsage;
2812     state->GopRefDist                   = (uint8_t)m_vp9SeqParams->GopPicSize;  // -1 ??
2813     state->num_ref_idx_l0_active_minus1 = m_numRefFrames - 1;
2814     state->num_ref_idx_l1_active_minus1 = 0;
2815 
2816     // Constant values
2817     state->Level                        = 51;
2818     state->direct_spatial_mv_pred_flag  = true;
2819     state->dwBiWeight                   = 32;
2820     state->CurrOriginalPic.PicFlags     = PICTURE_FRAME;
2821 
2822     // Buffers
2823     state->s4xMeMvDataBuffer     = m_4xMeMvDataBuffer;
2824     state->s16xMeMvDataBuffer    = m_16xMeMvDataBuffer;
2825     state->s4xMeDistortionBuffer = m_4xMeDistortionBuffer;
2826 
2827     // Reference lookups
2828     // Use max of HEVC num surfaces because this is shared functionality between HEVC and VP9 and HEVC has less
2829     for (auto i = 0; i < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC ; ++i)
2830     {
2831         state->pRefList[i] = m_refList[i];
2832     }
2833 
2834     for (auto i = 0 ; i < CODEC_VP9_NUM_REF_FRAMES ; ++i)
2835     {
2836         state->PicIdx[i] = m_picIdx[i];
2837     }
2838 
2839     // Add references
2840     CODEC_PICTURE codecPicture;
2841     MOS_ZeroMemory(&codecPicture, sizeof(codecPicture));
2842     codecPicture.PicFlags = PICTURE_FRAME;
2843     uint8_t picCount = 0;
2844     if (m_lastRefPic)
2845     {
2846         codecPicture.FrameIdx               = m_vp9PicParams->RefFlags.fields.LastRefIdx;
2847         state->RefPicList[LIST_0][picCount] = codecPicture;
2848         picCount++;
2849     }
2850 
2851     if (m_goldenRefPic)
2852     {
2853         codecPicture.FrameIdx               = m_vp9PicParams->RefFlags.fields.GoldenRefIdx;
2854         state->RefPicList[LIST_0][picCount] = codecPicture;
2855         picCount++;
2856     }
2857 
2858     if (m_altRefPic)
2859     {
2860         codecPicture.FrameIdx               = m_vp9PicParams->RefFlags.fields.AltRefIdx;
2861         state->RefPicList[LIST_0][picCount] = codecPicture;
2862         picCount++;
2863     }
2864 
2865     // Mark L1[0] as INVALID so it's not added later, L1 refs should never be added for VP9, L1[0] should
2866     // always be marked as invalid and num_ref_idx_l1_active_minus1 should always == 0
2867     state->RefPicList[LIST_1][0].PicFlags = PICTURE_INVALID;
2868 
2869     return eStatus;
2870 }
2871 
VdencSetCurbeHmeKernel(VdencVmeState * state)2872 MOS_STATUS CodechalVdencVp9State::VdencSetCurbeHmeKernel(
2873     VdencVmeState* state)
2874 {
2875     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2876 
2877     CODECHAL_ENCODE_FUNCTION_ENTER;
2878 
2879      CODECHAL_ENCODE_CHK_NULL_RETURN(state);
2880 
2881     bool isFramePicture  = CodecHal_PictureIsFrame(state->CurrOriginalPic);
2882     char qpPrimeY       = (state->QpY) + state->slice_qp_delta;
2883 
2884     VdencMeCurbe curbe;
2885     CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
2886         &curbe,
2887         sizeof(VdencMeCurbe),
2888         m_vdencMeCurbeInit,
2889         sizeof(VdencMeCurbe)));
2890 
2891     uint8_t mvShiftFactor = 0, prevMvReadPosFactor = 0;
2892     bool useMvFromPrevStep = false, writeDistortions = false;
2893     uint32_t scaleFactor = 0;
2894     PMHW_KERNEL_STATE kernelState;
2895     if (state->b16xMeInUse)
2896     {
2897         kernelState             = &m_vdencMeKernelState;
2898         useMvFromPrevStep       = false;
2899         writeDistortions        = false;
2900         scaleFactor            = SCALE_FACTOR_16x;
2901         mvShiftFactor          = 2;
2902         prevMvReadPosFactor    = 1;
2903     }
2904     else
2905     {
2906         kernelState             = &m_vdencStreaminKernelState;
2907         useMvFromPrevStep       = true;
2908         writeDistortions        = true;
2909         scaleFactor            = SCALE_FACTOR_4x;
2910         mvShiftFactor          = 2;
2911         prevMvReadPosFactor    = 0;
2912     }
2913 
2914     curbe.DW3.SubPelMode = 3;
2915 
2916     if (m_fieldScalingOutputInterleaved)
2917     {
2918         curbe.DW3.SrcAccess =
2919             curbe.DW3.RefAccess        = CodecHal_PictureIsField(state->CurrOriginalPic) ? 1 : 0;
2920         curbe.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(state->CurrOriginalPic) ? 1 : 0;
2921     }
2922 
2923     curbe.DW4.PictureHeightMinus1    = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1;
2924     curbe.DW4.PictureWidth           = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor);
2925     curbe.DW5.QpPrimeY               = qpPrimeY;
2926     curbe.DW6.WriteDistortions       = writeDistortions;
2927     curbe.DW6.UseMvFromPrevStep      = useMvFromPrevStep;
2928     curbe.DW6.SuperCombineDist       = 5;
2929     curbe.DW6.MaxVmvR                = m_maxMvLen;
2930 
2931     if (m_pictureCodingType == B_TYPE)
2932     {
2933         // This field is irrelevant since we are not using the bi-direct search.
2934         curbe.DW1.BiWeight              = state->dwBiWeight;
2935         curbe.DW13.NumRefIdxL1MinusOne  = state->num_ref_idx_l1_active_minus1;
2936     }
2937 
2938     if (m_pictureCodingType == P_TYPE ||  m_pictureCodingType == B_TYPE)
2939     {
2940         curbe.DW13.NumRefIdxL0MinusOne = state->num_ref_idx_l0_active_minus1;
2941     }
2942 
2943     curbe.DW30.ActualMBHeight   = (MOS_ALIGN_CEIL(m_frameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT ) / 32);
2944     curbe.DW30.ActualMBWidth    = (MOS_ALIGN_CEIL(m_frameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH) / 32);
2945     curbe.DW13.RefStreaminCost  = 0;
2946     // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not
2947     curbe.DW13.ROIEnable        = 0;
2948 
2949     uint8_t targetUsage = state->TargetUsage;
2950     uint8_t meMethod = 0;
2951     if (m_pictureCodingType == B_TYPE)
2952     {
2953         meMethod = m_bMeMethodGeneric[targetUsage];
2954     }
2955     else
2956     {
2957         meMethod = m_meMethodGeneric[targetUsage];
2958     }
2959 
2960     uint8_t tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0;
2961     eStatus = MOS_SecureMemcpy(&(curbe.SPDelta), 14 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 14 * sizeof(uint32_t));
2962     if (eStatus != MOS_STATUS_SUCCESS)
2963     {
2964         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
2965         return eStatus;
2966     }
2967 
2968     if (state->b4xMeInUse)
2969     {
2970         //StreamIn CURBE
2971         curbe.DW6.LCUSize                 = 1;//Only LCU64 supported by the VDEnc HW
2972         curbe.DW6.InputStreamInEn         = state->segmapProvided;
2973         curbe.DW31.NumImePredictors       = CODECHAL_VDENC_NUMIMEPREDICTORS;
2974         curbe.DW31.MaxCuSize              = 3;
2975         curbe.DW31.MaxTuSize              = 3;
2976         switch (state->TargetUsage)
2977         {
2978         case 1:
2979         case 4:
2980             curbe.DW36.NumMergeCandCu64x64 = 4;
2981             curbe.DW36.NumMergeCandCu32x32 = 3;
2982             curbe.DW36.NumMergeCandCu16x16 = 2;
2983             curbe.DW36.NumMergeCandCu8x8 = 1;
2984             break;
2985         case 7:
2986             curbe.DW36.NumMergeCandCu64x64 = 2;
2987             curbe.DW36.NumMergeCandCu32x32 = 2;
2988             curbe.DW36.NumMergeCandCu16x16 = 2;
2989             curbe.DW36.NumMergeCandCu8x8 = 0;
2990             break;
2991         }
2992     }
2993 
2994     curbe.DW40._4xMeMvOutputDataSurfIndex        = HmeMvDataSurfaceCm;
2995     curbe.DW41._16xOr32xMeMvInputDataSurfIndex   = Hme16xMeMvDataSurfaceCm;
2996     curbe.DW42._4xMeOutputDistSurfIndex          = HmeDistortionSurfaceCm;
2997     curbe.DW43._4xMeOutputBrcDistSurfIndex       = HmeBrcDistortionCm;
2998     curbe.DW44.VMEFwdInterPredictionSurfIndex    = HmeCurrForFwdRefCm;
2999     curbe.DW45.VMEBwdInterPredictionSurfIndex    = HmeCurrForBwdRefCm;
3000     curbe.DW46.VDEncStreamInOutputSurfIndex      = HmeVdencStreaminOutputCm;
3001     curbe.DW47.VDEncStreamInInputSurfIndex       = HmeVdencStreaminInputCm;
3002 
3003     CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData(
3004         &curbe,
3005         kernelState->dwCurbeOffset,
3006         sizeof(curbe)));
3007 
3008     return eStatus;
3009 }
3010 
VdencSendHmeSurfaces(VdencVmeState * state,PMOS_COMMAND_BUFFER cmdBuffer)3011 MOS_STATUS CodechalVdencVp9State::VdencSendHmeSurfaces(
3012     VdencVmeState* state,
3013     PMOS_COMMAND_BUFFER cmdBuffer)
3014 {
3015     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3016 
3017     CODECHAL_ENCODE_FUNCTION_ENTER;
3018 
3019     CODECHAL_ENCODE_CHK_NULL_RETURN(state);
3020 
3021     bool isCurrFieldPicture       = CodecHal_PictureIsField(m_currOriginalPic) ? true : false;
3022     bool isCurrBottomField        = CodecHal_PictureIsBottomField(m_currOriginalPic) ? true : false;
3023     uint8_t currVDirection        = (!isCurrFieldPicture) ? CODECHAL_VDIRECTION_FRAME :
3024         ((isCurrBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
3025 
3026     PMHW_KERNEL_STATE kernelState = nullptr;
3027     PCODECHAL_ENCODE_BINDING_TABLE_GENERIC bindingTable = nullptr;
3028     PMOS_SURFACE currScaledSurface = nullptr, meMvDataBuffer = nullptr;
3029     uint32_t meMvBottomFieldOffset = 0, currScaledBottomFieldOffset = 0;
3030     uint32_t downscaledWidthInMb = 0, downscaledHeightInMb = 0;
3031     if (state->b16xMeInUse)
3032     {
3033         CODECHAL_ENCODE_CHK_NULL_RETURN(&state->s16xMeMvDataBuffer);
3034         kernelState                   = &m_vdencMeKernelState;
3035         bindingTable                  = &m_vdencMeKernelBindingTable;
3036         currScaledSurface            = m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
3037         meMvDataBuffer               = &state->s16xMeMvDataBuffer;
3038         meMvBottomFieldOffset        = 0;
3039         currScaledBottomFieldOffset  = m_scaled16xBottomFieldOffset;
3040         downscaledWidthInMb          = m_downscaledWidthInMb16x;
3041         downscaledHeightInMb         = m_downscaledHeightInMb16x;
3042     }
3043     else
3044     {
3045         CODECHAL_ENCODE_CHK_NULL_RETURN(&state->s4xMeMvDataBuffer);
3046         CODECHAL_ENCODE_CHK_NULL_RETURN(&m_resVdencStreamInBuffer[m_currRecycledBufIdx]);
3047         kernelState                  = &m_vdencStreaminKernelState;
3048         bindingTable                 = &m_vdencStreaminKernelBindingTable;
3049         currScaledSurface           = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
3050         meMvDataBuffer              = &state->s4xMeMvDataBuffer;
3051         meMvBottomFieldOffset       = 0;
3052         currScaledBottomFieldOffset = m_scaledBottomFieldOffset;
3053         downscaledWidthInMb         = m_downscaledWidthInMb4x;
3054         downscaledHeightInMb        = m_downscaledHeightInMb4x;
3055     }
3056 
3057     uint32_t width  = MOS_ALIGN_CEIL(downscaledWidthInMb * 32, 64);
3058     uint32_t height = downscaledHeightInMb * 4 * 10;
3059 
3060     // Force the values
3061     meMvDataBuffer->dwWidth   = width;
3062     meMvDataBuffer->dwHeight  = height;
3063     meMvDataBuffer->dwPitch   = width;
3064 
3065     CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
3066     MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3067     surfaceCodecParams.bIs2DSurface    = true;
3068     surfaceCodecParams.bMediaBlockRW   = true;
3069     surfaceCodecParams.psSurface       = meMvDataBuffer;
3070     surfaceCodecParams.dwOffset        = meMvBottomFieldOffset;
3071     surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
3072     surfaceCodecParams.dwBindingTableOffset  = bindingTable->dwBindingTableEntries[HmeMvDataSurfaceCm];
3073     surfaceCodecParams.bIsWritable   = true;
3074     surfaceCodecParams.bRenderTarget = true;
3075     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3076         m_hwInterface,
3077         cmdBuffer,
3078         &surfaceCodecParams,
3079         kernelState));
3080 
3081     if (state->b4xMeInUse)
3082     {
3083         // Pass 16x MV to 4x ME operation
3084         MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3085         surfaceCodecParams.bIs2DSurface             = true;
3086         surfaceCodecParams.bMediaBlockRW            = true;
3087         surfaceCodecParams.psSurface                = &state->s16xMeMvDataBuffer;
3088         surfaceCodecParams.dwOffset                 = 0;
3089         surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
3090         surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[Hme16xMeMvDataSurfaceCm];
3091         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3092             m_hwInterface,
3093             cmdBuffer,
3094             &surfaceCodecParams,
3095             kernelState));
3096 
3097         MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3098         surfaceCodecParams.bIs2DSurface          = true;
3099         surfaceCodecParams.bMediaBlockRW         = true;
3100         surfaceCodecParams.psSurface             = &state->s4xMeDistortionBuffer;
3101         surfaceCodecParams.dwOffset              = 0;
3102         surfaceCodecParams.dwBindingTableOffset  = bindingTable->dwBindingTableEntries[HmeDistortionSurfaceCm];
3103         surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
3104         surfaceCodecParams.bIsWritable           = true;
3105         surfaceCodecParams.bRenderTarget         = true;
3106         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3107             m_hwInterface,
3108             cmdBuffer,
3109             &surfaceCodecParams,
3110             kernelState));
3111     }
3112 
3113     // Setup references 1...n
3114     // LIST 0 references
3115     MOS_SURFACE refScaledSurface = *currScaledSurface;
3116     for (uint8_t refIdx = 0; refIdx <= state->num_ref_idx_l0_active_minus1; refIdx++)
3117     {
3118         CODEC_PICTURE refPic = state->RefPicList[LIST_0][refIdx];
3119 
3120         if (!CodecHal_PictureIsInvalid(refPic))
3121         {
3122             if (refIdx == 0)
3123             {
3124                 // Current Picture Y - VME
3125                 MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3126                 surfaceCodecParams.bUseAdvState             = true;
3127                 surfaceCodecParams.psSurface                = currScaledSurface;
3128                 surfaceCodecParams.dwOffset                 = isCurrBottomField ? currScaledBottomFieldOffset : 0;
3129                 surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
3130                 surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[HmeCurrForFwdRefCm];
3131                 surfaceCodecParams.ucVDirection             = currVDirection;
3132                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3133                     m_hwInterface,
3134                     cmdBuffer,
3135                     &surfaceCodecParams,
3136                     kernelState));
3137             }
3138 
3139             bool isRefFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0;
3140             bool isRefBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
3141             uint8_t refPicIdx    = state->PicIdx[refPic.FrameIdx].ucPicIdx;
3142             uint8_t scaledIdx    = state->pRefList[refPicIdx]->ucScalingIdx;
3143             if (state->b16xMeInUse)
3144             {
3145                 MOS_SURFACE* p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx);
3146                 if (p16xSurface != nullptr)
3147                 {
3148                     refScaledSurface.OsResource = p16xSurface->OsResource;
3149                 }
3150                 else
3151                 {
3152                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
3153                 }
3154             }
3155             else
3156             {
3157                 MOS_SURFACE* p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx);
3158                 if (p4xSurface != nullptr)
3159                 {
3160                     refScaledSurface.OsResource = p4xSurface->OsResource;
3161                 }
3162                 else
3163                 {
3164                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
3165                 }
3166             }
3167             uint32_t refScaledBottomFieldOffset = isRefBottomField ? currScaledBottomFieldOffset : 0;
3168 
3169             // L0 Reference Picture Y - VME
3170             MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3171             surfaceCodecParams.bUseAdvState             = true;
3172             surfaceCodecParams.psSurface                = &refScaledSurface;
3173             surfaceCodecParams.dwOffset                 = isRefBottomField ? refScaledBottomFieldOffset : 0;
3174             surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
3175             surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[HmeFwdRefIdx0Cm + (refIdx * 2)];
3176             surfaceCodecParams.ucVDirection = !isCurrFieldPicture ? CODECHAL_VDIRECTION_FRAME :
3177                 ((isRefBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
3178             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3179                 m_hwInterface,
3180                 cmdBuffer,
3181                 &surfaceCodecParams,
3182                 kernelState));
3183         }
3184     }
3185 
3186     //List1
3187     for (uint8_t refIdx = 0; refIdx <= state->num_ref_idx_l1_active_minus1; refIdx++)
3188     {
3189         CODEC_PICTURE refPic = state->RefPicList[LIST_1][refIdx];
3190 
3191         if (!CodecHal_PictureIsInvalid(refPic))
3192         {
3193             if (refIdx == 0)
3194             {
3195                 // Current Picture Y - VME
3196                 MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3197                 surfaceCodecParams.bUseAdvState             = true;
3198                 surfaceCodecParams.psSurface                = currScaledSurface;
3199                 surfaceCodecParams.dwOffset                 = isCurrBottomField ? currScaledBottomFieldOffset : 0;
3200                 surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value;
3201                 surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[HmeCurrForBwdRefCm];
3202                 surfaceCodecParams.ucVDirection             = currVDirection;
3203                 CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3204                     m_hwInterface,
3205                     cmdBuffer,
3206                     &surfaceCodecParams,
3207                     kernelState));
3208             }
3209 
3210             bool isRefFieldPicture             = CodecHal_PictureIsField(refPic) ? 1 : 0;
3211             bool isRefBottomField              = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
3212             uint8_t refPicIdx                  = state->PicIdx[refPic.FrameIdx].ucPicIdx;
3213             uint8_t scaledIdx                  = state->pRefList[refPicIdx]->ucScalingIdx;
3214             if (state->b16xMeInUse)
3215             {
3216                 MOS_SURFACE* p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx);
3217                 if (p16xSurface != nullptr)
3218                 {
3219                     refScaledSurface.OsResource = p16xSurface->OsResource;
3220                 }
3221                 else
3222                 {
3223                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
3224                 }
3225             }
3226             else
3227             {
3228                 MOS_SURFACE* p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx);
3229                 if (p4xSurface != nullptr)
3230                 {
3231                     refScaledSurface.OsResource = p4xSurface->OsResource;
3232                 }
3233                 else
3234                 {
3235                     CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
3236                 }
3237             }
3238 
3239             uint32_t refScaledBottomFieldOffset = isRefBottomField ? currScaledBottomFieldOffset : 0;
3240 
3241             // L1 Reference Picture Y - VME
3242             MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3243             surfaceCodecParams.bUseAdvState             = true;
3244             surfaceCodecParams.psSurface                = &refScaledSurface;
3245             surfaceCodecParams.dwOffset                 = isRefBottomField ? refScaledBottomFieldOffset : 0;
3246             surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value;
3247             surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[HmeBwdRefIdx0Cm + (refIdx * 2)];
3248             surfaceCodecParams.ucVDirection = !isCurrFieldPicture ? CODECHAL_VDIRECTION_FRAME :
3249                 ((isRefBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
3250             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3251                 m_hwInterface,
3252                 cmdBuffer,
3253                 &surfaceCodecParams,
3254                 kernelState));
3255         }
3256     }
3257 
3258     if (state->b4xMeInUse)
3259     {
3260         MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams));
3261         surfaceCodecParams.dwSize                   = MOS_BYTES_TO_DWORDS(MOS_ALIGN_CEIL(m_frameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH) / 32 * MOS_ALIGN_CEIL(m_frameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT) / 32 * CODECHAL_CACHELINE_SIZE);
3262         surfaceCodecParams.bIs2DSurface             = false;
3263         surfaceCodecParams.presBuffer               = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
3264         surfaceCodecParams.dwBindingTableOffset     = bindingTable->dwBindingTableEntries[HmeVdencStreaminOutputCm];
3265         surfaceCodecParams.dwCacheabilityControl    = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
3266         surfaceCodecParams.bIsWritable              = true;
3267         surfaceCodecParams.bRenderTarget            = true;
3268         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
3269             m_hwInterface,
3270             cmdBuffer,
3271             &surfaceCodecParams,
3272             kernelState));
3273     }
3274 
3275     return eStatus;
3276 }
3277 
VdencHmeKernel(VdencVmeState * state)3278 MOS_STATUS CodechalVdencVp9State::VdencHmeKernel(
3279     VdencVmeState* state)
3280 {
3281     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3282 
3283     CODECHAL_ENCODE_FUNCTION_ENTER;
3284 
3285     CODECHAL_ENCODE_CHK_NULL_RETURN(state);
3286 
3287     PMHW_KERNEL_STATE kernelState = nullptr;
3288     CODECHAL_MEDIA_STATE_TYPE encFunctionType;
3289     if (state->b16xMeInUse)
3290     {
3291         kernelState    = &m_vdencMeKernelState;
3292         encFunctionType = CODECHAL_MEDIA_STATE_16X_ME;
3293     }
3294     else
3295     {
3296         kernelState    = &m_vdencStreaminKernelState;
3297         encFunctionType = CODECHAL_MEDIA_STATE_4X_ME;
3298     }
3299 
3300     // If Single Task Phase is not enabled, use BT count for the kernel state.
3301     if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
3302     {
3303         uint32_t maxBtCount = m_singleTaskPhaseSupported ?
3304             m_maxBtCount : kernelState->KernelParams.iBTCount;
3305         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
3306             m_stateHeapInterface,
3307             maxBtCount));
3308         m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount);
3309         CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3310     }
3311 
3312     // Set up the DSH/SSH as normal
3313     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace(
3314         m_stateHeapInterface,
3315         kernelState,
3316         false,
3317         0,
3318         false,
3319         m_storeData));
3320 
3321     MHW_INTERFACE_DESCRIPTOR_PARAMS idParams;
3322     MOS_ZeroMemory(&idParams, sizeof(idParams));
3323     idParams.pKernelState = kernelState;
3324     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor(
3325         m_stateHeapInterface,
3326         1,
3327         &idParams));
3328 
3329     //Setup curbe for StreamIn Kernel
3330     CODECHAL_ENCODE_CHK_STATUS_RETURN(VdencSetCurbeHmeKernel(
3331         state));
3332 
3333     CODECHAL_DEBUG_TOOL(
3334         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3335             encFunctionType,
3336             MHW_DSH_TYPE,
3337             kernelState));
3338     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe(
3339         encFunctionType,
3340         kernelState));
3341     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3342         encFunctionType,
3343         MHW_ISH_TYPE,
3344         kernelState));
3345     )
3346 
3347     MOS_COMMAND_BUFFER cmdBuffer;
3348     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
3349 
3350     SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams();
3351     sendKernelCmdsParams.EncFunctionType = encFunctionType;
3352     sendKernelCmdsParams.pKernelState = kernelState;
3353 
3354     CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams));
3355 
3356     // Add binding table
3357     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable(
3358         m_stateHeapInterface,
3359         kernelState));
3360 
3361     uint32_t scalingFactor = (state->b16xMeInUse) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x;
3362 
3363     VdencSendHmeSurfaces(state, &cmdBuffer);
3364 
3365     // Dump SSH for ME kernel
3366     CODECHAL_DEBUG_TOOL(
3367         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
3368             encFunctionType,
3369             MHW_SSH_TYPE,
3370             kernelState)));
3371 
3372     uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor);
3373     uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor);
3374 
3375     CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams;
3376     MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams));
3377     walkerCodecParams.WalkerMode                 = m_walkerMode;
3378     walkerCodecParams.dwResolutionX              = resolutionX;
3379     walkerCodecParams.dwResolutionY              = resolutionY;
3380     walkerCodecParams.bNoDependency              = true;
3381     walkerCodecParams.bMbaff                     = state->bMbaff ? true : false;
3382     walkerCodecParams.bGroupIdSelectSupported    = m_groupIdSelectSupported;
3383     walkerCodecParams.ucGroupId                  = m_groupId;
3384 
3385     MHW_WALKER_PARAMS walkerParams;
3386     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams(
3387         m_hwInterface,
3388         &walkerParams,
3389         &walkerCodecParams));
3390 
3391     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd(
3392         &cmdBuffer,
3393         &walkerParams));
3394 
3395     CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType));
3396 
3397     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks(
3398         m_stateHeapInterface,
3399         kernelState));
3400     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3401     {
3402         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId(
3403             m_stateHeapInterface));
3404         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
3405     }
3406 
3407     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
3408         &cmdBuffer,
3409         encFunctionType,
3410         nullptr)));
3411 
3412     m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase);
3413 
3414     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
3415 
3416     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
3417     {
3418         m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
3419         m_lastTaskInPhase = false;
3420     }
3421 
3422     return eStatus;
3423 }
3424 
ConstructPakInsertObjBatchBuf(PMOS_RESOURCE pakInsertObjBuffer)3425 MOS_STATUS CodechalVdencVp9State::ConstructPakInsertObjBatchBuf(
3426     PMOS_RESOURCE pakInsertObjBuffer)
3427 {
3428     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3429 
3430     CODECHAL_ENCODE_FUNCTION_ENTER;
3431 
3432     if (!pakInsertObjBuffer)
3433     {
3434         return MOS_STATUS_INVALID_PARAMETER;
3435     }
3436 
3437     CODECHAL_ENCODE_ASSERT(m_numNalUnit == 1);
3438 
3439     uint32_t nalUnitSize = m_nalUnitParams[0]->uiSize;
3440     uint32_t nalUnitOffset = m_nalUnitParams[0]->uiOffset;
3441     CODECHAL_ENCODE_ASSERT(nalUnitSize > 0 && nalUnitSize < CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER);
3442 
3443     MOS_LOCK_PARAMS lockFlagsWriteOnly;
3444     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
3445     lockFlagsWriteOnly.WriteOnly = 1;
3446     uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, pakInsertObjBuffer, &lockFlagsWriteOnly);
3447     CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3448 
3449     MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
3450     MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
3451     pakInsertObjectParams.bEmulationByteBitsInsert = false;
3452     pakInsertObjectParams.uiSkipEmulationCheckCount = m_nalUnitParams[0]->uiSkipEmulationCheckCount;
3453     pakInsertObjectParams.pBsBuffer = &m_bsBuffer;
3454     pakInsertObjectParams.dwBitSize = nalUnitSize * 8;
3455     pakInsertObjectParams.dwOffset = nalUnitOffset;
3456     pakInsertObjectParams.bEndOfSlice               = false;
3457     pakInsertObjectParams.bLastHeader               = true;
3458 
3459     MOS_COMMAND_BUFFER constructedCmdBuf;
3460     MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf));
3461     constructedCmdBuf.pCmdBase = (uint32_t *)data;
3462     constructedCmdBuf.pCmdPtr = (uint32_t *)data;
3463     constructedCmdBuf.iOffset = 0;
3464     constructedCmdBuf.iRemaining = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER;
3465 
3466     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPakInsertObject(&constructedCmdBuf, &pakInsertObjectParams));
3467     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr));
3468 
3469     if (data)
3470     {
3471         m_osInterface->pfnUnlockResource(
3472             m_osInterface,
3473             pakInsertObjBuffer);
3474     }
3475     return eStatus;
3476 }
3477 
PutDataForCompressedHdr(CompressedHeader * compressedHdr,uint32_t bit,uint32_t prob,uint32_t binIdx)3478 void CodechalVdencVp9State::PutDataForCompressedHdr(
3479     CompressedHeader* compressedHdr,
3480     uint32_t bit,
3481     uint32_t prob,
3482     uint32_t binIdx)
3483 {
3484     compressedHdr[binIdx].fields.valid = 1;
3485     compressedHdr[binIdx].fields.bin_probdiff = 1;
3486     compressedHdr[binIdx].fields.bin = bit;
3487     compressedHdr[binIdx].fields.prob = (prob == 128) ? 0 : 1;
3488 }
3489 
3490 // This function is NOT needed when HUC kernel is enabled.
3491 // It only uses the default probablity and can NOT handle probability update!
RefreshFrameInternalBuffers()3492 MOS_STATUS CodechalVdencVp9State::RefreshFrameInternalBuffers()
3493 {
3494     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3495 
3496     CODECHAL_ENCODE_FUNCTION_ENTER;
3497 
3498     CODECHAL_ENCODE_ASSERT(m_vp9PicParams->PicFlags.fields.refresh_frame_context == 0);
3499 
3500     MOS_LOCK_PARAMS lockFlagsWriteOnly;
3501     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
3502     lockFlagsWriteOnly.WriteOnly = 1;
3503 
3504     bool keyFrame  = !m_vp9PicParams->PicFlags.fields.frame_type;
3505     bool isScaling = (m_oriFrameWidth == m_prevFrameInfo.FrameWidth) &&
3506                              (m_oriFrameHeight == m_prevFrameInfo.FrameHeight)
3507                          ? false
3508                          : true;
3509     bool resetSegIdBuf = keyFrame || isScaling ||
3510                          m_vp9PicParams->PicFlags.fields.error_resilient_mode ||
3511                          m_vp9PicParams->PicFlags.fields.intra_only;
3512 
3513     if (resetSegIdBuf)
3514     {
3515         uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3516             m_osInterface,
3517             &m_resSegmentIdBuffer,
3518             &lockFlagsWriteOnly);
3519 
3520         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3521 
3522         MOS_ZeroMemory(data, m_picSizeInSb * CODECHAL_CACHELINE_SIZE);
3523 
3524         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
3525             m_osInterface,
3526             &m_resSegmentIdBuffer));
3527     }
3528 
3529     //refresh inter probs in needed frame context buffers
3530     bool clearAll = (keyFrame || m_vp9PicParams->PicFlags.fields.error_resilient_mode ||
3531                      (m_vp9PicParams->PicFlags.fields.reset_frame_context == 3 && m_vp9PicParams->PicFlags.fields.intra_only));
3532 
3533     bool clearSpecified = (m_vp9PicParams->PicFlags.fields.reset_frame_context == 2 &&
3534                            m_vp9PicParams->PicFlags.fields.intra_only);
3535 
3536     MOS_STATUS status1 = MOS_STATUS_SUCCESS;
3537     for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
3538     {
3539         if (clearAll || (clearSpecified && i == m_vp9PicParams->PicFlags.fields.frame_context_idx))
3540         {
3541             uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3542                 m_osInterface,
3543                 &m_resProbBuffer[i],
3544                 &lockFlagsWriteOnly);
3545             CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3546 
3547             status1 = ContextBufferInit(data, keyFrame || m_vp9PicParams->PicFlags.fields.intra_only);
3548 
3549             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
3550                 m_osInterface,
3551                 &m_resProbBuffer[i]));
3552             CODECHAL_ENCODE_CHK_STATUS_RETURN(status1);
3553 
3554             m_clearAllToKey[i] = keyFrame || m_vp9PicParams->PicFlags.fields.intra_only;
3555             if (i == 0)  //reset this flag when Ctx buffer 0 is cleared.
3556             {
3557                 m_isPreCtx0InterProbSaved = false;
3558             }
3559         }
3560         else if (m_clearAllToKey[i]) // this buffer is inside inter frame, but its interProb has not been init to default inter type data.
3561         {
3562             uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3563                 m_osInterface,
3564                 &m_resProbBuffer[i],
3565                 &lockFlagsWriteOnly);
3566             CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3567 
3568             if (m_vp9PicParams->PicFlags.fields.intra_only && i == 0)  // this buffer is used as intra_only context, do not need to set interprob to be inter type.
3569             {
3570                 status1 = CtxBufDiffInit(data, true);
3571             }
3572             else // set interprob to be inter type.
3573             {
3574                 status1 = CtxBufDiffInit(data, false);
3575                 m_clearAllToKey[i] = false;
3576             }
3577 
3578             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
3579                 m_osInterface,
3580                 &m_resProbBuffer[i]));
3581             CODECHAL_ENCODE_CHK_STATUS_RETURN(status1);
3582         }
3583         else if (i == 0) // this buffer do not need to clear in current frame, also it has not been cleared to key type in previous frame.
3584         {                // in this case, only context buffer 0 will be temporally overwritten.
3585             if (m_vp9PicParams->PicFlags.fields.intra_only)
3586             {
3587                 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3588                     m_osInterface,
3589                     &m_resProbBuffer[i],
3590                     &lockFlagsWriteOnly);
3591                 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3592 
3593                 if (!m_isPreCtx0InterProbSaved)  // only when non intra-only -> intra-only need save InterProb, otherwise leave saved InterProb unchanged.
3594                 {
3595                     //save current interprob
3596                     CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(m_preCtx0InterProbSaved, CODECHAL_VP9_INTER_PROB_SIZE, data + CODEC_VP9_INTER_PROB_OFFSET, CODECHAL_VP9_INTER_PROB_SIZE));
3597                     m_isPreCtx0InterProbSaved = true;
3598                 }
3599                 status1 = CtxBufDiffInit(data, true);
3600                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
3601                     m_osInterface,
3602                     &m_resProbBuffer[i]));
3603                 CODECHAL_ENCODE_CHK_STATUS_RETURN(status1);
3604             }
3605             else if (m_isPreCtx0InterProbSaved)
3606             {
3607                 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3608                     m_osInterface,
3609                     &m_resProbBuffer[i],
3610                     &lockFlagsWriteOnly);
3611                 CODECHAL_ENCODE_CHK_NULL_RETURN(data);
3612                 //reload former interprob
3613                 CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(data + CODEC_VP9_INTER_PROB_OFFSET, CODECHAL_VP9_INTER_PROB_SIZE, m_preCtx0InterProbSaved, CODECHAL_VP9_INTER_PROB_SIZE));
3614 
3615                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
3616                     m_osInterface,
3617                     &m_resProbBuffer[i]));
3618 
3619                 m_isPreCtx0InterProbSaved = false;
3620             }
3621         }
3622     }
3623 
3624     // compressed header
3625     uint32_t index = 0;
3626     CompressedHeader* compressedHdr = (CompressedHeader*)MOS_AllocAndZeroMemory(sizeof(CompressedHeader)* (PAK_COMPRESSED_HDR_SYNTAX_ELEMS + 1));
3627     CODECHAL_ENCODE_CHK_NULL_RETURN(compressedHdr);
3628 
3629     if (!m_vp9PicParams->PicFlags.fields.LosslessFlag)
3630     {
3631         if (m_txMode == CODEC_VP9_TX_SELECTABLE)
3632         {
3633             PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX);
3634             PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1);
3635             PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_SELECT_IDX);
3636         }
3637         else if (m_txMode == CODEC_VP9_TX_32X32)
3638         {
3639             PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX);
3640             PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1);
3641             PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_TX_MODE_SELECT_IDX);
3642         }
3643         else
3644         {
3645             PutDataForCompressedHdr(compressedHdr, (m_txMode & 0x02) >> 1, 128, PAK_TX_MODE_IDX);
3646             PutDataForCompressedHdr(compressedHdr, (m_txMode & 0x01), 128, PAK_TX_MODE_IDX + 1);
3647         }
3648 
3649         if (m_txMode == CODEC_VP9_TX_SELECTABLE)
3650         {
3651             index = PAK_TX_8x8_PROB_IDX;
3652             for (auto i = 0; i < 2; i++)
3653             {
3654                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3655                 index += 2;
3656             }
3657 
3658             index = PAK_TX_16x16_PROB_IDX;
3659             for (auto i = 0; i < 2; i++)
3660             {
3661                 for (auto j = 0; j < 2; j++)
3662                 {
3663                     PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3664                     index += 2;
3665                 }
3666             }
3667 
3668             index = PAK_TX_32x32_PROB_IDX;
3669             for (auto i = 0; i < 2; i++)
3670             {
3671                 for (auto j = 0; j < 3; j++)
3672                 {
3673                     PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3674                     index += 2;
3675                 }
3676             }
3677         }
3678     }
3679 
3680     for (auto coeffSize = 0; coeffSize < 4; coeffSize++)
3681     {
3682         if (coeffSize > m_txMode)
3683         {
3684             continue;
3685         }
3686 
3687         switch (coeffSize)
3688         {
3689         case 0: index = PAK_TX_4x4_COEFF_PROB_IDX;
3690             break;
3691         case 1: index = PAK_TX_8x8_COEFF_PROB_IDX;
3692             break;
3693         case 2: index = PAK_TX_16x16_COEFF_PROB_IDX;
3694             break;
3695         case 3: index = PAK_TX_32x32_COEFF_PROB_IDX;
3696             break;
3697         }
3698 
3699         PutDataForCompressedHdr(compressedHdr, 0, 128, index);
3700     }
3701 
3702     PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX);
3703     PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 2);
3704     PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 4);
3705 
3706     if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only)
3707     {
3708         index = PAK_INTER_MODE_CTX_IDX;
3709         for (auto i = 0; i < 7; i++)
3710         {
3711             for (auto j = 0; j < 3; j++)
3712             {
3713                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3714                 index += 2;
3715             }
3716         }
3717 
3718         if (m_vp9PicParams->PicFlags.fields.mcomp_filter_type == CODEC_VP9_SWITCHABLE_FILTERS)
3719         {
3720             index = PAK_SWITCHABLE_FILTER_CTX_IDX;
3721             for (auto i = 0; i < 4; i++)
3722             {
3723                 for (auto j = 0; j < 2; j++)
3724                 {
3725                     PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3726                     index += 2;
3727                 }
3728             }
3729         }
3730 
3731         index = PAK_INTRA_INTER_CTX_IDX;
3732         for (auto i = 0; i < 4; i++)
3733         {
3734             PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3735             index += 2;
3736         }
3737 
3738         bool allowComp = !(
3739             (m_vp9PicParams->RefFlags.fields.LastRefSignBias && m_vp9PicParams->RefFlags.fields.GoldenRefSignBias && m_vp9PicParams->RefFlags.fields.AltRefSignBias) ||
3740             (!m_vp9PicParams->RefFlags.fields.LastRefSignBias && !m_vp9PicParams->RefFlags.fields.GoldenRefSignBias && !m_vp9PicParams->RefFlags.fields.AltRefSignBias));
3741 
3742         if (allowComp)
3743         {
3744             if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode == PRED_MODE_HYBRID)
3745             {
3746                 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX);
3747                 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX + 1);
3748                 index = PAK_HYBRID_PRED_CTX_IDX;
3749                 for (auto i = 0; i < 5; i++)
3750                 {
3751                     PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3752                     index += 2;
3753                 }
3754             }
3755             else if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode == PRED_MODE_COMPOUND)
3756             {
3757                 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX);
3758                 PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX + 1);
3759             }
3760             else
3761             {
3762                 PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX);
3763             }
3764         }
3765 
3766         if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode != PRED_MODE_COMPOUND)
3767         {
3768             index = PAK_SINGLE_REF_PRED_CTX_IDX;
3769             for (auto i = 0; i < 5; i++)
3770             {
3771                 for (auto j = 0; j < 2; j++)
3772                 {
3773                     PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3774                     index += 2;
3775                 }
3776             }
3777         }
3778 
3779         if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode != PRED_MODE_SINGLE)
3780         {
3781             index = PAK_CMPUND_PRED_CTX_IDX;
3782             for (auto i = 0; i < 5; i++)
3783             {
3784                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3785                 index += 2;
3786             }
3787         }
3788 
3789         index = PAK_INTRA_MODE_PROB_CTX_IDX;
3790         for (auto i = 0; i < 4; i++)
3791         {
3792             for (auto j = 0; j < 9; j++)
3793             {
3794                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3795                 index += 2;
3796             }
3797         }
3798 
3799         index = PAK_PARTITION_PROB_IDX;
3800         for (auto i = 0; i < 16; i++)
3801         {
3802             for (auto j = 0; j < 3; j++)
3803             {
3804                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3805                 index += 2;
3806             }
3807         }
3808 
3809         index = PAK_MVJOINTS_PROB_IDX;
3810         for (auto i = 0; i < 3; i++)
3811         {
3812             PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3813             index += 8;
3814         }
3815 
3816         for (auto d = 0; d < 2; d++)
3817         {
3818             index = (d == 0) ? PAK_MVCOMP0_IDX : PAK_MVCOMP1_IDX;
3819             PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3820             index += 8;
3821             for (auto i = 0; i < 10; i++)
3822             {
3823                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3824                 index += 8;
3825             }
3826             PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3827             index += 8;
3828             for (auto i = 0; i < 10; i++)
3829             {
3830                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3831                 index += 8;
3832             }
3833         }
3834 
3835         for (auto d = 0; d < 2; d++)
3836         {
3837             index = (d == 0) ? PAK_MVFRAC_COMP0_IDX : PAK_MVFRAC_COMP1_IDX;
3838             for (auto i = 0; i < 3; i++)
3839             {
3840                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3841                 index += 8;
3842             }
3843             for (auto i = 0; i < 3; i++)
3844             {
3845                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3846                 index += 8;
3847             }
3848             for (auto i = 0; i < 3; i++)
3849             {
3850                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3851                 index += 8;
3852             }
3853         }
3854 
3855         if (m_vp9PicParams->PicFlags.fields.allow_high_precision_mv)
3856         {
3857             for (auto d = 0; d < 2; d++)
3858             {
3859                 index = (d == 0) ? PAK_MVHP_COMP0_IDX : PAK_MVHP_COMP1_IDX;
3860                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3861                 index += 8;
3862                 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
3863             }
3864         }
3865     }
3866 
3867     uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
3868         m_osInterface,
3869         &m_resCompressedHeaderBuffer,
3870         &lockFlagsWriteOnly);
3871     if(data == nullptr)
3872     {
3873         MOS_FreeMemory(compressedHdr);
3874         CODECHAL_ENCODE_CHK_NULL_RETURN(nullptr);
3875     }
3876 
3877     for (uint32_t i = 0; i < PAK_COMPRESSED_HDR_SYNTAX_ELEMS; i += 2)
3878     {
3879         data[i>>1] = (compressedHdr[i + 1].value << 0x04) | (compressedHdr[i].value);
3880     }
3881 
3882     eStatus = (MOS_STATUS) m_osInterface->pfnUnlockResource(
3883         m_osInterface,
3884         &m_resCompressedHeaderBuffer);
3885     if (eStatus != MOS_STATUS_SUCCESS)
3886     {
3887         MOS_FreeMemory(compressedHdr);
3888         CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
3889     }
3890 
3891     MOS_FreeMemory(compressedHdr);
3892     return eStatus;
3893 }
3894 
ExecutePictureLevel()3895 MOS_STATUS CodechalVdencVp9State::ExecutePictureLevel()
3896 {
3897     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
3898 
3899     CODECHAL_ENCODE_FUNCTION_ENTER;
3900 
3901     // resize CommandBuffer Size for every BRC pass
3902     if (!m_singleTaskPhaseSupported)
3903     {
3904         CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3905     }
3906 
3907     PerfTagSetting perfTag;
3908     CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE);
3909 
3910     if (m_currPass == 0)
3911     {
3912         CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPakInsertObjBatchBuf(&m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx]));
3913     }
3914 
3915     // For VDENC dynamic scaling, here are the steps we need to process
3916     //   Pass 0. VDENC + PAK Pass
3917     //     a. If this is Dys + BRC case, then run BRC Pass 0
3918     //     b. Ref frame scaling
3919     //    c. VDENC + PAK pass to stream out PakObjCmd
3920     //   Pass 1 -> Reset to Pass 0 so as to run HPU Pass 0
3921     //     a. If this is Dys + BRC case, then run BRC Pass 1
3922     //     b. Run HPU Pass 0
3923     //     c. Lite Pass (Pak only multi pass enabled) to stream in
3924     //        PakObjCmd from previous pass
3925     //   Pass 1 -> Only run HPU Pass 1 to update the probabilities for
3926     //   next frame. Repak is disabled for performance reasons
3927     if ( m_dysRefFrameFlags != DYS_REF_NONE)
3928     {
3929         if (m_currPass == 0)
3930         {
3931             if (m_dysVdencMultiPassEnabled)
3932             {
3933                 if (Mos_ResourceIsNull(&m_resVdencDysPictureState2NdLevelBatchBuffer))
3934                 {
3935                     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
3936 
3937                     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
3938                     allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
3939                     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
3940                     allocParamsForBufferLinear.Format = Format_Buffer;
3941                     allocParamsForBufferLinear.dwBytes = m_vdencPicStateSecondLevelBatchBufferSize;
3942                     allocParamsForBufferLinear.pBufName = "VDEnc DYS Picture Second Level Batch Buffer";
3943 
3944                     eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
3945                         m_osInterface,
3946                         &allocParamsForBufferLinear,
3947                         &m_resVdencDysPictureState2NdLevelBatchBuffer);
3948 
3949                     if (eStatus != MOS_STATUS_SUCCESS)
3950                     {
3951                         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc DYS Picture Second Level Batch Buffer.");
3952                         return eStatus;
3953                     }
3954                 }
3955 
3956                 CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
3957             }
3958         }
3959         else if (m_currPass == 1)
3960         {
3961             m_hucEnabled = m_dysHucEnabled; // recover huc state
3962             m_vdencPakonlyMultipassEnabled = true;
3963             m_dysRefFrameFlags = DYS_REF_NONE;
3964             m_currPass = 0; // reset ucCurrPass = 0 to run the Huc
3965             m_lastTaskInPhase = false;
3966         }
3967     }
3968     else
3969     {
3970         if (IsFirstPass() && m_vdencBrcEnabled)
3971         {
3972             m_vdencPakObjCmdStreamOutEnabled = true;
3973             m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface;
3974         }
3975         else
3976         {
3977             m_vdencPakObjCmdStreamOutEnabled = false;
3978         }
3979     }
3980 
3981     if ((m_dysRefFrameFlags != DYS_REF_NONE) && m_dysVdencMultiPassEnabled)
3982     {
3983         CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPicStateBatchBuf(&m_resVdencDysPictureState2NdLevelBatchBuffer));
3984     }
3985     else
3986     {
3987         CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPicStateBatchBuf(&m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]));
3988     }
3989 
3990     if (m_vdencBrcEnabled)
3991     {
3992         // Invoke BRC init/reset FW
3993         if (m_brcInit || m_brcReset)
3994         {
3995             if (!m_singleTaskPhaseSupported)
3996             {
3997                 //Reset earlier set PAK perf tag
3998                 m_osInterface->pfnResetPerfBufferID(m_osInterface);
3999                 CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET);
4000             }
4001             CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcInitReset());
4002             m_brcInit = m_brcReset = false;
4003         }
4004         // For multipass and singlepass+RePAK we call BRC update for all passes except last pass (RePAK)
4005         // For single pass w/o RePAK (1 total pass) we call BRC update on one and only pass
4006         if ((m_currPass < m_numPasses) || (m_currPass == 0 && m_numPasses == 0))
4007         {
4008             bool origSingleTaskPhase = m_singleTaskPhaseSupported;
4009             // If this is the case of Dynamic Scaling + BRC Pass 0'  VDENC + Pak  pass
4010             // As a WA, Disable SingleTaskPhase before running 1st BRC update
4011             // To run HPU0 on the next pass i.e Pak only pass, we make Pass 1 as Pass 0 in which case the
4012             // BRC dmem buffer( resVdencBrcUpdateDmemBuffer[0] ) will get overridden if we do not submit BRC command now.
4013             if (m_dysBrc && m_dysRefFrameFlags != DYS_REF_NONE)
4014             {
4015                 m_singleTaskPhaseSupported = false;
4016             }
4017             if (!m_singleTaskPhaseSupported)
4018             {
4019                 //Reset performance buffer used for BRC init
4020                 m_osInterface->pfnResetPerfBufferID(m_osInterface);
4021                 CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE);
4022             }
4023             CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcUpdate());
4024 
4025             //Restore the original state of SingleTaskPhaseSupported flag
4026             m_singleTaskPhaseSupported = origSingleTaskPhase;
4027         }
4028     }
4029 
4030     // run HuC_VP9Prob first pass (it runs in parallel with ENC)
4031     if (m_hucEnabled)
4032     {
4033         if ((m_currPass == 0) || (m_currPass == m_numPasses))  // Before the first PAK pass and for RePak pass
4034         {
4035             if (!m_singleTaskPhaseSupported)
4036             {
4037                 //Reset earlier set PAK perf tag
4038                 m_osInterface->pfnResetPerfBufferID(m_osInterface);
4039                 // Add Hpu tag here after added
4040             }
4041             CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCVp9Prob());
4042         }
4043     }
4044     else
4045     {
4046         CODECHAL_ENCODE_CHK_STATUS_RETURN(RefreshFrameInternalBuffers());
4047     }
4048 
4049     //Ref frame scaling
4050     if (m_dysRefFrameFlags != DYS_REF_NONE && m_currPass == 0)
4051     {
4052         CODECHAL_ENCODE_CHK_STATUS_RETURN(DysRefFrames());
4053 
4054         if (m_dysVdencMultiPassEnabled)
4055         {
4056             m_singleTaskPhaseSupported = true;
4057             m_firstTaskInPhase = true;
4058             m_vdencPakObjCmdStreamOutEnabled = true;
4059             m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface;
4060         }
4061         else
4062         {
4063             m_hucEnabled = m_dysHucEnabled; // recover huc state
4064         }
4065     }
4066 
4067     // set HCP_SURFACE_STATE values
4068     MHW_VDBOX_SURFACE_PARAMS surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID + 1];
4069     for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++)
4070     {
4071         MOS_ZeroMemory(&surfaceParams[i], sizeof(surfaceParams[i]));
4072         surfaceParams[i].Mode = m_mode;
4073         surfaceParams[i].ucSurfaceStateId = i;
4074         surfaceParams[i].ChromaType = m_outputChromaFormat;
4075         surfaceParams[i].bSrc8Pak10Mode   = (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) && (!m_vp9SeqParams->SeqFlags.fields.SourceBitDepth);
4076 
4077         switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth)
4078         {
4079             case VP9_ENCODED_BIT_DEPTH_10: //10 bit encoding
4080             {
4081                 surfaceParams[i].ucBitDepthChromaMinus8 = 2;
4082                 surfaceParams[i].ucBitDepthLumaMinus8 = 2;
4083                 break;
4084             }
4085             default:
4086             {
4087                 surfaceParams[i].ucBitDepthChromaMinus8 = 0;
4088                 surfaceParams[i].ucBitDepthLumaMinus8 = 0;
4089                 break;
4090             }
4091         }
4092     }
4093 
4094     // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled
4095     PMOS_SURFACE refSurface[3], refSurfaceNonScaled[3], dsRefSurface4x[3], dsRefSurface8x[3];
4096     for (auto i = 0; i < 3; i++)
4097     {
4098         refSurface[i] = refSurfaceNonScaled[i] = dsRefSurface4x[i] = dsRefSurface8x[i] = nullptr;
4099     }
4100     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetHcpSrcSurfaceParams(surfaceParams, refSurface, refSurfaceNonScaled, dsRefSurface4x, dsRefSurface8x));
4101 
4102     MOS_COMMAND_BUFFER cmdBuffer;
4103     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4104 
4105     if (!m_singleTaskPhaseSupported)
4106     {
4107         CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE);
4108     }
4109 
4110     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
4111     {
4112         // Send command buffer header at the beginning (OS dependent)
4113         // frame tracking tag is only added in the last command buffer header
4114         bool requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
4115         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
4116     }
4117 
4118     // Repak conditional batch buffer end based on repak flag written by Huc to HUC_STATUS regster
4119     if (m_hucEnabled && (m_numPasses > 0)  && (m_currPass == m_numPasses))
4120     {
4121         // Insert conditional batch buffer end
4122         // Success = bit 30 set to 1, Do RePAK = bit 31 set to 1, value is always 0; if 0 < memory, continue
4123         MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
4124         MOS_ZeroMemory(
4125             &miConditionalBatchBufferEndParams,
4126             sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
4127 
4128         miConditionalBatchBufferEndParams.presSemaphoreBuffer =
4129             &m_resHucPakMmioBuffer;
4130         // Make the DisableCompareMask 0, so that the HW will do AND operation on DW0 with Mask DW1, refer to HuCVp9Prob() for the settings
4131         // and compare the result against the Semaphore data which in our case dwValue = 0.
4132         // If result > dwValue then continue execution otherwise terminate the batch buffer
4133         miConditionalBatchBufferEndParams.bDisableCompareMask = false;
4134 
4135         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
4136             &cmdBuffer,
4137             &miConditionalBatchBufferEndParams));
4138     }
4139 
4140     CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4141 
4142     PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = nullptr;
4143     // set HCP_PIPE_MODE_SELECT values
4144     pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams();
4145     CODECHAL_ENCODE_CHK_NULL_RETURN(pipeModeSelectParams);
4146 
4147     auto release_func = [&]()
4148     {
4149         m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
4150         pipeModeSelectParams = nullptr;
4151     };
4152 
4153     SetHcpPipeModeSelectParams(*pipeModeSelectParams);
4154     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams), release_func);
4155 
4156     // This wait cmd is needed to make sure copy command is done as suggested by HW folk
4157     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_miInterface->AddMfxWaitCmd(&cmdBuffer, nullptr, false), release_func);
4158 
4159     // Decoded picture
4160     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID]), release_func);
4161 
4162     // Source input
4163     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID]), release_func);
4164 
4165     // Last reference picture
4166     if (refSurface[0])
4167     {
4168         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID]), release_func);
4169     }
4170 
4171     // Golden reference picture
4172     if (refSurface[1])
4173     {
4174         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID]), release_func);
4175     }
4176 
4177     // Alt reference picture
4178     if (refSurface[2])
4179     {
4180         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID]), release_func);
4181     }
4182 
4183     // set HCP_PIPE_BUF_ADDR_STATE values
4184     PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams = nullptr;
4185     pipeBufAddrParams = CreateHcpPipeBufAddrParams(pipeBufAddrParams);
4186 
4187     auto release_func2 = [&]()
4188     {
4189         m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
4190         pipeModeSelectParams = nullptr;
4191 
4192         if (pipeBufAddrParams)
4193         {
4194             MOS_Delete(pipeBufAddrParams);
4195             pipeBufAddrParams = nullptr;
4196         }
4197     };
4198 
4199     if (pipeBufAddrParams)
4200     {
4201         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(SetHcpPipeBufAddrParams(*pipeBufAddrParams, refSurface, refSurfaceNonScaled, dsRefSurface4x, dsRefSurface8x), release_func2);
4202         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(SetPipeBufAddr(pipeBufAddrParams, refSurface, &cmdBuffer), release_func2);
4203         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams), release_func2);
4204     }
4205 
4206     // set HCP_IND_OBJ_BASE_ADDR_STATE values
4207     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
4208     SetHcpIndObjBaseAddrParams(indObjBaseAddrParams);
4209     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams), release_func2);
4210 
4211     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams), release_func2);
4212 
4213     m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
4214 
4215     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencSrcSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID]), release_func2);
4216     if (m_pictureCodingType == I_TYPE)
4217     {
4218         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID]), release_func2);
4219     }
4220     else
4221     {
4222         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID]), release_func2);
4223         if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled)
4224         {
4225             if (m_refFrameFlags & 0x02)
4226             {
4227                 CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID]), release_func2);
4228             }
4229             if (m_refFrameFlags & 0x04)
4230             {
4231                 CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID]), release_func2);
4232             }
4233         }
4234     }
4235 
4236     MHW_VDBOX_SURFACE_PARAMS dsSurfaceParams[2];     // 8x and 4x DS surfaces
4237     SetHcpDsSurfaceParams(&dsSurfaceParams[0]);
4238     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencDsRefSurfaceStateCmd(&cmdBuffer, &dsSurfaceParams[0], 2), release_func2);
4239 
4240     if (pipeBufAddrParams)
4241     {
4242         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_vdencInterface->AddVdencPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams), release_func2);
4243         MOS_Delete(pipeBufAddrParams);
4244         pipeBufAddrParams = nullptr;
4245     }
4246 
4247     MHW_BATCH_BUFFER secondLevelBatchBuffer;
4248     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer));
4249     secondLevelBatchBuffer.dwOffset = 0;
4250     secondLevelBatchBuffer.bSecondLevel = true;
4251     if (m_hucEnabled)
4252     {
4253         secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex];
4254     }
4255     else
4256     {
4257         if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled)
4258         {
4259             // For DyS + BRC case, we run BRC on Pass 0, so although we dont run HPU on Pass 0
4260             // (VDENC + PAK pass) we will still use the write buffer here
4261             if (m_dysBrc)
4262             {
4263                 secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex];
4264             }
4265             else //CQP case for Pass 0 , HPU has not run yet.. so use this buffer
4266             {
4267                 secondLevelBatchBuffer.OsResource = m_resVdencDysPictureState2NdLevelBatchBuffer;
4268             }
4269         }
4270         else
4271         {
4272             secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex];
4273         }
4274     }
4275 
4276     CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
4277         &cmdBuffer,
4278         &secondLevelBatchBuffer), release_func);
4279 
4280     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4281 
4282     return eStatus;
4283 }
4284 
Resize4x8xforDS(uint8_t bufIdx)4285 MOS_STATUS CodechalVdencVp9State::Resize4x8xforDS(uint8_t bufIdx)
4286 {
4287     CODECHAL_ENCODE_FUNCTION_ENTER;
4288 
4289     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4290 
4291     // calculate the expected 4x dimensions
4292     uint32_t downscaledSurfaceWidth4x  = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
4293     uint32_t downscaledSurfaceHeight4x = ((m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
4294     downscaledSurfaceHeight4x          = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
4295 
4296     // calculate the expected 8x dimensions
4297     uint32_t downscaledSurfaceWidth8x  = downscaledSurfaceWidth4x >> 1;
4298     uint32_t downscaledSurfaceHeight8x = downscaledSurfaceHeight4x >> 1;
4299 
4300     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf);
4301 
4302     // get the 8x and 4x ds downscaled surfaces from tracked buffers
4303     auto m_trackedBuf8xDsReconSurface = m_trackedBuf->Get8xDsReconSurface(bufIdx);
4304     auto m_trackedBuf4xDsReconSurface = m_trackedBuf->Get4xDsReconSurface(bufIdx);
4305 
4306     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf8xDsReconSurface);
4307     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf4xDsReconSurface);
4308 
4309     // If any dimension of allocated surface is smaller, realloc needed
4310     if (m_trackedBuf8xDsReconSurface->dwWidth < downscaledSurfaceWidth8x || m_trackedBuf8xDsReconSurface->dwHeight < downscaledSurfaceHeight8x) {
4311 
4312         // Get the previously assigned dimensions to make sure we do not lower any dimension
4313         auto previous8xWidth = m_trackedBuf8xDsReconSurface->dwWidth;
4314         auto previous8xHeight = m_trackedBuf8xDsReconSurface->dwHeight;
4315 
4316         auto new8xWidth = MOS_MAX(previous8xWidth, downscaledSurfaceWidth8x);
4317         auto new8xHeight = MOS_MAX(previous8xHeight, downscaledSurfaceHeight8x);
4318 
4319         // Release the smaller resource
4320         m_allocator->ReleaseResource(m_standard, ds8xRecon, bufIdx);
4321 
4322         // Re alloc larger resource
4323         CODECHAL_ENCODE_CHK_NULL_RETURN(
4324             m_trackedBuf8xDsReconSurface = (MOS_SURFACE*)m_allocator->AllocateResource(
4325                 m_standard, new8xWidth, new8xHeight, ds8xRecon, "ds8xRecon", bufIdx, false, Format_NV12, MOS_TILE_Y));
4326 
4327         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBuf8xDsReconSurface));
4328     }
4329 
4330     if (m_trackedBuf4xDsReconSurface->dwWidth < downscaledSurfaceWidth4x || m_trackedBuf4xDsReconSurface->dwHeight < downscaledSurfaceHeight4x) {
4331 
4332         // Get the previously assigned dimensions to make sure we do not lower any dimension
4333         auto previous4xWidth = m_trackedBuf4xDsReconSurface->dwWidth;
4334         auto previous4xHeight = m_trackedBuf4xDsReconSurface->dwHeight;
4335 
4336         auto new4xWidth = MOS_MAX(previous4xWidth, downscaledSurfaceWidth4x);
4337         auto new4xHeight = MOS_MAX(previous4xHeight, downscaledSurfaceHeight4x);
4338 
4339         // Release the smaller resource
4340         m_allocator->ReleaseResource(m_standard, ds4xRecon, bufIdx);
4341 
4342         // Re alloc larger resource
4343         CODECHAL_ENCODE_CHK_NULL_RETURN(
4344             m_trackedBuf4xDsReconSurface = (MOS_SURFACE*)m_allocator->AllocateResource(
4345                 m_standard, new4xWidth, new4xHeight, ds4xRecon, "ds4xRecon", bufIdx, false, Format_NV12, MOS_TILE_Y));
4346 
4347         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBuf4xDsReconSurface));
4348     }
4349     return eStatus;
4350 }
4351 
SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * surfaceParams,PMOS_SURFACE * refSurface,PMOS_SURFACE * refSurfaceNonScaled,PMOS_SURFACE * dsRefSurface4x,PMOS_SURFACE * dsRefSurface8x)4352 MOS_STATUS CodechalVdencVp9State::SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS* surfaceParams,
4353     PMOS_SURFACE* refSurface,
4354     PMOS_SURFACE* refSurfaceNonScaled,
4355     PMOS_SURFACE* dsRefSurface4x,
4356     PMOS_SURFACE* dsRefSurface8x)
4357 {
4358     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4359 
4360     CODECHAL_ENCODE_FUNCTION_ENTER;
4361 
4362     if (m_pictureCodingType != I_TYPE)
4363     {
4364         uint8_t refPicIndex = 0, scalingIdx = 0;
4365         if (m_refFrameFlags & 0x01)
4366         {
4367             refPicIndex = m_vp9PicParams->RefFlags.fields.LastRefIdx;
4368 
4369             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])));
4370             refSurfaceNonScaled[0] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
4371             refSurface[0]          = (m_dysRefFrameFlags & DYS_REF_LAST) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[0];
4372 
4373             scalingIdx        = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx;
4374             CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx));
4375 
4376             CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf);
4377             dsRefSurface4x[0] = m_trackedBuf->Get4xDsReconSurface(scalingIdx);
4378             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[0]));
4379             dsRefSurface8x[0] = m_trackedBuf->Get8xDsReconSurface(scalingIdx);
4380             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[0]));
4381         }
4382 
4383         if (m_refFrameFlags & 0x02)
4384         {
4385             refPicIndex = m_vp9PicParams->RefFlags.fields.GoldenRefIdx;
4386 
4387             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])));
4388             refSurfaceNonScaled[1] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
4389             refSurface[1]          = (m_dysRefFrameFlags & DYS_REF_GOLDEN) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[1];
4390 
4391             scalingIdx        = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx;
4392             CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx));
4393 
4394             CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf);
4395             dsRefSurface4x[1] = m_trackedBuf->Get4xDsReconSurface(scalingIdx);
4396             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[1]));
4397             dsRefSurface8x[1] = m_trackedBuf->Get8xDsReconSurface(scalingIdx);
4398             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[1]));
4399         }
4400 
4401         if (m_refFrameFlags & 0x04)
4402         {
4403             refPicIndex = m_vp9PicParams->RefFlags.fields.AltRefIdx;
4404 
4405             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])));
4406             refSurfaceNonScaled[2] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
4407             refSurface[2]          = (m_dysRefFrameFlags & DYS_REF_ALT) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[2];
4408 
4409             scalingIdx        = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx;
4410             CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx));
4411 
4412             CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf);
4413             dsRefSurface4x[2] = m_trackedBuf->Get4xDsReconSurface(scalingIdx);
4414             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[2]));
4415             dsRefSurface8x[2] = m_trackedBuf->Get8xDsReconSurface(scalingIdx);
4416             CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[2]));
4417         }
4418 
4419         if (!refSurface[0])
4420         {
4421             refSurface[0] = (refSurface[1]) ? refSurface[1] : refSurface[2];
4422             refSurfaceNonScaled[0] = (refSurfaceNonScaled[1]) ? refSurfaceNonScaled[1] : refSurfaceNonScaled[2];
4423             dsRefSurface4x[0] = (dsRefSurface4x[1]) ? dsRefSurface4x[1] : dsRefSurface4x[2];
4424             dsRefSurface8x[0] = (dsRefSurface8x[1]) ? dsRefSurface8x[1] : dsRefSurface8x[2];
4425         }
4426 
4427         if (!refSurface[1])
4428         {
4429             refSurface[1] = (refSurface[0]) ? refSurface[0] : refSurface[2];
4430             refSurfaceNonScaled[1] = (refSurfaceNonScaled[0]) ? refSurfaceNonScaled[0] : refSurfaceNonScaled[2];
4431             dsRefSurface4x[1] = (dsRefSurface4x[0]) ? dsRefSurface4x[0] : dsRefSurface4x[2];
4432             dsRefSurface8x[1] = (dsRefSurface8x[0]) ? dsRefSurface8x[0] : dsRefSurface8x[2];
4433         }
4434 
4435         if (!refSurface[2])
4436         {
4437             refSurface[2] = (refSurface[0]) ? refSurface[0] : refSurface[1];
4438             refSurfaceNonScaled[2] = (refSurfaceNonScaled[0]) ? refSurfaceNonScaled[0] : refSurfaceNonScaled[1];
4439             dsRefSurface4x[2] = (dsRefSurface4x[0]) ? dsRefSurface4x[0] : dsRefSurface4x[1];
4440             dsRefSurface8x[2] = (dsRefSurface8x[0]) ? dsRefSurface8x[0] : dsRefSurface8x[1];
4441         }
4442 
4443         // Program Surface params for Reference surfaces
4444         if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled)
4445         {
4446             surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface               = refSurfaceNonScaled[0];
4447             surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].bVdencDynamicScaling    = true;
4448 
4449             surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface             = refSurfaceNonScaled[1];
4450             surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].bVdencDynamicScaling  = true;
4451 
4452             surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface             = refSurfaceNonScaled[2];
4453             surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].bVdencDynamicScaling = true;
4454         }
4455         else
4456         {
4457             surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface               = refSurface[0];
4458             surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface             = refSurface[1];
4459             surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface             = refSurface[2];
4460         }
4461 
4462         if (m_dysCurrFrameFlag)
4463         {
4464             if (m_dysVdencMultiPassEnabled)
4465             {
4466                 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight   = MOS_ALIGN_CEIL((refSurface[0] ? refSurface[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4467                 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[1] ? refSurface[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4468                 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[2] ? refSurface[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4469             }
4470             else
4471             {
4472                 surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight   = MOS_ALIGN_CEIL((refSurfaceNonScaled[0] ? refSurfaceNonScaled[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4473                 surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurfaceNonScaled[1] ? refSurfaceNonScaled[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4474                 surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurfaceNonScaled[2] ? refSurfaceNonScaled[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
4475             }
4476         }
4477         else
4478         {
4479             surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight =
4480             surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight =
4481             surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = m_rawSurfaceToPak->dwHeight;
4482         }
4483     }
4484 
4485     // Program Surface params for reconstructed surface
4486     surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].psSurface            = &m_reconSurface;
4487     surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwReconSurfHeight    = m_rawSurfaceToPak->dwHeight;
4488 
4489     // Program Surface params for source surface
4490     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].psSurface                = m_rawSurfaceToPak;
4491     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].bDisplayFormatSwizzle    = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle;
4492     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualWidth            = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH);
4493     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualHeight           = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH);
4494 
4495     return eStatus;
4496 }
4497 
SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & pipeModeSelectParams)4498 void CodechalVdencVp9State::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams)
4499 {
4500     pipeModeSelectParams = {};
4501     pipeModeSelectParams.Mode = m_mode;
4502     pipeModeSelectParams.bStreamOutEnabled = m_vdencBrcEnabled;
4503     pipeModeSelectParams.bVdencEnabled = true;
4504     pipeModeSelectParams.bVdencPakObjCmdStreamOutEnable = m_vdencPakObjCmdStreamOutEnabled;
4505     pipeModeSelectParams.bTlbPrefetchEnable = true;
4506     pipeModeSelectParams.isIFrame = (m_vp9PicParams->PicFlags.fields.frame_type == 0);
4507 
4508     // Add 1 to compensate for VdencPipeModeSelect params values
4509     pipeModeSelectParams.ChromaType = m_vp9SeqParams->SeqFlags.fields.EncodedFormat + 1;
4510     switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth)
4511     {
4512         case VP9_ENCODED_BIT_DEPTH_10:
4513         {
4514             pipeModeSelectParams.ucVdencBitDepthMinus8 = 2;
4515             break;
4516         }
4517         default:
4518         {
4519             pipeModeSelectParams.ucVdencBitDepthMinus8 = 0;
4520             break;
4521         }
4522     }
4523 }
4524 
CreateHcpPipeBufAddrParams(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams)4525 PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS CodechalVdencVp9State::CreateHcpPipeBufAddrParams(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams)
4526 {
4527     pipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS);
4528 
4529     return pipeBufAddrParams;
4530 }
4531 
SetPipeBufAddr(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams,PMOS_SURFACE refSurface[3],PMOS_COMMAND_BUFFER cmdBuffer)4532 MOS_STATUS CodechalVdencVp9State::SetPipeBufAddr(
4533     PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams,
4534     PMOS_SURFACE refSurface[3],
4535     PMOS_COMMAND_BUFFER cmdBuffer)
4536 {
4537     CODECHAL_ENCODE_FUNCTION_ENTER;
4538 
4539     CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
4540     return m_mmcState->SetPipeBufAddr(pipeBufAddrParams, cmdBuffer);
4541 }
4542 
SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams,PMOS_SURFACE * refSurface,PMOS_SURFACE * refSurfaceNonScaled,PMOS_SURFACE * dsRefSurface4x,PMOS_SURFACE * dsRefSurface8x)4543 MOS_STATUS CodechalVdencVp9State::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams,
4544     PMOS_SURFACE* refSurface,
4545     PMOS_SURFACE* refSurfaceNonScaled,
4546     PMOS_SURFACE* dsRefSurface4x,
4547     PMOS_SURFACE* dsRefSurface8x)
4548 {
4549     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4550 
4551     CODECHAL_ENCODE_FUNCTION_ENTER;
4552 
4553     pipeBufAddrParams = {};
4554     pipeBufAddrParams.Mode = m_mode;
4555     pipeBufAddrParams.psPreDeblockSurface = &m_reconSurface;
4556     pipeBufAddrParams.psPostDeblockSurface = &m_reconSurface;
4557     pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak;
4558 
4559     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
4560         &m_resDeblockingFilterLineBuffer;
4561 
4562     pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer =
4563         &m_resDeblockingFilterTileLineBuffer;
4564 
4565     pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer =
4566         &m_resDeblockingFilterTileColumnBuffer;
4567 
4568     pipeBufAddrParams.presMetadataLineBuffer       = &m_resMetadataLineBuffer;
4569     pipeBufAddrParams.presMetadataTileLineBuffer   = &m_resMetadataTileLineBuffer;
4570     pipeBufAddrParams.presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer;
4571     pipeBufAddrParams.presCurMvTempBuffer = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex);
4572 
4573     // Huc first pass doesn't write probabilities to output prob region but only updates to the input region. HuC run before repak writes to the ouput region.
4574     uint8_t frameCtxIdx = 0;
4575     if (m_hucEnabled && m_currPass == m_numPasses)
4576     {
4577         pipeBufAddrParams.presVp9ProbBuffer = &m_resHucProbOutputBuffer;
4578     }
4579     else
4580     {
4581         frameCtxIdx = m_vp9PicParams->PicFlags.fields.frame_context_idx;
4582         CODECHAL_ENCODE_ASSERT(frameCtxIdx < CODEC_VP9_NUM_CONTEXTS);
4583         pipeBufAddrParams.presVp9ProbBuffer = &m_resProbBuffer[frameCtxIdx];
4584     }
4585 
4586     pipeBufAddrParams.presVp9SegmentIdBuffer              = &m_resSegmentIdBuffer;
4587     pipeBufAddrParams.presHvdTileRowStoreBuffer           = &m_resHvcTileRowstoreBuffer;
4588     pipeBufAddrParams.ps4xDsSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
4589     pipeBufAddrParams.ps8xDsSurface = m_trackedBuf->Get8xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
4590     pipeBufAddrParams.presVdencIntraRowStoreScratchBuffer = &m_resVdencIntraRowStoreScratchBuffer;
4591     pipeBufAddrParams.dwNumRefIdxL0ActiveMinus1           = (m_vp9PicParams->PicFlags.fields.frame_type) ? m_numRefFrames - 1 : 0;
4592     pipeBufAddrParams.presVdencStreamOutBuffer            = &m_resVdencBrcStatsBuffer;
4593     pipeBufAddrParams.presStreamOutBuffer = nullptr;
4594     pipeBufAddrParams.presFrameStatStreamOutBuffer        = &m_resFrameStatStreamOutBuffer;
4595     pipeBufAddrParams.presSseSrcPixelRowStoreBuffer       = &m_resSseSrcPixelRowStoreBuffer;
4596     pipeBufAddrParams.presVdencStreamInBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
4597     pipeBufAddrParams.presSegmentMapStreamOut             = &m_resVdencSegmentMapStreamOut;
4598     pipeBufAddrParams.presPakCuLevelStreamoutBuffer =
4599         Mos_ResourceIsNull(&m_resPakcuLevelStreamoutData.sResource) ? nullptr : &m_resPakcuLevelStreamoutData.sResource;
4600     if (m_dysRefFrameFlags != DYS_REF_NONE)
4601     {
4602         pipeBufAddrParams.presVdencPakObjCmdStreamOutBuffer =
4603             (m_vdencPakObjCmdStreamOutEnabled) ? m_resVdencPakObjCmdStreamOutBuffer : nullptr;
4604     }
4605     else
4606     {
4607         pipeBufAddrParams.presVdencPakObjCmdStreamOutBuffer = m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface;
4608     }
4609 
4610     if (m_pictureCodingType != I_TYPE)
4611     {
4612         for (auto i = 0; i < 3; i++)
4613         {
4614             CODECHAL_ENCODE_CHK_NULL_RETURN(refSurface[i]);
4615             CODECHAL_ENCODE_CHK_NULL_RETURN(dsRefSurface4x[i]);
4616             CODECHAL_ENCODE_CHK_NULL_RETURN(dsRefSurface8x[i]);
4617 
4618             pipeBufAddrParams.presReferences[i]         = &refSurface[i]->OsResource;
4619             pipeBufAddrParams.presVdencReferences[i]    = &refSurface[i]->OsResource;
4620             pipeBufAddrParams.presVdenc4xDsSurface[i]   = &dsRefSurface4x[i]->OsResource;
4621             pipeBufAddrParams.presVdenc8xDsSurface[i]   = &dsRefSurface8x[i]->OsResource;
4622 
4623             if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled)
4624             {
4625                 pipeBufAddrParams.presReferences[i + 4] = &refSurfaceNonScaled[i]->OsResource;
4626             }
4627         }
4628 
4629         pipeBufAddrParams.presColMvTempBuffer[0] = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex ^ 0x01);
4630     }
4631 
4632     return eStatus;
4633 }
4634 
VerifyCommandBufferSize()4635 MOS_STATUS CodechalVdencVp9State::VerifyCommandBufferSize()
4636 {
4637     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4638 
4639     CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
4640     return eStatus;
4641 }
4642 
GetCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)4643 MOS_STATUS CodechalVdencVp9State::GetCommandBuffer(
4644     PMOS_COMMAND_BUFFER cmdBuffer)
4645 {
4646     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4647 
4648     CODECHAL_ENCODE_FUNCTION_ENTER;
4649 
4650     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4651 
4652     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, cmdBuffer, 0));
4653     return eStatus;
4654 }
4655 
ReturnCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer)4656 MOS_STATUS CodechalVdencVp9State::ReturnCommandBuffer(
4657     PMOS_COMMAND_BUFFER cmdBuffer)
4658 {
4659     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4660 
4661     CODECHAL_ENCODE_FUNCTION_ENTER;
4662 
4663     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4664 
4665     m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0);
4666 
4667     return eStatus;
4668 }
4669 
SubmitCommandBuffer(PMOS_COMMAND_BUFFER cmdBuffer,bool bNullRendering)4670 MOS_STATUS CodechalVdencVp9State::SubmitCommandBuffer(
4671     PMOS_COMMAND_BUFFER cmdBuffer,
4672     bool bNullRendering)
4673 {
4674     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4675 
4676     CODECHAL_ENCODE_FUNCTION_ENTER;
4677 
4678     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
4679 
4680     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, bNullRendering));
4681 
4682     return eStatus;
4683 }
4684 
SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & indObjBaseAddrParams)4685 void CodechalVdencVp9State::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
4686 {
4687     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
4688     indObjBaseAddrParams.Mode = m_mode;
4689     indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer;
4690     indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound;
4691     indObjBaseAddrParams.presProbabilityDeltaBuffer   = &m_resProbabilityDeltaBuffer;
4692     indObjBaseAddrParams.dwProbabilityDeltaSize = 29 * CODECHAL_CACHELINE_SIZE;
4693     indObjBaseAddrParams.presCompressedHeaderBuffer   = &m_resCompressedHeaderBuffer;
4694     indObjBaseAddrParams.dwCompressedHeaderSize = 32 * CODECHAL_CACHELINE_SIZE;
4695     indObjBaseAddrParams.presProbabilityCounterBuffer = &m_resProbabilityCounterBuffer;
4696     indObjBaseAddrParams.dwProbabilityCounterOffset = 0;
4697     indObjBaseAddrParams.dwProbabilityCounterSize = 193 * CODECHAL_CACHELINE_SIZE;
4698     indObjBaseAddrParams.presTileRecordBuffer         = &m_resTileRecordStrmOutBuffer;
4699     indObjBaseAddrParams.dwTileRecordSize = m_picSizeInSb * CODECHAL_CACHELINE_SIZE;
4700     indObjBaseAddrParams.presCuStatsBuffer            = &m_resCuStatsStrmOutBuffer;
4701     indObjBaseAddrParams.dwCuStatsSize = MOS_ALIGN_CEIL(m_picSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE);
4702 }
4703 
SetHcpDsSurfaceParams(MHW_VDBOX_SURFACE_PARAMS * dsSurfaceParams)4704 void CodechalVdencVp9State::SetHcpDsSurfaceParams(MHW_VDBOX_SURFACE_PARAMS* dsSurfaceParams)
4705 {
4706     // 8xDS surface
4707     MOS_ZeroMemory(&dsSurfaceParams[0], sizeof(MHW_VDBOX_SURFACE_PARAMS));
4708     dsSurfaceParams[0].Mode = m_mode;
4709     dsSurfaceParams[0].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID;
4710     dsSurfaceParams[0].psSurface = m_trackedBuf->Get8xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
4711     // 4xDS Surface
4712     MOS_ZeroMemory(&dsSurfaceParams[1], sizeof(MHW_VDBOX_SURFACE_PARAMS));
4713     dsSurfaceParams[1].Mode = m_mode;
4714     dsSurfaceParams[1].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID;
4715     dsSurfaceParams[1].psSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
4716 }
4717 
GetStatusReport(EncodeStatus * encodeStatus,EncodeStatusReport * encodeStatusReport)4718 MOS_STATUS CodechalVdencVp9State::GetStatusReport(
4719     EncodeStatus*       encodeStatus,
4720     EncodeStatusReport* encodeStatusReport)
4721 {
4722     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4723 
4724     CODECHAL_ENCODE_FUNCTION_ENTER;
4725 
4726     CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatus);
4727     CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusReport);
4728 
4729     encodeStatusReport->CodecStatus = CODECHAL_STATUS_SUCCESSFUL;
4730     encodeStatusReport->bitstreamSize =
4731         encodeStatus->dwMFCBitstreamByteCountPerFrame + encodeStatus->dwHeaderBytesInserted;
4732 
4733     encodeStatusReport->QpY          = m_vp9PicParams->LumaACQIndex;
4734     encodeStatusReport->NumberPasses = (uint8_t)encodeStatus->dwNumberPasses;
4735 
4736     if (m_brcEnabled)
4737     {
4738         MOS_LOCK_PARAMS lockFlagsReadOnly;
4739         MOS_ZeroMemory(&lockFlagsReadOnly, sizeof(MOS_LOCK_PARAMS));
4740         lockFlagsReadOnly.ReadOnly = 1;
4741 
4742         uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer, &lockFlagsReadOnly);
4743         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
4744 
4745         HucBrcDataBuffer* hucData = (HucBrcDataBuffer*)data;
4746 
4747         encodeStatusReport->NextFrameWidthMinus1  = (uint16_t) hucData->DW5.NextFrameWidth - 1;
4748         encodeStatusReport->NextFrameHeightMinus1 = (uint16_t) hucData->DW5.NextFrameHeight - 1;
4749 
4750         m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer);
4751     }
4752 
4753     return eStatus;
4754 }
4755 
ExecuteSliceLevel()4756 MOS_STATUS CodechalVdencVp9State::ExecuteSliceLevel()
4757 {
4758     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4759 
4760     CODECHAL_ENCODE_FUNCTION_ENTER;
4761 
4762     MOS_COMMAND_BUFFER cmdBuffer;
4763     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
4764 
4765     MHW_BATCH_BUFFER secondLevelBatchBuffer;
4766     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer));
4767     secondLevelBatchBuffer.dwOffset = 0;
4768     secondLevelBatchBuffer.bSecondLevel = true;
4769     if (!m_hucEnabled)
4770     {
4771         secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx];
4772     }
4773     else
4774     {
4775         secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderWriteBuffer;
4776     }
4777     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
4778         &cmdBuffer,
4779         &secondLevelBatchBuffer));
4780 
4781     MHW_VDBOX_VDENC_WEIGHT_OFFSET_PARAMS vdencWeightOffsetParams;
4782     MOS_ZeroMemory(&vdencWeightOffsetParams, sizeof(vdencWeightOffsetParams));
4783     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWeightsOffsetsStateCmd(&cmdBuffer, nullptr, &vdencWeightOffsetParams));
4784 
4785     MHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams;
4786     vdencWalkerStateParams.Mode = CODECHAL_ENCODE_MODE_VP9;
4787     vdencWalkerStateParams.pVp9EncPicParams = m_vp9PicParams;
4788     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWalkerStateCmd(&cmdBuffer, &vdencWalkerStateParams));
4789 
4790     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams;
4791     MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams));
4792     // MFXPipeDone should not be set for tail insertion
4793     vdPipelineFlushParams.Flags.bWaitDoneMFX = 1;
4794     vdPipelineFlushParams.Flags.bWaitDoneHEVC = 1;
4795     vdPipelineFlushParams.Flags.bFlushHEVC = 1;
4796     vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
4797 
4798     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams));
4799 
4800     CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
4801 
4802     CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(&cmdBuffer));
4803 
4804     uint32_t offset =
4805         (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize)  +
4806         m_encodeStatusBuf.dwNumPassesOffset                                      +
4807         sizeof(uint32_t) * 2; // encode status doesn't start until 3rd DW
4808 
4809     MHW_MI_STORE_DATA_PARAMS storeDataParams;
4810     storeDataParams.pOsResource         = &m_encodeStatusBuf.resStatusBuffer;
4811     storeDataParams.dwResourceOffset    = offset;
4812     storeDataParams.dwValue             = m_currPass + 1;
4813     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
4814 
4815     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
4816     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
4817     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
4818 
4819     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4820     {
4821         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
4822     }
4823 
4824     std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass));
4825     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
4826         &cmdBuffer,
4827         CODECHAL_NUM_MEDIA_STATES,
4828         pakPassName.data())));
4829 
4830     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
4831 
4832     if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
4833     {
4834         bool renderFlags;
4835 
4836         if (m_waitForEnc &&
4837             !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
4838         {
4839             MOS_SYNC_PARAMS syncParams;
4840             syncParams = g_cInitSyncParams;
4841             syncParams.GpuContext = m_videoContext;
4842             syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
4843 
4844             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4845             m_waitForEnc = false;
4846         }
4847 
4848         renderFlags = m_videoContextUsesNullHw;
4849 
4850         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags));
4851         m_lastTaskInPhase = false;
4852 
4853         CODECHAL_DEBUG_TOOL(
4854             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
4855                 m_resVdencPakObjCmdStreamOutBuffer,
4856                 CodechalDbgAttr::attrPakObjStreamout,
4857                 pakPassName.data(),
4858                 m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE,
4859                 0,
4860                 CODECHAL_NUM_MEDIA_STATES));
4861 
4862             if (m_vp9PicParams->PicFlags.fields.segmentation_enabled) {
4863                 ; //CodecHal_DbgDumpEncodeVp9SegmentStreamout(m_debugInterface, m_encoder);
4864             } if (m_mmcState) {
4865                 m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
4866             });
4867     }
4868 
4869     // Reset parameters for next PAK execution
4870     if (m_currPass == m_numPasses)
4871     {
4872         if (m_vp9PicParams->PicFlags.fields.super_frame && m_tsEnabled)
4873         {
4874             CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructSuperFrame());
4875         }
4876 
4877         if (m_signalEnc &&
4878             !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
4879         {
4880             // Check if the signal obj count exceeds max value
4881             MOS_SYNC_PARAMS syncParams;
4882             if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED))
4883             {
4884                 syncParams = g_cInitSyncParams;
4885                 syncParams.GpuContext = m_renderContext;
4886                 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4887 
4888                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
4889                 m_semaphoreObjCount--;
4890             }
4891 
4892             // signal semaphore
4893             syncParams = g_cInitSyncParams;
4894             syncParams.GpuContext = m_videoContext;
4895             syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
4896 
4897             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
4898             m_semaphoreObjCount++;
4899         }
4900 
4901         m_prevFrameInfo.KeyFrame    = !m_vp9PicParams->PicFlags.fields.frame_type;
4902         m_prevFrameInfo.IntraOnly   = (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME) || m_vp9PicParams->PicFlags.fields.intra_only;
4903         m_prevFrameInfo.ShowFrame   = m_vp9PicParams->PicFlags.fields.show_frame;
4904         m_prevFrameInfo.FrameWidth  = m_oriFrameWidth;
4905         m_prevFrameInfo.FrameHeight = m_oriFrameHeight;
4906         m_currMvTemporalBufferIndex ^= 0x01;
4907         m_contextFrameTypes[m_vp9PicParams->PicFlags.fields.frame_context_idx] = m_vp9PicParams->PicFlags.fields.frame_type;
4908         m_prevFrameSegEnabled                                                  = m_vp9PicParams->PicFlags.fields.segmentation_enabled;
4909 
4910         if (!m_singleTaskPhaseSupported)
4911         {
4912             m_osInterface->pfnResetPerfBufferID(m_osInterface);
4913         }
4914 
4915         m_newPpsHeader = 0;
4916         m_newSeqHeader = 0;
4917         m_frameNum++;
4918     }
4919 
4920     return eStatus;
4921 }
4922 
PakConstructPicStateBatchBuf(PMOS_RESOURCE picStateBuffer)4923 MOS_STATUS CodechalVdencVp9State::PakConstructPicStateBatchBuf(
4924     PMOS_RESOURCE picStateBuffer)
4925 {
4926     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4927 
4928     CODECHAL_ENCODE_FUNCTION_ENTER;
4929 
4930     CODECHAL_ENCODE_CHK_NULL_RETURN(picStateBuffer);
4931 
4932     MOS_LOCK_PARAMS lockFlagsWriteOnly;
4933     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
4934     lockFlagsWriteOnly.WriteOnly = 1;
4935     uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, picStateBuffer, &lockFlagsWriteOnly);
4936     CODECHAL_ENCODE_CHK_NULL_RETURN(data);
4937 
4938     // HCP_VP9_PIC_STATE
4939     MHW_VDBOX_VP9_ENCODE_PIC_STATE picState;
4940     MOS_ZeroMemory(&picState, sizeof(picState));
4941     picState.pVp9PicParams                    = m_vp9PicParams;
4942     picState.pVp9SeqParams                    = m_vp9SeqParams;
4943     picState.ppVp9RefList                     = &(m_refList[0]);
4944     picState.PrevFrameParams.fields.KeyFrame  = m_prevFrameInfo.KeyFrame;
4945     picState.PrevFrameParams.fields.IntraOnly = m_prevFrameInfo.IntraOnly;
4946     picState.PrevFrameParams.fields.Display   = m_prevFrameInfo.ShowFrame;
4947     picState.dwPrevFrmWidth                   = m_prevFrameInfo.FrameWidth;
4948     picState.dwPrevFrmHeight                  = m_prevFrameInfo.FrameHeight;
4949     picState.ucTxMode = m_txMode;
4950 
4951     for (auto i = 0; i < CODECHAL_ENCODE_VP9_BRC_MAX_NUM_OF_PASSES; i++)
4952     {
4953         picState.bNonFirstPassFlag = (i != 0) ? true : false;
4954 
4955         MOS_COMMAND_BUFFER constructedCmdBuf;
4956 
4957         constructedCmdBuf.pCmdBase   = (uint32_t *)data;
4958         constructedCmdBuf.pCmdPtr    = (uint32_t *)(data + i * CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS);
4959         constructedCmdBuf.iOffset    = 0;
4960         constructedCmdBuf.iRemaining = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS;
4961 
4962         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9PicStateEncCmd(&constructedCmdBuf, nullptr, &picState));
4963 
4964         // After adding pic State cmds in above function, pCmdPtr is not at the end of the picState Buffer, so adjusting it.
4965         constructedCmdBuf.pCmdPtr    = (uint32_t *)(data + (i+1) * CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS) - 1;  //-1 to go back one uint32_t where BB end will be added
4966 
4967         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr));
4968     }
4969 
4970     if (data)
4971     {
4972         m_osInterface->pfnUnlockResource(
4973             m_osInterface,
4974             picStateBuffer);
4975     }
4976     return eStatus;
4977 }
4978 
4979 // This is used only for DynamicScaling
ExecuteDysPictureLevel()4980 MOS_STATUS CodechalVdencVp9State::ExecuteDysPictureLevel()
4981 {
4982     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
4983 
4984     CODECHAL_ENCODE_FUNCTION_ENTER;
4985 
4986     CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()),"ERROR - vdbox index exceed the maximum");
4987     auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
4988     CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
4989     PerfTagSetting perfTag;
4990     perfTag.Value = 0;
4991     perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
4992     perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE;
4993     perfTag.PictureCodingType = m_pictureCodingType;
4994     m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
4995 
4996     // We only need to update Huc PAK insert object and picture state for the first pass
4997     if (m_currPass == 0)
4998     {
4999         CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPakInsertObjBatchBuf(&m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx]));
5000         CODECHAL_ENCODE_CHK_STATUS_RETURN(PakConstructPicStateBatchBuf(
5001             &m_brcBuffers.resPicStateBrcWriteHucReadBuffer));
5002 
5003     }
5004 
5005     MOS_COMMAND_BUFFER cmdBuffer;
5006     CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer));
5007 
5008     if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
5009     {
5010         bool requestFrameTracking = false;
5011 
5012         // Send command buffer header at the beginning (OS dependent)
5013         // frame tracking tag is only added in the last command buffer header
5014         requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase;
5015         CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
5016     }
5017 
5018     // Making sure ImgStatusCtrl is zeroed out before first PAK pass. HW supposedly does this before start of each frame. Remove this after confirming.
5019     if (m_currPass == 0)
5020     {
5021         MHW_MI_LOAD_REGISTER_IMM_PARAMS miLoadRegImmParams;
5022         MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
5023         miLoadRegImmParams.dwData     = 0;
5024         miLoadRegImmParams.dwRegister = mmioRegisters->hcpVp9EncImageStatusCtrlRegOffset;
5025         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiLoadRegisterImmCmd(&cmdBuffer, &miLoadRegImmParams));
5026     }
5027 
5028     // Read Image status before running PAK, to get correct cumulative delta applied for final pass.
5029     if (m_currPass != m_numPasses)        // Don't read it for Repak
5030     {
5031         CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadImageStatus(&cmdBuffer));
5032     }
5033 
5034     //updating the numberofpakpasses in encode staus buffer. should not update for repak.
5035     if (m_currPass < m_numPasses)
5036     {
5037         uint32_t offset =
5038             (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
5039             m_encodeStatusBuf.dwNumPassesOffset +
5040             sizeof(uint32_t)* 2; // encode status doesn't start until 3rd DW
5041 
5042         MHW_MI_STORE_DATA_PARAMS storeDataParams;
5043         MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
5044         storeDataParams.pOsResource = &m_encodeStatusBuf.resStatusBuffer;
5045         storeDataParams.dwResourceOffset = offset;
5046         storeDataParams.dwValue = m_currPass + 1;
5047         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
5048     }
5049 
5050     if (!m_currPass && m_osInterface->bTagResourceSync)
5051     {
5052         // This is a short term WA to solve the sync tag issue: the sync tag write for PAK is inserted at the end of 2nd pass PAK BB
5053         // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning
5054         // of the BB and keep the current frame's tag at the end of the BB. There will be a delay for tag update but it should be fine
5055         // as long as Dec/VP/Enc won't depend on this PAK so soon.
5056         PMOS_RESOURCE globalGpuContextSyncTagBuffer = nullptr;
5057         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource(
5058             m_osInterface,
5059             globalGpuContextSyncTagBuffer));
5060         CODECHAL_ENCODE_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer);
5061 
5062         uint32_t value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
5063         MHW_MI_STORE_DATA_PARAMS params;
5064         params.pOsResource = globalGpuContextSyncTagBuffer;
5065         params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal);
5066         params.dwValue = (value > 0) ? (value - 1) : 0;
5067         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiStoreDataImmCmd(&cmdBuffer, &params));
5068     }
5069 
5070     CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
5071 
5072     // set HCP_PIPE_MODE_SELECT values
5073     PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = nullptr;
5074     pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams();
5075     if (pipeModeSelectParams)
5076     {
5077         pipeModeSelectParams->Mode = m_mode;
5078         pipeModeSelectParams->bStreamOutEnabled  = false;
5079         pipeModeSelectParams->bVdencEnabled      = false;
5080         pipeModeSelectParams->ChromaType         = m_vp9SeqParams->SeqFlags.fields.EncodedFormat;
5081 
5082         eStatus = m_hcpInterface->AddHcpPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams);
5083         m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
5084         CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus);
5085     }
5086 
5087     // set HCP_SURFACE_STATE values
5088     MHW_VDBOX_SURFACE_PARAMS surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID + 1];
5089     for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++)
5090     {
5091         MOS_ZeroMemory(&surfaceParams[i], sizeof(surfaceParams[i]));
5092         surfaceParams[i].Mode = m_mode;
5093         surfaceParams[i].ucSurfaceStateId = i;
5094         surfaceParams[i].ChromaType = m_outputChromaFormat;
5095 
5096         switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth)
5097         {
5098         case VP9_ENCODED_BIT_DEPTH_10: //10 bit encoding
5099         {
5100             surfaceParams[i].ucBitDepthChromaMinus8 = 2;
5101             surfaceParams[i].ucBitDepthLumaMinus8 = 2;
5102             break;
5103         }
5104         default:
5105         {
5106             surfaceParams[i].ucBitDepthChromaMinus8 = 0;
5107             surfaceParams[i].ucBitDepthLumaMinus8 = 0;
5108             break;
5109         }
5110         }
5111     }
5112 
5113     // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled
5114     PMOS_SURFACE refSurface[3];
5115     for (auto i = 0; i < 3; i++)
5116     {
5117         refSurface[i] = nullptr;
5118     }
5119 
5120     if (m_pictureCodingType != I_TYPE)
5121     {
5122         uint8_t refPicIndex;
5123         if (m_refFrameFlags & 0x01)
5124         {
5125             refPicIndex = m_vp9PicParams->RefFlags.fields.LastRefIdx;
5126 
5127             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])));
5128             refSurface[0] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
5129         }
5130 
5131         if (m_refFrameFlags & 0x02)
5132         {
5133             refPicIndex = m_vp9PicParams->RefFlags.fields.GoldenRefIdx;
5134 
5135             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])));
5136             refSurface[1] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
5137         }
5138 
5139         if (m_refFrameFlags & 0x04)
5140         {
5141             refPicIndex = m_vp9PicParams->RefFlags.fields.AltRefIdx;
5142 
5143             CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex])))
5144             refSurface[2] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer);
5145         }
5146 
5147         if (!refSurface[0])
5148         {
5149             refSurface[0] = (refSurface[1]) ? refSurface[1] : refSurface[2];
5150         }
5151 
5152         if (!refSurface[1])
5153         {
5154             refSurface[1] = (refSurface[0]) ? refSurface[0] : refSurface[2];
5155         }
5156 
5157         if (!refSurface[2])
5158         {
5159             refSurface[2] = (refSurface[0]) ? refSurface[0] : refSurface[1];
5160         }
5161 
5162         // Program Surface params for Last/Golen/Alt Reference surface
5163         surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface               = refSurface[0];
5164         surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface             = refSurface[1];
5165         surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface             = refSurface[2];
5166 
5167         surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight   = MOS_ALIGN_CEIL((refSurface[0] ? refSurface[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
5168         surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[1] ? refSurface[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
5169         surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[2] ? refSurface[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH);
5170     }
5171 
5172     // recon
5173     surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].psSurface            = &m_reconSurface;
5174     surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwReconSurfHeight    = m_rawSurfaceToPak->dwHeight;
5175 
5176     // raw
5177     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].psSurface                = m_rawSurfaceToPak;
5178     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].bDisplayFormatSwizzle    = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle;
5179     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualWidth            = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH);
5180     surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualHeight           = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH);
5181 
5182     // Decodec picture
5183     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID]));
5184 
5185     // Source input
5186     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID]));
5187 
5188     // Last reference picture
5189     if (refSurface[0])
5190     {
5191         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID]));
5192     }
5193 
5194     // Golden reference picture
5195     if (refSurface[1])
5196     {
5197         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID]));
5198     }
5199 
5200     // Alt reference picture
5201     if (refSurface[2])
5202     {
5203         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID]));
5204     }
5205 
5206     // set HCP_PIPE_BUF_ADDR_STATE values
5207     PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams = nullptr;
5208     pipeBufAddrParams = CreateHcpPipeBufAddrParams(pipeBufAddrParams);
5209     if (pipeBufAddrParams)
5210     {
5211         auto delete_func = [&]()
5212         {
5213             MOS_Delete(pipeBufAddrParams);
5214             pipeBufAddrParams = nullptr;
5215         };
5216 
5217         pipeBufAddrParams->Mode = m_mode;
5218         pipeBufAddrParams->psPreDeblockSurface = &m_reconSurface;
5219         pipeBufAddrParams->psPostDeblockSurface = &m_reconSurface;
5220         pipeBufAddrParams->psRawSurface = m_rawSurfaceToPak;
5221 
5222         pipeBufAddrParams->presStreamOutBuffer = nullptr;
5223         pipeBufAddrParams->presMfdDeblockingFilterRowStoreScratchBuffer =
5224             &m_resDeblockingFilterLineBuffer;
5225 
5226         pipeBufAddrParams->presDeblockingFilterTileRowStoreScratchBuffer =
5227             &m_resDeblockingFilterTileLineBuffer;
5228 
5229         pipeBufAddrParams->presDeblockingFilterColumnRowStoreScratchBuffer =
5230             &m_resDeblockingFilterTileColumnBuffer;
5231 
5232         pipeBufAddrParams->presMetadataLineBuffer       = &m_resMetadataLineBuffer;
5233         pipeBufAddrParams->presMetadataTileLineBuffer   = &m_resMetadataTileLineBuffer;
5234         pipeBufAddrParams->presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer;
5235         pipeBufAddrParams->presCurMvTempBuffer = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex);
5236         if (m_pictureCodingType != I_TYPE)
5237         {
5238             for (auto i = 0; i < 3; i++)
5239             {
5240                 CODECHAL_ENCODE_CHK_NULL_WITH_DESTROY_RETURN(refSurface[i], delete_func);
5241                 pipeBufAddrParams->presReferences[i] = &refSurface[i]->OsResource;
5242             }
5243         }
5244 
5245 
5246         pipeBufAddrParams->pRawSurfParam      = &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID];
5247         pipeBufAddrParams->pDecodedReconParam = &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID];
5248         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(SetPipeBufAddr(pipeBufAddrParams, refSurface, &cmdBuffer), delete_func);
5249 
5250         //Huc is disabled for ref frame scaling, use input region
5251         uint8_t frameCtxIdx = m_vp9PicParams->PicFlags.fields.frame_context_idx;
5252         CODECHAL_ENCODE_ASSERT(frameCtxIdx < CODEC_VP9_NUM_CONTEXTS);
5253         pipeBufAddrParams->presVp9ProbBuffer      = &m_resProbBuffer[frameCtxIdx];
5254         pipeBufAddrParams->presVp9SegmentIdBuffer = &m_resSegmentIdBuffer;
5255 
5256         if (m_pictureCodingType != I_TYPE)
5257         {
5258             pipeBufAddrParams->presColMvTempBuffer[0] = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex ^ 0x01);
5259         }
5260         CODECHAL_ENCODE_CHK_STATUS_WITH_DESTROY_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams), delete_func);
5261 
5262         MOS_Delete(pipeBufAddrParams);
5263     }
5264 
5265     // set HCP_IND_OBJ_BASE_ADDR_STATE values
5266     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
5267     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
5268     indObjBaseAddrParams.Mode                           = m_mode;
5269     indObjBaseAddrParams.presMvObjectBuffer             = &m_resMbCodeSurface;
5270     indObjBaseAddrParams.dwMvObjectOffset               = m_mvOffset;
5271     indObjBaseAddrParams.dwMvObjectSize                 = m_mbCodeSize - m_mvOffset;
5272     indObjBaseAddrParams.presPakBaseObjectBuffer        = &m_resBitstreamBuffer;
5273     indObjBaseAddrParams.dwPakBaseObjectSize            = m_bitstreamUpperBound;
5274     indObjBaseAddrParams.presProbabilityDeltaBuffer     = &m_resProbabilityDeltaBuffer;
5275     indObjBaseAddrParams.dwProbabilityDeltaSize         = 29 * CODECHAL_CACHELINE_SIZE;
5276     indObjBaseAddrParams.presCompressedHeaderBuffer     = &m_resCompressedHeaderBuffer;
5277     indObjBaseAddrParams.dwCompressedHeaderSize         = 32 * CODECHAL_CACHELINE_SIZE;
5278     indObjBaseAddrParams.presProbabilityCounterBuffer   = &m_resProbabilityCounterBuffer;
5279     indObjBaseAddrParams.dwProbabilityCounterSize       = 193 * CODECHAL_CACHELINE_SIZE;
5280     indObjBaseAddrParams.presTileRecordBuffer           = &m_resTileRecordStrmOutBuffer;
5281     indObjBaseAddrParams.dwTileRecordSize               = m_picSizeInSb * CODECHAL_CACHELINE_SIZE;
5282     indObjBaseAddrParams.presCuStatsBuffer              = &m_resCuStatsStrmOutBuffer;
5283     indObjBaseAddrParams.dwCuStatsSize                  = MOS_ALIGN_CEIL(m_picSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE);
5284     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
5285 
5286     // Using picstate zero with updated QP and LF deltas by HuC for repak, irrespective of how many Pak passes were run in multi-pass mode.
5287     MHW_BATCH_BUFFER secondLevelBatchBuffer;
5288     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer));
5289     secondLevelBatchBuffer.dwOffset = (m_numPasses > 0) ? CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * (m_currPass % m_numPasses) : 0;
5290     secondLevelBatchBuffer.bSecondLevel = true;
5291     //As Huc is disabled for Ref frame scaling, use the ReadBuffer
5292     secondLevelBatchBuffer.OsResource = m_brcBuffers.resPicStateBrcWriteHucReadBuffer;
5293     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
5294         &cmdBuffer,
5295         &secondLevelBatchBuffer));
5296 
5297     // HCP_VP9_SEGMENT_STATE
5298     uint8_t segmentCount = (m_vp9PicParams->PicFlags.fields.segmentation_enabled) ? CODEC_VP9_MAX_SEGMENTS : 1;
5299 
5300     MHW_VDBOX_VP9_SEGMENT_STATE segmentState;
5301     MOS_ZeroMemory(&segmentState, sizeof(segmentState));
5302     segmentState.Mode                        = m_mode;
5303     segmentState.pVp9EncodeSegmentParams     = m_vp9SegmentParams;
5304     segmentState.ucQPIndexLumaAC             = m_vp9PicParams->LumaACQIndex;
5305 
5306     // For BRC with segmentation, seg state commands for PAK are copied from BRC seg state buffer
5307     // For CQP or BRC with no segmentation, PAK still needs seg state commands and driver prepares those commands.
5308     segmentState.pbSegStateBufferPtr = nullptr; // Set this to nullptr, for commands to be prepared by driver
5309     segmentState.pcucLfQpLookup          = &LF_VALUE_QP_LOOKUP[0];
5310     for (uint8_t i = 0; i < segmentCount; i++)
5311     {
5312         segmentState.ucCurrentSegmentId  = i;
5313         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9SegmentStateCmd(&cmdBuffer, nullptr, &segmentState));
5314     }
5315 
5316     CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer));
5317 
5318     return eStatus;
5319 }
5320 
ExecuteDysSliceLevel()5321 MOS_STATUS CodechalVdencVp9State::ExecuteDysSliceLevel()
5322 {
5323     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5324 
5325     CODECHAL_ENCODE_FUNCTION_ENTER;
5326 
5327     CODECHAL_ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
5328 
5329     MOS_COMMAND_BUFFER cmdBuffer;
5330     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
5331 
5332     MHW_BATCH_BUFFER secondLevelBatchBuffer;
5333     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer));
5334     secondLevelBatchBuffer.dwOffset = 0;
5335     secondLevelBatchBuffer.bSecondLevel = true;
5336     // This function is called only for Reference frame scaling for Dynamic Scaling feature
5337     // Huc is disabled for ref frame scaling so we use on the ReadBuffer
5338     secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx];
5339 
5340     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
5341         &cmdBuffer,
5342         &secondLevelBatchBuffer));
5343 
5344     MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
5345     secondLevelBatchBuffer.OsResource = m_resMbCodeSurface;
5346     secondLevelBatchBuffer.dwOffset = 0;
5347     secondLevelBatchBuffer.bSecondLevel = true;
5348     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &secondLevelBatchBuffer));
5349 
5350     MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams;
5351     MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams));
5352     // MFXPipeDone should not be set for tail insertion
5353     vdPipelineFlushParams.Flags.bWaitDoneMFX =
5354         (m_lastPicInStream || m_lastPicInSeq) ? 0 : 1;
5355     vdPipelineFlushParams.Flags.bWaitDoneHEVC = 1;
5356     vdPipelineFlushParams.Flags.bFlushHEVC = 1;
5357     vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
5358 
5359     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams));
5360 
5361     CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer));
5362 
5363     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
5364     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
5365     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
5366 
5367     CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
5368 
5369     if (m_currPass >= (m_numPasses - 1))    // Last pass and the one before last
5370     {
5371         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
5372     }
5373 
5374     std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass));
5375     CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
5376         &cmdBuffer,
5377         CODECHAL_NUM_MEDIA_STATES,
5378         pakPassName.data())));
5379 
5380     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
5381 
5382     if (m_waitForEnc &&
5383         !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse))
5384     {
5385         MOS_SYNC_PARAMS syncParams = g_cInitSyncParams;
5386         syncParams.GpuContext = m_videoContext;
5387         syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse;
5388 
5389         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
5390         m_waitForEnc = false;
5391     }
5392 
5393     if (m_currPass >= (m_numPasses - 1))    // Last pass and the one before last
5394     {
5395         bool renderFlags;
5396 
5397         renderFlags = m_videoContextUsesNullHw;
5398 
5399         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags));
5400     }
5401 
5402     CODECHAL_DEBUG_TOOL(
5403         if (m_vp9PicParams->PicFlags.fields.segmentation_enabled) {
5404             ; //CodecHal_DbgDumpEncodeVp9SegmentStreamout(m_debugInterface, m_encoder);
5405         } if (m_mmcState) {
5406             m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
5407         });
5408 
5409     return eStatus;
5410 }
5411 
AllocateMbBrcSegMapSurface()5412 MOS_STATUS CodechalVdencVp9State::AllocateMbBrcSegMapSurface()
5413 {
5414     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5415 
5416     CODECHAL_ENCODE_FUNCTION_ENTER;
5417 
5418     //MBBRC segment map surface needs to be allocated when mbbrc is enabled as segment map will not be
5419     //passed from APP when MBBRC is enabled
5420     uint32_t picWidthInMb = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_maxPicWidth);
5421     uint32_t picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_maxPicHeight);
5422 
5423     m_mbSegmentMapSurface.TileType      = MOS_TILE_LINEAR;
5424     m_mbSegmentMapSurface.bArraySpacing = true;
5425     m_mbSegmentMapSurface.Format        = Format_Buffer_2D;
5426     m_mbSegmentMapSurface.dwWidth       = MOS_ALIGN_CEIL(picWidthInMb, 4);
5427     m_mbSegmentMapSurface.dwHeight      = picHeightInMb;
5428     m_mbSegmentMapSurface.dwPitch       = MOS_ALIGN_CEIL(picWidthInMb, 64);
5429 
5430     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
5431     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
5432 
5433     allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
5434     allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
5435     allocParamsForBuffer2D.Format = Format_Buffer_2D;
5436     allocParamsForBuffer2D.dwWidth  = m_mbSegmentMapSurface.dwPitch;
5437     allocParamsForBuffer2D.dwHeight = picHeightInMb;
5438     allocParamsForBuffer2D.pBufName = "MBBRC driver Segment Map Surface";
5439 
5440     uint32_t size = allocParamsForBuffer2D.dwWidth * allocParamsForBuffer2D.dwHeight;
5441 
5442     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
5443         m_osInterface,
5444         &allocParamsForBuffer2D,
5445         &m_mbSegmentMapSurface.OsResource));
5446 
5447     MOS_LOCK_PARAMS lockFlagsWriteOnly;
5448     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
5449     lockFlagsWriteOnly.WriteOnly = 1;
5450 
5451     uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
5452         m_osInterface,
5453         &(m_mbSegmentMapSurface.OsResource),
5454         &lockFlagsWriteOnly);
5455 
5456     if (data == nullptr)
5457     {
5458         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MBBRC driver segment map resource.");
5459         return MOS_STATUS_UNKNOWN;
5460     }
5461 
5462     MOS_ZeroMemory(data, size);
5463     m_osInterface->pfnUnlockResource(m_osInterface, &m_mbSegmentMapSurface.OsResource);
5464 
5465     m_segmentMapAllocated = true;
5466 
5467     return eStatus;
5468 }
5469 
SetSequenceStructs()5470 MOS_STATUS CodechalVdencVp9State::SetSequenceStructs()
5471 {
5472     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5473 
5474     CODECHAL_ENCODE_FUNCTION_ENTER;
5475 
5476     if (m_osInterface->osCpInterface->IsHMEnabled())
5477     {
5478         m_advancedDshInUse = true;
5479     }
5480 
5481     m_numPasses = m_hucEnabled ? CODECHAL_ENCODE_VP9_CQP_NUM_OF_PASSES - 1 : 0;
5482     m_brcEnabled = CodecHalIsRateControlBrc(m_vp9SeqParams->RateControlMethod, CODECHAL_VP9);
5483     if (m_brcEnabled)
5484     {
5485         m_brcReset        = m_vp9SeqParams->SeqFlags.fields.bResetBRC;
5486         m_vdencBrcEnabled = true;
5487         m_numPasses = m_multipassBrcSupported ? CODECHAL_ENCODE_VP9_BRC_DEFAULT_NUM_OF_PASSES : CODECHAL_ENCODE_VP9_BRC_DEFAULT_NUM_OF_PASSES - 1;
5488     }
5489 
5490     if (m_adaptiveRepakSupported)
5491     {
5492         CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateRePakThresholds());
5493     }
5494 
5495     m_tsEnabled = (m_vp9SeqParams->NumTemporalLayersMinus1 > 0) ? true : false;
5496 
5497     if (m_tsEnabled && m_brcEnabled)
5498     {
5499         // check base layer properties
5500         CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[0].uiNumerator > 0 && m_vp9SeqParams->FrameRate[0].uiDenominator > 0);
5501         CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[0] > 0);
5502 
5503         for (auto i = 1; i < m_vp9SeqParams->NumTemporalLayersMinus1 + 1; i += 1)
5504         {
5505             // check current layer properties
5506             CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[i].uiNumerator > 0 && m_vp9SeqParams->FrameRate[i].uiDenominator > 0);
5507             CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[i] > 0);
5508 
5509             // check current layer properties are bigger than previous layer (since current includes previous layer properties)
5510             CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[i].uiNumerator / m_vp9SeqParams->FrameRate[i].uiDenominator >
5511                                    m_vp9SeqParams->FrameRate[i - 1].uiNumerator / m_vp9SeqParams->FrameRate[i - 1].uiDenominator);
5512             CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[i] > m_vp9SeqParams->TargetBitRate[i - 1]);
5513         }
5514     }
5515 
5516     if ((m_vp9SeqParams->SeqFlags.fields.MBBRC == MBBRC_ENABLED) || (m_vp9SeqParams->SeqFlags.fields.MBBRC == MBBRC_ENABLED_TU_DEPENDENCY))
5517     {
5518         if (!m_segmentMapAllocated)
5519         {
5520             CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateMbBrcSegMapSurface());
5521         }
5522     }
5523     else
5524     {
5525         //Allocated Driver MbBrc Segment map resource needs to be deallocated when MBBRC is disabled. The reason being
5526         //same segmnet map surface (sMbSegmentMapSurface) will be used in the driver referencing both the Application passed
5527         //as well as Driver allocated resource for segmentmap depending on mbbrc disabled or enabled.
5528         if (!Mos_ResourceIsNull(&m_mbSegmentMapSurface.OsResource) && m_segmentMapAllocated)
5529         {
5530             m_osInterface->pfnFreeResource(
5531                 m_osInterface,
5532                 &m_mbSegmentMapSurface.OsResource);
5533         }
5534 
5535         m_segmentMapAllocated = false;
5536     }
5537 
5538     // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
5539     m_gopIsIdrFrameOnly = (m_vp9SeqParams->GopPicSize == 1);
5540 
5541     // check output Chroma format
5542     if (VP9_ENCODED_CHROMA_FORMAT_YUV420 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat)
5543     {
5544         m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV420;
5545     }
5546     else if (VP9_ENCODED_CHROMA_FORMAT_YUV422 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat)
5547     {
5548         m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV422;
5549     }
5550     else if (VP9_ENCODED_CHROMA_FORMAT_YUV444 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat)
5551     {
5552         m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV444;
5553     }
5554     else
5555     {
5556         CODECHAL_ENCODE_ASSERTMESSAGE("Invalid output chromat format in VP9 Seq param!");
5557         return MOS_STATUS_INVALID_PARAMETER;
5558     }
5559 
5560     return eStatus;
5561 }
5562 
SetPictureStructs()5563 MOS_STATUS CodechalVdencVp9State::SetPictureStructs()
5564 {
5565     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5566 
5567     CODECHAL_ENCODE_FUNCTION_ENTER;
5568 
5569     //Enable only for TU1
5570     if (m_vp9SeqParams->TargetUsage != TU_QUALITY)
5571     {
5572         m_hmeEnabled = m_16xMeSupported = m_32xMeSupported = false;
5573         m_16xMeEnabled = false;
5574     }
5575 
5576     // setup internal parameters
5577     // dwOriFrameWidth and dwOriFrameHeight are encoded resolutions which might be different from source resoultions if dynamic scaling is enabled
5578     m_oriFrameWidth  = m_vp9PicParams->SrcFrameWidthMinus1 + 1;
5579     m_oriFrameHeight = m_vp9PicParams->SrcFrameHeightMinus1 + 1;
5580 
5581     if (m_oriFrameWidth == 0 || m_oriFrameWidth > m_maxPicWidth ||
5582         m_oriFrameHeight == 0 || m_oriFrameHeight > m_maxPicHeight)
5583     {
5584         return MOS_STATUS_INVALID_PARAMETER;
5585     }
5586 
5587     m_picWidthInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH);
5588     m_picHeightInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
5589     m_picSizeInSb = m_picWidthInSb * m_picHeightInSb;
5590 
5591     m_picWidthInMb  = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth);
5592     m_picHeightInMb = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight);
5593     m_frameWidth  = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH;
5594     m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT;
5595 
5596     // HME Scaling WxH
5597     m_downscaledWidthInMb4x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x);
5598     m_downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x);
5599     m_downscaledWidth4x = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
5600     m_downscaledHeight4x = m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT;
5601 
5602     // SuperHME Scaling WxH
5603     m_downscaledWidthInMb16x  = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_16x);
5604     m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x);
5605     m_downscaledWidth16x = m_downscaledWidthInMb16x * CODECHAL_MACROBLOCK_WIDTH;
5606     m_downscaledHeight16x = m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT;
5607 
5608     m_frameFieldHeight = m_frameHeight;
5609     m_frameFieldHeightInMb = m_picHeightInMb;
5610     m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x;
5611     m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x;
5612 
5613     MotionEstimationDisableCheck();
5614 
5615     if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling)
5616     {
5617             m_rawSurface.dwWidth  = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameWidthMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH);
5618             m_rawSurface.dwHeight = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_HEIGHT);
5619     }
5620 
5621     if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
5622         (!m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef || m_codecFunction != CODECHAL_FUNCTION_ENC))
5623     {
5624         return MOS_STATUS_INVALID_PARAMETER;
5625     }
5626 
5627     // Sync initialize
5628     m_waitForEnc = false;
5629     if ((m_firstFrame) ||
5630         (!m_brcEnabled && m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef) ||
5631         (!m_brcEnabled && (m_vp9PicParams->PicFlags.fields.frame_type == 0 || m_vp9PicParams->PicFlags.fields.intra_only)))
5632     {
5633         m_waitForPak = false;
5634     }
5635     else
5636     {
5637         m_waitForPak = true;
5638     }
5639 
5640     m_signalEnc = false;
5641 
5642     uint8_t currRefIdx = m_vp9PicParams->CurrReconstructedPic.FrameIdx;
5643 
5644     m_dysRefFrameFlags = DYS_REF_NONE;
5645     m_dysBrc = false;
5646     m_dysCqp = false;
5647 
5648     // m_refFrameFlags is to indicate which frames to be used as reference
5649     // m_refFrameFlags & 0x01 != 0: Last ref frames used as reference
5650     // m_refFrameFlags & 0x02 != 0: Golden ref frames used as reference
5651     // m_refFrameFlags & 0x04 != 0: Alternate ref frames used as reference
5652     m_refFrameFlags = 0;
5653     m_numRefFrames = 0;
5654     m_lastRefPic = 0;
5655     m_goldenRefPic = 0;
5656     m_altRefPic = 0;
5657 
5658     uint8_t index = 0;
5659     PCODEC_REF_LIST *refList = &m_refList[0];
5660     if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only)
5661     {
5662         m_refFrameFlags = m_vp9PicParams->RefFlags.fields.ref_frame_ctrl_l0 | m_vp9PicParams->RefFlags.fields.ref_frame_ctrl_l1;
5663 
5664         if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx]))
5665         {
5666             m_refFrameFlags &= ~0x1;
5667         }
5668         if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx]))
5669         {
5670             m_refFrameFlags &= ~0x2;
5671         }
5672         if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx]))
5673         {
5674             m_refFrameFlags &= ~0x4;
5675         }
5676 
5677         //consilidate the reference flag, becasue two reference frame may have the same index
5678         if ((m_refFrameFlags & 0x01) &&
5679             (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx))
5680         {
5681             m_refFrameFlags &= ~0x2;  //skip golden frame
5682         }
5683         if ((m_refFrameFlags & 0x01) &&
5684             (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx))
5685         {
5686             m_refFrameFlags &= ~0x4;  //skip alt frame
5687         }
5688         if ((m_refFrameFlags & 0x02) &&
5689             (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx))
5690         {
5691             m_refFrameFlags &= ~0x4;  //skip alt frame
5692         }
5693 
5694         if (m_refFrameFlags == 7 && !m_16xMeSupported)
5695         {
5696             // can support max 2 reference frames when SHME disabled, so ignore alt frame
5697             m_refFrameFlags &= ~0x4;
5698         }
5699 
5700         // MaxNum_Reference is 1 for TU7
5701         if (m_refFrameFlags != 1 && m_vp9SeqParams->TargetUsage == TU_PERFORMANCE)
5702         {
5703             m_refFrameFlags = 1;
5704         }
5705 
5706         if (m_refFrameFlags == 0)
5707         {
5708             CODECHAL_ENCODE_ASSERTMESSAGE("Ref list is empty!.");
5709             return MOS_STATUS_INVALID_PARAMETER;
5710         }
5711 
5712         if (m_refFrameFlags & 0x01)
5713         {
5714             index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx;
5715             refList[index]->sRefBuffer =
5716                 m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer;
5717 
5718             m_lastRefPic = &refList[index]->sRefBuffer;
5719             CodecHalGetResourceInfo(m_osInterface, m_lastRefPic);
5720             m_lastRefPic->dwWidth = refList[index]->dwFrameWidth;
5721             m_lastRefPic->dwHeight = refList[index]->dwFrameHeight;
5722             m_numRefFrames++;
5723 
5724             if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling &&
5725                 (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight))
5726             {
5727                 m_dysRefFrameFlags |= DYS_REF_LAST;
5728             }
5729         }
5730 
5731         if (m_refFrameFlags & 0x02)
5732         {
5733             index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx;
5734             refList[index]->sRefBuffer =
5735                 m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer;
5736 
5737             m_goldenRefPic = &refList[index]->sRefBuffer;
5738             CodecHalGetResourceInfo(m_osInterface, m_goldenRefPic);
5739             m_goldenRefPic->dwWidth = refList[index]->dwFrameWidth;
5740             m_goldenRefPic->dwHeight = refList[index]->dwFrameHeight;
5741             m_numRefFrames++;
5742 
5743             if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling &&
5744                 (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight))
5745             {
5746                 m_dysRefFrameFlags |= DYS_REF_GOLDEN;
5747             }
5748         }
5749 
5750         if (m_refFrameFlags & 0x04)
5751         {
5752             index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx;
5753             refList[index]->sRefBuffer =
5754                 m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer;
5755 
5756             m_altRefPic = &refList[index]->sRefBuffer;
5757             CodecHalGetResourceInfo(m_osInterface, m_altRefPic);
5758             m_altRefPic->dwWidth = refList[index]->dwFrameWidth;
5759             m_altRefPic->dwHeight = refList[index]->dwFrameHeight;
5760             m_numRefFrames++;
5761 
5762             if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling &&
5763                 (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight))
5764             {
5765                 m_dysRefFrameFlags |= DYS_REF_ALT;
5766             }
5767         }
5768     }
5769     m_dysCurrFrameFlag = m_dysRefFrameFlags;
5770 
5771     refList[currRefIdx]->sRefReconBuffer = m_reconSurface;
5772     refList[currRefIdx]->sRefRawBuffer = m_rawSurface;
5773     refList[currRefIdx]->RefPic             = m_vp9PicParams->CurrOriginalPic;
5774     refList[currRefIdx]->bUsedAsRef = true;
5775     refList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer;
5776     refList[currRefIdx]->dwFrameWidth = m_oriFrameWidth;
5777     refList[currRefIdx]->dwFrameHeight = m_oriFrameHeight;
5778 
5779     m_currOriginalPic            = m_vp9PicParams->CurrOriginalPic;
5780     m_currReconstructedPic       = m_vp9PicParams->CurrReconstructedPic;
5781     m_statusReportFeedbackNumber = m_vp9PicParams->StatusReportFeedbackNumber;
5782     m_pictureCodingType          = m_vp9PicParams->PicFlags.fields.frame_type == 0 ? I_TYPE : P_TYPE;
5783 
5784     PCODEC_PIC_ID picIdx = &m_picIdx[0];
5785     for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++)
5786     {
5787         picIdx[i].bValid = false;
5788     }
5789     if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only)
5790     {
5791         for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++)
5792         {
5793             if (m_vp9PicParams->RefFrameList[i].PicFlags != PICTURE_INVALID)
5794             {
5795                 index              = m_vp9PicParams->RefFrameList[i].FrameIdx;
5796                 bool duplicatedIdx = false;
5797                 for (auto ii = 0; ii < i; ii++)
5798                 {
5799                     if (picIdx[ii].bValid && index == m_vp9PicParams->RefFrameList[ii].FrameIdx)
5800                     {
5801                         // we find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same.
5802                         duplicatedIdx = true;
5803                         break;
5804                     }
5805                 }
5806                 if (duplicatedIdx)
5807                 {
5808                     continue;
5809                 }
5810 
5811                 // this reference frame in unique. Save it into the full reference list with 127 items
5812                 refList[index]->RefPic.PicFlags =
5813                     CodecHal_CombinePictureFlags(refList[index]->RefPic, m_vp9PicParams->RefFrameList[i]);
5814 
5815                 picIdx[i].bValid = true;
5816                 picIdx[i].ucPicIdx = index;
5817             }
5818         }
5819     }
5820 
5821     // Save the current RefList
5822     uint8_t ii = 0;
5823     for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++)
5824     {
5825         if (picIdx[i].bValid)
5826         {
5827             refList[currRefIdx]->RefList[ii] = m_vp9PicParams->RefFrameList[i];
5828             ii++;
5829         }
5830     }
5831     refList[currRefIdx]->ucNumRef = ii;
5832     m_currRefList             = refList[currRefIdx];
5833 
5834     // the actual MbCode/MvData surface to be allocated later
5835     m_trackedBuf->SetAllocationFlag(true);
5836 
5837     m_vdencPakonlyMultipassEnabled = false;
5838     m_vdencPakObjCmdStreamOutEnabled = false;
5839 
5840     // In case there is overflow
5841     if ((m_vp9PicParams->LumaACQIndex + m_vp9PicParams->LumaDCQIndexDelta) < 0)
5842     {
5843         m_vp9PicParams->LumaACQIndex = MOS_ABS(m_vp9PicParams->LumaDCQIndexDelta) + 1;
5844     }
5845     refList[currRefIdx]->ucQPValue[0] = m_vp9PicParams->LumaACQIndex + m_vp9PicParams->LumaDCQIndexDelta;
5846 
5847     m_txMode = CODEC_VP9_TX_SELECTABLE;
5848 
5849     // For VDEnc disable HME if HME hasn't been disabled by reg key AND TU != TU1
5850     m_hmeSupported   = m_hmeSupported && (m_vp9SeqParams->TargetUsage == TU_QUALITY);
5851     m_16xMeSupported = m_16xMeSupported && m_hmeSupported;
5852 
5853     // Enable HME/SHME for frame
5854     m_hmeEnabled   = m_hmeSupported && m_pictureCodingType != I_TYPE && !m_vp9PicParams->PicFlags.fields.intra_only;
5855     m_16xMeEnabled = m_16xMeSupported && m_hmeEnabled;
5856 
5857     if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled )
5858     {
5859         if (!m_hucEnabled)
5860         {
5861             m_numPasses = m_dysRefFrameFlags != DYS_REF_NONE;
5862         }
5863         if (m_vdencBrcEnabled)
5864         {
5865             m_dysBrc = true;
5866             //Reduce the total passes by 1, as m_currPass == 1 becomes m_currPass = 0 for Huc to run
5867             m_numPasses = (m_numPasses > 0 ) ? m_numPasses - 1 : m_numPasses;
5868         }
5869         else
5870         {
5871             m_dysCqp = true;
5872         }
5873     }
5874 
5875     // We cannot use refresh_frame_context if HuC isn't enabled to update probs
5876     if (m_vp9PicParams->PicFlags.fields.refresh_frame_context && !m_hucEnabled)
5877     {
5878         CODECHAL_ENCODE_ASSERTMESSAGE("Refresh_frame_context cannot be enabled while HuC is disabled.  HuC is needed for refresh_frame_context to be enabled.");
5879         return MOS_STATUS_INVALID_PARAMETER;
5880     }
5881 
5882     return eStatus;
5883 }
5884 
SetRowstoreCachingOffsets()5885 MOS_STATUS CodechalVdencVp9State::SetRowstoreCachingOffsets()
5886 {
5887     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5888     if (m_vdencEnabled &&
5889         m_hwInterface->GetHcpInterface()->IsRowStoreCachingSupported())
5890     {
5891         MHW_VDBOX_ROWSTORE_PARAMS rowStoreParams;
5892         rowStoreParams.Mode             = m_mode;
5893         rowStoreParams.dwPicWidth       = m_frameWidth;
5894         rowStoreParams.ucChromaFormat   = m_chromaFormat;
5895         rowStoreParams.ucBitDepthMinus8 = m_bitDepth * 2;  // 0(8bit) -> 0, 1(10bit)->2, 2(12bit)->4
5896         m_hwInterface->SetRowstoreCachingOffsets(&rowStoreParams);
5897     }
5898     return eStatus;
5899 }
5900 
InitializePicture(const EncoderParams & params)5901 MOS_STATUS CodechalVdencVp9State::InitializePicture(const EncoderParams& params)
5902 {
5903     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
5904 
5905     CODECHAL_ENCODE_FUNCTION_ENTER;
5906 
5907     m_vp9SeqParams  = (PCODEC_VP9_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams);
5908     m_vp9PicParams  = (PCODEC_VP9_ENCODE_PIC_PARAMS)(params.pPicParams);
5909     m_nalUnitParams = params.ppNALUnitParams;
5910     m_numNalUnit    = params.uiNumNalUnits;
5911 
5912     CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9SeqParams);
5913     CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9PicParams);
5914     CODECHAL_ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
5915 
5916     m_segmentMapProvided = params.bSegmentMapProvided && m_vp9PicParams->PicFlags.fields.segmentation_enabled;
5917     // In MBBRC case, without a SegMap provided by the app, we need to set the SegMapUpdate ON
5918     // as the Segmap is generated by HuC and it can be different for every frame
5919     if (m_vp9PicParams->PicFlags.fields.segmentation_enabled && !params.bSegmentMapProvided)
5920     {
5921         m_vp9PicParams->PicFlags.fields.segmentation_update_map = 1;
5922     }
5923 
5924     // For dynamic scaling, the SingleTaskPhaseSupported is set to true and it does not get restored
5925     // to the original value after encoding of the frame. So need to restore to the original state
5926     m_singleTaskPhaseSupported = m_storeSingleTaskPhaseSupported;
5927 
5928     m_mbBrcEnabled = false;
5929     m_vp9SeqParams->SeqFlags.fields.MBBRC = MBBRC_DISABLED;
5930 
5931     // Filter level is decided by driver in VDEnc, app value is ignored
5932     // Uncomment when PSNR thresholds are set properly
5933     //pVp9PicParams->filter_level = CODECHAL_ENCODE_VP9_LF_VALUE_QP_LOOKUP[pVp9PicParams->LumaACQIndex];
5934 
5935     // We do not support segmentation w/o seg map in CQP case, only support segmentation w/ seg map in CQP
5936     // BRC/ACQP supports segmentation both w/ and w/o seg map
5937     if (m_vp9PicParams->PicFlags.fields.segmentation_enabled && !params.bSegmentMapProvided &&
5938         m_vp9SeqParams->RateControlMethod == RATECONTROL_CQP)
5939     {
5940         return MOS_STATUS_INVALID_PARAMETER;
5941     }
5942 
5943     // Need to index properly when more than one temporal layer is present.
5944     CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[0].uiDenominator > 0);
5945 
5946     CODECHAL_ENCODE_CHK_COND_RETURN(m_vp9SeqParams->FrameRate[0].uiDenominator == 0, "uiDenominator cannot be zero.");
5947     uint32_t frameRate = m_vp9SeqParams->FrameRate[0].uiNumerator / m_vp9SeqParams->FrameRate[0].uiDenominator;
5948     m_vp9SegmentParams = (PCODEC_VP9_ENCODE_SEGMENT_PARAMS)(params.pSegmentParams);
5949 
5950     CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9SegmentParams);
5951 
5952     CODECHAL_ENCODE_CHK_STATUS_RETURN(PlatformCapabilityCheck());
5953 
5954     if (m_newSeq)
5955     {
5956         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
5957     }
5958 
5959     //when MBBRC is enabled App will not pass segment map.
5960     if (!m_mbBrcEnabled)
5961     {
5962         m_mbStatsEnabled = false;
5963         if (m_segmentMapProvided)
5964         {
5965             m_mbSegmentMapSurface = *(params.psMbSegmentMapSurface);
5966             CodecHalGetResourceInfo(m_osInterface, &(m_mbSegmentMapSurface));
5967         }
5968     }
5969     else
5970     {
5971         //Kernel C model fixed Qindex delta's when MBBRC is enabled
5972         int16_t segmentQIndexDelta[CODEC_VP9_MAX_SEGMENTS] = { 0, -8, -6, -4, -2, 2, 4, 6 };
5973 
5974         for (uint8_t i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++)
5975         {
5976             m_vp9SegmentParams->SegData[i].SegmentFlags.value  = 0;
5977             m_vp9SegmentParams->SegData[i].SegmentLFLevelDelta = 0;
5978             m_vp9SegmentParams->SegData[i].SegmentQIndexDelta  = segmentQIndexDelta[i];
5979         }
5980         m_mbStatsEnabled = true;
5981     }
5982 
5983     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
5984 
5985     CODECHAL_ENCODE_CHK_STATUS_RETURN(SetRowstoreCachingOffsets());
5986 
5987     m_pictureStatesSize = m_defaultPictureStatesSize;
5988     m_picturePatchListSize = m_defaultPicturePatchListSize;
5989 
5990     m_hucCommandsSize = m_defaultHucCmdsSize;
5991 
5992     // Scaling occurs when HME is enabled
5993     m_scalingEnabled = m_hmeSupported;
5994     m_useRawForRef   = m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef;
5995 
5996     if (m_currReconstructedPic.FrameIdx >= m_numUncompressedSurface)
5997     {
5998         return MOS_STATUS_INVALID_PARAMETER;
5999     }
6000         CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(m_refList[m_currReconstructedPic.FrameIdx]));
6001 
6002     CODECHAL_DEBUG_TOOL(
6003         m_debugInterface->m_currPic            = m_vp9PicParams->CurrOriginalPic;
6004         m_debugInterface->m_bufferDumpFrameNum = m_storeData;
6005         m_debugInterface->m_frameType          = m_pictureCodingType;
6006 
6007         if (m_newSeq) {
6008             CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
6009                 m_vp9SeqParams));
6010         }
6011 
6012         CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
6013             m_vp9PicParams));
6014 
6015         CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSegmentParams(
6016             m_vp9SegmentParams));)
6017 
6018     CODECHAL_DEBUG_TOOL(
6019         m_resVdencStatsBuffer = &(m_resVdencBrcStatsBuffer);)
6020 
6021     m_bitstreamUpperBound = params.dwBitstreamSize;
6022 
6023     return eStatus;
6024 }
6025 
AllocateResourcesBrc()6026 MOS_STATUS CodechalVdencVp9State::AllocateResourcesBrc()
6027 {
6028     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
6029 
6030     CODECHAL_ENCODE_FUNCTION_ENTER;
6031 
6032     // initiate allocation paramters and lock flags
6033     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
6034     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
6035     allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
6036     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
6037     allocParamsForBufferLinear.Format = Format_Buffer;
6038 
6039     MOS_LOCK_PARAMS lockFlagsWriteOnly;
6040     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
6041     lockFlagsWriteOnly.WriteOnly = 1;
6042 
6043     // BRC history buffer
6044     uint32_t size = m_brcHistoryBufferSize;
6045     allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(size, CODECHAL_PAGE_SIZE) : size;
6046     allocParamsForBufferLinear.pBufName = "BRC History Buffer";
6047 
6048     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6049         m_osInterface,
6050         &allocParamsForBufferLinear,
6051         &m_brcBuffers.resBrcHistoryBuffer));
6052 
6053     // BRC Constant Data Buffer
6054     allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(m_brcConstantSurfaceSize, CODECHAL_PAGE_SIZE) : CODECHAL_ENCODE_VP9_BRC_CONSTANTSURFACE_SIZE;
6055     allocParamsForBufferLinear.pBufName = "BRC Constant Data Buffer";
6056     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6057         m_osInterface,
6058         &allocParamsForBufferLinear,
6059         &m_brcBuffers.resBrcConstantDataBuffer[0]));
6060     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6061         m_osInterface,
6062         &allocParamsForBufferLinear,
6063         &m_brcBuffers.resBrcConstantDataBuffer[1]));
6064 
6065     // PicState Brc read buffer
6066     size = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * m_brcMaxNumPasses;
6067     allocParamsForBufferLinear.dwBytes = size;
6068     allocParamsForBufferLinear.pBufName = "BRC Pic State Read Buffer";
6069 
6070     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6071         m_osInterface,
6072         &allocParamsForBufferLinear,
6073         &m_brcBuffers.resPicStateBrcReadBuffer));
6074 
6075     uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
6076         m_osInterface,
6077         &m_brcBuffers.resPicStateBrcReadBuffer,
6078         &lockFlagsWriteOnly);
6079 
6080     if (data == nullptr)
6081     {
6082         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC Pic State Read Buffer.");
6083         return MOS_STATUS_UNKNOWN;
6084     }
6085 
6086     MOS_ZeroMemory(data, size);
6087     m_osInterface->pfnUnlockResource(
6088         m_osInterface,
6089         &m_brcBuffers.resPicStateBrcReadBuffer);
6090 
6091     // PicState Brc Write and Huc Read buffer
6092     allocParamsForBufferLinear.dwBytes = size;
6093     allocParamsForBufferLinear.pBufName = "BRC Pic State Write Buffer";
6094 
6095     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6096         m_osInterface,
6097         &allocParamsForBufferLinear,
6098         &m_brcBuffers.resPicStateBrcWriteHucReadBuffer));
6099 
6100     data = (uint8_t*)m_osInterface->pfnLockResource(
6101         m_osInterface,
6102         &m_brcBuffers.resPicStateBrcWriteHucReadBuffer,
6103         &lockFlagsWriteOnly);
6104 
6105     if (data == nullptr)
6106     {
6107         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC Pic State Write Buffer.");
6108         return MOS_STATUS_UNKNOWN;
6109     }
6110 
6111     MOS_ZeroMemory(data, size);
6112     m_osInterface->pfnUnlockResource(
6113         m_osInterface,
6114         &m_brcBuffers.resPicStateBrcWriteHucReadBuffer);
6115 
6116     // PicState HuC Write buffer
6117     allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * m_brcMaxNumPasses;
6118     allocParamsForBufferLinear.pBufName = "BRC Huc Pic State Write Buffer";
6119 
6120     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6121         m_osInterface,
6122         &allocParamsForBufferLinear,
6123         &m_brcBuffers.resPicStateHucWriteBuffer));
6124 
6125     // SegmentState Brc Read buffer
6126     allocParamsForBufferLinear.dwBytes  = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE;
6127     allocParamsForBufferLinear.pBufName = "BRC Segment State Read Buffer";
6128 
6129     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6130         m_osInterface,
6131         &allocParamsForBufferLinear,
6132         &m_brcBuffers.resSegmentStateBrcReadBuffer));
6133 
6134     // SegmentState Brc Write buffer
6135     allocParamsForBufferLinear.dwBytes  = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE;
6136     allocParamsForBufferLinear.pBufName = "BRC Segment State Write Buffer";
6137 
6138     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6139         m_osInterface,
6140         &allocParamsForBufferLinear,
6141         &m_brcBuffers.resSegmentStateBrcWriteBuffer));
6142 
6143     // BRC Bitstream Size Data buffer
6144     allocParamsForBufferLinear.dwBytes = m_vdencEnabled ?
6145         MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE, CODECHAL_PAGE_SIZE) :
6146         CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE;
6147     allocParamsForBufferLinear.pBufName = "BRC Bitstream Size Data buffer";
6148 
6149     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6150         m_osInterface,
6151         &allocParamsForBufferLinear,
6152         &m_brcBuffers.resBrcBitstreamSizeBuffer));
6153 
6154     // BRC HuC Data Buffer
6155     allocParamsForBufferLinear.dwBytes = m_vdencEnabled ?
6156         MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE, CODECHAL_PAGE_SIZE) :
6157         CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE;
6158     allocParamsForBufferLinear.pBufName = "BRC HuC Data Buffer";
6159 
6160     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6161         m_osInterface,
6162         &allocParamsForBufferLinear,
6163         &m_brcBuffers.resBrcHucDataBuffer));
6164 
6165     allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_BRC_MSDK_PAK_BUFFER_SIZE;
6166     allocParamsForBufferLinear.pBufName = "BRC MSDK Buffer";
6167 
6168     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6169         m_osInterface,
6170         &allocParamsForBufferLinear,
6171         &m_brcBuffers.resBrcMsdkPakBuffer));
6172 
6173     return eStatus;
6174 }
6175 
ReleaseResourcesBrc()6176 void CodechalVdencVp9State::ReleaseResourcesBrc()
6177 {
6178     CODECHAL_ENCODE_FUNCTION_ENTER;
6179 
6180     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHistoryBuffer))
6181     {
6182         m_osInterface->pfnFreeResource(
6183             m_osInterface,
6184             &m_brcBuffers.resBrcHistoryBuffer);
6185     }
6186 
6187     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcConstantDataBuffer[0]))
6188     {
6189         m_osInterface->pfnFreeResource(
6190             m_osInterface,
6191             &m_brcBuffers.resBrcConstantDataBuffer[0]);
6192     }
6193 
6194     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcConstantDataBuffer[1]))
6195     {
6196         m_osInterface->pfnFreeResource(
6197             m_osInterface,
6198             &m_brcBuffers.resBrcConstantDataBuffer[1]);
6199     }
6200 
6201     if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateBrcReadBuffer))
6202     {
6203         m_osInterface->pfnFreeResource(
6204             m_osInterface,
6205             &m_brcBuffers.resPicStateBrcReadBuffer);
6206     }
6207 
6208     if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateBrcWriteHucReadBuffer))
6209     {
6210         m_osInterface->pfnFreeResource(
6211             m_osInterface,
6212             &m_brcBuffers.resPicStateBrcWriteHucReadBuffer);
6213     }
6214 
6215     if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateHucWriteBuffer))
6216     {
6217         m_osInterface->pfnFreeResource(
6218             m_osInterface,
6219             &m_brcBuffers.resPicStateHucWriteBuffer);
6220     }
6221 
6222     if (!Mos_ResourceIsNull(&m_brcBuffers.resSegmentStateBrcReadBuffer))
6223     {
6224         m_osInterface->pfnFreeResource(
6225             m_osInterface,
6226             &m_brcBuffers.resSegmentStateBrcReadBuffer);
6227     }
6228 
6229     if (!Mos_ResourceIsNull(&m_brcBuffers.resSegmentStateBrcWriteBuffer))
6230     {
6231         m_osInterface->pfnFreeResource(
6232             m_osInterface,
6233             &m_brcBuffers.resSegmentStateBrcWriteBuffer);
6234     }
6235 
6236     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcBitstreamSizeBuffer))
6237     {
6238         m_osInterface->pfnFreeResource(
6239             m_osInterface,
6240             &m_brcBuffers.resBrcBitstreamSizeBuffer);
6241     }
6242 
6243     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHucDataBuffer))
6244     {
6245         m_osInterface->pfnFreeResource(
6246             m_osInterface,
6247             &m_brcBuffers.resBrcHucDataBuffer);
6248     }
6249 
6250     if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcMsdkPakBuffer))
6251     {
6252         m_osInterface->pfnFreeResource(
6253             m_osInterface,
6254             &m_brcBuffers.resBrcMsdkPakBuffer);
6255     }
6256 
6257     return;
6258 }
6259 
AllocateResources()6260 MOS_STATUS CodechalVdencVp9State::AllocateResources()
6261 {
6262     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
6263 
6264     CODECHAL_ENCODE_FUNCTION_ENTER;
6265 
6266     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources());
6267 
6268     // Application needs to pass the maxinum frame width/height
6269     m_maxPicWidth = m_frameWidth;
6270     m_maxPicHeight = m_frameHeight;
6271 
6272     uint32_t maxPicWidthInSb = MOS_ROUNDUP_DIVIDE(m_maxPicWidth, CODEC_VP9_SUPER_BLOCK_WIDTH);
6273     uint32_t maxPicHeightInSb = MOS_ROUNDUP_DIVIDE(m_maxPicHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT);
6274     uint32_t maxPicSizeInSb = maxPicWidthInSb * maxPicHeightInSb;
6275     uint32_t maxNumCuRecords = maxPicSizeInSb * 64;
6276 
6277     // initiate allocation paramters and lock flags
6278     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
6279     MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
6280     allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
6281     allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
6282     allocParamsForBufferLinear.Format = Format_Buffer;
6283 
6284     MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D;
6285     MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS));
6286     allocParamsForBuffer2D.Type = MOS_GFXRES_2D;
6287     allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR;
6288     allocParamsForBuffer2D.Format = Format_Buffer_2D;
6289 
6290     MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12;
6291     MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS));
6292     allocParamsForBufferNV12.Type     = MOS_GFXRES_2D;
6293     allocParamsForBufferNV12.TileType = MOS_TILE_Y;
6294     allocParamsForBufferNV12.Format   = Format_NV12;
6295 
6296     MOS_LOCK_PARAMS lockFlagsWriteOnly;
6297     MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
6298     lockFlagsWriteOnly.WriteOnly = 1;
6299 
6300     // Allocate Ref Lists
6301     CodecHalAllocateDataList(
6302         m_refList,
6303         m_numUncompressedSurface);
6304 
6305     if (m_pakEnabled)
6306     {
6307         // m_mvoffset looks not correct here, and corresponding setting of buffer offset in HCP_IND_OBJ, need to check with HW team.
6308         // keep current logic unchanged but increase the buffer size for now in case regression before we know how to correctly program these.
6309         m_mvOffset = MOS_ALIGN_CEIL((maxPicSizeInSb * 4 * sizeof(uint32_t)), CODECHAL_PAGE_SIZE); // 3 uint32_t for HCP_PAK_OBJECT and 1 uint32_t for padding zero in kernel
6310 
6311         // we need additional buffer for (1) 1 CL for size info at the beginning of each tile column (max of 4 vdbox in scalability mode)
6312         // (2) CL alignment at end of every tile column for every SB of width
6313         // as a result, increase the height by 1 for allocation purposes
6314         uint32_t numOfLCU = maxPicSizeInSb + maxPicWidthInSb;
6315 
6316         //the following code used to calculate ulMBCodeSize:
6317         //pakObjCmdStreamOutDataSize = 2*BYTES_PER_DWORD*(numOfLcu*NUM_PAK_DWS_PER_LCU + numOfLcu*maxNumOfCUperLCU*NUM_DWS_PER_CU); // Multiply by 2 for sideband
6318         //const uint32_t maxNumOfCUperLCU = (64/8)*(64/8);
6319         // NUM_PAK_DWS_PER_LCU 5
6320         // NUM_DWS_PER_CU 8
6321         m_mbCodeSize = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * numOfLCU * (5 + 64 * 8), CODECHAL_PAGE_SIZE);
6322 
6323         uint32_t formatMultiFactor = (m_chromaFormat == VP9_ENCODED_CHROMA_FORMAT_YUV444) ? 3 : 2;
6324         formatMultiFactor *= (m_bitDepth == VP9_ENCODED_BIT_DEPTH_8) ? 1 : 2;
6325         uint32_t size = (18 * formatMultiFactor) / 2;
6326         // Deblocking filter line buffer
6327         size = maxPicWidthInSb * size * CODECHAL_CACHELINE_SIZE;
6328         allocParamsForBufferLinear.dwBytes = size;
6329         allocParamsForBufferLinear.pBufName = "DeblockingFilterLineBuffer";
6330 
6331         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6332             m_osInterface,
6333             &allocParamsForBufferLinear,
6334             &m_resDeblockingFilterLineBuffer));
6335 
6336         // Deblocking filter tile line buffer
6337         allocParamsForBufferLinear.dwBytes = size;
6338         allocParamsForBufferLinear.pBufName = "DeblockingFilterTileLineBuffer";
6339 
6340         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6341             m_osInterface,
6342             &allocParamsForBufferLinear,
6343             &m_resDeblockingFilterTileLineBuffer));
6344 
6345         formatMultiFactor = m_chromaFormat == VP9_ENCODED_CHROMA_FORMAT_YUV444 ? 25 : 17;
6346         size = formatMultiFactor * ((m_bitDepth == VP9_ENCODED_BIT_DEPTH_8) ? 1 : 2);
6347         // Deblocking filter tile column buffer
6348         size = maxPicHeightInSb * size * CODECHAL_CACHELINE_SIZE;
6349         allocParamsForBufferLinear.dwBytes = size;
6350         allocParamsForBufferLinear.pBufName = "DeblockingFilterTileColumnBuffer";
6351 
6352         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6353             m_osInterface,
6354             &allocParamsForBufferLinear,
6355             &m_resDeblockingFilterTileColumnBuffer));
6356 
6357         // Metadata Line buffer
6358         size = maxPicWidthInSb * 5 * CODECHAL_CACHELINE_SIZE;
6359         allocParamsForBufferLinear.dwBytes = size;
6360         allocParamsForBufferLinear.pBufName = "MetadataLineBuffer";
6361 
6362         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6363             m_osInterface,
6364             &allocParamsForBufferLinear,
6365             &m_resMetadataLineBuffer));
6366 
6367         // Metadata Tile Line buffer
6368         size = maxPicWidthInSb * 5 * CODECHAL_CACHELINE_SIZE;
6369         allocParamsForBufferLinear.dwBytes = size;
6370         allocParamsForBufferLinear.pBufName = "MetadataTileLineBuffer";
6371 
6372         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6373             m_osInterface,
6374             &allocParamsForBufferLinear,
6375             &m_resMetadataTileLineBuffer));
6376 
6377         // Metadata Tile Column buffer
6378         size = maxPicHeightInSb * 5 * CODECHAL_CACHELINE_SIZE;
6379         allocParamsForBufferLinear.dwBytes = size;
6380         allocParamsForBufferLinear.pBufName = "MetadataTileColumnBuffer";
6381 
6382         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6383             m_osInterface,
6384             &allocParamsForBufferLinear,
6385             &m_resMetadataTileColumnBuffer));
6386 
6387         // Current MV temporal buffer
6388         size = maxPicSizeInSb * 9 * CODECHAL_CACHELINE_SIZE;
6389         CODECHAL_ENCODE_CHK_NULL_RETURN(m_allocator->AllocateResource(m_standard, size, 1, mvTemporalBuffer, "mvTemporalBuffer", 0));
6390         CODECHAL_ENCODE_CHK_NULL_RETURN(m_allocator->AllocateResource(m_standard, size, 1, mvTemporalBuffer, "mvTemporalBuffer", 1));
6391 
6392         // Probability buffer
6393         size = 32 * CODECHAL_CACHELINE_SIZE;
6394         allocParamsForBufferLinear.dwBytes = size;
6395         allocParamsForBufferLinear.pBufName = "ProbabilityBuffer";
6396 
6397         for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
6398         {
6399             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6400                 m_osInterface,
6401                 &allocParamsForBufferLinear,
6402                 &m_resProbBuffer[i]));
6403         }
6404 
6405         // Segment ID buffer
6406         size = maxPicSizeInSb * CODECHAL_CACHELINE_SIZE;
6407         allocParamsForBufferLinear.dwBytes = size;
6408         allocParamsForBufferLinear.pBufName = "SegmentIdBuffer";
6409 
6410         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6411             m_osInterface,
6412             &allocParamsForBufferLinear,
6413             &m_resSegmentIdBuffer));
6414 
6415         uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
6416             m_osInterface,
6417             &m_resSegmentIdBuffer,
6418             &lockFlagsWriteOnly);
6419         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
6420 
6421         MOS_ZeroMemory(data, size);
6422         m_osInterface->pfnUnlockResource(m_osInterface, &m_resSegmentIdBuffer);
6423 
6424         // Probability delta buffer
6425         size = 29 * CODECHAL_CACHELINE_SIZE;
6426         allocParamsForBufferLinear.dwBytes = size;
6427         allocParamsForBufferLinear.pBufName = "ProbabilityDeltaBuffer";
6428 
6429         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6430             m_osInterface,
6431             &allocParamsForBufferLinear,
6432             &m_resProbabilityDeltaBuffer));
6433 
6434         // Compressed header buffer
6435         size = 32 * CODECHAL_CACHELINE_SIZE;
6436         allocParamsForBufferLinear.dwBytes = size;
6437         allocParamsForBufferLinear.pBufName = "CompressedHeaderBuffer";
6438 
6439         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6440             m_osInterface,
6441             &allocParamsForBufferLinear,
6442             &m_resCompressedHeaderBuffer));
6443 
6444         // Probability counter buffer
6445         allocParamsForBufferLinear.dwBytes = m_probabilityCounterBufferSize * m_maxTileNumber;
6446         allocParamsForBufferLinear.pBufName = "ProbabilityCounterBuffer";
6447 
6448         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6449             m_osInterface,
6450             &allocParamsForBufferLinear,
6451             &m_resProbabilityCounterBuffer));
6452 
6453         // Tile record stream out buffer
6454         size = maxPicSizeInSb * CODECHAL_CACHELINE_SIZE; // worst case: each SB is a tile
6455         allocParamsForBufferLinear.dwBytes = size;
6456         allocParamsForBufferLinear.pBufName = "TileRecordStrmOutBuffer";
6457 
6458         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6459             m_osInterface,
6460             &allocParamsForBufferLinear,
6461             &m_resTileRecordStrmOutBuffer));
6462 
6463         // CU statistics stream out buffer
6464         size = MOS_ALIGN_CEIL(maxPicSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE);
6465         allocParamsForBufferLinear.dwBytes = size;
6466         allocParamsForBufferLinear.pBufName = "CuStatsStrmOutBuffer";
6467 
6468         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6469             m_osInterface,
6470             &allocParamsForBufferLinear,
6471             &m_resCuStatsStrmOutBuffer));
6472 
6473         // HUC Prob DMEM buffer
6474         allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(MOS_MAX(sizeof(HucProbDmem), sizeof(HucProbDmem)), CODECHAL_CACHELINE_SIZE);
6475         allocParamsForBufferLinear.pBufName = "HucProbDmemBuffer";
6476         for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j)
6477         {
6478             for (auto i = 0; i < 3; i++)
6479             {
6480                 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6481                                                       m_osInterface,
6482                                                       &allocParamsForBufferLinear,
6483                                                       &m_resHucProbDmemBuffer[i][j]));
6484             }
6485         }
6486         // Huc default prob buffer
6487         allocParamsForBufferLinear.dwBytes = sizeof(Keyframe_Default_Probs)+sizeof(Inter_Default_Probs);
6488         allocParamsForBufferLinear.pBufName = "HucDefaultProbBuffer";
6489 
6490         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6491             m_osInterface,
6492             &allocParamsForBufferLinear,
6493             &m_resHucDefaultProbBuffer));
6494 
6495         data = (uint8_t *)m_osInterface->pfnLockResource(
6496             m_osInterface,
6497             &m_resHucDefaultProbBuffer,
6498             &lockFlagsWriteOnly);
6499         CODECHAL_ENCODE_CHK_NULL_RETURN(data);
6500 
6501         MOS_SecureMemcpy(data, sizeof(Keyframe_Default_Probs),
6502             Keyframe_Default_Probs, sizeof(Keyframe_Default_Probs));
6503         MOS_SecureMemcpy(data + sizeof(Keyframe_Default_Probs), sizeof(Inter_Default_Probs),
6504             Inter_Default_Probs, sizeof(Inter_Default_Probs));
6505 
6506         m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucDefaultProbBuffer);
6507 
6508         // Huc probability output buffer
6509         allocParamsForBufferLinear.dwBytes = 32 * CODECHAL_CACHELINE_SIZE;
6510         allocParamsForBufferLinear.pBufName = "HucProbabilityOutputBuffer";
6511 
6512         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6513             m_osInterface,
6514             &allocParamsForBufferLinear,
6515             &m_resHucProbOutputBuffer));
6516 
6517         // Huc VP9 pak insert uncompressed header
6518         allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER;
6519         allocParamsForBufferLinear.pBufName = "HucPakInsertUncompressedHeaderReadBuffer";
6520 
6521         for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
6522         {
6523             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6524                                                   m_osInterface,
6525                                                   &allocParamsForBufferLinear,
6526                                                   &m_resHucPakInsertUncompressedHeaderReadBuffer[i]));
6527         }
6528         allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER;
6529         allocParamsForBufferLinear.pBufName = "HucPakInsertUncompressedHeaderWriteBuffer";
6530 
6531         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6532             m_osInterface,
6533             &allocParamsForBufferLinear,
6534             &m_resHucPakInsertUncompressedHeaderWriteBuffer));
6535 
6536         // Huc VP9 pak mmio buffer
6537         allocParamsForBufferLinear.dwBytes = 4 * sizeof(uint32_t);
6538         allocParamsForBufferLinear.pBufName = "HucPakMmioBuffer";
6539 
6540         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6541             m_osInterface,
6542             &allocParamsForBufferLinear,
6543             &m_resHucPakMmioBuffer));
6544 
6545         // Huc debug output buffer
6546         allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(1024 * sizeof(uint32_t), CODECHAL_PAGE_SIZE);
6547         allocParamsForBufferLinear.pBufName = "HucDebugOutputBuffer";
6548 
6549         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6550             m_osInterface,
6551             &allocParamsForBufferLinear,
6552             &m_resHucDebugOutputBuffer));
6553     }
6554 
6555     if (m_encEnabled)
6556     {
6557         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesBrc());
6558 
6559         if (m_hmeSupported)
6560         {
6561             MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(MOS_SURFACE));
6562             m_4xMeMvDataBuffer.TileType = MOS_TILE_LINEAR;
6563             m_4xMeMvDataBuffer.bArraySpacing = true;
6564             m_4xMeMvDataBuffer.Format = Format_Buffer_2D;
6565             m_4xMeMvDataBuffer.dwWidth = m_downscaledWidthInMb4x * 32;
6566             m_4xMeMvDataBuffer.dwHeight = m_downscaledHeightInMb4x * 4 * 10;
6567             m_4xMeMvDataBuffer.dwPitch = MOS_ALIGN_CEIL(m_4xMeMvDataBuffer.dwWidth, 128);
6568 
6569             allocParamsForBuffer2D.dwWidth = m_4xMeMvDataBuffer.dwWidth;
6570             allocParamsForBuffer2D.dwHeight = m_4xMeMvDataBuffer.dwHeight;
6571             allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer";
6572             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6573                 m_osInterface,
6574                 &allocParamsForBuffer2D,
6575                 &m_4xMeMvDataBuffer.OsResource));
6576 
6577             MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(MOS_SURFACE));
6578             m_4xMeDistortionBuffer.TileType = MOS_TILE_LINEAR;
6579             m_4xMeDistortionBuffer.bArraySpacing = true;
6580             m_4xMeDistortionBuffer.Format = Format_Buffer_2D;
6581             m_4xMeDistortionBuffer.dwWidth = m_downscaledWidthInMb4x * 8;
6582             m_4xMeDistortionBuffer.dwHeight = m_downscaledHeightInMb4x * 4 * 10;
6583             m_4xMeDistortionBuffer.dwPitch = MOS_ALIGN_CEIL(m_4xMeDistortionBuffer.dwWidth, 128);
6584 
6585             allocParamsForBuffer2D.dwWidth = m_4xMeDistortionBuffer.dwWidth;
6586             allocParamsForBuffer2D.dwHeight = m_4xMeDistortionBuffer.dwHeight;
6587             allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer";
6588             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6589                 m_osInterface,
6590                 &allocParamsForBuffer2D,
6591                 &m_4xMeDistortionBuffer.OsResource));
6592         }
6593 
6594         if (m_16xMeSupported)
6595         {
6596             MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(MOS_SURFACE));
6597             m_16xMeMvDataBuffer.TileType = MOS_TILE_LINEAR;
6598             m_16xMeMvDataBuffer.bArraySpacing = true;
6599             m_16xMeMvDataBuffer.Format = Format_Buffer_2D;
6600 
6601             m_16xMeMvDataBuffer.dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64);
6602             m_16xMeMvDataBuffer.dwHeight = m_downscaledHeightInMb16x * 4 * 10;
6603             m_16xMeMvDataBuffer.dwPitch = MOS_ALIGN_CEIL(m_16xMeMvDataBuffer.dwWidth, 128);
6604 
6605             allocParamsForBuffer2D.dwWidth = m_4xMeMvDataBuffer.dwWidth;
6606             allocParamsForBuffer2D.dwHeight = m_4xMeMvDataBuffer.dwHeight;
6607             allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer";
6608             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6609                 m_osInterface,
6610                 &allocParamsForBuffer2D,
6611                 &m_16xMeMvDataBuffer.OsResource));
6612         }
6613 
6614         // intermediate surface to be used by the P kernel to help reduce number of SIC calls
6615         MOS_ZeroMemory(&m_output16X16InterModes, sizeof(MOS_SURFACE));
6616         m_output16X16InterModes.TileType      = MOS_TILE_LINEAR;
6617         m_output16X16InterModes.bArraySpacing = true;
6618         m_output16X16InterModes.Format        = Format_Buffer_2D;
6619         m_output16X16InterModes.dwWidth       = 16 * m_picWidthInMb;
6620         m_output16X16InterModes.dwHeight      = 8 * m_picHeightInMb;
6621         m_output16X16InterModes.dwPitch       = MOS_ALIGN_CEIL(m_output16X16InterModes.dwWidth, 64);
6622 
6623         allocParamsForBuffer2D.dwWidth  = m_output16X16InterModes.dwWidth;
6624         allocParamsForBuffer2D.dwHeight = m_output16X16InterModes.dwHeight;
6625         allocParamsForBuffer2D.pBufName = "Intermediate surface";
6626 
6627         CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6628             m_osInterface,
6629             &allocParamsForBuffer2D,
6630             &m_output16X16InterModes.OsResource));
6631 
6632         uint32_t picSizeInMb                = m_picWidthInMb * m_picHeightInMb;
6633         uint32_t size                       = 16 * picSizeInMb * sizeof(uint32_t);
6634         allocParamsForBufferLinear.dwBytes  = size;
6635         allocParamsForBufferLinear.pBufName = "Mode Decision Buffer";
6636 
6637         for (auto i = 0; i < 2; i++)
6638         {
6639             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
6640                 m_osInterface,
6641                 &allocParamsForBufferLinear,
6642                 &m_resModeDecision[i]));
6643         }
6644     }
6645 
6646     // VDENC Intra Row Store Scratch buffer
6647     allocParamsForBufferLinear.dwBytes = m_picWidthInMb * CODECHAL_CACHELINE_SIZE;
6648     allocParamsForBufferLinear.pBufName = "VDENC Intra Row Store Scratch Buffer";
6649 
6650     eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6651         m_osInterface,
6652         &allocParamsForBufferLinear,
6653         &m_resVdencIntraRowStoreScratchBuffer);
6654 
6655     if (eStatus != MOS_STATUS_SUCCESS)
6656     {
6657         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC Intra Row Store Scratch Buffer.");
6658         return eStatus;
6659     }
6660 
6661     // VDENC BRC Statistics buffer
6662     allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_maxTileNumber * m_vdencBrcStatsBufferSize, CODECHAL_PAGE_SIZE);
6663     allocParamsForBufferLinear.pBufName = "VDENC BRC Statistics Buffer";
6664 
6665     eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6666         m_osInterface,
6667         &allocParamsForBufferLinear,
6668         &m_resVdencBrcStatsBuffer);
6669 
6670     if (eStatus != MOS_STATUS_SUCCESS)
6671     {
6672         CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC Statistics Buffer\n", __FUNCTION__);
6673         return eStatus;
6674     }
6675 
6676     // HVC Tile Row Store Buffer
6677     allocParamsForBufferLinear.dwBytes = CODECHAL_CACHELINE_SIZE * maxPicWidthInSb;
6678     allocParamsForBufferLinear.pBufName = "HvcTileRowStoreBuffer";
6679 
6680     eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6681         m_osInterface,
6682         &allocParamsForBufferLinear,
6683         &m_resHvcTileRowstoreBuffer);
6684 
6685     if (eStatus != MOS_STATUS_SUCCESS)
6686     {
6687         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate HVC Tile Row Store Buffer.");
6688         return eStatus;
6689     }
6690 
6691     // VDENC picture second level batch buffer
6692     allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencPicStateSecondLevelBatchBufferSize, CODECHAL_PAGE_SIZE);
6693     allocParamsForBufferLinear.pBufName = "VDEnc Picture Second Level Batch Buffer Read";
6694 
6695     for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++)
6696     {
6697         for (auto j = 0; j < 3; j++)
6698         {
6699             eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6700                 m_osInterface,
6701                 &allocParamsForBufferLinear,
6702                 &m_resVdencPictureState2NdLevelBatchBufferRead[j][i]);
6703         }
6704     }
6705 
6706     if (eStatus != MOS_STATUS_SUCCESS)
6707     {
6708         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Picture Second Level Batch Buffer Read.");
6709         return eStatus;
6710     }
6711 
6712     allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencPicStateSecondLevelBatchBufferSize, CODECHAL_PAGE_SIZE);
6713     allocParamsForBufferLinear.pBufName = "VDEnc Picture Second Level Batch Buffer Write";
6714 
6715     for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++)
6716     {
6717         eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6718             m_osInterface,
6719             &allocParamsForBufferLinear,
6720             &m_resVdencPictureState2NdLevelBatchBufferWrite[i]);
6721     }
6722 
6723     if (eStatus != MOS_STATUS_SUCCESS)
6724     {
6725         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Picture Second Level Batch Buffer Write.");
6726         return eStatus;
6727     }
6728 
6729     // BRC init/reset DMEM
6730     allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE);
6731     allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer";
6732     eStatus                             = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6733         m_osInterface,
6734         &allocParamsForBufferLinear,
6735         &m_resVdencBrcInitDmemBuffer);
6736 
6737     if (eStatus != MOS_STATUS_SUCCESS)
6738     {
6739         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC BRC Init DMEM Buffer\n");
6740         return eStatus;
6741     }
6742 
6743     // BRC update DMEM
6744     for (auto i = 0; i < 3; i++)
6745     {
6746         for (auto ib = 0; ib < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; ib++)
6747         {
6748             // BRC update DMEM
6749             allocParamsForBufferLinear.dwBytes  = MOS_ALIGN_CEIL(sizeof(HucBrcUpdateDmem), CODECHAL_CACHELINE_SIZE);
6750             allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer";
6751             eStatus                             = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6752                 m_osInterface,
6753                 &allocParamsForBufferLinear,
6754                 &m_resVdencBrcUpdateDmemBuffer[i][ib]);
6755         }
6756     }
6757 
6758     if (eStatus != MOS_STATUS_SUCCESS)
6759     {
6760         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC BRC Update DMEM Buffer\n");
6761         return eStatus;
6762     }
6763 
6764     // This stream out/stream in buffer may need to be a separate buffer on HW, in which case
6765     // we'll create 2 and ping-pong back and forth per-frame.  For now, though, on simulation/SW,
6766     // they can be the same buffer.
6767     allocParamsForBufferLinear.dwBytes = CODECHAL_CACHELINE_SIZE * maxPicSizeInSb;
6768     allocParamsForBufferLinear.pBufName = "VDEnc Segment Map Stream Out";
6769 
6770     eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
6771         m_osInterface,
6772         &allocParamsForBufferLinear,
6773         &m_resVdencSegmentMapStreamOut);
6774 
6775     if (eStatus != MOS_STATUS_SUCCESS)
6776     {
6777         CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Segment Map Stream Out Buffer.");
6778         return eStatus;
6779     }
6780 
6781     // Allocate Frame Statistics Streamout Data Destination Buffer
6782     uint32_t size = MOS_ALIGN_CEIL(m_vdencBrcPakStatsBufferSize, CODECHAL_PAGE_SIZE); // Align to page is HuC requirement
6783     allocParamsForBufferLinear.dwBytes  = size * m_maxTileNumber;
6784     allocParamsForBufferLinear.pBufName = "FrameStatStreamOutBuffer";
6785 
6786     CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
6787                                                   m_osInterface,
6788                                                   &allocParamsForBufferLinear,
6789                                                   &m_resFrameStatStreamOutBuffer),
6790         "Failed to allocate VP9 FrameStatStreamOutBuffer");
6791 
6792     uint8_t* data = nullptr;
6793     CODECHAL_ENCODE_CHK_NULL_RETURN(
6794         data = (uint8_t *)m_osInterface->pfnLockResource(
6795             m_osInterface,
6796             &m_resFrameStatStreamOutBuffer,
6797             &lockFlagsWriteOnly));
6798 
6799     MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes);
6800 
6801     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
6802         m_osInterface,
6803         &m_resFrameStatStreamOutBuffer));
6804 
6805     // Allocate SSE Source Pixel Row Store Buffer
6806     m_sizeOfSseSrcPixelRowStoreBufferPerLcu = ((maxPicWidthInSb + 2) << 5) * CODECHAL_CACHELINE_SIZE;
6807     size = m_sizeOfSseSrcPixelRowStoreBufferPerLcu * m_maxTileNumber;
6808     allocParamsForBufferLinear.dwBytes = size;
6809     allocParamsForBufferLinear.pBufName = "SseSrcPixelRowStoreBuffer";
6810 
6811     CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
6812                                                   m_osInterface,
6813                                                   &allocParamsForBufferLinear,
6814                                                   &m_resSseSrcPixelRowStoreBuffer),
6815         "Failed to allocate VP9 SseSrcPixelRowStoreBuffer");
6816 
6817     CODECHAL_ENCODE_CHK_NULL_RETURN(
6818         data = (uint8_t *)m_osInterface->pfnLockResource(
6819             m_osInterface,
6820             &m_resSseSrcPixelRowStoreBuffer,
6821             &lockFlagsWriteOnly));
6822 
6823     MOS_ZeroMemory(data, size);
6824 
6825     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
6826         m_osInterface,
6827         &m_resSseSrcPixelRowStoreBuffer));
6828 
6829     // Allocate data extension buffer
6830     size = CODECHAL_ENCODE_VP9_VDENC_DATA_EXTENSION_SIZE;
6831     allocParamsForBufferLinear.dwBytes = size;
6832     allocParamsForBufferLinear.pBufName = "DataExtensionBuffer";
6833 
6834     CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
6835                                                   m_osInterface,
6836                                                   &allocParamsForBufferLinear,
6837                                                   &m_resVdencDataExtensionBuffer),
6838         "Failed to allocate VP9 HuC data extension buffer");
6839 
6840     CODECHAL_ENCODE_CHK_NULL_RETURN(
6841         data = (uint8_t *)m_osInterface->pfnLockResource(
6842             m_osInterface,
6843             &m_resVdencDataExtensionBuffer,
6844             &lockFlagsWriteOnly));
6845 
6846     MOS_ZeroMemory(data, size);
6847 
6848     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(
6849         m_osInterface,
6850         &m_resVdencDataExtensionBuffer));
6851 
6852     if (m_hucCmdInitializer)
6853     {
6854         m_hucCmdInitializer->CmdInitializerAllocateResources(m_hwInterface);
6855     }
6856 
6857     return eStatus;
6858 }
6859 
FreeResources()6860 void CodechalVdencVp9State::FreeResources()
6861 {
6862     CODECHAL_ENCODE_FUNCTION_ENTER;
6863 
6864     CodechalEncoderState::FreeResources();
6865 
6866     PCODEC_REF_LIST *refList = &m_refList[0];
6867 
6868     // Release Ref Lists
6869     for (uint32_t i = 0; i < m_numUncompressedSurface; i++)
6870     {
6871         if (!Mos_ResourceIsNull(&refList[i]->sDysSurface.OsResource))
6872         {
6873             m_osInterface->pfnFreeResource(
6874                 m_osInterface,
6875                 &refList[i]->sDysSurface.OsResource);
6876         }
6877 
6878         if (!Mos_ResourceIsNull(&refList[i]->sDys4xScaledSurface.OsResource))
6879         {
6880             m_osInterface->pfnFreeResource(
6881                 m_osInterface,
6882                 &refList[i]->sDys4xScaledSurface.OsResource);
6883         }
6884 
6885         if (!Mos_ResourceIsNull(&refList[i]->sDys16xScaledSurface.OsResource))
6886         {
6887             m_osInterface->pfnFreeResource(
6888                 m_osInterface,
6889                 &refList[i]->sDys16xScaledSurface.OsResource);
6890         }
6891     }
6892 
6893     CodecHalFreeDataList(m_refList, m_numUncompressedSurface);
6894 
6895     m_osInterface->pfnFreeResource(
6896         m_osInterface,
6897         &m_resDeblockingFilterLineBuffer);
6898 
6899     m_osInterface->pfnFreeResource(
6900         m_osInterface,
6901         &m_resDeblockingFilterTileLineBuffer);
6902 
6903     m_osInterface->pfnFreeResource(
6904         m_osInterface,
6905         &m_resDeblockingFilterTileColumnBuffer);
6906 
6907     m_osInterface->pfnFreeResource(
6908         m_osInterface,
6909         &m_resMetadataLineBuffer);
6910 
6911     m_osInterface->pfnFreeResource(
6912         m_osInterface,
6913         &m_resMetadataTileLineBuffer);
6914 
6915     m_osInterface->pfnFreeResource(
6916         m_osInterface,
6917         &m_resMetadataTileColumnBuffer);
6918 
6919     for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
6920     {
6921         m_osInterface->pfnFreeResource(
6922             m_osInterface,
6923             &m_resProbBuffer[i]);
6924     }
6925 
6926     m_osInterface->pfnFreeResource(
6927         m_osInterface,
6928         &m_resSegmentIdBuffer);
6929 
6930     m_osInterface->pfnFreeResource(
6931         m_osInterface,
6932         &m_resProbabilityDeltaBuffer);
6933 
6934     m_osInterface->pfnFreeResource(
6935         m_osInterface,
6936         &m_resCompressedHeaderBuffer);
6937 
6938     m_osInterface->pfnFreeResource(
6939         m_osInterface,
6940         &m_resProbabilityCounterBuffer);
6941 
6942     m_osInterface->pfnFreeResource(
6943         m_osInterface,
6944         &m_resTileRecordStrmOutBuffer);
6945 
6946     m_osInterface->pfnFreeResource(
6947         m_osInterface,
6948         &m_resCuStatsStrmOutBuffer);
6949 
6950     for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j)
6951     {
6952         for (auto i = 0; i < 3; i++)
6953         {
6954             m_osInterface->pfnFreeResource(
6955                 m_osInterface,
6956                 &m_resHucProbDmemBuffer[i][j]);
6957         }
6958     }
6959     m_osInterface->pfnFreeResource(
6960         m_osInterface,
6961         &m_resHucPakMmioBuffer);
6962 
6963     m_osInterface->pfnFreeResource(
6964         m_osInterface,
6965         &m_resHucDefaultProbBuffer);
6966 
6967     m_osInterface->pfnFreeResource(
6968         m_osInterface,
6969         &m_resHucProbOutputBuffer);
6970     for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++i)
6971     {
6972         m_osInterface->pfnFreeResource(
6973             m_osInterface,
6974             &m_resHucPakInsertUncompressedHeaderReadBuffer[i]);
6975     }
6976     m_osInterface->pfnFreeResource(
6977         m_osInterface,
6978         &m_resHucPakInsertUncompressedHeaderWriteBuffer);
6979 
6980     m_osInterface->pfnFreeResource(
6981         m_osInterface,
6982         &m_resHucDebugOutputBuffer);
6983 
6984     m_osInterface->pfnFreeResource(
6985         m_osInterface,
6986         &m_resVdencDataExtensionBuffer);
6987 
6988     if (m_encEnabled)
6989     {
6990         ReleaseResourcesBrc();
6991         for (auto i = 0; i < 2; i++)
6992         {
6993             if (!Mos_ResourceIsNull(&m_resModeDecision[i]))
6994             {
6995                 m_osInterface->pfnFreeResource(
6996                     m_osInterface,
6997                     &m_resModeDecision[i]);
6998             }
6999         }
7000 
7001         if (!Mos_ResourceIsNull(&m_output16X16InterModes.OsResource))
7002         {
7003             m_osInterface->pfnFreeResource(
7004                 m_osInterface,
7005                 &m_output16X16InterModes.OsResource);
7006         }
7007 
7008         if (!Mos_ResourceIsNull(&m_4xMeMvDataBuffer.OsResource))
7009         {
7010             m_osInterface->pfnFreeResource(
7011                 m_osInterface,
7012                 &m_4xMeMvDataBuffer.OsResource);
7013         }
7014 
7015         if (!Mos_ResourceIsNull(&m_4xMeDistortionBuffer.OsResource))
7016         {
7017             m_osInterface->pfnFreeResource(
7018                 m_osInterface,
7019                 &m_4xMeDistortionBuffer.OsResource);
7020         }
7021 
7022         if (!Mos_ResourceIsNull(&m_16xMeMvDataBuffer.OsResource))
7023         {
7024             m_osInterface->pfnFreeResource(
7025                 m_osInterface,
7026                 &m_16xMeMvDataBuffer.OsResource);
7027         }
7028 
7029         if (!Mos_ResourceIsNull(&m_mbSegmentMapSurface.OsResource) && m_segmentMapAllocated)
7030         {
7031             m_osInterface->pfnFreeResource(
7032                 m_osInterface,
7033                 &m_mbSegmentMapSurface.OsResource);
7034         }
7035     }
7036 
7037     m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencIntraRowStoreScratchBuffer);
7038     m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcStatsBuffer);
7039     m_osInterface->pfnFreeResource(m_osInterface, &m_resHvcTileRowstoreBuffer);
7040 
7041     m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencDysPictureState2NdLevelBatchBuffer);
7042     m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencSegmentMapStreamOut);
7043     m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcInitDmemBuffer);
7044     for (auto i = 0; i < 3; i++)
7045     {
7046         for (auto ib = 0; ib < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; ib++)
7047         {
7048             m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[i][ib]);
7049         }
7050     }
7051     m_osInterface->pfnFreeResource(m_osInterface, &m_resFrameStatStreamOutBuffer);
7052     m_osInterface->pfnFreeResource(m_osInterface, &m_resSseSrcPixelRowStoreBuffer);
7053     MOS_FreeMemory(m_mapBuffer);
7054 
7055     for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++)
7056     {
7057         for (auto j = 0; j < 3; j++)
7058         {
7059             m_osInterface->pfnFreeResource(
7060                 m_osInterface,
7061                 &m_resVdencPictureState2NdLevelBatchBufferRead[j][i]);
7062         }
7063         m_osInterface->pfnFreeResource(
7064             m_osInterface,
7065             &m_resVdencPictureState2NdLevelBatchBufferWrite[i]);
7066     }
7067     if (m_hucCmdInitializer)
7068     {
7069         m_hucCmdInitializer->CmdInitializerFreeResources();
7070         MOS_Delete(m_hucCmdInitializer);
7071         m_hucCmdInitializer = nullptr;
7072     }
7073 
7074 #if (_DEBUG || _RELEASE_INTERNAL)
7075     if (m_swBrcMode != nullptr)
7076     {
7077         bool result = MosUtilities::MosFreeLibrary(m_swBrcMode) ? true : false;
7078         CODECHAL_ENCODE_ASSERT(result == true);
7079         m_swBrcMode = nullptr;
7080     }
7081 #endif
7082 
7083     return;
7084 }
7085 
CalculateVdencPictureStateCommandSize()7086 MOS_STATUS CodechalVdencVp9State::CalculateVdencPictureStateCommandSize()
7087 {
7088     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
7089 
7090     CODECHAL_ENCODE_FUNCTION_ENTER;
7091 
7092     MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams;
7093     uint32_t vdencPictureStatesSize = 0, vdencPicturePatchListSize = 0;
7094     stateCmdSizeParams.bHucDummyStream = true;
7095     m_hwInterface->GetHxxStateCommandSize(
7096         CODECHAL_ENCODE_MODE_VP9,
7097         &vdencPictureStatesSize,
7098         &vdencPicturePatchListSize,
7099         &stateCmdSizeParams);
7100 
7101     m_defaultPictureStatesSize += vdencPictureStatesSize;
7102     m_defaultPicturePatchListSize += vdencPicturePatchListSize;
7103 
7104     m_hwInterface->GetVdencStateCommandsDataSize(
7105         CODECHAL_ENCODE_MODE_VP9,
7106         &vdencPictureStatesSize,
7107         &vdencPicturePatchListSize);
7108 
7109     m_defaultPictureStatesSize += vdencPictureStatesSize;
7110     m_defaultPicturePatchListSize += vdencPicturePatchListSize;
7111 
7112     //Set to max huc commands
7113     uint32_t vdencHucStatesSize = 0, hucPatchListSize = 0;
7114     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->GetHucStateCommandSize(
7115         CODECHAL_ENCODE_MODE_VP9, (uint32_t*)&vdencHucStatesSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams));
7116     m_defaultHucCmdsSize += m_defaultHucCmdsSize;
7117     m_defaultHucPatchListSize += hucPatchListSize;
7118     return eStatus;
7119 }
7120 
Initialize(CodechalSetting * settings)7121 MOS_STATUS CodechalVdencVp9State::Initialize(CodechalSetting * settings)
7122 {
7123     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
7124 
7125     CODECHAL_ENCODE_FUNCTION_ENTER;
7126 #ifndef _FULL_OPEN_SOURCE
7127     if (m_cscDsState)
7128     {
7129         // support non-aligned and csc ds copy usages
7130         m_cscDsState->EnableCopy();
7131         m_cscDsState->EnableColor();
7132 
7133         // Temp WA until cscDs Codec/Platform LUT is completed
7134         m_cscDsState->DisableCsc();
7135     }
7136 #endif
7137     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(settings));
7138 #ifdef _MMC_SUPPORTED
7139     CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState());
7140 #endif
7141     m_bitDepth     = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS) ? VP9_ENCODED_BIT_DEPTH_10 : VP9_ENCODED_BIT_DEPTH_8;
7142     m_chromaFormat = settings->chromaFormat;
7143 
7144     CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateVdencPictureStateCommandSize());
7145 
7146     // Slice Level Commands
7147     CODECHAL_ENCODE_CHK_STATUS_RETURN(
7148         m_hwInterface->GetHxxPrimitiveCommandSize(
7149             CODECHAL_ENCODE_MODE_VP9,
7150             &m_sliceStatesSize,
7151             &m_slicePatchListSize,
7152             false));
7153 
7154     m_hwInterface->GetVdencPictureSecondLevelCommandsSize(
7155         CODECHAL_ENCODE_MODE_VP9,
7156         &m_vdencPicStateSecondLevelBatchBufferSize);
7157 
7158     return eStatus;
7159 }
7160 
7161 //------------------------------------------------------------------------------
7162 //| Purpose:    Reports user feature keys used for VP9 encoding
7163 //| Return:     N/A
7164 //------------------------------------------------------------------------------
UserFeatureKeyReport()7165 MOS_STATUS CodechalVdencVp9State::UserFeatureKeyReport()
7166 {
7167     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
7168 
7169     CODECHAL_ENCODE_FUNCTION_ENTER;
7170 
7171     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::UserFeatureKeyReport())
7172 
7173     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_BRC_IN_USE_ID, m_brcEnabled, m_osInterface->pOsContext);
7174     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_MULTIPASS_BRC_IN_USE_ID, m_multipassBrcSupported, m_osInterface->pOsContext);
7175     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_ADAPTIVE_REPAK_IN_USE_ID, m_adaptiveRepakSupported, m_osInterface->pOsContext);
7176     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_ME_ENABLE_ID, m_hmeSupported, m_osInterface->pOsContext);
7177     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_16xME_ENABLE_ID, m_16xMeSupported, m_osInterface->pOsContext);
7178     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_HUC_ENABLE_ID, m_hucEnabled, m_osInterface->pOsContext);
7179 
7180 #if (_DEBUG || _RELEASE_INTERNAL)
7181     CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VDENC_IN_USE_ID, m_vdencEnabled, m_osInterface->pOsContext);
7182 #endif
7183 
7184     return eStatus;
7185 }
7186 
7187 //------------------------------------------------------------------------------
7188 //| Purpose:    Retrieves the HCP registers and stores them in the status report
7189 //| Return:     N/A
7190 //------------------------------------------------------------------------------
ReadHcpStatus(PMOS_COMMAND_BUFFER cmdBuffer)7191 MOS_STATUS CodechalVdencVp9State::ReadHcpStatus(
7192     PMOS_COMMAND_BUFFER cmdBuffer)
7193 {
7194     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
7195 
7196     CODECHAL_ENCODE_FUNCTION_ENTER;
7197 
7198     CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
7199 
7200     CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()),"ERROR - vdbox index exceed the maximum");
7201 
7202     EncodeStatusBuffer* encodeStatusBuf   = &m_encodeStatusBuf;
7203     uint32_t baseOffset =
7204         (encodeStatusBuf->wCurrIndex * m_encodeStatusBuf.dwReportSize) +
7205         sizeof(uint32_t)* 2;  // encodeStatus is offset by 2 DWs in the resource
7206 
7207     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
7208     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
7209     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
7210 
7211     auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex);
7212     CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
7213     MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
7214     MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
7215     miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer;
7216     miStoreRegMemParams.dwOffset        = baseOffset + encodeStatusBuf->dwBSByteCountOffset;
7217     miStoreRegMemParams.dwRegister      = mmioRegisters->hcpVp9EncBitstreamBytecountFrameRegOffset;
7218     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
7219 
7220     MHW_MI_COPY_MEM_MEM_PARAMS copyMemMemParams;
7221     MOS_ZeroMemory(&copyMemMemParams , sizeof(copyMemMemParams));
7222 
7223     copyMemMemParams.presSrc        = &encodeStatusBuf->resStatusBuffer;
7224     copyMemMemParams.dwSrcOffset    = baseOffset + encodeStatusBuf->dwBSByteCountOffset;
7225     copyMemMemParams.presDst        = &m_brcBuffers.resBrcBitstreamSizeBuffer;
7226     copyMemMemParams.dwDstOffset    = CODECHAL_OFFSETOF(BRC_BITSTREAM_SIZE_BUFFER, dwHcpBitstreamByteCountFrame);
7227 
7228     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd(
7229         cmdBuffer,
7230         &copyMemMemParams));
7231 
7232     MOS_ZeroMemory(&copyMemMemParams, sizeof(copyMemMemParams));
7233 
7234     // write frame size directly to huc second pass dmem buffer
7235     // it is needed for correct pipeline synchronization and dmem initialization
7236     copyMemMemParams.presSrc = &encodeStatusBuf->resStatusBuffer;
7237     copyMemMemParams.dwSrcOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset;
7238     // For BRC cases, do not overwrite the HPU probability in huc Dmen buffer in the last pass
7239     copyMemMemParams.presDst = &m_resHucProbDmemBuffer[m_vdencBrcEnabled ? 2 : 1][m_currRecycledBufIdx];
7240     copyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(HucProbDmem, FrameSize);
7241 
7242     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd(
7243         cmdBuffer,
7244         &copyMemMemParams));
7245 
7246     return eStatus;
7247 }
7248 
CodechalVdencVp9State(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)7249 CodechalVdencVp9State::CodechalVdencVp9State(
7250     CodechalHwInterface* hwInterface,
7251     CodechalDebugInterface* debugInterface,
7252     PCODECHAL_STANDARD_INFO standardInfo)
7253     :CodechalEncoderState(hwInterface, debugInterface, standardInfo)
7254 {
7255     m_32xMeSupported = false;
7256 
7257     // VP9 uses a CM based down scale kernel
7258     m_useCmScalingKernel      = true;
7259     m_interlacedFieldDisabled = true;
7260     m_firstField              = true; // each frame is treated as the first field
7261 
7262     // No field pictures in VP9
7263     m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME;
7264     m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD;
7265 
7266     // enable codec specific user feature key reporting
7267     m_userFeatureKeyReport = true;
7268 
7269     m_codecGetStatusReportDefined = true;       // Codec specific GetStatusReport is implemented.
7270 
7271     m_brcInit = true;
7272 
7273     MOS_ZeroMemory(&m_resDeblockingFilterLineBuffer, sizeof(m_resDeblockingFilterLineBuffer));
7274     MOS_ZeroMemory(&m_resDeblockingFilterTileLineBuffer, sizeof(m_resDeblockingFilterTileLineBuffer));
7275     MOS_ZeroMemory(&m_resDeblockingFilterTileColumnBuffer, sizeof(m_resDeblockingFilterTileColumnBuffer));
7276     MOS_ZeroMemory(&m_resMetadataLineBuffer, sizeof(m_resMetadataLineBuffer));
7277     MOS_ZeroMemory(&m_resMetadataTileLineBuffer, sizeof(m_resMetadataTileLineBuffer));
7278     MOS_ZeroMemory(&m_resMetadataTileColumnBuffer, sizeof(m_resMetadataTileColumnBuffer));
7279 
7280     for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
7281     {
7282         MOS_ZeroMemory(&m_resProbBuffer[i], sizeof(m_resProbBuffer[i]));
7283     }
7284     MOS_ZeroMemory(&m_resSegmentIdBuffer, sizeof(m_resSegmentIdBuffer));
7285     MOS_ZeroMemory(&m_resHvcLineRowstoreBuffer, sizeof(m_resHvcLineRowstoreBuffer));  // Handle of HVC Line Row Store surface
7286     MOS_ZeroMemory(&m_resHvcTileRowstoreBuffer, sizeof(m_resHvcTileRowstoreBuffer));  // Handle of HVC Tile Row Store surface
7287     MOS_ZeroMemory(&m_resProbabilityDeltaBuffer, sizeof(m_resProbabilityDeltaBuffer));
7288     MOS_ZeroMemory(&m_resTileRecordStrmOutBuffer, sizeof(m_resTileRecordStrmOutBuffer));
7289     MOS_ZeroMemory(&m_resCuStatsStrmOutBuffer, sizeof(m_resCuStatsStrmOutBuffer));
7290     MOS_ZeroMemory(&m_resCompressedHeaderBuffer, sizeof(m_resCompressedHeaderBuffer));
7291     MOS_ZeroMemory(&m_resProbabilityCounterBuffer, sizeof(m_resProbabilityCounterBuffer));
7292     for (auto i = 0; i < 2; i++)
7293     {
7294         MOS_ZeroMemory(&m_resModeDecision[i], sizeof(m_resModeDecision[i]));
7295     }
7296     MOS_ZeroMemory(&m_resFrameStatStreamOutBuffer, sizeof(m_resFrameStatStreamOutBuffer));
7297     MOS_ZeroMemory(&m_resSseSrcPixelRowStoreBuffer, sizeof(m_resSseSrcPixelRowStoreBuffer));
7298 
7299     MOS_ZeroMemory(&m_prevFrameInfo, sizeof(m_prevFrameInfo));
7300 
7301     for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j)
7302     {
7303         for (auto i = 0; i < 3; i++)
7304         {
7305             MOS_ZeroMemory(&m_resHucProbDmemBuffer[i][j], sizeof(m_resHucProbDmemBuffer[i][j]));
7306         }
7307     }
7308     MOS_ZeroMemory(&m_resHucDefaultProbBuffer, sizeof(m_resHucDefaultProbBuffer));
7309     MOS_ZeroMemory(&m_resHucProbOutputBuffer, sizeof(m_resHucProbOutputBuffer));
7310     for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
7311     {
7312         MOS_ZeroMemory(&m_resHucPakInsertUncompressedHeaderReadBuffer[i], sizeof(m_resHucPakInsertUncompressedHeaderReadBuffer[i]));
7313     }
7314     MOS_ZeroMemory(&m_resHucPakInsertUncompressedHeaderWriteBuffer, sizeof(m_resHucPakInsertUncompressedHeaderWriteBuffer));
7315     MOS_ZeroMemory(&m_resHucPakMmioBuffer, sizeof(m_resHucPakMmioBuffer));
7316     MOS_ZeroMemory(&m_resHucDebugOutputBuffer, sizeof(m_resHucDebugOutputBuffer));
7317     MOS_ZeroMemory(&m_mbSegmentMapSurface, sizeof(m_mbSegmentMapSurface));
7318     MOS_ZeroMemory(&m_output16X16InterModes, sizeof(m_output16X16InterModes));
7319 
7320     MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(m_4xMeMvDataBuffer));
7321     MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(m_16xMeMvDataBuffer));
7322     MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(m_4xMeDistortionBuffer));
7323 
7324     MOS_ZeroMemory(&m_resVdencIntraRowStoreScratchBuffer, sizeof(m_resVdencIntraRowStoreScratchBuffer));  // Handle of intra row store surface
7325     MOS_ZeroMemory(&m_resVdencBrcStatsBuffer, sizeof(m_resVdencBrcStatsBuffer));
7326     MOS_ZeroMemory(&m_resVdencSegmentMapStreamOut, sizeof(m_resVdencSegmentMapStreamOut));
7327 
7328     for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++)
7329     {
7330         for (auto j = 0; j < 3; j++)
7331         {
7332             MOS_ZeroMemory(&m_resVdencPictureState2NdLevelBatchBufferRead[j][i], sizeof(m_resVdencPictureState2NdLevelBatchBufferRead[j][i]));
7333         }
7334 
7335         MOS_ZeroMemory(&m_resVdencPictureState2NdLevelBatchBufferWrite[i], sizeof(m_resVdencPictureState2NdLevelBatchBufferWrite[i]));
7336     }
7337 
7338     MOS_ZeroMemory(&m_resVdencDysPictureState2NdLevelBatchBuffer, sizeof(m_resVdencDysPictureState2NdLevelBatchBuffer));
7339     MOS_ZeroMemory(&m_resVdencBrcInitDmemBuffer, sizeof(m_resVdencBrcInitDmemBuffer));
7340     for (auto i = 0; i < 3; i++)
7341     {
7342         for (auto ib = 0; ib < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; ib++)
7343         {
7344             MOS_ZeroMemory(&m_resVdencBrcUpdateDmemBuffer[i][ib], sizeof(m_resVdencBrcUpdateDmemBuffer[i][ib]));
7345         }
7346     }
7347     MOS_ZeroMemory(&m_resVdencDataExtensionBuffer, sizeof(m_resVdencDataExtensionBuffer));
7348 
7349     MOS_ZeroMemory(&m_dysKernelState, sizeof(m_dysKernelState));
7350 
7351     m_vdboxOneDefaultUsed = true;
7352 }
7353 
InitMmcState()7354 MOS_STATUS CodechalVdencVp9State::InitMmcState()
7355 {
7356     CODECHAL_ENCODE_FUNCTION_ENTER;
7357 #ifdef _MMC_SUPPORTED
7358     m_mmcState = MOS_New(CodechalMmcEncodeVp9, m_hwInterface, this);
7359     CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
7360 #endif
7361     return MOS_STATUS_SUCCESS;
7362 }
7363 
CtxBufDiffInit(uint8_t * ctxBuffer,bool setToKey)7364 MOS_STATUS CodechalVdencVp9State::CtxBufDiffInit(
7365     uint8_t *ctxBuffer,
7366     bool setToKey)
7367 {
7368     int32_t i, j;
7369     uint32_t byteCnt = CODEC_VP9_INTER_PROB_OFFSET;
7370     //inter mode probs. have to be zeros for Key frame
7371     for (i = 0; i < CODEC_VP9_INTER_MODE_CONTEXTS; i++)
7372     {
7373         for (j = 0; j < CODEC_VP9_INTER_MODES - 1; j++)
7374         {
7375             if (!setToKey)
7376             {
7377                 ctxBuffer[byteCnt++] = DefaultInterModeProbs[i][j];
7378             }
7379             else
7380             {
7381                 //zeros for key frame
7382                 byteCnt++;
7383             }
7384         }
7385     }
7386     //switchable interprediction probs
7387     for (i = 0; i < CODEC_VP9_SWITCHABLE_FILTERS + 1; i++)
7388     {
7389         for (j = 0; j < CODEC_VP9_SWITCHABLE_FILTERS - 1; j++)
7390         {
7391             if (!setToKey)
7392             {
7393                 ctxBuffer[byteCnt++] = DefaultSwitchableInterpProb[i][j];
7394             }
7395             else
7396             {
7397                 //zeros for key frame
7398                 byteCnt++;
7399             }
7400         }
7401     }
7402     //intra inter probs
7403     for (i = 0; i < CODEC_VP9_INTRA_INTER_CONTEXTS; i++)
7404     {
7405         if (!setToKey)
7406         {
7407             ctxBuffer[byteCnt++] = DefaultIntraInterProb[i];
7408         }
7409         else
7410         {
7411             //zeros for key frame
7412             byteCnt++;
7413         }
7414     }
7415     //comp inter probs
7416     for (i = 0; i < CODEC_VP9_COMP_INTER_CONTEXTS; i++)
7417     {
7418         if (!setToKey)
7419         {
7420             ctxBuffer[byteCnt++] = DefaultCompInterProb[i];
7421         }
7422         else
7423         {
7424             //zeros for key frame
7425             byteCnt++;
7426         }
7427     }
7428     //single ref probs
7429     for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++)
7430     {
7431         for (j = 0; j < 2; j++)
7432         {
7433             if (!setToKey)
7434             {
7435                 ctxBuffer[byteCnt++] = DefaultSingleRefProb[i][j];
7436             }
7437             else
7438             {
7439                 //zeros for key frame
7440                 byteCnt++;
7441             }
7442         }
7443     }
7444     //comp ref probs
7445     for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++)
7446     {
7447         if (!setToKey)
7448         {
7449             ctxBuffer[byteCnt++] = DefaultCompRefProb[i];
7450         }
7451         else
7452         {
7453             //zeros for key frame
7454             byteCnt++;
7455         }
7456     }
7457     //y mode probs
7458     for (i = 0; i < CODEC_VP9_BLOCK_SIZE_GROUPS; i++)
7459     {
7460         for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++)
7461         {
7462             if (!setToKey)
7463             {
7464                 ctxBuffer[byteCnt++] = DefaultIFYProb[i][j];
7465             }
7466             else
7467             {
7468                 //zeros for key frame, since HW will not use this buffer, but default right buffer.
7469                 byteCnt++;
7470             }
7471         }
7472     }
7473     //partition probs, key & intra-only frames use key type, other inter frames use inter type
7474     for (i = 0; i < CODECHAL_VP9_PARTITION_CONTEXTS; i++)
7475     {
7476         for (j = 0; j < CODEC_VP9_PARTITION_TYPES - 1; j++)
7477         {
7478             if (setToKey)
7479             {
7480                 ctxBuffer[byteCnt++] = DefaultKFPartitionProb[i][j];
7481             }
7482             else
7483             {
7484                 ctxBuffer[byteCnt++] = DefaultPartitionProb[i][j];
7485             }
7486         }
7487     }
7488     //nmvc joints
7489     for (i = 0; i < (CODEC_VP9_MV_JOINTS - 1); i++)
7490     {
7491         if (!setToKey)
7492         {
7493             ctxBuffer[byteCnt++] = DefaultNmvContext.joints[i];
7494         }
7495         else
7496         {
7497             //zeros for key frame
7498             byteCnt++;
7499         }
7500     }
7501     //nmvc comps
7502     for (i = 0; i < 2; i++)
7503     {
7504         if (!setToKey)
7505         {
7506             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].sign;
7507             for (j = 0; j < (CODEC_VP9_MV_CLASSES - 1); j++)
7508             {
7509                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].classes[j];
7510             }
7511             for (j = 0; j < (CODECHAL_VP9_CLASS0_SIZE - 1); j++)
7512             {
7513                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0[j];
7514             }
7515             for (j = 0; j < CODECHAL_VP9_MV_OFFSET_BITS; j++)
7516             {
7517                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].bits[j];
7518             }
7519         }
7520         else
7521         {
7522             byteCnt += 1;
7523             byteCnt += (CODEC_VP9_MV_CLASSES - 1);
7524             byteCnt += (CODECHAL_VP9_CLASS0_SIZE - 1);
7525             byteCnt += (CODECHAL_VP9_MV_OFFSET_BITS);
7526         }
7527     }
7528     for (i = 0; i < 2; i++)
7529     {
7530         if (!setToKey)
7531         {
7532             for (j = 0; j < CODECHAL_VP9_CLASS0_SIZE; j++)
7533             {
7534                 for (int32_t k = 0; k < (CODEC_VP9_MV_FP_SIZE - 1); k++)
7535                 {
7536                     ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_fp[j][k];
7537                 }
7538             }
7539             for (j = 0; j < (CODEC_VP9_MV_FP_SIZE - 1); j++)
7540             {
7541                 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].fp[j];
7542             }
7543         }
7544         else
7545         {
7546             byteCnt += (CODECHAL_VP9_CLASS0_SIZE * (CODEC_VP9_MV_FP_SIZE - 1));
7547             byteCnt += (CODEC_VP9_MV_FP_SIZE - 1);
7548         }
7549     }
7550     for (i = 0; i < 2; i++)
7551     {
7552         if (!setToKey)
7553         {
7554             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_hp;
7555             ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].hp;
7556         }
7557         else
7558         {
7559             byteCnt += 2;
7560         }
7561     }
7562 
7563     //47 bytes of zeros
7564     byteCnt += 47;
7565 
7566     //uv mode probs
7567     for (i = 0; i < CODEC_VP9_INTRA_MODES; i++)
7568     {
7569         for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++)
7570         {
7571             if (setToKey)
7572             {
7573                 ctxBuffer[byteCnt++] = DefaultKFUVModeProb[i][j];
7574             }
7575             else
7576             {
7577                 ctxBuffer[byteCnt++] = DefaultIFUVProbs[i][j];
7578             }
7579         }
7580     }
7581 
7582     return MOS_STATUS_SUCCESS;
7583 }
7584 
ContextBufferInit(uint8_t * ctxBuffer,bool setToKey)7585 MOS_STATUS CodechalVdencVp9State::ContextBufferInit(
7586     uint8_t *ctxBuffer,
7587     bool setToKey)
7588 {
7589 
7590     MOS_ZeroMemory(ctxBuffer, CODEC_VP9_SEG_PROB_OFFSET);
7591 
7592     int32_t i, j;
7593     uint32_t byteCnt = 0;
7594     //TX probs
7595     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
7596     {
7597         for (j = 0; j < CODEC_VP9_TX_SIZES - 3; j++)
7598         {
7599             ctxBuffer[byteCnt++] = DefaultTxProbs.p8x8[i][j];
7600         }
7601     }
7602     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
7603     {
7604         for (j = 0; j < CODEC_VP9_TX_SIZES - 2; j++)
7605         {
7606             ctxBuffer[byteCnt++] = DefaultTxProbs.p16x16[i][j];
7607         }
7608     }
7609     for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++)
7610     {
7611         for (j = 0; j < CODEC_VP9_TX_SIZES - 1; j++)
7612         {
7613             ctxBuffer[byteCnt++] = DefaultTxProbs.p32x32[i][j];
7614         }
7615     }
7616 
7617     //52 bytes of zeros
7618     byteCnt += 52;
7619 
7620     uint8_t blocktype = 0;
7621     uint8_t reftype = 0;
7622     uint8_t coeffbands = 0;
7623     uint8_t unConstrainedNodes = 0;
7624     uint8_t prevCoefCtx = 0;
7625     //coeff probs
7626     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
7627     {
7628         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
7629         {
7630             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
7631             {
7632                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
7633                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
7634                 {
7635                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
7636                     {
7637                         ctxBuffer[byteCnt++] = DefaultCoefProbs4x4[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
7638                     }
7639                 }
7640             }
7641         }
7642     }
7643 
7644     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
7645     {
7646         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
7647         {
7648             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
7649             {
7650                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
7651                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
7652                 {
7653                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
7654                     {
7655                         ctxBuffer[byteCnt++] = DefaultCoefPprobs8x8[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
7656                     }
7657                 }
7658             }
7659         }
7660     }
7661 
7662     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
7663     {
7664         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
7665         {
7666             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
7667             {
7668                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
7669                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
7670                 {
7671                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
7672                     {
7673                         ctxBuffer[byteCnt++] = DefaultCoefProbs16x16[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
7674                     }
7675                 }
7676             }
7677         }
7678     }
7679 
7680     for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++)
7681     {
7682         for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++)
7683         {
7684             for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++)
7685             {
7686                 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
7687                 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++)
7688                 {
7689                     for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++)
7690                     {
7691                         ctxBuffer[byteCnt++] = DefaultCoefProbs32x32[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
7692                     }
7693                 }
7694             }
7695         }
7696     }
7697 
7698     //16 bytes of zeros
7699     byteCnt += 16;
7700 
7701     // mb skip probs
7702     for (i = 0; i < CODEC_VP9_MBSKIP_CONTEXTS; i++)
7703     {
7704         ctxBuffer[byteCnt++] = DefaultMbskipProbs[i];
7705     }
7706 
7707     // populate prob values which are different between Key and Non-Key frame
7708     CtxBufDiffInit(ctxBuffer, setToKey);
7709 
7710     //skip Seg tree/pred probs, updating not done in this function.
7711     byteCnt = CODEC_VP9_SEG_PROB_OFFSET;
7712     byteCnt += 7;
7713     byteCnt += 3;
7714 
7715     //28 bytes of zeros
7716     for (i = 0; i < 28; i++)
7717     {
7718         ctxBuffer[byteCnt++] = 0;
7719     }
7720 
7721     //Just a check.
7722     if (byteCnt > CODEC_VP9_PROB_MAX_NUM_ELEM)
7723     {
7724         CODECHAL_PUBLIC_ASSERTMESSAGE("Error: FrameContext array out-of-bounds, byteCnt = %d!\n", byteCnt);
7725         return MOS_STATUS_NO_SPACE;
7726     }
7727     else
7728     {
7729         return MOS_STATUS_SUCCESS;
7730     }
7731 }
7732 
7733 #if USE_CODECHAL_DEBUG_TOOL
DumpSeqParams(PCODEC_VP9_ENCODE_SEQUENCE_PARAMS seqParams)7734 MOS_STATUS CodechalVdencVp9State::DumpSeqParams(
7735     PCODEC_VP9_ENCODE_SEQUENCE_PARAMS seqParams)
7736 {
7737     CODECHAL_DEBUG_FUNCTION_ENTER;
7738 
7739     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams))
7740     {
7741         return MOS_STATUS_SUCCESS;
7742     }
7743 
7744     CODECHAL_DEBUG_CHK_NULL(seqParams);
7745 
7746     std::ostringstream oss;
7747     oss.setf(std::ios::showbase | std::ios::uppercase);
7748 
7749     oss << "# DDI Parameters:" << std::endl;
7750     oss << "MaxFrameWidth = " << std::dec << +seqParams->wMaxFrameWidth << std::endl;
7751     oss << "MaxFrameHeight = " << std::dec << +seqParams->wMaxFrameHeight << std::endl;
7752     oss << "GopPicSize = " << std::dec << +seqParams->GopPicSize << std::endl;
7753     oss << "TargetUsage = " << std::dec << +seqParams->TargetUsage << std::endl;
7754     oss << "RateControlMethod = " << std::dec << +seqParams->RateControlMethod << std::endl;
7755 
7756     for (uint8_t i = 0; i < 8; i++)
7757     {
7758         oss << "TargetBitRate[" << +i << "] = " << std::dec << +seqParams->TargetBitRate[i] << std::endl;
7759     }
7760     oss << "MaxBitRate = " << std::dec << +seqParams->MaxBitRate << std::endl;
7761     oss << "MinBitRate = " << std::dec << +seqParams->MinBitRate << std::endl;
7762     oss << "InitVBVBufferFullnessInBit = " << +seqParams->InitVBVBufferFullnessInBit << std::endl;
7763     oss << "VBVBufferSizeInBit = " << std::dec << +seqParams->VBVBufferSizeInBit << std::endl;
7764     oss << "OptimalVBVBufferLevelInBit = " << std::dec << +seqParams->OptimalVBVBufferLevelInBit << std::endl;
7765     oss << "UpperVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->UpperVBVBufferLevelThresholdInBit << std::endl;
7766     oss << "LowerVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->LowerVBVBufferLevelThresholdInBit << std::endl;
7767     oss << "DisplayFormatSwizzle = " << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl;
7768     // begining of union/struct
7769     oss << "# bResetBRC = " << std::dec << +seqParams->SeqFlags.fields.bResetBRC << std::endl;
7770     oss << "# bNoFrameHeaderInsertion = " << std::dec << +seqParams->SeqFlags.fields.bNoFrameHeaderInsertion << std::endl;
7771     // Next 5 fields not currently implemented.  nullptr output
7772     oss << "# UseRawReconRef = " << std::dec << +seqParams->SeqFlags.fields.bUseRawReconRef << std::endl;
7773     oss << "# MBBRC = " << std::dec << +seqParams->SeqFlags.fields.MBBRC << std::endl;
7774     oss << "EnableDynamicScaling = " << std::dec << +seqParams->SeqFlags.fields.EnableDynamicScaling << std::endl;
7775     oss << "SourceFormat = " << std::dec << +seqParams->SeqFlags.fields.SourceFormat << std::endl;
7776     oss << "SourceBitDepth = " << std::dec << +seqParams->SeqFlags.fields.SourceBitDepth << std::endl;
7777     oss << "EncodedFormat = " << std::dec << +seqParams->SeqFlags.fields.EncodedFormat << std::endl;
7778     oss << "EncodedBitDepth = " << std::dec << +seqParams->SeqFlags.fields.EncodedBitDepth << std::endl;
7779     oss << "DisplayFormatSwizzle = " << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl;
7780     // end of union/struct
7781 
7782     oss << "UserMaxFrameSize = " << std::dec << +seqParams->UserMaxFrameSize << std::endl;
7783     for (uint8_t i = 0; i < 8; i++)
7784     {
7785         oss << "FrameRateNumerator[" << +i << "] = " << std::dec << +seqParams->FrameRate[i].uiNumerator << std::endl;
7786         oss << "FrameRateDenominator[" << +i << "] = " << std::dec << +seqParams->FrameRate[i].uiDenominator << std::endl;
7787     }
7788 
7789     oss << "NumTemporalLayersMinus1 = " << std::dec << +seqParams->NumTemporalLayersMinus1 << std::endl;
7790 
7791     const char *fileName = m_debugInterface->CreateFileName(
7792         "_DDIEnc",
7793         CodechalDbgBufferType::bufSeqParams,
7794         CodechalDbgExtType::txt);
7795 
7796     std::ofstream ofs(fileName, std::ios::out);
7797     ofs << oss.str();
7798     ofs.close();
7799 
7800     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
7801     {
7802         if (!m_debugInterface->m_ddiFileName.empty())
7803         {
7804             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
7805             ofs << "SeqParamFile"
7806                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
7807             ofs.close();
7808         }
7809     }
7810 
7811     return MOS_STATUS_SUCCESS;
7812 }
7813 
DumpPicParams(PCODEC_VP9_ENCODE_PIC_PARAMS picParams)7814 MOS_STATUS CodechalVdencVp9State::DumpPicParams(
7815     PCODEC_VP9_ENCODE_PIC_PARAMS picParams)
7816 {
7817     CODECHAL_DEBUG_FUNCTION_ENTER;
7818 
7819     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
7820     {
7821         return MOS_STATUS_SUCCESS;
7822     }
7823 
7824     CODECHAL_DEBUG_CHK_NULL(picParams);
7825 
7826     std::ostringstream oss;
7827     oss.setf(std::ios::showbase | std::ios::uppercase);
7828 
7829     oss << "# DDI Parameters:" << std::endl;
7830     oss << "SrcFrameHeightMinus1 = " << std::dec << +picParams->SrcFrameHeightMinus1 << std::endl;
7831     oss << "SrcFrameWidthMinus1 = " << std::dec << +picParams->SrcFrameWidthMinus1 << std::endl;
7832     oss << "CurrOriginalPic = " << std::dec << +picParams->CurrOriginalPic.FrameIdx << std::endl;
7833     oss << "CurrReconstructedPic = " << std::dec << +picParams->CurrReconstructedPic.FrameIdx << std::endl;
7834 
7835     for (uint16_t i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i)
7836     {
7837         oss << "RefFrameList[" << +i << "] = " << std::dec << +picParams->RefFrameList[i].FrameIdx << std::endl;
7838     }
7839     oss << "frame_type = " << std::dec << +picParams->PicFlags.fields.frame_type << std::endl;
7840     oss << "show_frame = " << std::dec << +picParams->PicFlags.fields.show_frame << std::endl;
7841     oss << "error_resilient_mode = " << std::dec << +picParams->PicFlags.fields.error_resilient_mode << std::endl;
7842     oss << "intra_only = " << std::dec << +picParams->PicFlags.fields.intra_only << std::endl;
7843     oss << "allow_high_precision_mv = " << std::dec << +picParams->PicFlags.fields.allow_high_precision_mv << std::endl;
7844     oss << "mcomp_filter_type = " << std::dec << +picParams->PicFlags.fields.mcomp_filter_type << std::endl;
7845     oss << "frame_parallel_decoding_mode = " << std::dec << +picParams->PicFlags.fields.frame_parallel_decoding_mode << std::endl;
7846     oss << "segmentation_enabled = " << std::dec << +picParams->PicFlags.fields.segmentation_enabled << std::endl;
7847     oss << "segmentation_temporal_update = " << std::dec << +picParams->PicFlags.fields.segmentation_temporal_update << std::endl;
7848     oss << "segmentation_update_map = " << std::dec << +picParams->PicFlags.fields.segmentation_update_map << std::endl;
7849     oss << "reset_frame_context = " << std::dec << +picParams->PicFlags.fields.reset_frame_context << std::endl;
7850     oss << "refresh_frame_context = " << std::dec << +picParams->PicFlags.fields.refresh_frame_context << std::endl;
7851     oss << "frame_context_idx = " << std::dec << +picParams->PicFlags.fields.frame_context_idx << std::endl;
7852     oss << "LosslessFlag = " << std::dec << +picParams->PicFlags.fields.LosslessFlag << std::endl;
7853     oss << "comp_prediction_mode = " << std::dec << +picParams->PicFlags.fields.comp_prediction_mode << std::endl;
7854     oss << "super_frame = " << std::dec << +picParams->PicFlags.fields.super_frame << std::endl;
7855     oss << "seg_id_block_size = " << std::dec << +picParams->PicFlags.fields.seg_id_block_size << std::endl;
7856     oss << "seg_update_data = " << std::dec << +picParams->PicFlags.fields.seg_update_data << std::endl;
7857     oss << "LastRefIdx = " << std::dec << +picParams->RefFlags.fields.LastRefIdx << std::endl;
7858     oss << "LastRefSignBias = " << std::dec << +picParams->RefFlags.fields.LastRefSignBias << std::endl;
7859     oss << "GoldenRefIdx = " << std::dec << +picParams->RefFlags.fields.GoldenRefIdx << std::endl;
7860     oss << "GoldenRefSignBias = " << std::dec << +picParams->RefFlags.fields.GoldenRefSignBias << std::endl;
7861     oss << "AltRefIdx = " << std::dec << +picParams->RefFlags.fields.AltRefIdx << std::endl;
7862     oss << "AltRefSignBias = " << std::dec << +picParams->RefFlags.fields.AltRefSignBias << std::endl;
7863     oss << "ref_frame_ctrl_l0 = " << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l0 << std::endl;
7864     oss << "ref_frame_ctrl_l1 = " << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l1 << std::endl;
7865     oss << "refresh_frame_flags = " << std::dec << +picParams->RefFlags.fields.refresh_frame_flags << std::endl;
7866     oss << "LumaACQIndex = " << std::dec << +picParams->LumaACQIndex << std::endl;
7867     oss << "LumaDCQIndexDelta = " << std::dec << +picParams->LumaDCQIndexDelta << std::endl;
7868     oss << "ChromaACQIndexDelta = " << std::dec << +picParams->ChromaACQIndexDelta << std::endl;
7869     oss << "ChromaDCQIndexDelta = " << std::dec << +picParams->ChromaDCQIndexDelta << std::endl;
7870     oss << "filter_level = " << std::dec << +picParams->filter_level << std::endl;
7871     oss << "sharpness_level = " << std::dec << +picParams->sharpness_level << std::endl;
7872 
7873     for (uint8_t i = 0; i < 4; ++i)
7874     {
7875         oss << "LFRefDelta[" << +i << "] = " << std::dec << +picParams->LFRefDelta[i] << std::endl;
7876     }
7877 
7878     for (uint8_t i = 0; i < 2; ++i)
7879     {
7880         oss << "LFModeDelta[" << +i << "] = " << std::dec << +picParams->LFModeDelta[i] << std::endl;
7881     }
7882 
7883     oss << "BitOffsetForLFRefDelta = " << std::dec << +picParams->BitOffsetForLFRefDelta << std::endl;
7884     oss << "BitOffsetForLFModeDelta = " << std::dec << +picParams->BitOffsetForLFModeDelta << std::endl;
7885     oss << "BitOffsetForLFLevel = " << std::dec << +picParams->BitOffsetForLFLevel << std::endl;
7886     oss << "BitOffsetForQIndex = " << std::dec << +picParams->BitOffsetForQIndex << std::endl;
7887     oss << "BitOffsetForFirstPartitionSize = " << std::dec << +picParams->BitOffsetForFirstPartitionSize << std::endl;
7888     oss << "BitOffsetForSegmentation = " << std::dec << +picParams->BitOffsetForSegmentation << std::endl;
7889     oss << "BitSizeForSegmentation = " << std::dec << +picParams->BitSizeForSegmentation << std::endl;
7890     oss << "log2_tile_rows = " << std::dec << +picParams->log2_tile_rows << std::endl;
7891     oss << "log2_tile_columns = " << std::dec << +picParams->log2_tile_columns << std::endl;
7892     oss << "temporal_id = " << std::dec << +picParams->temporal_id << std::endl;
7893     oss << "StatusReportFeedbackNumber = " << std::dec << +picParams->StatusReportFeedbackNumber << std::endl;
7894     oss << "SkipFrameFlag = " << std::dec << +picParams->SkipFrameFlag << std::endl;
7895     oss << "NumSkipFrames = " << std::dec << +picParams->NumSkipFrames << std::endl;
7896     oss << "SizeSkipFrames = " << std::dec << +picParams->SizeSkipFrames << std::endl;
7897 
7898     const char *fileName = m_debugInterface->CreateFileName(
7899         "_DDIEnc",
7900         CodechalDbgBufferType::bufPicParams,
7901         CodechalDbgExtType::txt);
7902 
7903     std::ofstream ofs(fileName, std::ios::out);
7904     ofs << oss.str();
7905     ofs.close();
7906 
7907     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
7908     {
7909         if (!m_debugInterface->m_ddiFileName.empty())
7910         {
7911             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
7912             ofs << "PicNum"
7913                 << " = " << m_debugInterface->m_bufferDumpFrameNum << std::endl;
7914             ofs << "PicParamFile"
7915                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
7916             ofs.close();
7917         }
7918     }
7919 
7920     return MOS_STATUS_SUCCESS;
7921 }
7922 
DumpSegmentParams(PCODEC_VP9_ENCODE_SEGMENT_PARAMS segmentParams)7923 MOS_STATUS CodechalVdencVp9State::DumpSegmentParams(
7924     PCODEC_VP9_ENCODE_SEGMENT_PARAMS segmentParams)
7925 {
7926     CODECHAL_DEBUG_FUNCTION_ENTER;
7927 
7928     if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSegmentParams))
7929     {
7930         return MOS_STATUS_SUCCESS;
7931     }
7932     CODECHAL_DEBUG_CHK_NULL(segmentParams);
7933 
7934     std::ostringstream oss;
7935     oss.setf(std::ios::showbase | std::ios::uppercase);
7936 
7937     for (uint8_t i = 0; i < 8; ++i)
7938     {
7939         oss << "Segment_id = " << std::dec << +i << std::endl;
7940         oss << "SegmentReferenceEnabled = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled << std::endl;
7941         oss << "SegmentReference = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReference << std::endl;
7942         oss << "SegmentSkipped = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped << std::endl;
7943         oss << "SegmentLFLevelDelta = " << std::dec << +segmentParams->SegData[i].SegmentLFLevelDelta << std::endl;
7944         oss << "SegmentQIndexDelta = " << std::dec << +segmentParams->SegData[i].SegmentQIndexDelta << std::endl;
7945     }
7946 
7947     if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump))
7948     {
7949         if (!m_debugInterface->m_ddiFileName.empty())
7950         {
7951             std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app);
7952             ofs << "SegmentParamFileParamFile"
7953                 << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl;
7954             ofs.close();
7955         }
7956     }
7957 
7958     const char *fileName = m_debugInterface->CreateFileName(
7959         "_DDIEnc",
7960         CodechalDbgBufferType::bufSegmentParams,
7961         CodechalDbgExtType::txt);
7962 
7963     std::ofstream ofs(fileName, std::ios::out);
7964     ofs << oss.str();
7965     ofs.close();
7966 
7967     return MOS_STATUS_SUCCESS;
7968 }
7969 #endif
7970 
fill_pad_with_value(PMOS_SURFACE psSurface,uint32_t real_height,uint32_t aligned_height)7971 void CodechalVdencVp9State::fill_pad_with_value(PMOS_SURFACE psSurface, uint32_t real_height, uint32_t aligned_height)
7972 {
7973     CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(psSurface);
7974 
7975     // unaligned surfaces only
7976     if (aligned_height <= real_height || aligned_height > psSurface->dwHeight)
7977     {
7978         return;
7979     }
7980 
7981     // avoid DYS frames cases
7982     if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled)
7983     {
7984         return;
7985     }
7986 
7987     if (psSurface->OsResource.TileType == MOS_TILE_INVALID)
7988     {
7989         return;
7990     }
7991 
7992     if (psSurface->Format == Format_NV12 || psSurface->Format == Format_P010)
7993     {
7994         uint32_t pitch         = psSurface->dwPitch;
7995         uint32_t UVPlaneOffset = psSurface->UPlaneOffset.iSurfaceOffset;
7996         uint32_t YPlaneOffset  = psSurface->dwOffset;
7997         uint32_t pad_rows = aligned_height - real_height;
7998         uint32_t y_plane_size   = pitch * real_height;
7999         uint32_t uv_plane_size   = pitch * real_height / 2;
8000 
8001         MOS_LOCK_PARAMS lockFlags;
8002         MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
8003         lockFlags.WriteOnly = 1;
8004 
8005         // padding for the linear format buffer.
8006         if (psSurface->OsResource.TileType == MOS_TILE_LINEAR)
8007         {
8008             uint8_t *src_data = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
8009             CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);
8010 
8011             uint8_t *src_data_y     = src_data + YPlaneOffset;
8012             uint8_t *src_data_y_end = src_data_y + y_plane_size;
8013             for (uint32_t i = 0; i < pad_rows; i++)
8014             {
8015                 MOS_SecureMemcpy(src_data_y_end + i * pitch, pitch, src_data_y_end - pitch, pitch);
8016             }
8017 
8018             uint8_t *src_data_uv     = src_data + UVPlaneOffset;
8019             uint8_t *src_data_uv_end = src_data_uv + uv_plane_size;
8020             for (uint32_t i = 0; i < pad_rows / 2; i++)
8021             {
8022                 MOS_SecureMemcpy(src_data_uv_end + i * pitch, pitch, src_data_uv_end - pitch, pitch);
8023             }
8024 
8025             m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
8026         }
8027         else
8028         {
8029             // we don't copy out the whole tiled buffer to linear and padding on the tiled buffer directly.
8030             lockFlags.TiledAsTiled = 1;
8031 
8032             uint8_t *src_data   = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &(psSurface->OsResource), &lockFlags);
8033             CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(src_data);
8034 
8035             uint8_t* padding_data = (uint8_t *)MOS_AllocMemory(pitch * pad_rows);
8036             CODECHAL_ENCODE_CHK_NULL_NO_STATUS_RETURN(padding_data);
8037 
8038             // Copy last Y row data to linear padding data.
8039             GMM_RES_COPY_BLT    gmmResCopyBlt  = {0};
8040             gmmResCopyBlt.Gpu.pData      = src_data;
8041             gmmResCopyBlt.Gpu.OffsetX    = 0;
8042             gmmResCopyBlt.Gpu.OffsetY    = (YPlaneOffset + y_plane_size - pitch) / pitch;
8043             gmmResCopyBlt.Sys.pData      = padding_data;
8044             gmmResCopyBlt.Sys.RowPitch   = pitch;
8045             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
8046             gmmResCopyBlt.Sys.SlicePitch = pitch;
8047             gmmResCopyBlt.Blt.Slices     = 1;
8048             gmmResCopyBlt.Blt.Upload     = false;
8049             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
8050             gmmResCopyBlt.Blt.Height     = 1;
8051             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
8052             // Fill the remain padding lines with last Y row data.
8053             for (uint32_t i = 1; i < pad_rows; i++)
8054             {
8055                 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
8056             }
8057             // Filling the padding for Y.
8058             gmmResCopyBlt.Gpu.pData      = src_data;
8059             gmmResCopyBlt.Gpu.OffsetX    = 0;
8060             gmmResCopyBlt.Gpu.OffsetY    = (YPlaneOffset + y_plane_size) / pitch;
8061             gmmResCopyBlt.Sys.pData      = padding_data;
8062             gmmResCopyBlt.Sys.RowPitch   = pitch;
8063             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows;
8064             gmmResCopyBlt.Sys.SlicePitch = pitch;
8065             gmmResCopyBlt.Blt.Slices     = 1;
8066             gmmResCopyBlt.Blt.Upload     = true;
8067             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
8068             gmmResCopyBlt.Blt.Height     = pad_rows;
8069             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
8070 
8071             // Copy last UV row data to linear padding data.
8072             gmmResCopyBlt.Gpu.pData      = src_data;
8073             gmmResCopyBlt.Gpu.OffsetX    = 0;
8074             gmmResCopyBlt.Gpu.OffsetY    = (UVPlaneOffset + uv_plane_size - pitch) / pitch;
8075             gmmResCopyBlt.Sys.pData      = padding_data;
8076             gmmResCopyBlt.Sys.RowPitch   = pitch;
8077             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
8078             gmmResCopyBlt.Sys.SlicePitch = pitch;
8079             gmmResCopyBlt.Blt.Slices     = 1;
8080             gmmResCopyBlt.Blt.Upload     = false;
8081             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
8082             gmmResCopyBlt.Blt.Height     = 1;
8083             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
8084             // Fill the remain padding lines with last UV row data.
8085             for (uint32_t i = 1; i < pad_rows / 2; i++)
8086             {
8087                 MOS_SecureMemcpy(padding_data + i * pitch, pitch, padding_data, pitch);
8088             }
8089             // Filling the padding for UV.
8090             gmmResCopyBlt.Gpu.pData      = src_data;
8091             gmmResCopyBlt.Gpu.OffsetX    = 0;
8092             gmmResCopyBlt.Gpu.OffsetY    = (UVPlaneOffset + uv_plane_size) / pitch;
8093             gmmResCopyBlt.Sys.pData      = padding_data;
8094             gmmResCopyBlt.Sys.RowPitch   = pitch;
8095             gmmResCopyBlt.Sys.BufferSize = pitch * pad_rows / 2;
8096             gmmResCopyBlt.Sys.SlicePitch = pitch;
8097             gmmResCopyBlt.Blt.Slices     = 1;
8098             gmmResCopyBlt.Blt.Upload     = true;
8099             gmmResCopyBlt.Blt.Width      = psSurface->dwWidth;
8100             gmmResCopyBlt.Blt.Height     = pad_rows / 2;
8101             psSurface->OsResource.pGmmResInfo->CpuBlt(&gmmResCopyBlt);
8102 
8103             MOS_FreeMemory(padding_data);
8104             padding_data = nullptr;
8105             m_osInterface->pfnUnlockResource(m_osInterface, &(psSurface->OsResource));
8106         }
8107     }
8108 }
8109