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(©MemMemParams, 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 ©MemMemParams));
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, ¶ms));
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(©MemMemParams , 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 ©MemMemParams));
7231
7232 MOS_ZeroMemory(©MemMemParams, 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 ©MemMemParams));
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