| /* |
| * Copyright (c) 2017-2018, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| /* |
| * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| //! |
| //! \file codechal_vdenc_vp9_base.cpp |
| //! \brief Defines base class for VP9 VDENC encoder. |
| //! |
| |
| #include "codechal_vdenc_vp9_base.h" |
| #include "codechal_mmc_encode_vp9.h" |
| #include "codec_def_vp9_probs.h" |
| |
| extern const uint8_t Keyframe_Default_Probs[2048] = { |
| 0x64, 0x42, 0x14, 0x98, 0x0f, 0x65, 0x03, 0x88, 0x25, 0x05, 0x34, 0x0d, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0xc3, 0x1d, 0xb7, 0x54, 0x31, 0x88, 0x08, 0x2a, 0x47, 0x1f, 0x6b, 0xa9, 0x23, 0x63, 0x9f, 0x11, |
| 0x52, 0x8c, 0x08, 0x42, 0x72, 0x02, 0x2c, 0x4c, 0x01, 0x13, 0x20, 0x28, 0x84, 0xc9, 0x1d, 0x72, |
| 0xbb, 0x0d, 0x5b, 0x9d, 0x07, 0x4b, 0x7f, 0x03, 0x3a, 0x5f, 0x01, 0x1c, 0x2f, 0x45, 0x8e, 0xdd, |
| 0x2a, 0x7a, 0xc9, 0x0f, 0x5b, 0x9f, 0x06, 0x43, 0x79, 0x01, 0x2a, 0x4d, 0x01, 0x11, 0x1f, 0x66, |
| 0x94, 0xe4, 0x43, 0x75, 0xcc, 0x11, 0x52, 0x9a, 0x06, 0x3b, 0x72, 0x02, 0x27, 0x4b, 0x01, 0x0f, |
| 0x1d, 0x9c, 0x39, 0xe9, 0x77, 0x39, 0xd4, 0x3a, 0x30, 0xa3, 0x1d, 0x28, 0x7c, 0x0c, 0x1e, 0x51, |
| 0x03, 0x0c, 0x1f, 0xbf, 0x6b, 0xe2, 0x7c, 0x75, 0xcc, 0x19, 0x63, 0x9b, 0x1d, 0x94, 0xd2, 0x25, |
| 0x7e, 0xc2, 0x08, 0x5d, 0x9d, 0x02, 0x44, 0x76, 0x01, 0x27, 0x45, 0x01, 0x11, 0x21, 0x29, 0x97, |
| 0xd5, 0x1b, 0x7b, 0xc1, 0x03, 0x52, 0x90, 0x01, 0x3a, 0x69, 0x01, 0x20, 0x3c, 0x01, 0x0d, 0x1a, |
| 0x3b, 0x9f, 0xdc, 0x17, 0x7e, 0xc6, 0x04, 0x58, 0x97, 0x01, 0x42, 0x72, 0x01, 0x26, 0x47, 0x01, |
| 0x12, 0x22, 0x72, 0x88, 0xe8, 0x33, 0x72, 0xcf, 0x0b, 0x53, 0x9b, 0x03, 0x38, 0x69, 0x01, 0x21, |
| 0x41, 0x01, 0x11, 0x22, 0x95, 0x41, 0xea, 0x79, 0x39, 0xd7, 0x3d, 0x31, 0xa6, 0x1c, 0x24, 0x72, |
| 0x0c, 0x19, 0x4c, 0x03, 0x10, 0x2a, 0xd6, 0x31, 0xdc, 0x84, 0x3f, 0xbc, 0x2a, 0x41, 0x89, 0x55, |
| 0x89, 0xdd, 0x68, 0x83, 0xd8, 0x31, 0x6f, 0xc0, 0x15, 0x57, 0x9b, 0x02, 0x31, 0x57, 0x01, 0x10, |
| 0x1c, 0x59, 0xa3, 0xe6, 0x5a, 0x89, 0xdc, 0x1d, 0x64, 0xb7, 0x0a, 0x46, 0x87, 0x02, 0x2a, 0x51, |
| 0x01, 0x11, 0x21, 0x6c, 0xa7, 0xed, 0x37, 0x85, 0xde, 0x0f, 0x61, 0xb3, 0x04, 0x48, 0x87, 0x01, |
| 0x2d, 0x55, 0x01, 0x13, 0x26, 0x7c, 0x92, 0xf0, 0x42, 0x7c, 0xe0, 0x11, 0x58, 0xaf, 0x04, 0x3a, |
| 0x7a, 0x01, 0x24, 0x4b, 0x01, 0x12, 0x25, 0x8d, 0x4f, 0xf1, 0x7e, 0x46, 0xe3, 0x42, 0x3a, 0xb6, |
| 0x1e, 0x2c, 0x88, 0x0c, 0x22, 0x60, 0x02, 0x14, 0x2f, 0xe5, 0x63, 0xf9, 0x8f, 0x6f, 0xeb, 0x2e, |
| 0x6d, 0xc0, 0x52, 0x9e, 0xec, 0x5e, 0x92, 0xe0, 0x19, 0x75, 0xbf, 0x09, 0x57, 0x95, 0x03, 0x38, |
| 0x63, 0x01, 0x21, 0x39, 0x53, 0xa7, 0xed, 0x44, 0x91, 0xde, 0x0a, 0x67, 0xb1, 0x02, 0x48, 0x83, |
| 0x01, 0x29, 0x4f, 0x01, 0x14, 0x27, 0x63, 0xa7, 0xef, 0x2f, 0x8d, 0xe0, 0x0a, 0x68, 0xb2, 0x02, |
| 0x49, 0x85, 0x01, 0x2c, 0x55, 0x01, 0x16, 0x2f, 0x7f, 0x91, 0xf3, 0x47, 0x81, 0xe4, 0x11, 0x5d, |
| 0xb1, 0x03, 0x3d, 0x7c, 0x01, 0x29, 0x54, 0x01, 0x15, 0x34, 0x9d, 0x4e, 0xf4, 0x8c, 0x48, 0xe7, |
| 0x45, 0x3a, 0xb8, 0x1f, 0x2c, 0x89, 0x0e, 0x26, 0x69, 0x08, 0x17, 0x3d, 0x7d, 0x22, 0xbb, 0x34, |
| 0x29, 0x85, 0x06, 0x1f, 0x38, 0x25, 0x6d, 0x99, 0x33, 0x66, 0x93, 0x17, 0x57, 0x80, 0x08, 0x43, |
| 0x65, 0x01, 0x29, 0x3f, 0x01, 0x13, 0x1d, 0x1f, 0x9a, 0xb9, 0x11, 0x7f, 0xaf, 0x06, 0x60, 0x91, |
| 0x02, 0x49, 0x72, 0x01, 0x33, 0x52, 0x01, 0x1c, 0x2d, 0x17, 0xa3, 0xc8, 0x0a, 0x83, 0xb9, 0x02, |
| 0x5d, 0x94, 0x01, 0x43, 0x6f, 0x01, 0x29, 0x45, 0x01, 0x0e, 0x18, 0x1d, 0xb0, 0xd9, 0x0c, 0x91, |
| 0xc9, 0x03, 0x65, 0x9c, 0x01, 0x45, 0x6f, 0x01, 0x27, 0x3f, 0x01, 0x0e, 0x17, 0x39, 0xc0, 0xe9, |
| 0x19, 0x9a, 0xd7, 0x06, 0x6d, 0xa7, 0x03, 0x4e, 0x76, 0x01, 0x30, 0x45, 0x01, 0x15, 0x1d, 0xca, |
| 0x69, 0xf5, 0x6c, 0x6a, 0xd8, 0x12, 0x5a, 0x90, 0x21, 0xac, 0xdb, 0x40, 0x95, 0xce, 0x0e, 0x75, |
| 0xb1, 0x05, 0x5a, 0x8d, 0x02, 0x3d, 0x5f, 0x01, 0x25, 0x39, 0x21, 0xb3, 0xdc, 0x0b, 0x8c, 0xc6, |
| 0x01, 0x59, 0x94, 0x01, 0x3c, 0x68, 0x01, 0x21, 0x39, 0x01, 0x0c, 0x15, 0x1e, 0xb5, 0xdd, 0x08, |
| 0x8d, 0xc6, 0x01, 0x57, 0x91, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x14, 0x20, 0xba, |
| 0xe0, 0x07, 0x8e, 0xc6, 0x01, 0x56, 0x8f, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x16, |
| 0x39, 0xc0, 0xe3, 0x14, 0x8f, 0xcc, 0x03, 0x60, 0x9a, 0x01, 0x44, 0x70, 0x01, 0x2a, 0x45, 0x01, |
| 0x13, 0x20, 0xd4, 0x23, 0xd7, 0x71, 0x2f, 0xa9, 0x1d, 0x30, 0x69, 0x4a, 0x81, 0xcb, 0x6a, 0x78, |
| 0xcb, 0x31, 0x6b, 0xb2, 0x13, 0x54, 0x90, 0x04, 0x32, 0x54, 0x01, 0x0f, 0x19, 0x47, 0xac, 0xd9, |
| 0x2c, 0x8d, 0xd1, 0x0f, 0x66, 0xad, 0x06, 0x4c, 0x85, 0x02, 0x33, 0x59, 0x01, 0x18, 0x2a, 0x40, |
| 0xb9, 0xe7, 0x1f, 0x94, 0xd8, 0x08, 0x67, 0xaf, 0x03, 0x4a, 0x83, 0x01, 0x2e, 0x51, 0x01, 0x12, |
| 0x1e, 0x41, 0xc4, 0xeb, 0x19, 0x9d, 0xdd, 0x05, 0x69, 0xae, 0x01, 0x43, 0x78, 0x01, 0x26, 0x45, |
| 0x01, 0x0f, 0x1e, 0x41, 0xcc, 0xee, 0x1e, 0x9c, 0xe0, 0x07, 0x6b, 0xb1, 0x02, 0x46, 0x7c, 0x01, |
| 0x2a, 0x49, 0x01, 0x12, 0x22, 0xe1, 0x56, 0xfb, 0x90, 0x68, 0xeb, 0x2a, 0x63, 0xb5, 0x55, 0xaf, |
| 0xef, 0x70, 0xa5, 0xe5, 0x1d, 0x88, 0xc8, 0x0c, 0x67, 0xa2, 0x06, 0x4d, 0x7b, 0x02, 0x35, 0x54, |
| 0x4b, 0xb7, 0xef, 0x1e, 0x9b, 0xdd, 0x03, 0x6a, 0xab, 0x01, 0x4a, 0x80, 0x01, 0x2c, 0x4c, 0x01, |
| 0x11, 0x1c, 0x49, 0xb9, 0xf0, 0x1b, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x4b, 0x7f, 0x01, 0x2a, |
| 0x49, 0x01, 0x11, 0x1d, 0x3e, 0xbe, 0xee, 0x15, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x48, 0x7a, |
| 0x01, 0x28, 0x47, 0x01, 0x12, 0x20, 0x3d, 0xc7, 0xf0, 0x1b, 0xa1, 0xe2, 0x04, 0x71, 0xb4, 0x01, |
| 0x4c, 0x81, 0x01, 0x2e, 0x50, 0x01, 0x17, 0x29, 0x07, 0x1b, 0x99, 0x05, 0x1e, 0x5f, 0x01, 0x10, |
| 0x1e, 0x32, 0x4b, 0x7f, 0x39, 0x4b, 0x7c, 0x1b, 0x43, 0x6c, 0x0a, 0x36, 0x56, 0x01, 0x21, 0x34, |
| 0x01, 0x0c, 0x12, 0x2b, 0x7d, 0x97, 0x1a, 0x6c, 0x94, 0x07, 0x53, 0x7a, 0x02, 0x3b, 0x59, 0x01, |
| 0x26, 0x3c, 0x01, 0x11, 0x1b, 0x17, 0x90, 0xa3, 0x0d, 0x70, 0x9a, 0x02, 0x4b, 0x75, 0x01, 0x32, |
| 0x51, 0x01, 0x1f, 0x33, 0x01, 0x0e, 0x17, 0x12, 0xa2, 0xb9, 0x06, 0x7b, 0xab, 0x01, 0x4e, 0x7d, |
| 0x01, 0x33, 0x56, 0x01, 0x1f, 0x36, 0x01, 0x0e, 0x17, 0x0f, 0xc7, 0xe3, 0x03, 0x96, 0xcc, 0x01, |
| 0x5b, 0x92, 0x01, 0x37, 0x5f, 0x01, 0x1e, 0x35, 0x01, 0x0b, 0x14, 0x13, 0x37, 0xf0, 0x13, 0x3b, |
| 0xc4, 0x03, 0x34, 0x69, 0x29, 0xa6, 0xcf, 0x68, 0x99, 0xc7, 0x1f, 0x7b, 0xb5, 0x0e, 0x65, 0x98, |
| 0x05, 0x48, 0x6a, 0x01, 0x24, 0x34, 0x23, 0xb0, 0xd3, 0x0c, 0x83, 0xbe, 0x02, 0x58, 0x90, 0x01, |
| 0x3c, 0x65, 0x01, 0x24, 0x3c, 0x01, 0x10, 0x1c, 0x1c, 0xb7, 0xd5, 0x08, 0x86, 0xbf, 0x01, 0x56, |
| 0x8e, 0x01, 0x38, 0x60, 0x01, 0x1e, 0x35, 0x01, 0x0c, 0x14, 0x14, 0xbe, 0xd7, 0x04, 0x87, 0xc0, |
| 0x01, 0x54, 0x8b, 0x01, 0x35, 0x5b, 0x01, 0x1c, 0x31, 0x01, 0x0b, 0x14, 0x0d, 0xc4, 0xd8, 0x02, |
| 0x89, 0xc0, 0x01, 0x56, 0x8f, 0x01, 0x39, 0x63, 0x01, 0x20, 0x38, 0x01, 0x0d, 0x18, 0xd3, 0x1d, |
| 0xd9, 0x60, 0x2f, 0x9c, 0x16, 0x2b, 0x57, 0x4e, 0x78, 0xc1, 0x6f, 0x74, 0xba, 0x2e, 0x66, 0xa4, |
| 0x0f, 0x50, 0x80, 0x02, 0x31, 0x4c, 0x01, 0x12, 0x1c, 0x47, 0xa1, 0xcb, 0x2a, 0x84, 0xc0, 0x0a, |
| 0x62, 0x96, 0x03, 0x45, 0x6d, 0x01, 0x2c, 0x46, 0x01, 0x12, 0x1d, 0x39, 0xba, 0xd3, 0x1e, 0x8c, |
| 0xc4, 0x04, 0x5d, 0x92, 0x01, 0x3e, 0x66, 0x01, 0x26, 0x41, 0x01, 0x10, 0x1b, 0x2f, 0xc7, 0xd9, |
| 0x0e, 0x91, 0xc4, 0x01, 0x58, 0x8e, 0x01, 0x39, 0x62, 0x01, 0x24, 0x3e, 0x01, 0x0f, 0x1a, 0x1a, |
| 0xdb, 0xe5, 0x05, 0x9b, 0xcf, 0x01, 0x5e, 0x97, 0x01, 0x3c, 0x68, 0x01, 0x24, 0x3e, 0x01, 0x10, |
| 0x1c, 0xe9, 0x1d, 0xf8, 0x92, 0x2f, 0xdc, 0x2b, 0x34, 0x8c, 0x64, 0xa3, 0xe8, 0xb3, 0xa1, 0xde, |
| 0x3f, 0x8e, 0xcc, 0x25, 0x71, 0xae, 0x1a, 0x59, 0x89, 0x12, 0x44, 0x61, 0x55, 0xb5, 0xe6, 0x20, |
| 0x92, 0xd1, 0x07, 0x64, 0xa4, 0x03, 0x47, 0x79, 0x01, 0x2d, 0x4d, 0x01, 0x12, 0x1e, 0x41, 0xbb, |
| 0xe6, 0x14, 0x94, 0xcf, 0x02, 0x61, 0x9f, 0x01, 0x44, 0x74, 0x01, 0x28, 0x46, 0x01, 0x0e, 0x1d, |
| 0x28, 0xc2, 0xe3, 0x08, 0x93, 0xcc, 0x01, 0x5e, 0x9b, 0x01, 0x41, 0x70, 0x01, 0x27, 0x42, 0x01, |
| 0x0e, 0x1a, 0x10, 0xd0, 0xe4, 0x03, 0x97, 0xcf, 0x01, 0x62, 0xa0, 0x01, 0x43, 0x75, 0x01, 0x29, |
| 0x4a, 0x01, 0x11, 0x1f, 0x11, 0x26, 0x8c, 0x07, 0x22, 0x50, 0x01, 0x11, 0x1d, 0x25, 0x4b, 0x80, |
| 0x29, 0x4c, 0x80, 0x1a, 0x42, 0x74, 0x0c, 0x34, 0x5e, 0x02, 0x20, 0x37, 0x01, 0x0a, 0x10, 0x32, |
| 0x7f, 0x9a, 0x25, 0x6d, 0x98, 0x10, 0x52, 0x79, 0x05, 0x3b, 0x55, 0x01, 0x23, 0x36, 0x01, 0x0d, |
| 0x14, 0x28, 0x8e, 0xa7, 0x11, 0x6e, 0x9d, 0x02, 0x47, 0x70, 0x01, 0x2c, 0x48, 0x01, 0x1b, 0x2d, |
| 0x01, 0x0b, 0x11, 0x1e, 0xaf, 0xbc, 0x09, 0x7c, 0xa9, 0x01, 0x4a, 0x74, 0x01, 0x30, 0x4e, 0x01, |
| 0x1e, 0x31, 0x01, 0x0b, 0x12, 0x0a, 0xde, 0xdf, 0x02, 0x96, 0xc2, 0x01, 0x53, 0x80, 0x01, 0x30, |
| 0x4f, 0x01, 0x1b, 0x2d, 0x01, 0x0b, 0x11, 0x24, 0x29, 0xeb, 0x1d, 0x24, 0xc1, 0x0a, 0x1b, 0x6f, |
| 0x55, 0xa5, 0xde, 0xb1, 0xa2, 0xd7, 0x6e, 0x87, 0xc3, 0x39, 0x71, 0xa8, 0x17, 0x53, 0x78, 0x0a, |
| 0x31, 0x3d, 0x55, 0xbe, 0xdf, 0x24, 0x8b, 0xc8, 0x05, 0x5a, 0x92, 0x01, 0x3c, 0x67, 0x01, 0x26, |
| 0x41, 0x01, 0x12, 0x1e, 0x48, 0xca, 0xdf, 0x17, 0x8d, 0xc7, 0x02, 0x56, 0x8c, 0x01, 0x38, 0x61, |
| 0x01, 0x24, 0x3d, 0x01, 0x10, 0x1b, 0x37, 0xda, 0xe1, 0x0d, 0x91, 0xc8, 0x01, 0x56, 0x8d, 0x01, |
| 0x39, 0x63, 0x01, 0x23, 0x3d, 0x01, 0x0d, 0x16, 0x0f, 0xeb, 0xd4, 0x01, 0x84, 0xb8, 0x01, 0x54, |
| 0x8b, 0x01, 0x39, 0x61, 0x01, 0x22, 0x38, 0x01, 0x0e, 0x17, 0xb5, 0x15, 0xc9, 0x3d, 0x25, 0x7b, |
| 0x0a, 0x26, 0x47, 0x2f, 0x6a, 0xac, 0x5f, 0x68, 0xad, 0x2a, 0x5d, 0x9f, 0x12, 0x4d, 0x83, 0x04, |
| 0x32, 0x51, 0x01, 0x11, 0x17, 0x3e, 0x93, 0xc7, 0x2c, 0x82, 0xbd, 0x1c, 0x66, 0x9a, 0x12, 0x4b, |
| 0x73, 0x02, 0x2c, 0x41, 0x01, 0x0c, 0x13, 0x37, 0x99, 0xd2, 0x18, 0x82, 0xc2, 0x03, 0x5d, 0x92, |
| 0x01, 0x3d, 0x61, 0x01, 0x1f, 0x32, 0x01, 0x0a, 0x10, 0x31, 0xba, 0xdf, 0x11, 0x94, 0xcc, 0x01, |
| 0x60, 0x8e, 0x01, 0x35, 0x53, 0x01, 0x1a, 0x2c, 0x01, 0x0b, 0x11, 0x0d, 0xd9, 0xd4, 0x02, 0x88, |
| 0xb4, 0x01, 0x4e, 0x7c, 0x01, 0x32, 0x53, 0x01, 0x1d, 0x31, 0x01, 0x0e, 0x17, 0xc5, 0x0d, 0xf7, |
| 0x52, 0x11, 0xde, 0x19, 0x11, 0xa2, 0x7e, 0xba, 0xf7, 0xea, 0xbf, 0xf3, 0xb0, 0xb1, 0xea, 0x68, |
| 0x9e, 0xdc, 0x42, 0x80, 0xba, 0x37, 0x5a, 0x89, 0x6f, 0xc5, 0xf2, 0x2e, 0x9e, 0xdb, 0x09, 0x68, |
| 0xab, 0x02, 0x41, 0x7d, 0x01, 0x2c, 0x50, 0x01, 0x11, 0x5b, 0x68, 0xd0, 0xf5, 0x27, 0xa8, 0xe0, |
| 0x03, 0x6d, 0xa2, 0x01, 0x4f, 0x7c, 0x01, 0x32, 0x66, 0x01, 0x2b, 0x66, 0x54, 0xdc, 0xf6, 0x1f, |
| 0xb1, 0xe7, 0x02, 0x73, 0xb4, 0x01, 0x4f, 0x86, 0x01, 0x37, 0x4d, 0x01, 0x3c, 0x4f, 0x2b, 0xf3, |
| 0xf0, 0x08, 0xb4, 0xd9, 0x01, 0x73, 0xa6, 0x01, 0x54, 0x79, 0x01, 0x33, 0x43, 0x01, 0x10, 0x06, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0xc0, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x61, 0x5e, 0x5d, |
| 0x18, 0x63, 0x55, 0x77, 0x2c, 0x3e, 0x3b, 0x43, 0x95, 0x35, 0x35, 0x5e, 0x14, 0x30, 0x53, 0x35, |
| 0x18, 0x34, 0x12, 0x12, 0x96, 0x28, 0x27, 0x4e, 0x0c, 0x1a, 0x43, 0x21, 0x0b, 0x18, 0x07, 0x05, |
| 0xae, 0x23, 0x31, 0x44, 0x0b, 0x1b, 0x39, 0x0f, 0x09, 0x0c, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x90, 0x0b, 0x36, 0x9d, 0xc3, 0x82, 0x2e, 0x3a, 0x6c, 0x76, 0x0f, 0x7b, 0x94, 0x83, 0x65, 0x2c, |
| 0x5d, 0x83, 0x71, 0x0c, 0x17, 0xbc, 0xe2, 0x8e, 0x1a, 0x20, 0x7d, 0x78, 0x0b, 0x32, 0x7b, 0xa3, |
| 0x87, 0x40, 0x4d, 0x67, 0x71, 0x09, 0x24, 0x9b, 0x6f, 0x9d, 0x20, 0x2c, 0xa1, 0x74, 0x09, 0x37, |
| 0xb0, 0x4c, 0x60, 0x25, 0x3d, 0x95, 0x73, 0x09, 0x1c, 0x8d, 0xa1, 0xa7, 0x15, 0x19, 0xc1, 0x78, |
| 0x0c, 0x20, 0x91, 0xc3, 0x8e, 0x20, 0x26, 0x56, 0x74, 0x0c, 0x40, 0x78, 0x8c, 0x7d, 0x31, 0x73, |
| 0x79, 0x66, 0x13, 0x42, 0xa2, 0xb6, 0x7a, 0x23, 0x3b, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| }; |
| |
| extern const uint8_t Inter_Default_Probs[2048] = { |
| 0x64, 0x42, 0x14, 0x98, 0x0f, 0x65, 0x03, 0x88, 0x25, 0x05, 0x34, 0x0d, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0xc3, 0x1d, 0xb7, 0x54, 0x31, 0x88, 0x08, 0x2a, 0x47, 0x1f, 0x6b, 0xa9, 0x23, 0x63, 0x9f, 0x11, |
| 0x52, 0x8c, 0x08, 0x42, 0x72, 0x02, 0x2c, 0x4c, 0x01, 0x13, 0x20, 0x28, 0x84, 0xc9, 0x1d, 0x72, |
| 0xbb, 0x0d, 0x5b, 0x9d, 0x07, 0x4b, 0x7f, 0x03, 0x3a, 0x5f, 0x01, 0x1c, 0x2f, 0x45, 0x8e, 0xdd, |
| 0x2a, 0x7a, 0xc9, 0x0f, 0x5b, 0x9f, 0x06, 0x43, 0x79, 0x01, 0x2a, 0x4d, 0x01, 0x11, 0x1f, 0x66, |
| 0x94, 0xe4, 0x43, 0x75, 0xcc, 0x11, 0x52, 0x9a, 0x06, 0x3b, 0x72, 0x02, 0x27, 0x4b, 0x01, 0x0f, |
| 0x1d, 0x9c, 0x39, 0xe9, 0x77, 0x39, 0xd4, 0x3a, 0x30, 0xa3, 0x1d, 0x28, 0x7c, 0x0c, 0x1e, 0x51, |
| 0x03, 0x0c, 0x1f, 0xbf, 0x6b, 0xe2, 0x7c, 0x75, 0xcc, 0x19, 0x63, 0x9b, 0x1d, 0x94, 0xd2, 0x25, |
| 0x7e, 0xc2, 0x08, 0x5d, 0x9d, 0x02, 0x44, 0x76, 0x01, 0x27, 0x45, 0x01, 0x11, 0x21, 0x29, 0x97, |
| 0xd5, 0x1b, 0x7b, 0xc1, 0x03, 0x52, 0x90, 0x01, 0x3a, 0x69, 0x01, 0x20, 0x3c, 0x01, 0x0d, 0x1a, |
| 0x3b, 0x9f, 0xdc, 0x17, 0x7e, 0xc6, 0x04, 0x58, 0x97, 0x01, 0x42, 0x72, 0x01, 0x26, 0x47, 0x01, |
| 0x12, 0x22, 0x72, 0x88, 0xe8, 0x33, 0x72, 0xcf, 0x0b, 0x53, 0x9b, 0x03, 0x38, 0x69, 0x01, 0x21, |
| 0x41, 0x01, 0x11, 0x22, 0x95, 0x41, 0xea, 0x79, 0x39, 0xd7, 0x3d, 0x31, 0xa6, 0x1c, 0x24, 0x72, |
| 0x0c, 0x19, 0x4c, 0x03, 0x10, 0x2a, 0xd6, 0x31, 0xdc, 0x84, 0x3f, 0xbc, 0x2a, 0x41, 0x89, 0x55, |
| 0x89, 0xdd, 0x68, 0x83, 0xd8, 0x31, 0x6f, 0xc0, 0x15, 0x57, 0x9b, 0x02, 0x31, 0x57, 0x01, 0x10, |
| 0x1c, 0x59, 0xa3, 0xe6, 0x5a, 0x89, 0xdc, 0x1d, 0x64, 0xb7, 0x0a, 0x46, 0x87, 0x02, 0x2a, 0x51, |
| 0x01, 0x11, 0x21, 0x6c, 0xa7, 0xed, 0x37, 0x85, 0xde, 0x0f, 0x61, 0xb3, 0x04, 0x48, 0x87, 0x01, |
| 0x2d, 0x55, 0x01, 0x13, 0x26, 0x7c, 0x92, 0xf0, 0x42, 0x7c, 0xe0, 0x11, 0x58, 0xaf, 0x04, 0x3a, |
| 0x7a, 0x01, 0x24, 0x4b, 0x01, 0x12, 0x25, 0x8d, 0x4f, 0xf1, 0x7e, 0x46, 0xe3, 0x42, 0x3a, 0xb6, |
| 0x1e, 0x2c, 0x88, 0x0c, 0x22, 0x60, 0x02, 0x14, 0x2f, 0xe5, 0x63, 0xf9, 0x8f, 0x6f, 0xeb, 0x2e, |
| 0x6d, 0xc0, 0x52, 0x9e, 0xec, 0x5e, 0x92, 0xe0, 0x19, 0x75, 0xbf, 0x09, 0x57, 0x95, 0x03, 0x38, |
| 0x63, 0x01, 0x21, 0x39, 0x53, 0xa7, 0xed, 0x44, 0x91, 0xde, 0x0a, 0x67, 0xb1, 0x02, 0x48, 0x83, |
| 0x01, 0x29, 0x4f, 0x01, 0x14, 0x27, 0x63, 0xa7, 0xef, 0x2f, 0x8d, 0xe0, 0x0a, 0x68, 0xb2, 0x02, |
| 0x49, 0x85, 0x01, 0x2c, 0x55, 0x01, 0x16, 0x2f, 0x7f, 0x91, 0xf3, 0x47, 0x81, 0xe4, 0x11, 0x5d, |
| 0xb1, 0x03, 0x3d, 0x7c, 0x01, 0x29, 0x54, 0x01, 0x15, 0x34, 0x9d, 0x4e, 0xf4, 0x8c, 0x48, 0xe7, |
| 0x45, 0x3a, 0xb8, 0x1f, 0x2c, 0x89, 0x0e, 0x26, 0x69, 0x08, 0x17, 0x3d, 0x7d, 0x22, 0xbb, 0x34, |
| 0x29, 0x85, 0x06, 0x1f, 0x38, 0x25, 0x6d, 0x99, 0x33, 0x66, 0x93, 0x17, 0x57, 0x80, 0x08, 0x43, |
| 0x65, 0x01, 0x29, 0x3f, 0x01, 0x13, 0x1d, 0x1f, 0x9a, 0xb9, 0x11, 0x7f, 0xaf, 0x06, 0x60, 0x91, |
| 0x02, 0x49, 0x72, 0x01, 0x33, 0x52, 0x01, 0x1c, 0x2d, 0x17, 0xa3, 0xc8, 0x0a, 0x83, 0xb9, 0x02, |
| 0x5d, 0x94, 0x01, 0x43, 0x6f, 0x01, 0x29, 0x45, 0x01, 0x0e, 0x18, 0x1d, 0xb0, 0xd9, 0x0c, 0x91, |
| 0xc9, 0x03, 0x65, 0x9c, 0x01, 0x45, 0x6f, 0x01, 0x27, 0x3f, 0x01, 0x0e, 0x17, 0x39, 0xc0, 0xe9, |
| 0x19, 0x9a, 0xd7, 0x06, 0x6d, 0xa7, 0x03, 0x4e, 0x76, 0x01, 0x30, 0x45, 0x01, 0x15, 0x1d, 0xca, |
| 0x69, 0xf5, 0x6c, 0x6a, 0xd8, 0x12, 0x5a, 0x90, 0x21, 0xac, 0xdb, 0x40, 0x95, 0xce, 0x0e, 0x75, |
| 0xb1, 0x05, 0x5a, 0x8d, 0x02, 0x3d, 0x5f, 0x01, 0x25, 0x39, 0x21, 0xb3, 0xdc, 0x0b, 0x8c, 0xc6, |
| 0x01, 0x59, 0x94, 0x01, 0x3c, 0x68, 0x01, 0x21, 0x39, 0x01, 0x0c, 0x15, 0x1e, 0xb5, 0xdd, 0x08, |
| 0x8d, 0xc6, 0x01, 0x57, 0x91, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x14, 0x20, 0xba, |
| 0xe0, 0x07, 0x8e, 0xc6, 0x01, 0x56, 0x8f, 0x01, 0x3a, 0x64, 0x01, 0x1f, 0x37, 0x01, 0x0c, 0x16, |
| 0x39, 0xc0, 0xe3, 0x14, 0x8f, 0xcc, 0x03, 0x60, 0x9a, 0x01, 0x44, 0x70, 0x01, 0x2a, 0x45, 0x01, |
| 0x13, 0x20, 0xd4, 0x23, 0xd7, 0x71, 0x2f, 0xa9, 0x1d, 0x30, 0x69, 0x4a, 0x81, 0xcb, 0x6a, 0x78, |
| 0xcb, 0x31, 0x6b, 0xb2, 0x13, 0x54, 0x90, 0x04, 0x32, 0x54, 0x01, 0x0f, 0x19, 0x47, 0xac, 0xd9, |
| 0x2c, 0x8d, 0xd1, 0x0f, 0x66, 0xad, 0x06, 0x4c, 0x85, 0x02, 0x33, 0x59, 0x01, 0x18, 0x2a, 0x40, |
| 0xb9, 0xe7, 0x1f, 0x94, 0xd8, 0x08, 0x67, 0xaf, 0x03, 0x4a, 0x83, 0x01, 0x2e, 0x51, 0x01, 0x12, |
| 0x1e, 0x41, 0xc4, 0xeb, 0x19, 0x9d, 0xdd, 0x05, 0x69, 0xae, 0x01, 0x43, 0x78, 0x01, 0x26, 0x45, |
| 0x01, 0x0f, 0x1e, 0x41, 0xcc, 0xee, 0x1e, 0x9c, 0xe0, 0x07, 0x6b, 0xb1, 0x02, 0x46, 0x7c, 0x01, |
| 0x2a, 0x49, 0x01, 0x12, 0x22, 0xe1, 0x56, 0xfb, 0x90, 0x68, 0xeb, 0x2a, 0x63, 0xb5, 0x55, 0xaf, |
| 0xef, 0x70, 0xa5, 0xe5, 0x1d, 0x88, 0xc8, 0x0c, 0x67, 0xa2, 0x06, 0x4d, 0x7b, 0x02, 0x35, 0x54, |
| 0x4b, 0xb7, 0xef, 0x1e, 0x9b, 0xdd, 0x03, 0x6a, 0xab, 0x01, 0x4a, 0x80, 0x01, 0x2c, 0x4c, 0x01, |
| 0x11, 0x1c, 0x49, 0xb9, 0xf0, 0x1b, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x4b, 0x7f, 0x01, 0x2a, |
| 0x49, 0x01, 0x11, 0x1d, 0x3e, 0xbe, 0xee, 0x15, 0x9f, 0xde, 0x02, 0x6b, 0xac, 0x01, 0x48, 0x7a, |
| 0x01, 0x28, 0x47, 0x01, 0x12, 0x20, 0x3d, 0xc7, 0xf0, 0x1b, 0xa1, 0xe2, 0x04, 0x71, 0xb4, 0x01, |
| 0x4c, 0x81, 0x01, 0x2e, 0x50, 0x01, 0x17, 0x29, 0x07, 0x1b, 0x99, 0x05, 0x1e, 0x5f, 0x01, 0x10, |
| 0x1e, 0x32, 0x4b, 0x7f, 0x39, 0x4b, 0x7c, 0x1b, 0x43, 0x6c, 0x0a, 0x36, 0x56, 0x01, 0x21, 0x34, |
| 0x01, 0x0c, 0x12, 0x2b, 0x7d, 0x97, 0x1a, 0x6c, 0x94, 0x07, 0x53, 0x7a, 0x02, 0x3b, 0x59, 0x01, |
| 0x26, 0x3c, 0x01, 0x11, 0x1b, 0x17, 0x90, 0xa3, 0x0d, 0x70, 0x9a, 0x02, 0x4b, 0x75, 0x01, 0x32, |
| 0x51, 0x01, 0x1f, 0x33, 0x01, 0x0e, 0x17, 0x12, 0xa2, 0xb9, 0x06, 0x7b, 0xab, 0x01, 0x4e, 0x7d, |
| 0x01, 0x33, 0x56, 0x01, 0x1f, 0x36, 0x01, 0x0e, 0x17, 0x0f, 0xc7, 0xe3, 0x03, 0x96, 0xcc, 0x01, |
| 0x5b, 0x92, 0x01, 0x37, 0x5f, 0x01, 0x1e, 0x35, 0x01, 0x0b, 0x14, 0x13, 0x37, 0xf0, 0x13, 0x3b, |
| 0xc4, 0x03, 0x34, 0x69, 0x29, 0xa6, 0xcf, 0x68, 0x99, 0xc7, 0x1f, 0x7b, 0xb5, 0x0e, 0x65, 0x98, |
| 0x05, 0x48, 0x6a, 0x01, 0x24, 0x34, 0x23, 0xb0, 0xd3, 0x0c, 0x83, 0xbe, 0x02, 0x58, 0x90, 0x01, |
| 0x3c, 0x65, 0x01, 0x24, 0x3c, 0x01, 0x10, 0x1c, 0x1c, 0xb7, 0xd5, 0x08, 0x86, 0xbf, 0x01, 0x56, |
| 0x8e, 0x01, 0x38, 0x60, 0x01, 0x1e, 0x35, 0x01, 0x0c, 0x14, 0x14, 0xbe, 0xd7, 0x04, 0x87, 0xc0, |
| 0x01, 0x54, 0x8b, 0x01, 0x35, 0x5b, 0x01, 0x1c, 0x31, 0x01, 0x0b, 0x14, 0x0d, 0xc4, 0xd8, 0x02, |
| 0x89, 0xc0, 0x01, 0x56, 0x8f, 0x01, 0x39, 0x63, 0x01, 0x20, 0x38, 0x01, 0x0d, 0x18, 0xd3, 0x1d, |
| 0xd9, 0x60, 0x2f, 0x9c, 0x16, 0x2b, 0x57, 0x4e, 0x78, 0xc1, 0x6f, 0x74, 0xba, 0x2e, 0x66, 0xa4, |
| 0x0f, 0x50, 0x80, 0x02, 0x31, 0x4c, 0x01, 0x12, 0x1c, 0x47, 0xa1, 0xcb, 0x2a, 0x84, 0xc0, 0x0a, |
| 0x62, 0x96, 0x03, 0x45, 0x6d, 0x01, 0x2c, 0x46, 0x01, 0x12, 0x1d, 0x39, 0xba, 0xd3, 0x1e, 0x8c, |
| 0xc4, 0x04, 0x5d, 0x92, 0x01, 0x3e, 0x66, 0x01, 0x26, 0x41, 0x01, 0x10, 0x1b, 0x2f, 0xc7, 0xd9, |
| 0x0e, 0x91, 0xc4, 0x01, 0x58, 0x8e, 0x01, 0x39, 0x62, 0x01, 0x24, 0x3e, 0x01, 0x0f, 0x1a, 0x1a, |
| 0xdb, 0xe5, 0x05, 0x9b, 0xcf, 0x01, 0x5e, 0x97, 0x01, 0x3c, 0x68, 0x01, 0x24, 0x3e, 0x01, 0x10, |
| 0x1c, 0xe9, 0x1d, 0xf8, 0x92, 0x2f, 0xdc, 0x2b, 0x34, 0x8c, 0x64, 0xa3, 0xe8, 0xb3, 0xa1, 0xde, |
| 0x3f, 0x8e, 0xcc, 0x25, 0x71, 0xae, 0x1a, 0x59, 0x89, 0x12, 0x44, 0x61, 0x55, 0xb5, 0xe6, 0x20, |
| 0x92, 0xd1, 0x07, 0x64, 0xa4, 0x03, 0x47, 0x79, 0x01, 0x2d, 0x4d, 0x01, 0x12, 0x1e, 0x41, 0xbb, |
| 0xe6, 0x14, 0x94, 0xcf, 0x02, 0x61, 0x9f, 0x01, 0x44, 0x74, 0x01, 0x28, 0x46, 0x01, 0x0e, 0x1d, |
| 0x28, 0xc2, 0xe3, 0x08, 0x93, 0xcc, 0x01, 0x5e, 0x9b, 0x01, 0x41, 0x70, 0x01, 0x27, 0x42, 0x01, |
| 0x0e, 0x1a, 0x10, 0xd0, 0xe4, 0x03, 0x97, 0xcf, 0x01, 0x62, 0xa0, 0x01, 0x43, 0x75, 0x01, 0x29, |
| 0x4a, 0x01, 0x11, 0x1f, 0x11, 0x26, 0x8c, 0x07, 0x22, 0x50, 0x01, 0x11, 0x1d, 0x25, 0x4b, 0x80, |
| 0x29, 0x4c, 0x80, 0x1a, 0x42, 0x74, 0x0c, 0x34, 0x5e, 0x02, 0x20, 0x37, 0x01, 0x0a, 0x10, 0x32, |
| 0x7f, 0x9a, 0x25, 0x6d, 0x98, 0x10, 0x52, 0x79, 0x05, 0x3b, 0x55, 0x01, 0x23, 0x36, 0x01, 0x0d, |
| 0x14, 0x28, 0x8e, 0xa7, 0x11, 0x6e, 0x9d, 0x02, 0x47, 0x70, 0x01, 0x2c, 0x48, 0x01, 0x1b, 0x2d, |
| 0x01, 0x0b, 0x11, 0x1e, 0xaf, 0xbc, 0x09, 0x7c, 0xa9, 0x01, 0x4a, 0x74, 0x01, 0x30, 0x4e, 0x01, |
| 0x1e, 0x31, 0x01, 0x0b, 0x12, 0x0a, 0xde, 0xdf, 0x02, 0x96, 0xc2, 0x01, 0x53, 0x80, 0x01, 0x30, |
| 0x4f, 0x01, 0x1b, 0x2d, 0x01, 0x0b, 0x11, 0x24, 0x29, 0xeb, 0x1d, 0x24, 0xc1, 0x0a, 0x1b, 0x6f, |
| 0x55, 0xa5, 0xde, 0xb1, 0xa2, 0xd7, 0x6e, 0x87, 0xc3, 0x39, 0x71, 0xa8, 0x17, 0x53, 0x78, 0x0a, |
| 0x31, 0x3d, 0x55, 0xbe, 0xdf, 0x24, 0x8b, 0xc8, 0x05, 0x5a, 0x92, 0x01, 0x3c, 0x67, 0x01, 0x26, |
| 0x41, 0x01, 0x12, 0x1e, 0x48, 0xca, 0xdf, 0x17, 0x8d, 0xc7, 0x02, 0x56, 0x8c, 0x01, 0x38, 0x61, |
| 0x01, 0x24, 0x3d, 0x01, 0x10, 0x1b, 0x37, 0xda, 0xe1, 0x0d, 0x91, 0xc8, 0x01, 0x56, 0x8d, 0x01, |
| 0x39, 0x63, 0x01, 0x23, 0x3d, 0x01, 0x0d, 0x16, 0x0f, 0xeb, 0xd4, 0x01, 0x84, 0xb8, 0x01, 0x54, |
| 0x8b, 0x01, 0x39, 0x61, 0x01, 0x22, 0x38, 0x01, 0x0e, 0x17, 0xb5, 0x15, 0xc9, 0x3d, 0x25, 0x7b, |
| 0x0a, 0x26, 0x47, 0x2f, 0x6a, 0xac, 0x5f, 0x68, 0xad, 0x2a, 0x5d, 0x9f, 0x12, 0x4d, 0x83, 0x04, |
| 0x32, 0x51, 0x01, 0x11, 0x17, 0x3e, 0x93, 0xc7, 0x2c, 0x82, 0xbd, 0x1c, 0x66, 0x9a, 0x12, 0x4b, |
| 0x73, 0x02, 0x2c, 0x41, 0x01, 0x0c, 0x13, 0x37, 0x99, 0xd2, 0x18, 0x82, 0xc2, 0x03, 0x5d, 0x92, |
| 0x01, 0x3d, 0x61, 0x01, 0x1f, 0x32, 0x01, 0x0a, 0x10, 0x31, 0xba, 0xdf, 0x11, 0x94, 0xcc, 0x01, |
| 0x60, 0x8e, 0x01, 0x35, 0x53, 0x01, 0x1a, 0x2c, 0x01, 0x0b, 0x11, 0x0d, 0xd9, 0xd4, 0x02, 0x88, |
| 0xb4, 0x01, 0x4e, 0x7c, 0x01, 0x32, 0x53, 0x01, 0x1d, 0x31, 0x01, 0x0e, 0x17, 0xc5, 0x0d, 0xf7, |
| 0x52, 0x11, 0xde, 0x19, 0x11, 0xa2, 0x7e, 0xba, 0xf7, 0xea, 0xbf, 0xf3, 0xb0, 0xb1, 0xea, 0x68, |
| 0x9e, 0xdc, 0x42, 0x80, 0xba, 0x37, 0x5a, 0x89, 0x6f, 0xc5, 0xf2, 0x2e, 0x9e, 0xdb, 0x09, 0x68, |
| 0xab, 0x02, 0x41, 0x7d, 0x01, 0x2c, 0x50, 0x01, 0x11, 0x5b, 0x68, 0xd0, 0xf5, 0x27, 0xa8, 0xe0, |
| 0x03, 0x6d, 0xa2, 0x01, 0x4f, 0x7c, 0x01, 0x32, 0x66, 0x01, 0x2b, 0x66, 0x54, 0xdc, 0xf6, 0x1f, |
| 0xb1, 0xe7, 0x02, 0x73, 0xb4, 0x01, 0x4f, 0x86, 0x01, 0x37, 0x4d, 0x01, 0x3c, 0x4f, 0x2b, 0xf3, |
| 0xf0, 0x08, 0xb4, 0xd9, 0x01, 0x73, 0xa6, 0x01, 0x54, 0x79, 0x01, 0x33, 0x43, 0x01, 0x10, 0x06, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0xc0, 0x80, 0x40, 0x02, 0xad, 0x22, 0x07, 0x91, 0x55, 0x07, 0xa6, 0x3f, 0x07, 0x5e, 0x42, 0x08, |
| 0x40, 0x2e, 0x11, 0x51, 0x1f, 0x19, 0x1d, 0x1e, 0xeb, 0xa2, 0x24, 0xff, 0x22, 0x03, 0x95, 0x90, |
| 0x09, 0x66, 0xbb, 0xe1, 0xef, 0xb7, 0x77, 0x60, 0x29, 0x21, 0x10, 0x4d, 0x4a, 0x8e, 0x8e, 0xac, |
| 0xaa, 0xee, 0xf7, 0x32, 0x7e, 0x7b, 0xdd, 0xe2, 0x41, 0x20, 0x12, 0x90, 0xa2, 0xc2, 0x29, 0x33, |
| 0x62, 0x84, 0x44, 0x12, 0xa5, 0xd9, 0xc4, 0x2d, 0x28, 0x4e, 0xad, 0x50, 0x13, 0xb0, 0xf0, 0xc1, |
| 0x40, 0x23, 0x2e, 0xdd, 0x87, 0x26, 0xc2, 0xf8, 0x79, 0x60, 0x55, 0x1d, 0xc7, 0x7a, 0x8d, 0x93, |
| 0x3f, 0x9f, 0x94, 0x85, 0x76, 0x79, 0x68, 0x72, 0xae, 0x49, 0x57, 0x5c, 0x29, 0x53, 0x52, 0x63, |
| 0x32, 0x35, 0x27, 0x27, 0xb1, 0x3a, 0x3b, 0x44, 0x1a, 0x3f, 0x34, 0x4f, 0x19, 0x11, 0x0e, 0x0c, |
| 0xde, 0x22, 0x1e, 0x48, 0x10, 0x2c, 0x3a, 0x20, 0x0c, 0x0a, 0x07, 0x06, 0x20, 0x40, 0x60, 0x80, |
| 0xe0, 0x90, 0xc0, 0xa8, 0xc0, 0xb0, 0xc0, 0xc6, 0xc6, 0xf5, 0xd8, 0x88, 0x8c, 0x94, 0xa0, 0xb0, |
| 0xc0, 0xe0, 0xea, 0xea, 0xf0, 0x80, 0xd8, 0x80, 0xb0, 0xa0, 0xb0, 0xb0, 0xc0, 0xc6, 0xc6, 0xd0, |
| 0xd0, 0x88, 0x8c, 0x94, 0xa0, 0xb0, 0xc0, 0xe0, 0xea, 0xea, 0xf0, 0x80, 0x80, 0x40, 0x60, 0x70, |
| 0x40, 0x40, 0x60, 0x40, 0x80, 0x80, 0x40, 0x60, 0x70, 0x40, 0x40, 0x60, 0x40, 0xa0, 0x80, 0xa0, |
| 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x78, 0x07, 0x4c, 0xb0, 0xd0, 0x7e, 0x1c, 0x36, 0x67, 0x30, 0x0c, 0x9a, 0x9b, 0x8b, 0x5a, 0x22, |
| 0x75, 0x77, 0x43, 0x06, 0x19, 0xcc, 0xf3, 0x9e, 0x0d, 0x15, 0x60, 0x61, 0x05, 0x2c, 0x83, 0xb0, |
| 0x8b, 0x30, 0x44, 0x61, 0x53, 0x05, 0x2a, 0x9c, 0x6f, 0x98, 0x1a, 0x31, 0x98, 0x50, 0x05, 0x3a, |
| 0xb2, 0x4a, 0x53, 0x21, 0x3e, 0x91, 0x56, 0x05, 0x20, 0x9a, 0xc0, 0xa8, 0x0e, 0x16, 0xa3, 0x55, |
| 0x05, 0x20, 0x9c, 0xd8, 0x94, 0x13, 0x1d, 0x49, 0x4d, 0x07, 0x40, 0x74, 0x84, 0x7a, 0x25, 0x7e, |
| 0x78, 0x65, 0x15, 0x6b, 0xb5, 0xc0, 0x67, 0x13, 0x43, 0x7d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| }; |
| |
| // loop filter value based on qp index look up table |
| extern const uint8_t LF_VALUE_QP_LOOKUP[CODEC_VP9_QINDEX_RANGE] = { |
| 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, |
| 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, |
| 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
| 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, |
| 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, |
| 0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, |
| 0x13, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x19, |
| 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1f, |
| 0x1f, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, |
| 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2c, |
| 0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x31, 0x31, 0x31, 0x32, 0x32, |
| 0x32, 0x33, 0x33, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, |
| 0x38, 0x39, 0x39, 0x39, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d, |
| 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, |
| 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, |
| 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f |
| }; |
| |
| constexpr int8_t CodechalVdencVp9State::m_instRateThresholdI[CodechalVdencVp9State::m_numInstRateThresholds]; |
| constexpr int8_t CodechalVdencVp9State::m_instRateThresholdP[CodechalVdencVp9State::m_numInstRateThresholds]; |
| constexpr double CodechalVdencVp9State::m_devThresholdFpNegI[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| constexpr double CodechalVdencVp9State::m_devThresholdFpPosI[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| constexpr double CodechalVdencVp9State::m_devThresholdFpNegPB[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| constexpr double CodechalVdencVp9State::m_devThresholdFpPosPB[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| constexpr double CodechalVdencVp9State::m_devThresholdVbrNeg[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| constexpr double CodechalVdencVp9State::m_devThresholdVbrPos[CodechalVdencVp9State::m_numDevThresholds / 2]; |
| |
| const uint32_t CodechalVdencVp9State::m_vdencMeCurbeInit[48] = |
| { |
| 0x00000000, 0x00200010, 0x00003939, 0x77a43000, 0x00000000, 0x28300000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000200, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff |
| }; |
| |
| const uint32_t CodechalVdencVp9State::m_brcInitDmem[48] = |
| { |
| 0x00000000, 0x00038400, 0x00030D40, 0x000C3500, 0x00061A80, 0x00061A80, 0x00000000, 0x0000001E, |
| 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x270F0020, 0x02800000, 0x00010168, |
| 0x000000FF, 0x0000000E, 0x00000073, 0x00000000, 0x00000000, 0x7846321E, 0x7846321E, 0x735A321E, |
| 0xE5DFD8D1, 0x2F29211B, 0xE5DDD7D1, 0x5E56463F, 0xEAE3DAD4, 0x2F281F16, 0x01007488, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
| }; |
| |
| const uint32_t CodechalVdencVp9State::m_brcUpdateDmem[64] = |
| { |
| 0x00061A80, 0x00000000, 0x0007A120, 0x000493E0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x0032000A, 0x00960064, 0x01680280, 0x02200000, 0x007802B8, |
| 0x00000000, 0x00000000, 0x00000000, 0x02032000, 0xB4785028, 0x67614B28, 0x0101A07D, 0x28010203, |
| 0x01030505, 0x00FEFCFA, 0x04060402, 0x78503C1E, 0x00FFC88C, 0x503C1E04, 0xFFC88C78, 0x28140200, |
| 0xC8A08246, 0x090800FF, 0x040C0B0A, 0x07060605, 0x06060504, 0xFB650007, 0xFB0501FF, 0x000501FE, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
| }; |
| |
| const uint32_t CodechalVdencVp9State::m_probDmem[320] = |
| { |
| 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000, |
| 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, |
| 0x00000004, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x0000FF00, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, |
| 0x00540049, 0x00000060, 0x00000072, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x02B80078, 0x00000001, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
| }; |
| |
| const uint32_t CodechalVdencVp9State::m_brcConstData[2][416] = |
| { |
| // I Frame |
| { |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, |
| 0x00000000, 0x00000000, 0x32191900, 0x00264B4B, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000, |
| 0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000, |
| 0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A, |
| 0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600, |
| 0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000, |
| 0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A, |
| 0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600, |
| 0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA, |
| 0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000, |
| 0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000, |
| 0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802, |
| 0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
| }, |
| // P Frame |
| { |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, |
| 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, |
| 0x0B0B001E, 0x0000000B, 0x13194B0D, 0x1F5E2626, 0x19321F4B, 0x1E1E1904, 0x0B0B001E, 0x0000000B, |
| 0x0E0A0602, 0x06040212, 0x00000E0A, 0x00080402, 0x04020000, 0x000000FE, 0xFEFCFA02, 0xF8F60000, |
| 0xF200FEFC, 0xFEFCF8F4, 0xFCF6F2EE, 0x0A0402FE, 0x04021410, 0x00100C08, 0x0C080402, 0x02000000, |
| 0x0000FE04, 0xFEFC0200, 0xFA0000FE, 0x00FEFEFC, 0xFEFCFAF6, 0xF8F4F200, 0x0402FEFC, 0x0214100A, |
| 0x100C0804, 0x08040200, 0x0000000C, 0x00FE0402, 0xFC020000, 0x0000FEFE, 0xFEFEFCFA, 0xFCFAF600, |
| 0xF4F200FE, 0x00FEFCF8, 0x00000000, 0x14100C08, 0x00000000, 0x0E0A0600, 0x0000FE12, 0x08060000, |
| 0xFEFC0E0C, 0x02000000, 0xFA0A0604, 0x0000FEFC, 0x0A060200, 0x00FEFCF8, 0x06020000, 0xFCFAF60A, |
| 0x020000FE, 0xF8F40A06, 0x0000FEFC, 0xF40A0602, 0x00FEFCF8, 0x0A060200, 0x00000000, 0x0E0A0600, |
| 0x00000012, 0x0A060000, 0x00FE100C, 0x06000000, 0xFC100E0A, 0x000000FE, 0x0C0A0804, 0x00FEFCFA, |
| 0x08020000, 0xFEFCF80A, 0x02000000, 0xFCF80A08, 0x0000FEFE, 0xF80A0800, 0x00FEFCFA, 0x0A020000, |
| 0xFEFCF8F6, 0x02000000, 0x00000008, 0x0A060000, 0x0000120E, 0x06000000, 0xFE100C0A, 0x00000000, |
| 0x100E0A06, 0x0000FEFC, 0x0A080400, 0xFEFCFA0C, 0x02000000, 0xFCF80A08, 0x000000FE, 0xF80A0802, |
| 0x00FEFEFC, 0x0A080000, 0xFEFCFAF8, 0x02000000, 0xFCF8F60A, 0x000000FE, 0x00000802, 0x00000000, |
| 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
| } |
| }; |
| |
| const uint32_t CodechalVdencVp9State::m_samplerFilterCoeffs[32][6] = { |
| {0x40000000, 0x00000000, 0x40000000, 0x00000000, 0x00004000, 0x00004000}, |
| {0x40fe01ff, 0x0001ff02, 0x40fe01ff, 0x0001ff02, 0x000140ff, 0x000140ff}, |
| {0x41fc02ff, 0xff01fe04, 0x41fc02ff, 0xff01fe04, 0x00033ffe, 0x00033ffe}, |
| {0x3ffb03ff, 0xff02fd06, 0x3ffb03ff, 0xff02fd06, 0x00053efd, 0x00053efd}, |
| {0x40f903fe, 0xff02fc09, 0x40f903fe, 0xff02fc09, 0x00063efc, 0x00063efc}, |
| {0x3ff804fe, 0xfe03fb0b, 0x3ff804fe, 0xfe03fb0b, 0x00083cfc, 0x00083cfc}, |
| {0x3ef705fd, 0xfe03fa0e, 0x3ef705fd, 0xfe03fa0e, 0xff0a3cfb, 0xff0a3cfb}, |
| {0x3df505fd, 0xfe04f911, 0x3df505fd, 0xfe04f911, 0xff0d39fb, 0xff0d39fb}, |
| {0x3bf506fd, 0xfd04f814, 0x3bf506fd, 0xfd04f814, 0xff0f37fb, 0xff0f37fb}, |
| {0x3bf406fc, 0xfd05f716, 0x3bf406fc, 0xfd05f716, 0xff1135fb, 0xff1135fb}, |
| {0x39f307fc, 0xfd05f619, 0x39f307fc, 0xfd05f619, 0xfe1433fb, 0xfe1433fb}, |
| {0x37f307fc, 0xfc06f51c, 0x37f307fc, 0xfc06f51c, 0xfe1631fb, 0xfe1631fb}, |
| {0x35f207fc, 0xfc06f51f, 0x35f207fc, 0xfc06f51f, 0xfe192efb, 0xfe192efb}, |
| {0x32f207fc, 0xfc07f422, 0x32f207fc, 0xfc07f422, 0xfd1c2cfb, 0xfd1c2cfb}, |
| {0x30f207fc, 0xfc07f325, 0x30f207fc, 0xfc07f325, 0xfd1f29fb, 0xfd1f29fb}, |
| {0x2df207fc, 0xfc07f328, 0x2df207fc, 0xfc07f328, 0xfc2127fc, 0xfc2127fc}, |
| {0x29f307fc, 0xfc07f32b, 0x29f307fc, 0xfc07f32b, 0xfc2424fc, 0xfc2424fc}, |
| {0x28f307fc, 0xfc07f22d, 0x28f307fc, 0xfc07f22d, 0xfc2721fc, 0xfc2721fc}, |
| {0x25f307fc, 0xfc07f230, 0x25f307fc, 0xfc07f230, 0xfb291ffd, 0xfb291ffd}, |
| {0x22f407fc, 0xfc07f232, 0x22f407fc, 0xfc07f232, 0xfb2c1cfd, 0xfb2c1cfd}, |
| {0x1ff506fc, 0xfc07f235, 0x1ff506fc, 0xfc07f235, 0xfb2e19fe, 0xfb2e19fe}, |
| {0x1cf506fc, 0xfc07f337, 0x1cf506fc, 0xfc07f337, 0xfb3116fe, 0xfb3116fe}, |
| {0x19f605fd, 0xfc07f339, 0x19f605fd, 0xfc07f339, 0xfb3314fe, 0xfb3314fe}, |
| {0x16f705fd, 0xfc06f43b, 0x16f705fd, 0xfc06f43b, 0xfb3511ff, 0xfb3511ff}, |
| {0x14f804fd, 0xfd06f53b, 0x14f804fd, 0xfd06f53b, 0xfb370fff, 0xfb370fff}, |
| {0x11f904fe, 0xfd05f53d, 0x11f904fe, 0xfd05f53d, 0xfb390dff, 0xfb390dff}, |
| {0x0efa03fe, 0xfd05f73e, 0x0efa03fe, 0xfd05f73e, 0xfb3c0aff, 0xfb3c0aff}, |
| {0x0bfb03fe, 0xfe04f83f, 0x0bfb03fe, 0xfe04f83f, 0xfc3c0800, 0xfc3c0800}, |
| {0x09fc02ff, 0xfe03f940, 0x09fc02ff, 0xfe03f940, 0xfc3e0600, 0xfc3e0600}, |
| {0x06fd02ff, 0xff03fb3f, 0x06fd02ff, 0xff03fb3f, 0xfd3e0500, 0xfd3e0500}, |
| {0x04fe01ff, 0xff02fc41, 0x04fe01ff, 0xff02fc41, 0xfe3f0300, 0xfe3f0300}, |
| {0x02ff0100, 0xff01fe40, 0x02ff0100, 0xff01fe40, 0xff400100, 0xff400100} |
| }; |
| |
| MOS_STATUS CodechalVdencVp9State::CalculateRePakThresholds() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| int32_t repakSavingThreshold = 0; |
| if (m_prevFrameInfo.FrameWidth != m_oriFrameWidth || |
| m_prevFrameInfo.FrameHeight != m_oriFrameHeight) |
| { |
| switch (m_vp9SeqParams->TargetUsage) |
| { |
| case TU_QUALITY: |
| case 2: |
| repakSavingThreshold = 2; |
| break; |
| case TU_PERFORMANCE: |
| repakSavingThreshold = 80; |
| break; |
| default: // normal settings |
| repakSavingThreshold = 10; |
| break; |
| } |
| |
| int32_t scale = (m_oriFrameWidth * m_oriFrameHeight) / (176 * 144); |
| if (!scale) |
| { |
| scale = 1; |
| } |
| |
| for (auto i = 0; i < CODEC_VP9_QINDEX_RANGE; i += 1) |
| { |
| double tempQp = i - 144.0; |
| |
| int32_t b = (int32_t)(92.5 * i); |
| int32_t c = (int32_t)(1.6 * tempQp * tempQp); |
| int32_t d = (int32_t)(0.01 * tempQp * tempQp * tempQp); |
| int32_t threshold = (int32_t)((18630 - b + c - d) / 10); |
| int32_t calculatedRepakSavingThreshold = repakSavingThreshold * scale; |
| |
| // to avoid overflow of the integer threshold, it must be (RepakSavingThreshold * scale) <= 40342 |
| if (calculatedRepakSavingThreshold > 40342) |
| { |
| calculatedRepakSavingThreshold = 40342; |
| } |
| m_rePakThreshold[i] = calculatedRepakSavingThreshold * threshold; |
| } |
| } |
| |
| return eStatus; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Calculate Normalized Denominator for VP9 BRC Curbe Setup |
| //| based on LCM of provided framerates denominators |
| //| Return: uint32_t |
| //------------------------------------------------------------------------------ |
| uint32_t CodechalVdencVp9State::CalculateNormalizedDenominator( |
| FRAME_RATE* frameRates, |
| uint16_t numberOfLayers, |
| uint32_t normalizedDenominator) |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| // If pointer to the list of FrameRates is null, return the current Normalized Denominator. |
| if (!frameRates) |
| { |
| return normalizedDenominator; |
| } |
| |
| if (numberOfLayers == 0) |
| { |
| return normalizedDenominator; |
| } |
| |
| normalizedDenominator = normalizedDenominator * frameRates[numberOfLayers - 1].uiDenominator / MOS_GCD(normalizedDenominator, frameRates[numberOfLayers - 1].uiDenominator); |
| |
| return CalculateNormalizedDenominator(frameRates, numberOfLayers - 1, normalizedDenominator); |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Calculate the max level ratios for temporal scalability |
| //| Return: STATUS via return & max level ratios inside of maxLevelRatios |
| //------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::CalculateTemporalRatios( |
| uint16_t numberOfLayers, |
| uint32_t maxTemporalBitrate, |
| FRAME_RATE maxTemporalFrameRate, |
| uint8_t* maxLevelRatios) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(maxLevelRatios); |
| |
| if (numberOfLayers <= 1) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Need to have multiple temporal layers to calculate ratios"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (numberOfLayers > CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("VP9 VDEnc supports only %d temporal layers (%d provided)", |
| CODECHAL_ENCODE_VP9_MAX_NUM_TEMPORAL_LAYERS, numberOfLayers); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (!maxTemporalBitrate || !maxTemporalFrameRate.uiDenominator) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Invalid bitrate or framerate provided to calculate ratios"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| // calculate normalized denominator as least common multiplier of all layers denominators |
| uint32_t normalizedDenominator = 1; |
| normalizedDenominator = CalculateNormalizedDenominator(m_vp9SeqParams->FrameRate, numberOfLayers, normalizedDenominator); |
| |
| // calculate 0 layer framerate multiplier and apply it |
| FRAME_RATE currentLayerFrameRate = m_vp9SeqParams->FrameRate[0]; |
| uint32_t frameRateMultiplier = normalizedDenominator / currentLayerFrameRate.uiDenominator; |
| currentLayerFrameRate.uiNumerator *= frameRateMultiplier; |
| currentLayerFrameRate.uiDenominator *= frameRateMultiplier; |
| |
| uint32_t currentLayerBitrate = m_vp9SeqParams->TargetBitRate[0] * CODECHAL_ENCODE_BRC_KBPS; |
| maxLevelRatios[0] = (currentLayerBitrate << 6) / maxTemporalBitrate * currentLayerFrameRate.uiDenominator / maxTemporalFrameRate.uiDenominator * |
| maxTemporalFrameRate.uiNumerator / currentLayerFrameRate.uiNumerator; |
| |
| for (auto i = 1; i < numberOfLayers; ++i) |
| { |
| // per ddi |
| // framerate and bitrate are provided on asceding order |
| // 0 indexed is base player properties (bitrate and framerate) |
| // 1 indexed is first layer properties including layer below (which is base) |
| // so on, every current layer properties values include current and all previous layers properties values |
| |
| // extract actual layer bitrate |
| currentLayerBitrate = m_vp9SeqParams->TargetBitRate[i] * CODECHAL_ENCODE_BRC_KBPS - m_vp9SeqParams->TargetBitRate[i - 1] * CODECHAL_ENCODE_BRC_KBPS; |
| |
| // extract actual layer framerate |
| 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); |
| currentLayerFrameRate.uiDenominator = normalizedDenominator; |
| |
| // based on hardware behavior calculate ratio |
| // current layer bitrate is in unit of 1 / 64 |
| // 64 is just a number to represent a range or temporal bitrate for different layers |
| // 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 |
| maxLevelRatios[i] = (currentLayerBitrate << 6) / maxTemporalBitrate * currentLayerFrameRate.uiDenominator / maxTemporalFrameRate.uiDenominator * |
| maxTemporalFrameRate.uiNumerator / currentLayerFrameRate.uiNumerator; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ConstructPicStateBatchBuf( |
| PMOS_RESOURCE picStateBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(picStateBuffer); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_hucCmdInitializer); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucCmdInitializer->CommandInitializerSetVp9Params(this)); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| // Send command buffer header at the beginning (OS dependent) |
| bool requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : 0; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| m_firstTaskInPhase = false; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucCmdInitializer->CmdInitializerVp9Execute(&cmdBuffer, picStateBuffer)); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, picStateBuffer, &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MOS_COMMAND_BUFFER constructedCmdBuf; |
| MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); |
| constructedCmdBuf.pCmdBase = (uint32_t *)data; |
| constructedCmdBuf.pCmdPtr = (uint32_t *)data; |
| constructedCmdBuf.iOffset = 0; |
| constructedCmdBuf.iRemaining = m_vdencPicStateSecondLevelBatchBufferSize; |
| |
| // HCP_VP9_PIC_STATE |
| MHW_VDBOX_VP9_ENCODE_PIC_STATE picState; |
| MOS_ZeroMemory(&picState, sizeof(picState)); |
| picState.pVp9PicParams = m_vp9PicParams; |
| picState.pVp9SeqParams = m_vp9SeqParams; |
| picState.ppVp9RefList = &(m_refList[0]); |
| picState.PrevFrameParams.fields.KeyFrame = m_prevFrameInfo.KeyFrame; |
| picState.PrevFrameParams.fields.IntraOnly = m_prevFrameInfo.IntraOnly; |
| picState.PrevFrameParams.fields.Display = m_prevFrameInfo.ShowFrame; |
| picState.dwPrevFrmWidth = m_prevFrameInfo.FrameWidth; |
| picState.dwPrevFrmHeight = m_prevFrameInfo.FrameHeight; |
| picState.ucTxMode = m_txMode; |
| picState.bSSEEnable = m_vdencBrcEnabled; |
| picState.bUseDysRefSurface = (m_dysRefFrameFlags != DYS_REF_NONE) && m_dysVdencMultiPassEnabled; |
| picState.bVdencPakOnlyPassFlag = m_vdencPakonlyMultipassEnabled; |
| picState.uiMaxBitRate = m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS; |
| picState.uiMinBitRate = m_vp9SeqParams->MinBitRate * CODECHAL_ENCODE_BRC_KBPS; |
| constructedCmdBuf.iOffset += m_cmd1Size; |
| m_hucPicStateOffset = (uint16_t)constructedCmdBuf.iOffset; |
| constructedCmdBuf.pCmdPtr += constructedCmdBuf.iOffset/sizeof(uint32_t); |
| eStatus = m_hcpInterface->AddHcpVp9PicStateEncCmd(&constructedCmdBuf, nullptr, &picState); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer); |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add HCP_VP9_PIC_STATE command."); |
| return eStatus; |
| } |
| |
| // HCP_VP9_SEGMENT_STATE |
| MHW_VDBOX_VP9_SEGMENT_STATE segmentState; |
| MOS_ZeroMemory(&segmentState, sizeof(segmentState)); |
| segmentState.Mode = m_mode; |
| segmentState.pVp9EncodeSegmentParams = m_vp9SegmentParams; |
| uint8_t segmentCount = (m_vp9PicParams->PicFlags.fields.segmentation_enabled) ? CODEC_VP9_MAX_SEGMENTS : 1; |
| |
| for (uint8_t i = 0; i < segmentCount; i++) |
| { |
| segmentState.ucCurrentSegmentId = i; |
| eStatus = m_hcpInterface->AddHcpVp9SegmentStateCmd(&constructedCmdBuf, nullptr, &segmentState); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer); |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add MHW_VDBOX_VP9_SEGMENT_STATE command."); |
| return eStatus; |
| } |
| } |
| |
| // Adjust cmd buffer offset to have 8 segment state blocks |
| if (segmentCount < CODEC_VP9_MAX_SEGMENTS) |
| { |
| // Max 7 segments, 32 bytes each |
| uint8_t zeroBlock[m_segmentStateBlockSize * (CODEC_VP9_MAX_SEGMENTS - 1)]; |
| MOS_ZeroMemory(zeroBlock, sizeof(zeroBlock)); |
| Mhw_AddCommandCmdOrBB(&constructedCmdBuf, nullptr, zeroBlock, (CODEC_VP9_MAX_SEGMENTS - segmentCount) * m_segmentStateBlockSize); |
| } |
| m_slbbImgStateOffset = (uint16_t)constructedCmdBuf.iOffset; |
| constructedCmdBuf.iOffset += m_cmd2Size; |
| constructedCmdBuf.pCmdPtr += m_cmd2Size/ sizeof(uint32_t); |
| |
| // BB_END |
| eStatus = m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer); |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to add MI Batch Buffer End command."); |
| return eStatus; |
| } |
| m_hucSlbbSize = (uint16_t)constructedCmdBuf.iOffset; |
| |
| m_osInterface->pfnUnlockResource(m_osInterface,picStateBuffer); |
| |
| return eStatus; |
| } |
| |
| uint8_t CodechalVdencVp9State::GetReferenceBufferSlotIndex(uint8_t refreshFlags) |
| { |
| // even if there could be multiple reference frames in the buffer |
| // but here we only retrieve the one which has the smallest index |
| |
| if (refreshFlags == 0) |
| { |
| return 0; |
| } |
| |
| refreshFlags = ~refreshFlags; |
| |
| uint8_t refSlotIndex = 0; |
| while (refreshFlags & 1) |
| { |
| refreshFlags >>= 1; |
| refSlotIndex++; |
| } |
| |
| return refSlotIndex; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetDmemHuCVp9Prob() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| HucProbDmem* dmem = nullptr; |
| HucProbDmem* dmemTemp = nullptr; |
| int currPass = GetCurrentPass(); |
| if (IsFirstPass()) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| dmem = (HucProbDmem *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resHucProbDmemBuffer[i][m_currRecycledBufIdx], &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dmem); |
| |
| if (i == 0) |
| { |
| dmemTemp = dmem; |
| } |
| |
| MOS_SecureMemcpy(dmem, sizeof(HucProbDmem), |
| m_probDmem, sizeof(HucProbDmem)); |
| |
| if (i != 0) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucProbDmemBuffer[i][m_currRecycledBufIdx])); |
| dmem = dmemTemp; |
| } |
| } |
| } |
| else |
| { |
| dmem = (HucProbDmem *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resHucProbDmemBuffer[currPass][m_currRecycledBufIdx], &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dmem); |
| } |
| |
| // for BRC cases, HuC needs to be called on Pass 1 |
| if (m_superFrameHucPass) |
| { |
| dmem->HuCPassNum = CODECHAL_ENCODE_VP9_HUC_SUPERFRAME_PASS; |
| } |
| else |
| { |
| if (m_dysBrc) |
| { |
| //For BRC+Dynamic Scaling, we need to run as HUC pass 1 in the last pass since the curr_pass was changed to 0. |
| dmem->HuCPassNum = currPass != 0; |
| } |
| else |
| { |
| //For Non-dynamic scaling BRC cases, HuC needs to run as HuC pass one only in last pass. |
| dmem->HuCPassNum = ((m_vdencBrcEnabled && currPass == 1) ? 0 : (currPass != 0)); |
| } |
| } |
| |
| dmem->FrameWidth = m_oriFrameWidth; |
| dmem->FrameHeight = m_oriFrameHeight; |
| |
| for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++) |
| { |
| dmem->SegmentRef[i] = (m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled == true) ? m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentReference : CODECHAL_ENCODE_VP9_REF_SEGMENT_DISABLED; |
| dmem->SegmentSkip[i] = m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped; |
| } |
| |
| if (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME && m_currPass == 0) |
| { |
| for (auto i = 1; i < CODEC_VP9_NUM_CONTEXTS; i++) |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resProbBuffer[i], |
| &lockFlagsWriteOnly); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| ContextBufferInit(data, 0); |
| CtxBufDiffInit(data, 0); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resProbBuffer[i])); |
| } |
| } |
| |
| // in multipasses, only delta seg qp (SegCodeAbs = 0) is supported, confirmed by the arch team |
| dmem->SegCodeAbs = 0; |
| dmem->SegTemporalUpdate = m_vp9PicParams->PicFlags.fields.segmentation_temporal_update; |
| dmem->LastRefIndex = m_vp9PicParams->RefFlags.fields.LastRefIdx; |
| dmem->GoldenRefIndex = m_vp9PicParams->RefFlags.fields.GoldenRefIdx; |
| dmem->AltRefIndex = m_vp9PicParams->RefFlags.fields.AltRefIdx; |
| dmem->RefreshFrameFlags = m_vp9PicParams->RefFlags.fields.refresh_frame_flags; |
| dmem->RefFrameFlags = m_refFrameFlags; |
| dmem->ContextFrameTypes = m_contextFrameTypes[m_vp9PicParams->PicFlags.fields.frame_context_idx]; |
| dmem->FrameToShow = GetReferenceBufferSlotIndex(dmem->RefreshFrameFlags); |
| |
| dmem->FrameCtrl.FrameType = m_vp9PicParams->PicFlags.fields.frame_type; |
| dmem->FrameCtrl.ShowFrame = m_vp9PicParams->PicFlags.fields.show_frame; |
| dmem->FrameCtrl.ErrorResilientMode = m_vp9PicParams->PicFlags.fields.error_resilient_mode; |
| dmem->FrameCtrl.IntraOnly = m_vp9PicParams->PicFlags.fields.intra_only; |
| dmem->FrameCtrl.ContextReset = m_vp9PicParams->PicFlags.fields.reset_frame_context; |
| dmem->FrameCtrl.LastRefFrameBias = m_vp9PicParams->RefFlags.fields.LastRefSignBias; |
| dmem->FrameCtrl.GoldenRefFrameBias = m_vp9PicParams->RefFlags.fields.GoldenRefSignBias; |
| dmem->FrameCtrl.AltRefFrameBias = m_vp9PicParams->RefFlags.fields.AltRefSignBias; |
| dmem->FrameCtrl.AllowHighPrecisionMv = m_vp9PicParams->PicFlags.fields.allow_high_precision_mv; |
| dmem->FrameCtrl.McompFilterMode = m_vp9PicParams->PicFlags.fields.mcomp_filter_type; |
| dmem->FrameCtrl.TxMode = m_txMode; |
| dmem->FrameCtrl.RefreshFrameContext = m_vp9PicParams->PicFlags.fields.refresh_frame_context; |
| dmem->FrameCtrl.FrameParallelDecode = m_vp9PicParams->PicFlags.fields.frame_parallel_decoding_mode; |
| dmem->FrameCtrl.CompPredMode = m_vp9PicParams->PicFlags.fields.comp_prediction_mode; |
| dmem->FrameCtrl.FrameContextIdx = m_vp9PicParams->PicFlags.fields.frame_context_idx; |
| dmem->FrameCtrl.SharpnessLevel = m_vp9PicParams->sharpness_level; |
| dmem->FrameCtrl.SegOn = m_vp9PicParams->PicFlags.fields.segmentation_enabled; |
| dmem->FrameCtrl.SegMapUpdate = m_vp9PicParams->PicFlags.fields.segmentation_update_map; |
| dmem->FrameCtrl.SegUpdateData = m_vp9PicParams->PicFlags.fields.seg_update_data; |
| dmem->StreamInSegEnable = (uint8_t)m_segmentMapProvided; |
| dmem->StreamInEnable = (uint8_t)m_segmentMapProvided; // Currently unused, if used may || with HME enabled |
| |
| dmem->FrameCtrl.log2TileRows = m_vp9PicParams->log2_tile_rows; |
| dmem->FrameCtrl.log2TileCols = m_vp9PicParams->log2_tile_columns; |
| |
| dmem->PrevFrameInfo = m_prevFrameInfo; |
| // For DyS CQP or BRC case there is no Repak on last pass. So disable the Repak flag here |
| // We also disable repak pass in TU7 speed mode usage for performance reasons. |
| if (m_dysVdencMultiPassEnabled) |
| { |
| dmem->RePak = (m_numPasses > 0 && IsLastPass() && !(m_dysCqp || m_dysBrc) && (m_vp9SeqParams->TargetUsage != TU_PERFORMANCE)); |
| } |
| else |
| { |
| dmem->RePak = (m_numPasses > 0 && IsLastPass() && (m_vp9SeqParams->TargetUsage != TU_PERFORMANCE)); |
| } |
| if (dmem->RePak && m_adaptiveRepakSupported) |
| { |
| MOS_SecureMemcpy(dmem->RePakThreshold, sizeof(uint32_t) * CODEC_VP9_QINDEX_RANGE, m_rePakThreshold, sizeof(uint32_t) * CODEC_VP9_QINDEX_RANGE); |
| } |
| |
| dmem->LFLevelBitOffset = m_vp9PicParams->BitOffsetForLFLevel; |
| dmem->QIndexBitOffset = m_vp9PicParams->BitOffsetForQIndex; |
| dmem->SegBitOffset = m_vp9PicParams->BitOffsetForSegmentation + 1; // exclude segment_enable bit |
| dmem->SegLengthInBits = m_vp9PicParams->BitSizeForSegmentation - 1; // exclude segment_enable bit |
| dmem->UnCompHdrTotalLengthInBits = m_vp9PicParams->BitOffsetForFirstPartitionSize + 16; |
| dmem->PicStateOffset = m_hucPicStateOffset; |
| dmem->SLBBSize = m_hucSlbbSize; |
| dmem->IVFHeaderSize = (m_frameNum == 0) ? 44 : 12; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucProbDmemBuffer[currPass][m_currRecycledBufIdx])); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : StoreHuCStatus2Register |
| | Purpose : Store HUC_STATUS2 register bit 6 before HUC_Start command |
| | BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::StoreHuCStatus2Register( |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| // Write HUC_STATUS2 mask - bit 6 - valid IMEM loaded |
| MHW_MI_STORE_DATA_PARAMS storeDataParams; |
| MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); |
| storeDataParams.pOsResource = &m_resHucStatus2Buffer; |
| storeDataParams.dwResourceOffset = 0; |
| storeDataParams.dwValue = m_hucInterface->GetHucStatus2ImemLoadedMask(); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams)); |
| |
| // Store HUC_STATUS2 register |
| MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; |
| MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); |
| storeRegParams.presStoreBuffer = &m_resHucStatus2Buffer; |
| storeRegParams.dwOffset = sizeof(uint32_t); |
| storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(m_vdboxIndex)->hucStatus2RegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegParams)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::StoreHucErrorStatus(MmioRegistersHuc *mmioRegisters, PMOS_COMMAND_BUFFER cmdBuffer, bool addToEncodeStatus) |
| { |
| // Write Huc Error Flag mask: DW1 (mask value) |
| MHW_MI_STORE_DATA_PARAMS storeDataParams; |
| MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); |
| storeDataParams.pOsResource = &m_resHucErrorStatusBuffer; |
| storeDataParams.dwResourceOffset = sizeof(uint32_t); |
| storeDataParams.dwValue = CODECHAL_VDENC_VP9_BRC_HUC_STATUS_MEMORY_ACCESS_ERROR_MASK; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams)); |
| |
| // store HUC_STATUS register: DW0 (actual value) |
| MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; |
| MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); |
| storeRegParams.presStoreBuffer = &m_resHucErrorStatusBuffer; |
| storeRegParams.dwOffset = 0; |
| storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegParams)); |
| |
| if (addToEncodeStatus) |
| { |
| EncodeStatusBuffer encodeStatusBuf = m_encodeStatusBuf; |
| |
| uint32_t baseOffset = |
| (encodeStatusBuf.wCurrIndex * encodeStatusBuf.dwReportSize) + sizeof(uint32_t) * 2; // pEncodeStatus is offset by 2 DWs in the resource |
| |
| // store HUC_STATUS register |
| MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; |
| MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); |
| storeRegParams.presStoreBuffer = &encodeStatusBuf.resStatusBuffer; |
| storeRegParams.dwOffset = baseOffset + encodeStatusBuf.dwHuCStatusRegOffset; |
| storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd( |
| cmdBuffer, |
| &storeRegParams)); |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::HuCVp9Prob() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_TOOL( |
| uint32_t hucRegionSize[16] = { 0 }; |
| const char* hucRegionName[16] = {"\0"}; |
| |
| 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. |
| hucRegionSize[0] = 32 * CODECHAL_CACHELINE_SIZE; |
| hucRegionName[1] = "_CountersBuffer"; |
| hucRegionSize[1] = 193 * CODECHAL_CACHELINE_SIZE; |
| hucRegionName[2] = "_ProbBuffer"; |
| hucRegionSize[2] = 32 * CODECHAL_CACHELINE_SIZE; |
| hucRegionName[3] = "_ProbDeltaBuffer"; |
| hucRegionSize[3] = 29 * CODECHAL_CACHELINE_SIZE; |
| hucRegionName[4] = "_UncompressedHdr"; |
| hucRegionSize[4] = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER; |
| hucRegionName[5] = "_CompressedHdr"; |
| hucRegionSize[5] = 32 * CODECHAL_CACHELINE_SIZE; |
| hucRegionName[6] = "_SecondLevelBatchBuffer"; |
| hucRegionSize[6] = m_vdencPicStateSecondLevelBatchBufferSize; |
| hucRegionName[7] = "_SecondLevelBatchBuffer"; |
| hucRegionSize[7] = m_vdencPicStateSecondLevelBatchBufferSize; |
| hucRegionName[8] = "_UncompressedHdr"; |
| hucRegionSize[8] = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER; |
| hucRegionName[9] = "_DefaultProbs"; |
| hucRegionSize[9] = sizeof(Keyframe_Default_Probs)+sizeof(Inter_Default_Probs); |
| hucRegionName[10] = "_SuperFrameBuffer"; |
| hucRegionSize[10] = CODECHAL_ENCODE_VP9_BRC_SUPER_FRAME_BUFFER_SIZE; |
| hucRegionName[11] = "_DataExtension"; |
| hucRegionSize[11] = CODECHAL_ENCODE_VP9_VDENC_DATA_EXTENSION_SIZE; |
| ) |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| bool requestFrameTracking = false; |
| |
| // Send command buffer header at the beginning (OS dependent) |
| // frame tracking tag is only added in the last command buffer header |
| requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false)); |
| |
| m_firstTaskInPhase = false; |
| } |
| |
| // load kernel from WOPCM into L2 storage RAM |
| MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams; |
| MOS_ZeroMemory(&imemParams, sizeof(imemParams)); |
| imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencProbKernelDescriptor; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams)); |
| |
| // pipe mode select |
| MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; |
| pipeModeSelectParams.Mode = m_mode; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCVp9Prob()); |
| int currPass = GetCurrentPass(); |
| MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams; |
| MOS_ZeroMemory(&dmemParams, sizeof(dmemParams)); |
| dmemParams.presHucDataSource = &m_resHucProbDmemBuffer[m_currPass][m_currRecycledBufIdx]; |
| dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucProbDmem), CODECHAL_CACHELINE_SIZE); |
| dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams)); |
| |
| // Add Virtual addr |
| MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams; |
| MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams)); |
| // Input regions |
| virtualAddrParams.regionParams[0].presRegion = &m_resProbBuffer[m_vp9PicParams->PicFlags.fields.frame_context_idx]; |
| 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 |
| virtualAddrParams.regionParams[1].presRegion = &m_resProbabilityCounterBuffer; |
| virtualAddrParams.regionParams[7].presRegion = m_vdencBrcEnabled ? &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex] : &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]; |
| virtualAddrParams.regionParams[8].presRegion = &m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx]; |
| virtualAddrParams.regionParams[9].presRegion = &m_resHucDefaultProbBuffer; |
| |
| // Output regions |
| virtualAddrParams.regionParams[2].presRegion = &m_resHucProbOutputBuffer; // Final probability output from HuC after each pass |
| virtualAddrParams.regionParams[2].isWritable = true; |
| virtualAddrParams.regionParams[3].presRegion = &m_resProbabilityDeltaBuffer; |
| virtualAddrParams.regionParams[3].isWritable = true; |
| virtualAddrParams.regionParams[4].presRegion = &m_resHucPakInsertUncompressedHeaderWriteBuffer; |
| virtualAddrParams.regionParams[4].isWritable = true; |
| virtualAddrParams.regionParams[5].presRegion = &m_resCompressedHeaderBuffer; |
| virtualAddrParams.regionParams[5].isWritable = true; |
| virtualAddrParams.regionParams[6].presRegion = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]; |
| virtualAddrParams.regionParams[6].isWritable = true; |
| virtualAddrParams.regionParams[10].presRegion = &m_resBitstreamBuffer; |
| virtualAddrParams.regionParams[10].isWritable = true; |
| virtualAddrParams.regionParams[11].presRegion = &m_resVdencDataExtensionBuffer; |
| virtualAddrParams.regionParams[11].isWritable = true; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams)); |
| // Store HUC_STATUS2 register bit 6 before HUC_Start command |
| // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload |
| // (HUC_Start command with last start bit set). |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer)); |
| ) |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true)); |
| |
| // wait Huc completion (use HEVC bit for now) |
| MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams; |
| MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams)); |
| vdPipeFlushParams.Flags.bFlushHEVC = 1; |
| vdPipeFlushParams.Flags.bWaitDoneHEVC = 1; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams)); |
| |
| // Flush the engine to ensure memory written out |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| flushDwParams.bVideoPipelineCacheInvalidate = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| // Write HUC_STATUS mask: DW1 (mask value) |
| MHW_MI_STORE_DATA_PARAMS storeDataParams; |
| MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); |
| storeDataParams.pOsResource = &m_resHucPakMmioBuffer; |
| storeDataParams.dwResourceOffset = sizeof(uint32_t); |
| storeDataParams.dwValue = 1 << 31; //Repak bit for HUC is bit 31 |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams) ); |
| |
| // store HUC_STATUS register |
| MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams; |
| MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams)); |
| storeRegParams.presStoreBuffer = &m_resHucPakMmioBuffer; |
| storeRegParams.dwOffset = 0; |
| storeRegParams.dwRegister = m_hucInterface->GetMmioRegisters(MHW_VDBOX_NODE_1)->hucStatusRegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &storeRegParams)); |
| |
| // For superframe pass, after HuC executes, write the updated size (combined frame size) to status report |
| // So app knows total size instead of just the showframe size |
| if (m_superFrameHucPass) |
| { |
| EncodeStatusBuffer* encodeStatusBuf = &m_encodeStatusBuf; |
| uint32_t baseOffset = |
| (encodeStatusBuf->wCurrIndex * m_encodeStatusBuf.dwReportSize) + |
| sizeof(uint32_t) * 2; // encodeStatus is offset by 2 DWs in the resource |
| |
| MHW_MI_COPY_MEM_MEM_PARAMS copyMemMemParams; |
| MOS_ZeroMemory(©MemMemParams, sizeof(copyMemMemParams)); |
| |
| copyMemMemParams.presSrc = virtualAddrParams.regionParams[11].presRegion; |
| copyMemMemParams.dwSrcOffset = 0; // Updated framesize is 1st DW in buffer |
| copyMemMemParams.presDst = &encodeStatusBuf->resStatusBuffer; |
| copyMemMemParams.dwDstOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd( |
| &cmdBuffer, |
| ©MemMemParams)); |
| } |
| |
| if (!m_singleTaskPhaseSupported || m_superFrameHucPass) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| // Dump input probabilites before running HuC |
| CODECHAL_DEBUG_TOOL(m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[0].presRegion, |
| virtualAddrParams.regionParams[0].dwOffset, |
| hucRegionSize[0], |
| 0, |
| "_ProbBuffer", |
| (virtualAddrParams.regionParams[0].isWritable ? true : false), |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpDefault); |
| ) |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| // For Temporal scaling, super frame pass is initiated after the command buffer submission in ExecuteSliceLevel. |
| // So if Single Task Phase is enabled, then we need to explicitly submit the command buffer here to call HuC |
| if (!m_singleTaskPhaseSupported || m_superFrameHucPass) |
| { |
| bool renderFlags = m_videoContextUsesNullHw; |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| "_ENC"))); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( |
| &m_resHucProbDmemBuffer[m_currPass][m_currRecycledBufIdx], |
| sizeof(HucProbDmem), |
| currPass, |
| CodechalHucRegionDumpType::hucRegionDumpDefault)); |
| |
| for (auto i = 0; i < 16; i++) { |
| if (virtualAddrParams.regionParams[i].presRegion) |
| { |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[i].presRegion, |
| virtualAddrParams.regionParams[i].dwOffset, |
| hucRegionSize[i], |
| i, |
| hucRegionName[i], |
| !virtualAddrParams.regionParams[i].isWritable, |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpDefault); |
| } |
| }) |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::InitBrcConstantBuffer( |
| PMOS_RESOURCE brcConstResource, |
| uint16_t pictureCodingType) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(brcConstResource); |
| CODECHAL_ENCODE_ASSERT(pictureCodingType == I_TYPE || pictureCodingType == P_TYPE); |
| |
| MOS_LOCK_PARAMS lockFlags; |
| MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.WriteOnly = 1; |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, |
| brcConstResource, |
| &lockFlags); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| // Fill surface with BRC const data corresponding to I/P frame |
| // -1 converts from frame type to index |
| eStatus = MOS_SecureMemcpy( |
| data, |
| sizeof(m_brcConstData[pictureCodingType-1]), |
| m_brcConstData[pictureCodingType-1], |
| sizeof(m_brcConstData[pictureCodingType-1])); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to initialize constant memory buffer."); |
| return eStatus; |
| } |
| |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| brcConstResource); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : ComputeVDEncBRCInitQP |
| | Purpose : Calculate VP9 BRC init QP value |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::ComputeVDEncBRCInitQP( |
| int32_t* initQpI, |
| int32_t* initQpP) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(initQpI); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(initQpP); |
| |
| uint32_t frameSize = ((m_frameWidth * m_frameHeight * 3) >> 1); |
| |
| const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f; |
| 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); |
| qpP = (int32_t)((float)qpP * (5.0)); |
| qpP -= 20; |
| qpP = MOS_CLAMP_MIN_MAX(qpP, 1, 200); |
| |
| int32_t qpI = (qpP > 4) ? (qpP - 4) : qpP; |
| uint16_t numP = m_vp9SeqParams->GopPicSize - 1; |
| int16_t qiboost = numP / 30 - 1; |
| qiboost = MOS_CLAMP_MIN_MAX(qiboost, 0, 20); |
| |
| qpI -= qiboost; |
| qpI = MOS_CLAMP_MIN_MAX(qpI, 1, 200); |
| |
| qpP = qpI + 20; |
| |
| *initQpI = qpI; |
| *initQpP = qpP; |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : SetDmemHuCBrcUpdate |
| | Purpose : Setup DMEM for VP9 BrcUpdate HuC kernel |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::SetDmemHuCBrcUpdate() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| // Setup BRC DMEM |
| int currPass = GetCurrentPass(); |
| HucBrcUpdateDmem *dmem = (HucBrcUpdateDmem *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencBrcUpdateDmemBuffer[currPass], &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dmem); |
| |
| MOS_SecureMemcpy(dmem, sizeof(HucBrcUpdateDmem), |
| m_brcUpdateDmem, sizeof(m_brcUpdateDmem)); |
| |
| // BRC Settings |
| if (m_curTargetFullness > m_vp9SeqParams->VBVBufferSizeInBit) |
| { |
| dmem->UPD_OVERFLOW_FLAG_U8 = 0x1; |
| m_curTargetFullness -= m_vp9SeqParams->VBVBufferSizeInBit; |
| } |
| if (IsFirstPass()) // we only set target fullness on first BRC pass |
| { |
| dmem->UPD_TARGET_BUF_FULLNESS_U32 = (int32_t)m_curTargetFullness; |
| } |
| dmem->UPD_FRAMENUM_U32 = m_frameNum; |
| dmem->UPD_Temporal_Level_U8 = m_vp9PicParams->temporal_id; |
| dmem->UPD_HRD_BUFF_FULLNESS_UPPER_I32 = m_vp9SeqParams->UpperVBVBufferLevelThresholdInBit; |
| dmem->UPD_HRD_BUFF_FULLNESS_LOWER_I32 = m_vp9SeqParams->LowerVBVBufferLevelThresholdInBit; |
| |
| // Frame info |
| dmem->UPD_CurWidth_U16 = (uint16_t)m_frameWidth; |
| dmem->UPD_CurHeight_U16 = (uint16_t)m_frameHeight; |
| dmem->UPD_CurrFrameType_U8 = (m_pictureCodingType == I_TYPE) ? 2 : 0; |
| |
| // PAK info |
| dmem->UPD_MaxNumPAKs_U8 = (uint8_t)GetNumPasses(); // do not add 1 because we do not run update for RePAK |
| dmem->UPD_PAKPassNum_U8 = (uint8_t)currPass; |
| |
| // Offsets |
| dmem->UPD_VDEncImgStateOffset = m_slbbImgStateOffset; |
| dmem->UPD_SLBBSize = m_hucSlbbSize; |
| dmem->UPD_PicStateOffset = m_hucPicStateOffset; |
| |
| // Thresholds not programmed by driver.currently |
| |
| // Global adjust settings not programmed by driver currently |
| |
| // QP's |
| dmem->UPD_ACQQp_U8 = m_vp9PicParams->LumaACQIndex; |
| // If app gives segment map, we honor the QP deltas provided, if not, and segmentation is enabled, |
| // BRC generates the QP deltas and patches them into the segment states |
| dmem->UPD_SegMapGenerating_U8 = m_vp9PicParams->PicFlags.fields.segmentation_enabled && !m_segmentMapProvided; |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[currPass]); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : SetDmemHuCBrcInitReset |
| | Purpose : Setup DMEM for VP9 BrcInit HuC kernel |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::SetDmemHuCBrcInitReset() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_ASSERT(m_brcInit || m_brcReset); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| // Setup BRC DMEM |
| HucBrcInitDmem *dmem = (HucBrcInitDmem *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencBrcInitDmemBuffer, &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dmem); |
| |
| MOS_SecureMemcpy(dmem, sizeof(HucBrcInitDmem), |
| m_brcInitDmem, sizeof(m_brcInitDmem)); |
| |
| dmem->BRCFunc = m_brcInit ? 0 : 2; // 0 for init, 2 for reset |
| dmem->ProfileLevelMaxFrame = m_frameWidth * m_frameHeight; |
| if (m_vp9SeqParams->UserMaxFrameSize > 0) |
| { |
| dmem->ProfileLevelMaxFrame = MOS_MIN(dmem->ProfileLevelMaxFrame, m_vp9SeqParams->UserMaxFrameSize); |
| } |
| dmem->InitBufFullness = m_vp9SeqParams->InitVBVBufferFullnessInBit; |
| dmem->BufSize = m_vp9SeqParams->VBVBufferSizeInBit; |
| |
| dmem->TargetBitrate = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS; |
| dmem->MaxRate = m_vp9SeqParams->MaxBitRate * CODECHAL_ENCODE_BRC_KBPS; |
| |
| FRAME_RATE targetFR = m_vp9SeqParams->FrameRate[m_vp9SeqParams->NumTemporalLayersMinus1]; |
| dmem->FrameRateM = targetFR.uiNumerator; |
| dmem->FrameRateD = targetFR.uiDenominator; |
| |
| switch (m_vp9SeqParams->RateControlMethod) |
| { |
| case RATECONTROL_CBR: |
| dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISCBR; |
| dmem->MaxRate = dmem->TargetBitrate; |
| break; |
| case RATECONTROL_VBR: |
| dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISVBR; |
| break; |
| case RATECONTROL_AVBR: |
| dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISAVBR; |
| break; |
| case RATECONTROL_CQL: |
| dmem->BRCFlag = CODECHAL_ENCODE_BRCINIT_ISCQL; |
| dmem->LevelQP = m_vp9SeqParams->ICQQualityFactor; |
| break; |
| default: |
| CODECHAL_ENCODE_ASSERTMESSAGE("BRCInit: Invalid rate control provided (%d)", m_vp9SeqParams->RateControlMethod); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (dmem->MaxRate < dmem->TargetBitrate) |
| { |
| dmem->MaxRate = 2 * dmem->TargetBitrate; |
| } |
| |
| dmem->GopP = m_vp9SeqParams->GopPicSize - 1; |
| dmem->FrameWidth = (uint16_t)m_frameWidth; |
| dmem->FrameHeight = (uint16_t)m_frameHeight; |
| |
| /* Limit 1-255 as the QP range */ |
| dmem->MinQP = 1; |
| dmem->MaxQP = CODEC_VP9_MAX_QP; |
| |
| dmem->EnableScaling = m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling; |
| |
| for (auto i = 0; i < m_numInstRateThresholds; i++) |
| { |
| dmem->InstRateThreshI0[i] = m_instRateThresholdI[i]; |
| dmem->InstRateThreshP0[i] = m_instRateThresholdP[i]; |
| } |
| |
| double m_inputBitsPerFrame = ((double)dmem->MaxRate * (double)dmem->FrameRateD) / (double)dmem->FrameRateM; |
| |
| //make sure the buffer size can contain at least 4 frames in average |
| if (dmem->BufSize < (uint32_t)(m_inputBitsPerFrame * 4)) |
| { |
| dmem->BufSize = (uint32_t)(m_inputBitsPerFrame * 4); |
| } |
| |
| //make sure the initial buffer size is larger than 2 average frames and smaller than the max buffer size. |
| if (dmem->InitBufFullness == 0) |
| { |
| dmem->InitBufFullness = 7 * dmem->BufSize / 8; |
| } |
| if (dmem->InitBufFullness < (uint32_t)(m_inputBitsPerFrame * 2)) |
| { |
| dmem->InitBufFullness = (uint32_t)(m_inputBitsPerFrame * 2); |
| } |
| if (dmem->InitBufFullness > dmem->BufSize) |
| { |
| dmem->InitBufFullness = dmem->BufSize; |
| } |
| |
| double bpsRatio = m_inputBitsPerFrame / ((double)dmem->BufSize / m_devStdFps); |
| bpsRatio = MOS_CLAMP_MIN_MAX(bpsRatio, m_bpsRatioLow, m_bpsRatioHigh); |
| |
| for (auto i = 0; i < m_numDevThresholds / 2; i++) |
| { |
| dmem->DevThreshPB0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegPB[i], bpsRatio)); |
| dmem->DevThreshPB0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosPB[i], bpsRatio)); |
| |
| dmem->DevThreshI0[i] = (int8_t)(m_negMultPb * pow(m_devThresholdFpNegI[i], bpsRatio)); |
| dmem->DevThreshI0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultPb * pow(m_devThresholdFpPosI[i], bpsRatio)); |
| |
| dmem->DevThreshVBR0[i] = (int8_t)(m_negMultVbr * pow(m_devThresholdVbrNeg[i], bpsRatio)); |
| dmem->DevThreshVBR0[i + m_numDevThresholds / 2] = (int8_t)(m_posMultVbr * pow(m_devThresholdVbrPos[i], bpsRatio)); |
| } |
| |
| int32_t qpI = 0, qpP = 0; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ComputeVDEncBRCInitQP(&qpI, &qpP)); |
| |
| dmem->InitQPI = (uint8_t)qpI; |
| dmem->InitQPP = (uint8_t)qpP; |
| |
| dmem->Total_Level = m_vp9SeqParams->NumTemporalLayersMinus1 + 1; |
| if (dmem->Total_Level > 1) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateTemporalRatios( |
| dmem->Total_Level, dmem->TargetBitrate, targetFR, dmem->MaxLevel_Ratio)); |
| } |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcInitDmemBuffer); |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : HuCBrcUpdate |
| | Purpose : Start/Submit VP9 HuC BrcUpdate kernel to HW |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::HuCBrcUpdate() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_TOOL( |
| uint32_t hucRegionSize[16]; |
| const char* hucRegionName[16]; |
| |
| hucRegionName[0] = "_BrcHistory"; |
| hucRegionSize[0] = m_brcHistoryBufferSize; |
| hucRegionName[1] = "_VDEncStats"; |
| hucRegionSize[1] = m_vdencBrcStatsBufferSize; |
| hucRegionName[2] = "_PAKStats"; |
| hucRegionSize[2] = m_vdencBrcPakStatsBufferSize; |
| hucRegionName[3] = "_InputSLBB"; |
| hucRegionSize[3] = m_vdencPicStateSecondLevelBatchBufferSize; |
| hucRegionName[4] = "_BRCData"; |
| hucRegionSize[4] = CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE; |
| hucRegionName[5] = "_ConstData"; |
| hucRegionSize[5] = m_brcConstantSurfaceSize; |
| hucRegionName[6] = "_OutputSLBB"; |
| hucRegionSize[6] = m_vdencPicStateSecondLevelBatchBufferSize; |
| hucRegionName[7] = "_PAKMMIO"; |
| hucRegionSize[7] = CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE; |
| ) |
| |
| MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams; |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (m_swBrcMode) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcUpdate()); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer, m_pictureCodingType)); |
| // Set region params for dumping only |
| MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams)); |
| virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer; |
| virtualAddrParams.regionParams[0].isWritable = true; |
| virtualAddrParams.regionParams[1].presRegion = &m_resVdencBrcStatsBuffer; |
| virtualAddrParams.regionParams[2].presRegion = &m_resFrameStatStreamOutBuffer; |
| virtualAddrParams.regionParams[3].presRegion = &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]; |
| virtualAddrParams.regionParams[4].presRegion = &m_brcBuffers.resBrcHucDataBuffer; |
| virtualAddrParams.regionParams[4].isWritable = true; |
| virtualAddrParams.regionParams[5].presRegion = &m_brcBuffers.resBrcConstantDataBuffer; |
| virtualAddrParams.regionParams[6].presRegion = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]; |
| virtualAddrParams.regionParams[6].isWritable = true; |
| virtualAddrParams.regionParams[7].presRegion = &m_brcBuffers.resBrcBitstreamSizeBuffer; |
| 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) |
| virtualAddrParams.regionParams[0].presRegion, |
| virtualAddrParams.regionParams[0].dwOffset, |
| hucRegionSize[0], |
| 0, |
| hucRegionName[0], |
| true, |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SoftwareBRC(true)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( |
| |
| &m_resVdencBrcUpdateDmemBuffer[m_currPass], |
| sizeof(HucBrcUpdateDmem), // Change buffer and size to update dmem |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate)); |
| |
| for (auto i = 0; i < 16; i++) { |
| if (virtualAddrParams.regionParams[i].presRegion) |
| { |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[i].presRegion, |
| virtualAddrParams.regionParams[i].dwOffset, |
| hucRegionSize[i], |
| i, |
| hucRegionName[i], |
| !virtualAddrParams.regionParams[i].isWritable, |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate); |
| } |
| }) |
| // We increment by the average frame value once for each frame |
| if (m_currPass == 0) |
| { |
| m_curTargetFullness += m_inputBitsPerFrame; |
| } |
| |
| return eStatus; |
| } |
| #endif |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| bool requestFrameTracking = false; |
| |
| // Send command buffer header at the beginning (OS dependent) |
| requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| |
| m_firstTaskInPhase = false; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(InitBrcConstantBuffer(&m_brcBuffers.resBrcConstantDataBuffer, m_pictureCodingType)); |
| |
| // load kernel from WOPCM into L2 storage RAM |
| MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams; |
| MOS_ZeroMemory(&imemParams, sizeof(imemParams)); |
| imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencBrcUpdateKernelDescriptor; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams)); |
| |
| // pipe mode select |
| MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; |
| pipeModeSelectParams.Mode = m_mode; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcUpdate()); |
| |
| // set HuC DMEM param |
| MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams; |
| MOS_ZeroMemory(&dmemParams, sizeof(dmemParams)); |
| dmemParams.presHucDataSource = &m_resVdencBrcUpdateDmemBuffer[m_currPass]; |
| dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucBrcUpdateDmem), CODECHAL_CACHELINE_SIZE); |
| dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; // how to set? |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams)); |
| |
| // Set surfaces to HuC regions |
| MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams)); |
| |
| // History Buffer - IN/OUT |
| virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer; |
| virtualAddrParams.regionParams[0].isWritable = true; |
| |
| // VDEnc Stats Buffer - IN |
| virtualAddrParams.regionParams[1].presRegion = &m_resVdencBrcStatsBuffer; |
| |
| // Frame (not PAK) Stats Buffer - IN |
| virtualAddrParams.regionParams[2].presRegion = &m_resFrameStatStreamOutBuffer; |
| |
| // Input SLBB (second level batch buffer) - IN |
| //For Dys + BRC Pass 0, use the resVdencDysPictureState2ndLevelBatchBuffer as input buffer |
| virtualAddrParams.regionParams[3].presRegion = (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled) ? &m_resVdencDysPictureState2NdLevelBatchBuffer : &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]; |
| |
| // BRC Data - OUT |
| virtualAddrParams.regionParams[4].presRegion = &m_brcBuffers.resBrcHucDataBuffer; |
| virtualAddrParams.regionParams[4].isWritable = true; |
| |
| // Const Data - IN |
| virtualAddrParams.regionParams[5].presRegion = &m_brcBuffers.resBrcConstantDataBuffer; |
| |
| // Output SLBB - OUT |
| virtualAddrParams.regionParams[6].presRegion = &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]; |
| virtualAddrParams.regionParams[6].isWritable = true; |
| |
| // PAK MMIO - IN |
| virtualAddrParams.regionParams[7].presRegion = &m_brcBuffers.resBrcBitstreamSizeBuffer; |
| |
| // Load HuC Regions into Cmd Buf |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams)); |
| |
| // Store HUC_STATUS2 register bit 6 before HUC_Start command |
| // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload |
| // (HUC_Start command with last start bit set). |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer)); |
| ) |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true)); |
| |
| // wait Huc completion (use HEVC bit for now) |
| MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams; |
| MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams)); |
| vdPipeFlushParams.Flags.bFlushHEVC = 1; |
| vdPipeFlushParams.Flags.bWaitDoneHEVC = 1; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams)); |
| |
| // Flush the engine to ensure memory written out |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| flushDwParams.bVideoPipelineCacheInvalidate = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| if (!m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd)) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if (!m_singleTaskPhaseSupported) |
| { |
| bool renderingFlags = m_videoContextUsesNullHw; |
| |
| // Dump history input before HuC runs |
| CODECHAL_DEBUG_TOOL( |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[0].presRegion, |
| virtualAddrParams.regionParams[0].dwOffset, |
| hucRegionSize[0], |
| 0, |
| hucRegionName[0], |
| true, |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate); |
| ); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( |
| &m_resVdencBrcUpdateDmemBuffer[m_currPass], |
| sizeof(HucBrcUpdateDmem), // Change buffer and size to update dmem |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate)); |
| |
| for (auto i = 0; i < 16; i++) { |
| if (virtualAddrParams.regionParams[i].presRegion) |
| { |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[i].presRegion, |
| virtualAddrParams.regionParams[i].dwOffset, |
| hucRegionSize[i], |
| i, |
| hucRegionName[i], |
| !virtualAddrParams.regionParams[i].isWritable, |
| m_currPass, |
| CodechalHucRegionDumpType::hucRegionDumpUpdate); |
| } |
| }) |
| } |
| |
| // We increment by the average frame value once for each frame |
| if (m_currPass == 0) |
| { |
| m_curTargetFullness += m_inputBitsPerFrame; |
| } |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : ConstructSuperFrame |
| | Purpose : Enable VP9 third HUC phase to construct super frame in case of temporal scalability. |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::ConstructSuperFrame() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| // enable super frame state |
| m_superFrameHucPass = true; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCVp9Prob()); |
| |
| // disable super frame state |
| m_superFrameHucPass = false; |
| |
| return eStatus; |
| } |
| |
| /*---------------------------------------------------------------------------- |
| | Name : HuCBrcInitReset |
| | Purpose : Start/Submit VP9 HuC BrcInit kernel to HW |
| | |
| | Returns : MOS_STATUS |
| \---------------------------------------------------------------------------*/ |
| MOS_STATUS CodechalVdencVp9State::HuCBrcInitReset() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_DEBUG_TOOL( |
| uint32_t hucRegionSize[16]; |
| const char* hucRegionName[16]; |
| |
| hucRegionName[0] = "_BrcHistoryBuffer"; |
| hucRegionSize[0] = m_brcHistoryBufferSize; |
| ) |
| |
| MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams; |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (m_swBrcMode) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcInitReset()); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SoftwareBRC(false)); |
| // Set region params for dumping only |
| MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams)); |
| virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer; |
| virtualAddrParams.regionParams[0].isWritable = true; |
| 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); |
| m_curTargetFullness = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS; |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( |
| &m_resVdencBrcInitDmemBuffer, |
| sizeof(HucBrcInitDmem), |
| 0, |
| CodechalHucRegionDumpType::hucRegionDumpInit)); |
| |
| for (auto i = 0; i < 16; i++) { |
| if (virtualAddrParams.regionParams[i].presRegion) |
| { |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[i].presRegion, |
| virtualAddrParams.regionParams[i].dwOffset, |
| hucRegionSize[i], |
| i, |
| hucRegionName[i], |
| !virtualAddrParams.regionParams[i].isWritable, |
| 0, |
| CodechalHucRegionDumpType::hucRegionDumpInit); |
| } |
| }) |
| return eStatus; |
| } |
| #endif |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| bool requestFrameTracking = false; |
| |
| // Send command buffer header at the beginning (OS dependent) |
| requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| |
| m_firstTaskInPhase = false; |
| } |
| |
| // load kernel from WOPCM into L2 storage RAM |
| MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams; |
| MOS_ZeroMemory(&imemParams, sizeof(imemParams)); |
| imemParams.dwKernelDescriptor = m_vdboxHucVp9VdencBrcInitKernelDescriptor; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams)); |
| |
| // pipe mode select |
| MHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams; |
| pipeModeSelectParams.Mode = m_mode; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, &pipeModeSelectParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcInitReset()); |
| |
| 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); |
| m_curTargetFullness = m_vp9SeqParams->TargetBitRate[m_vp9SeqParams->NumTemporalLayersMinus1] * CODECHAL_ENCODE_BRC_KBPS; |
| |
| // set HuC DMEM param |
| MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams; |
| MOS_ZeroMemory(&dmemParams, sizeof(dmemParams)); |
| dmemParams.presHucDataSource = &m_resVdencBrcInitDmemBuffer; |
| dmemParams.dwDataLength = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE); |
| dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams)); |
| |
| MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams)); |
| virtualAddrParams.regionParams[0].presRegion = &m_brcBuffers.resBrcHistoryBuffer; |
| virtualAddrParams.regionParams[0].isWritable = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams)); |
| |
| // Store HUC_STATUS2 register bit 6 before HUC_Start command |
| // BitField: VALID IMEM LOADED - This bit will be cleared by HW at the end of a HUC workload |
| // (HUC_Start command with last start bit set). |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreHuCStatus2Register(&cmdBuffer)); |
| ) |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStartCmd(&cmdBuffer, true)); |
| |
| // wait Huc completion (use HEVC bit for now) |
| MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipeFlushParams; |
| MOS_ZeroMemory(&vdPipeFlushParams, sizeof(vdPipeFlushParams)); |
| vdPipeFlushParams.Flags.bFlushHEVC = 1; |
| vdPipeFlushParams.Flags.bWaitDoneHEVC = 1; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipeFlushParams)); |
| |
| // Flush the engine to ensure memory written out |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| flushDwParams.bVideoPipelineCacheInvalidate = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| if (!m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd)) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if (!m_singleTaskPhaseSupported) |
| { |
| bool renderingFlags = m_videoContextUsesNullHw; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem( |
| &m_resVdencBrcInitDmemBuffer, |
| sizeof(HucBrcInitDmem), |
| 0, |
| CodechalHucRegionDumpType::hucRegionDumpInit)); |
| |
| for (auto i = 0; i < 16; i++) { |
| if (virtualAddrParams.regionParams[i].presRegion) |
| { |
| m_debugInterface->DumpHucRegion( |
| virtualAddrParams.regionParams[i].presRegion, |
| virtualAddrParams.regionParams[i].dwOffset, |
| hucRegionSize[i], |
| i, |
| hucRegionName[i], |
| !virtualAddrParams.regionParams[i].isWritable, |
| 0, |
| CodechalHucRegionDumpType::hucRegionDumpInit); |
| } |
| }) |
| } |
| |
| return eStatus; |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_STATUS CodechalVdencVp9State::SoftwareBRC(bool update) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| typedef void* (*BrcCreateInstance)(); |
| typedef void(*BrcReleaseInstance)(void*); |
| typedef int(*BrcProcess)(void*, ProcessType); |
| typedef int(*BrcSetBuff)(uint8_t*, VP9BufferType, void*); |
| |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_swBrcMode); |
| |
| MOS_LOCK_PARAMS lpReadOnly; |
| MOS_ZeroMemory(&lpReadOnly, sizeof(lpReadOnly)); |
| lpReadOnly.ReadOnly = 1; |
| |
| MOS_LOCK_PARAMS lpWriteOnly; |
| MOS_ZeroMemory(&lpWriteOnly, sizeof(lpWriteOnly)); |
| lpWriteOnly.WriteOnly = 1; |
| |
| MOS_LOCK_PARAMS lpReadWrite; |
| MOS_ZeroMemory(&lpReadWrite, sizeof(lpReadWrite)); |
| lpReadWrite.ReadOnly = lpReadWrite.WriteOnly = 1; |
| |
| BrcCreateInstance pfnCreateInstance = (BrcCreateInstance)MOS_GetProcAddress(m_swBrcMode, "VP9BRC_CreateInstance"); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pfnCreateInstance); |
| BrcReleaseInstance pfnReleaseInstance = (BrcReleaseInstance)MOS_GetProcAddress(m_swBrcMode, "VP9BRC_ReleaseInstance"); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pfnReleaseInstance); |
| BrcProcess pfnProcess = (BrcProcess)MOS_GetProcAddress(m_swBrcMode, "VP9BRC_Process"); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pfnProcess); |
| BrcSetBuff pfnSetBuffer = (BrcSetBuff)MOS_GetProcAddress(m_swBrcMode, "VP9BRC_SetBuff"); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pfnSetBuffer); |
| |
| void* pvBrcIfHandle = pfnCreateInstance(); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(pvBrcIfHandle); |
| |
| if (!update) // BRC INIT / RESET |
| { |
| // Set DMEM |
| uint8_t* data = NULL; |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencBrcInitDmemBuffer, &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9INLINE_DMEM, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcInitDmemBuffer); |
| |
| // Set History OUT Buffer |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_brcBuffers.resBrcHistoryBuffer, &lpWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9HISTORY_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHistoryBuffer); |
| |
| // Execute init/reset firmware |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnProcess(pvBrcIfHandle, m_brcInit ? BRCInit : BRCReset)); |
| } |
| else // BRC UPDATE |
| { |
| // Set DMEM |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencBrcUpdateDmemBuffer[0], &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9INLINE_DMEM, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[0]); |
| |
| // Set History IN/OUT Buffer |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_brcBuffers.resBrcHistoryBuffer, &lpReadWrite); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9HISTORY_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHistoryBuffer); |
| |
| // Set VDEnc Stats IN |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencBrcStatsBuffer, &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9VDENC_STATISTICS_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcStatsBuffer); |
| |
| // Set Frame Stats IN |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resFrameStatStreamOutBuffer, &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9PAK_STATISTICS_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resFrameStatStreamOutBuffer); |
| |
| // Set SLBB IN |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex], &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9INPUT_SLBB_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]); |
| |
| // Set BRC data OUT |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_brcBuffers.resBrcHucDataBuffer, &lpWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9BRC_DATA_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer); |
| |
| // Set Const Data IN |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_brcBuffers.resBrcConstantDataBuffer, &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9CONSTANT_DATA_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcConstantDataBuffer); |
| |
| // Set SLBB OUT |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex], &lpWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9OUTPUT_SLBB_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]); |
| |
| // PAK MMIO IN |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_brcBuffers.resBrcBitstreamSizeBuffer, &lpReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer(data, eVp9PAKMMIO_BUFF, pvBrcIfHandle)); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcBitstreamSizeBuffer); |
| |
| // AUX Buffer IN/OUT (DLL extension buffer) |
| HUC_AUX_BUFFER auxBuffer = { 0 }; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnSetBuffer((uint8_t *)&auxBuffer, eVp9AUX_BUFF, pvBrcIfHandle)); |
| |
| // Execute update firmware |
| pfnProcess(pvBrcIfHandle, BRCUpdate); |
| } |
| |
| pfnReleaseInstance(pvBrcIfHandle); |
| |
| return eStatus; |
| } |
| #endif |
| |
| uint32_t CodechalVdencVp9State::CalculateBufferOffset( |
| uint32_t idx, |
| uint32_t width, |
| uint32_t blockSize, |
| uint32_t bufferPitch) |
| { |
| uint32_t y = idx / (MOS_ALIGN_CEIL(width, CODEC_VP9_SUPER_BLOCK_WIDTH) / 32); |
| uint32_t x = idx % (MOS_ALIGN_CEIL(width, CODEC_VP9_SUPER_BLOCK_WIDTH)/ 32); |
| |
| switch (blockSize) |
| { |
| case 0: // 16x16 |
| x *= 2; |
| y *= 2; |
| break; |
| case 1: // 32x32 (no multiplier since streamin chunks are for 32x32) |
| break; |
| case 2: // 64x64 |
| x /= 2; |
| y /= 2; |
| break; |
| case 3: // 8x8 |
| x *= 4; |
| y *= 4; |
| break; |
| } |
| |
| uint32_t addr = y * bufferPitch; |
| addr += x; |
| |
| return addr; |
| } |
| |
| bool CodechalVdencVp9State::IsToBeCompressed(bool isDownScaledSurface) |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| // For regular encoding, we always compress this surface regardless of downscaling |
| return m_mmcState ? m_mmcState->IsMmcEnabled() : false; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::DysRefFrames() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (m_dysRefFrameFlags == DYS_REF_NONE) |
| { |
| return eStatus; |
| } |
| |
| // allocate dynamic scaled surfaces if needed |
| uint8_t idx = 0, refIdx = 0, numDysRefFrames = 0; |
| if (m_dysRefFrameFlags & DYS_REF_LAST) |
| { |
| idx = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx; |
| refIdx = 1; |
| numDysRefFrames++; |
| } |
| |
| if (m_dysRefFrameFlags & DYS_REF_GOLDEN) |
| { |
| idx = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx; |
| refIdx = 2; |
| numDysRefFrames++; |
| } |
| |
| if (m_dysRefFrameFlags & DYS_REF_ALT) |
| { |
| idx = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx; |
| refIdx = 3; |
| numDysRefFrames++; |
| } |
| |
| if (numDysRefFrames > 1) |
| { |
| // for performance reason, we can only support single reference for dynamic scaling |
| CODECHAL_ENCODE_ASSERTMESSAGE("Only single reference is supported for dynamic scaling!"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer; |
| MOS_ZeroMemory(&allocParamsForBuffer, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBuffer.Type = MOS_GFXRES_2D; |
| allocParamsForBuffer.TileType = MOS_TILE_Y; |
| allocParamsForBuffer.Format = m_reconSurface.Format; |
| allocParamsForBuffer.bIsCompressible = IsToBeCompressed(true); |
| |
| PCODEC_REF_LIST *refList = &m_refList[0]; |
| if (Mos_ResourceIsNull(&refList[idx]->sDysSurface.OsResource) || |
| (refList[idx]->sDysSurface.dwWidth != m_reconSurface.dwWidth) || (refList[idx]->sDysSurface.dwHeight != m_reconSurface.dwHeight)) |
| { |
| // free existing resource first if resolution changes |
| if (!Mos_ResourceIsNull(&refList[idx]->sDysSurface.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &refList[idx]->sDysSurface.OsResource); |
| } |
| |
| allocParamsForBuffer.dwWidth = MOS_ALIGN_CEIL(m_reconSurface.dwWidth, CODEC_VP9_SUPER_BLOCK_WIDTH); |
| allocParamsForBuffer.dwHeight = MOS_ALIGN_CEIL(m_reconSurface.dwHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT); |
| allocParamsForBuffer.pBufName = "Dynamic Scaled Surface for VP9"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer, |
| &refList[idx]->sDysSurface.OsResource)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( |
| m_osInterface, |
| &refList[idx]->sDysSurface)); |
| } |
| |
| refList[idx]->sDysSurface.dwWidth = m_oriFrameWidth; |
| refList[idx]->sDysSurface.dwHeight = m_oriFrameHeight; |
| |
| // We use PAK to perform dynamic scaling for reference frame, basically if every CU is inter and skipped, the reconstructed picture will be |
| // the down scaled copy of reference frame. |
| // Here driver needs to prepare pak obj and cu record, since PAK has a limitation that input picture needs to be CU boundary aligned, |
| // and to simplify handling the boundary condition, we set each CU with size 8x8, inter and zero MV. |
| // Segment skip needs to be turned on also. |
| |
| auto oriFrameHeight = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_HEIGHT); |
| auto oriFrameWidth = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH); |
| |
| uint32_t numCuLastSbCol = (oriFrameWidth / CODEC_VP9_MIN_BLOCK_WIDTH) - (m_picWidthInSb - 1) * (CODEC_VP9_SUPER_BLOCK_WIDTH / CODEC_VP9_MIN_BLOCK_WIDTH); |
| uint32_t numCuLastSbRow = (oriFrameHeight / CODEC_VP9_MIN_BLOCK_HEIGHT) - (m_picHeightInSb - 1) * (CODEC_VP9_SUPER_BLOCK_HEIGHT / CODEC_VP9_MIN_BLOCK_HEIGHT); |
| |
| MOS_LOCK_PARAMS lockFlags; |
| MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); |
| lockFlags.WriteOnly = 1; |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, &m_resMbCodeSurface, &lockFlags); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| HcpPakObject* pakObjData = (HcpPakObject*)data; |
| CU_DATA* cuDataPtr = (CU_DATA*)(data + m_mvOffset); |
| |
| // fill pak object |
| HcpPakObject pakObj; |
| MOS_ZeroMemory(&pakObj, sizeof(pakObj)); |
| pakObj.DW0.Type = 0x03; |
| pakObj.DW0.Opcode = 0x27; |
| pakObj.DW0.SubOp = 0x35; |
| 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 |
| |
| pakObj.DW1.Split_flag_level0 = 1; |
| pakObj.DW1.Split_flag_level1 = 0xF; |
| pakObj.DW1.Split_flag_level2_level1part0 = 0xF; |
| pakObj.DW1.Split_flag_level2_level1part1 = 0xF; |
| pakObj.DW1.Split_flag_level2_level1part2 = 0xF; |
| pakObj.DW1.Split_flag_level2_level1part3 = 0xF; |
| |
| // fill cu data |
| CU_DATA cuData; |
| MOS_ZeroMemory(&cuData, sizeof(cuData)); |
| cuData.cu_size = 0; // 8x8 |
| cuData.cu_pred_mode0 = cuData.cu_pred_mode1 = 1; // Inter |
| cuData.refframe_part0_l0 = cuData.refframe_part1_l0 = refIdx; |
| |
| for (uint32_t j = 0; j < m_picHeightInSb; j++) |
| { |
| for (uint32_t i = 0; i < m_picWidthInSb; i++) |
| { |
| if ((j == m_picHeightInSb - 1) && (i == m_picWidthInSb - 1)) |
| { |
| pakObj.DW1.CU_count_minus1 = numCuLastSbCol * numCuLastSbRow - 1; |
| pakObj.DW1.IsLastSBFrameflag = pakObj.DW1.IsLastSBTileflag = 1; |
| pakObj.Reserved_DW03 = 0x05000000; // add batch buffer end flag |
| } |
| else if (i == m_picWidthInSb - 1) |
| { |
| pakObj.DW1.CU_count_minus1 = numCuLastSbCol * 8 - 1; |
| } |
| else if (j == m_picHeightInSb - 1) |
| { |
| pakObj.DW1.CU_count_minus1 = numCuLastSbRow * 8 - 1; |
| } |
| else |
| { |
| pakObj.DW1.CU_count_minus1 = 63; |
| } |
| |
| pakObj.DW2.Current_SB_X_Addr = i; |
| pakObj.DW2.Current_SB_Y_Addr = j; |
| |
| *pakObjData++ = pakObj; |
| |
| for (unsigned int cuIdx = 0; cuIdx < 64; cuIdx++) |
| { |
| *cuDataPtr++ = cuData; |
| } |
| } |
| } |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resMbCodeSurface); |
| |
| // save current state |
| // we only need to run PAK to get the recon picture, so disable HuC and VDENC here |
| m_vdencEnabled = false; |
| m_dysHucEnabled = m_hucEnabled; |
| m_hucEnabled = false; |
| bool origWaitForENC = m_waitForEnc; |
| m_waitForEnc = false; |
| MOS_SURFACE origReconSurface = m_reconSurface; |
| // Set the downscaled surface as the recon output surface |
| m_reconSurface = refList[idx]->sDysSurface; |
| // save the ucNumPasses and set the ucNumPasses = ucCurrPass + 1. otherwise SliceLevel will mistakenly treat current pass as last pass |
| uint8_t origNumPasses = m_numPasses; |
| m_numPasses = m_currPass + 1; |
| |
| bool origSegmentSkip[CODEC_VP9_MAX_SEGMENTS] = {false}; |
| for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++) |
| { |
| origSegmentSkip[i] = m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped; |
| m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped = true; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ExecuteDysPictureLevel()); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ExecuteDysSliceLevel()); |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface( |
| &refList[idx]->sDysSurface, |
| CodechalDbgAttr::attrReferenceSurfaces, |
| (refIdx == 1) ? "DysLastScaledSurf" : (refIdx == 2) ? "DysGoldenScaledSurf" : "DysAltScaledSurf"))); |
| // recover state |
| m_vdencEnabled = true; |
| m_waitForEnc = origWaitForENC; |
| m_reconSurface = origReconSurface; |
| m_numPasses = origNumPasses; |
| m_hucEnabled = (m_dysHucEnabled && !m_dysVdencMultiPassEnabled); |
| for (auto i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++) |
| { |
| m_vp9SegmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped = origSegmentSkip[i]; |
| } |
| |
| return eStatus; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Setup Sampler State for VP9 DYS Kernels |
| //| Return: N/A |
| //------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::SetSamplerStateDys( |
| DysSamplerStateParams* params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| |
| MHW_SAMPLER_STATE_PARAM samplerParams; |
| MOS_ZeroMemory(&samplerParams, sizeof(samplerParams)); |
| |
| samplerParams.bInUse = true; |
| samplerParams.SamplerType = MHW_SAMPLER_TYPE_AVS; |
| samplerParams.Avs.bEnableAVS = true; |
| samplerParams.Avs.wR3cCoefficient = 15; |
| samplerParams.Avs.wR3xCoefficient = 6; |
| samplerParams.Avs.StrongEdgeThr = 8; |
| samplerParams.Avs.WeakEdgeThr = 1; |
| samplerParams.Avs.GainFactor = 32; |
| samplerParams.Avs.bHdcDwEnable = 1; |
| |
| samplerParams.Avs.wR5cCoefficient = 3; |
| samplerParams.Avs.wR5cxCoefficient = 8; |
| samplerParams.Avs.wR5xCoefficient = 9; |
| samplerParams.Avs.StrongEdgeWght = 6; |
| samplerParams.Avs.RegularWght = 3; |
| samplerParams.Avs.NonEdgeWght = 2; |
| samplerParams.Avs.GlobalNoiseEstm = 255; |
| |
| samplerParams.Avs.AdditionalOverridesUsed = 1; |
| samplerParams.Avs.YSlope2 = 24; |
| samplerParams.Avs.S0L = 1792; |
| samplerParams.Avs.YSlope1 = 24; |
| samplerParams.Avs.S2U = 1792; |
| samplerParams.Avs.S1U = 0; |
| |
| MHW_SAMPLER_AVS_TABLE_PARAM samplerTableParams; |
| MOS_ZeroMemory(&samplerTableParams, sizeof(samplerTableParams)); |
| samplerParams.Avs.pMhwSamplerAvsTableParam = &samplerTableParams; |
| |
| MOS_SecureMemcpy(samplerTableParams.paMhwAvsCoeffParam, |
| sizeof(samplerTableParams.paMhwAvsCoeffParam), |
| m_samplerFilterCoeffs, |
| MHW_NUM_HW_POLYPHASE_TABLES * 6 * sizeof(uint32_t)); |
| |
| MOS_SecureMemcpy(samplerTableParams.paMhwAvsCoeffParamExtra, |
| sizeof(samplerTableParams.paMhwAvsCoeffParamExtra), |
| &m_samplerFilterCoeffs[MHW_NUM_HW_POLYPHASE_TABLES][0], |
| MHW_NUM_HW_POLYPHASE_EXTRA_TABLES_G9 * 6 * sizeof(uint32_t)); |
| |
| samplerTableParams.byteDefaultSharpnessLevel = 255; |
| samplerTableParams.byteMaxDerivative4Pixels = 7; |
| samplerTableParams.byteMaxDerivative8Pixels = 20; |
| samplerTableParams.byteTransitionArea4Pixels = 4; |
| samplerTableParams.byteTransitionArea8Pixels = 5; |
| |
| samplerTableParams.bBypassXAdaptiveFiltering = 1; |
| samplerTableParams.bBypassYAdaptiveFiltering = 1; |
| samplerTableParams.bAdaptiveFilterAllChannels = 0; |
| |
| MHW_RENDER_STATE_SIZES* hwSizes = m_stateHeapInterface->pStateHeapInterface->GetHwSizesPointer(); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(hwSizes); |
| uint8_t* sampler = (uint8_t*)MOS_AllocAndZeroMemory(hwSizes->dwSizeSamplerStateAvs); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(sampler); |
| |
| eStatus = m_stateHeapInterface->pfnSetSamplerState(m_stateHeapInterface, sampler, &samplerParams); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| MOS_FreeMemory(sampler); |
| return eStatus; |
| } |
| |
| eStatus = params->pKernelState->m_dshRegion.AddData( |
| sampler, |
| params->pKernelState->dwSamplerOffset, |
| hwSizes->dwSizeSamplerStateAvs); |
| |
| MOS_FreeMemory(sampler); |
| return eStatus; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Setup Curbe for VP9 DYS Kernels |
| //| Return: N/A |
| //------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::SetCurbeDys( |
| DysCurbeParams* params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState); |
| |
| DysStaticData cmd; |
| MOS_ZeroMemory(&cmd, sizeof(DysStaticData)); |
| |
| cmd.DW0.InputFrameWidth = params->dwInputWidth;; |
| cmd.DW0.InputFrameHeight = params->dwInputHeight; |
| |
| cmd.DW1.OutputFrameWidth = params->dwOutputWidth; |
| cmd.DW1.OutputFrameHeight = params->dwOutputHeight; |
| |
| cmd.DW2.DeltaU = 1.0f / params->dwOutputWidth; |
| cmd.DW3.DeltaV = 1.0f / params->dwOutputHeight; |
| |
| cmd.DW16.InputFrameNV12SurfBTI = 0; //Surface 0 |
| cmd.DW17.OutputFrameYSurfBTI = 1; //surface 1 |
| cmd.DW18.AVSSampleIdx = 0; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData( |
| &cmd, |
| params->pKernelState->dwCurbeOffset, |
| sizeof(cmd))); |
| |
| return eStatus; |
| } |
| |
| // ------------------------------------------------------------------------------ |
| // Send surfaces for the VP9 DYS kernel |
| //------------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::SendDysSurfaces( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| DysSurfaceParams* params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->kernelState); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(params->dysBindingTable); |
| |
| DysBindingTable* dysBindingTable = (DysBindingTable*)params->dysBindingTable; |
| |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = params->inputFrameSurface; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.ucVDirection = g_cMhw_VDirection[MHW_FRAME]; |
| surfaceCodecParams.dwBindingTableOffset = dysBindingTable->dysInputFrameNv12; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| params->kernelState)); |
| |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.bUseUVPlane = true; |
| surfaceCodecParams.psSurface = params->outputFrameSurface; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = dysBindingTable->dysOutputFrameY; |
| surfaceCodecParams.dwUVBindingTableOffset = dysBindingTable->dysOutputFrameUV; |
| surfaceCodecParams.dwVerticalLineStride = params->verticalLineStride; |
| surfaceCodecParams.dwVerticalLineStrideOffset = params->verticalLineStrideOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| params->kernelState)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::DysKernel( |
| DysKernelParams* dysKernelParams) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dysKernelParams); |
| |
| PerfTagSetting perfTag; |
| CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL); |
| |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12; |
| MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBufferNV12.Type = MOS_GFXRES_2D; |
| allocParamsForBufferNV12.TileType = MOS_TILE_Y; |
| allocParamsForBufferNV12.Format = Format_NV12; |
| |
| PMHW_KERNEL_STATE kernelState = &m_dysKernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( |
| m_stateHeapInterface, |
| kernelState->KernelParams.iBTCount)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( |
| m_stateHeapInterface, |
| kernelState, |
| false, |
| m_dysDshSize, |
| false, |
| m_storeData)); |
| |
| DysSamplerStateParams dysSamplerStateParams; |
| MOS_ZeroMemory(&dysSamplerStateParams, sizeof(dysSamplerStateParams)); |
| dysSamplerStateParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSamplerStateDys(&dysSamplerStateParams)); |
| |
| DysCurbeParams dysCurbeParams; |
| MOS_ZeroMemory(&dysCurbeParams, sizeof(dysCurbeParams)); |
| dysCurbeParams.dwInputWidth = dysKernelParams->dwInputWidth; |
| dysCurbeParams.dwInputHeight = dysKernelParams->dwInputHeight; |
| dysCurbeParams.dwOutputWidth = dysKernelParams->dwOutputWidth; |
| dysCurbeParams.dwOutputHeight = dysKernelParams->dwOutputHeight; |
| dysCurbeParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeDys(&dysCurbeParams)); |
| |
| MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; |
| MOS_ZeroMemory(&idParams, sizeof(idParams)); |
| idParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( |
| m_stateHeapInterface, |
| 1, |
| &idParams)); |
| |
| CODECHAL_MEDIA_STATE_TYPE encFunctionType = CODECHAL_MEDIA_STATE_VP9_DYS; |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_DSH_TYPE, |
| kernelState)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( |
| encFunctionType, |
| kernelState)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_ISH_TYPE, |
| kernelState)); |
| ) |
| |
| m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(kernelState->KernelParams.iBTCount); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifyCommandBufferSize()); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer)); |
| |
| SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); |
| sendKernelCmdsParams.EncFunctionType = encFunctionType; |
| sendKernelCmdsParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); |
| |
| // Add binding table |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( |
| m_stateHeapInterface, |
| kernelState)); |
| |
| // allocate dynamic scaled surfaces if needed |
| if (Mos_ResourceIsNull(&dysKernelParams->psOutputSurface->OsResource) || |
| (dysKernelParams->psOutputSurface->dwWidth != dysKernelParams->dwOutputWidth) || (dysKernelParams->psOutputSurface->dwHeight != dysKernelParams->dwOutputHeight)) |
| { |
| // free existing resource first if resolution changes |
| if (!Mos_ResourceIsNull(&dysKernelParams->psOutputSurface->OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &dysKernelParams->psOutputSurface->OsResource); |
| } |
| |
| allocParamsForBufferNV12.dwWidth = MOS_ALIGN_CEIL(dysKernelParams->dwOutputWidth, 64); |
| allocParamsForBufferNV12.dwHeight = MOS_ALIGN_CEIL(dysKernelParams->dwOutputHeight, 64); |
| allocParamsForBufferNV12.pBufName = "Dynamic Scaled Surface for VP9"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferNV12, |
| &dysKernelParams->psOutputSurface->OsResource)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo( |
| m_osInterface, |
| dysKernelParams->psOutputSurface)); |
| |
| dysKernelParams->psOutputSurface->dwWidth = dysKernelParams->dwOutputWidth; |
| dysKernelParams->psOutputSurface->dwHeight = dysKernelParams->dwOutputHeight; |
| } |
| |
| // Add surface states |
| DysSurfaceParams dysSurfaceParams; |
| MOS_ZeroMemory(&dysSurfaceParams, sizeof(DysSurfaceParams)); |
| dysSurfaceParams.inputFrameSurface = dysKernelParams->psInputSurface; |
| dysSurfaceParams.outputFrameSurface = dysKernelParams->psOutputSurface; |
| dysSurfaceParams.verticalLineStride = m_verticalLineStride; |
| dysSurfaceParams.verticalLineStrideOffset = m_verticalLineStrideOffset; |
| dysSurfaceParams.kernelState = kernelState; |
| dysSurfaceParams.dysBindingTable = &m_dysBindingTable; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendDysSurfaces(&cmdBuffer, &dysSurfaceParams)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_SSH_TYPE, |
| kernelState)) |
| ); |
| |
| if (m_hwWalker) |
| { |
| uint32_t resolutionX = (uint32_t)m_picWidthInMb; |
| uint32_t resolutionY = (uint32_t)m_frameFieldHeightInMb; |
| |
| CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; |
| MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); |
| walkerCodecParams.WalkerMode = m_walkerMode; |
| walkerCodecParams.dwResolutionX = resolutionX; |
| walkerCodecParams.dwResolutionY = resolutionY; |
| walkerCodecParams.bNoDependency = true; |
| |
| MHW_WALKER_PARAMS walkerParams; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( |
| m_hwInterface, |
| &walkerParams, |
| &walkerCodecParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetRenderInterface()->AddMediaObjectWalkerCmd( |
| &cmdBuffer, |
| &walkerParams)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( |
| m_stateHeapInterface)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd( |
| &cmdBuffer, |
| nullptr)); |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| encFunctionType, |
| nullptr))); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, m_renderContextUsesNullHw)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::InitMEState( |
| VdencVmeState* state) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(state); |
| MOS_ZeroMemory(state, sizeof(VdencVmeState)); |
| // Frame settings |
| state->QpY = m_vp9PicParams->LumaACQIndex; |
| state->CurrOriginalPic = m_vp9PicParams->CurrOriginalPic; |
| state->TargetUsage = m_vp9SeqParams->TargetUsage; |
| state->GopRefDist = (uint8_t)m_vp9SeqParams->GopPicSize; // -1 ?? |
| state->num_ref_idx_l0_active_minus1 = m_numRefFrames - 1; |
| state->num_ref_idx_l1_active_minus1 = 0; |
| |
| // Constant values |
| state->Level = 51; |
| state->direct_spatial_mv_pred_flag = true; |
| state->dwBiWeight = 32; |
| state->CurrOriginalPic.PicFlags = PICTURE_FRAME; |
| |
| // Buffers |
| state->s4xMeMvDataBuffer = m_4xMeMvDataBuffer; |
| state->s16xMeMvDataBuffer = m_16xMeMvDataBuffer; |
| state->s4xMeDistortionBuffer = m_4xMeDistortionBuffer; |
| |
| // Reference lookups |
| // Use max of HEVC num surfaces because this is shared functionality between HEVC and VP9 and HEVC has less |
| for (auto i = 0; i < CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC ; ++i) |
| { |
| state->pRefList[i] = m_refList[i]; |
| } |
| |
| for (auto i = 0 ; i < CODEC_VP9_NUM_REF_FRAMES ; ++i) |
| { |
| state->PicIdx[i] = m_picIdx[i]; |
| } |
| |
| // Add references |
| CODEC_PICTURE codecPicture; |
| MOS_ZeroMemory(&codecPicture, sizeof(codecPicture)); |
| codecPicture.PicFlags = PICTURE_FRAME; |
| uint8_t picCount = 0; |
| if (m_lastRefPic) |
| { |
| codecPicture.FrameIdx = m_vp9PicParams->RefFlags.fields.LastRefIdx; |
| state->RefPicList[LIST_0][picCount] = codecPicture; |
| picCount++; |
| } |
| |
| if (m_goldenRefPic) |
| { |
| codecPicture.FrameIdx = m_vp9PicParams->RefFlags.fields.GoldenRefIdx; |
| state->RefPicList[LIST_0][picCount] = codecPicture; |
| picCount++; |
| } |
| |
| if (m_altRefPic) |
| { |
| codecPicture.FrameIdx = m_vp9PicParams->RefFlags.fields.AltRefIdx; |
| state->RefPicList[LIST_0][picCount] = codecPicture; |
| picCount++; |
| } |
| |
| // Mark L1[0] as INVALID so it's not added later, L1 refs should never be added for VP9, L1[0] should |
| // always be marked as invalid and num_ref_idx_l1_active_minus1 should always == 0 |
| state->RefPicList[LIST_1][0].PicFlags = PICTURE_INVALID; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::VdencSetCurbeHmeKernel( |
| VdencVmeState* state) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(state); |
| |
| bool isFramePicture = CodecHal_PictureIsFrame(state->CurrOriginalPic); |
| char qpPrimeY = (state->QpY) + state->slice_qp_delta; |
| |
| VdencMeCurbe curbe; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( |
| &curbe, |
| sizeof(VdencMeCurbe), |
| m_vdencMeCurbeInit, |
| sizeof(VdencMeCurbe))); |
| |
| uint8_t mvShiftFactor = 0, prevMvReadPosFactor = 0; |
| bool useMvFromPrevStep = false, writeDistortions = false; |
| uint32_t scaleFactor = 0; |
| PMHW_KERNEL_STATE kernelState; |
| if (state->b16xMeInUse) |
| { |
| kernelState = &m_vdencMeKernelState; |
| useMvFromPrevStep = false; |
| writeDistortions = false; |
| scaleFactor = SCALE_FACTOR_16x; |
| mvShiftFactor = 2; |
| prevMvReadPosFactor = 1; |
| } |
| else |
| { |
| kernelState = &m_vdencStreaminKernelState; |
| useMvFromPrevStep = true; |
| writeDistortions = true; |
| scaleFactor = SCALE_FACTOR_4x; |
| mvShiftFactor = 2; |
| prevMvReadPosFactor = 0; |
| } |
| |
| curbe.DW3.SubPelMode = 3; |
| |
| if (m_fieldScalingOutputInterleaved) |
| { |
| curbe.DW3.SrcAccess = |
| curbe.DW3.RefAccess = CodecHal_PictureIsField(state->CurrOriginalPic) ? 1 : 0; |
| curbe.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(state->CurrOriginalPic) ? 1 : 0; |
| } |
| |
| curbe.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1; |
| curbe.DW4.PictureWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor); |
| curbe.DW5.QpPrimeY = qpPrimeY; |
| curbe.DW6.WriteDistortions = writeDistortions; |
| curbe.DW6.UseMvFromPrevStep = useMvFromPrevStep; |
| curbe.DW6.SuperCombineDist = 5; |
| curbe.DW6.MaxVmvR = m_maxMvLen; |
| |
| if (m_pictureCodingType == B_TYPE) |
| { |
| // This field is irrelevant since we are not using the bi-direct search. |
| curbe.DW1.BiWeight = state->dwBiWeight; |
| curbe.DW13.NumRefIdxL1MinusOne = state->num_ref_idx_l1_active_minus1; |
| } |
| |
| if (m_pictureCodingType == P_TYPE || m_pictureCodingType == B_TYPE) |
| { |
| curbe.DW13.NumRefIdxL0MinusOne = state->num_ref_idx_l0_active_minus1; |
| } |
| |
| curbe.DW30.ActualMBHeight = (MOS_ALIGN_CEIL(m_frameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT ) / 32); |
| curbe.DW30.ActualMBWidth = (MOS_ALIGN_CEIL(m_frameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH) / 32); |
| curbe.DW13.RefStreaminCost = 0; |
| // This flag is to indicate the ROI source type instead of indicating ROI is enabled or not |
| curbe.DW13.ROIEnable = 0; |
| |
| uint8_t targetUsage = state->TargetUsage; |
| uint8_t meMethod = 0; |
| if (m_pictureCodingType == B_TYPE) |
| { |
| meMethod = m_bMeMethodGeneric[targetUsage]; |
| } |
| else |
| { |
| meMethod = m_meMethodGeneric[targetUsage]; |
| } |
| |
| uint8_t tableIdx = (m_pictureCodingType == B_TYPE) ? 1 : 0; |
| eStatus = MOS_SecureMemcpy(&(curbe.SPDelta), 14 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][meMethod], 14 * sizeof(uint32_t)); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory."); |
| return eStatus; |
| } |
| |
| if (state->b4xMeInUse) |
| { |
| //StreamIn CURBE |
| curbe.DW6.LCUSize = 1;//Only LCU64 supported by the VDEnc HW |
| curbe.DW6.InputStreamInEn = state->segmapProvided; |
| curbe.DW31.NumImePredictors = CODECHAL_VDENC_NUMIMEPREDICTORS; |
| curbe.DW31.MaxCuSize = 3; |
| curbe.DW31.MaxTuSize = 3; |
| switch (state->TargetUsage) |
| { |
| case 1: |
| case 4: |
| curbe.DW36.NumMergeCandCu64x64 = 4; |
| curbe.DW36.NumMergeCandCu32x32 = 3; |
| curbe.DW36.NumMergeCandCu16x16 = 2; |
| curbe.DW36.NumMergeCandCu8x8 = 1; |
| break; |
| case 7: |
| curbe.DW36.NumMergeCandCu64x64 = 2; |
| curbe.DW36.NumMergeCandCu32x32 = 2; |
| curbe.DW36.NumMergeCandCu16x16 = 2; |
| curbe.DW36.NumMergeCandCu8x8 = 0; |
| break; |
| } |
| } |
| |
| curbe.DW40._4xMeMvOutputDataSurfIndex = HmeMvDataSurfaceCm; |
| curbe.DW41._16xOr32xMeMvInputDataSurfIndex = Hme16xMeMvDataSurfaceCm; |
| curbe.DW42._4xMeOutputDistSurfIndex = HmeDistortionSurfaceCm; |
| curbe.DW43._4xMeOutputBrcDistSurfIndex = HmeBrcDistortionCm; |
| curbe.DW44.VMEFwdInterPredictionSurfIndex = HmeCurrForFwdRefCm; |
| curbe.DW45.VMEBwdInterPredictionSurfIndex = HmeCurrForBwdRefCm; |
| curbe.DW46.VDEncStreamInOutputSurfIndex = HmeVdencStreaminOutputCm; |
| curbe.DW47.VDEncStreamInInputSurfIndex = HmeVdencStreaminInputCm; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(kernelState->m_dshRegion.AddData( |
| &curbe, |
| kernelState->dwCurbeOffset, |
| sizeof(curbe))); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::VdencSendHmeSurfaces( |
| VdencVmeState* state, |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(state); |
| |
| bool isCurrFieldPicture = CodecHal_PictureIsField(m_currOriginalPic) ? true : false; |
| bool isCurrBottomField = CodecHal_PictureIsBottomField(m_currOriginalPic) ? true : false; |
| uint8_t currVDirection = (!isCurrFieldPicture) ? CODECHAL_VDIRECTION_FRAME : |
| ((isCurrBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); |
| |
| PMHW_KERNEL_STATE kernelState = nullptr; |
| PCODECHAL_ENCODE_BINDING_TABLE_GENERIC bindingTable = nullptr; |
| PMOS_SURFACE currScaledSurface = nullptr, meMvDataBuffer = nullptr; |
| uint32_t meMvBottomFieldOffset = 0, currScaledBottomFieldOffset = 0; |
| uint32_t downscaledWidthInMb = 0, downscaledHeightInMb = 0; |
| if (state->b16xMeInUse) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(&state->s16xMeMvDataBuffer); |
| kernelState = &m_vdencMeKernelState; |
| bindingTable = &m_vdencMeKernelBindingTable; |
| currScaledSurface = m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER); |
| meMvDataBuffer = &state->s16xMeMvDataBuffer; |
| meMvBottomFieldOffset = 0; |
| currScaledBottomFieldOffset = m_scaled16xBottomFieldOffset; |
| downscaledWidthInMb = m_downscaledWidthInMb16x; |
| downscaledHeightInMb = m_downscaledHeightInMb16x; |
| } |
| else |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(&state->s4xMeMvDataBuffer); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(&m_resVdencStreamInBuffer[m_currRecycledBufIdx]); |
| kernelState = &m_vdencStreaminKernelState; |
| bindingTable = &m_vdencStreaminKernelBindingTable; |
| currScaledSurface = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER); |
| meMvDataBuffer = &state->s4xMeMvDataBuffer; |
| meMvBottomFieldOffset = 0; |
| currScaledBottomFieldOffset = m_scaledBottomFieldOffset; |
| downscaledWidthInMb = m_downscaledWidthInMb4x; |
| downscaledHeightInMb = m_downscaledHeightInMb4x; |
| } |
| |
| uint32_t width = MOS_ALIGN_CEIL(downscaledWidthInMb * 32, 64); |
| uint32_t height = downscaledHeightInMb * 4 * 10; |
| |
| // Force the values |
| meMvDataBuffer->dwWidth = width; |
| meMvDataBuffer->dwHeight = height; |
| meMvDataBuffer->dwPitch = width; |
| |
| CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams; |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = meMvDataBuffer; |
| surfaceCodecParams.dwOffset = meMvBottomFieldOffset; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeMvDataSurfaceCm]; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| if (state->b4xMeInUse) |
| { |
| // Pass 16x MV to 4x ME operation |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = &state->s16xMeMvDataBuffer; |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[Hme16xMeMvDataSurfaceCm]; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bIs2DSurface = true; |
| surfaceCodecParams.bMediaBlockRW = true; |
| surfaceCodecParams.psSurface = &state->s4xMeDistortionBuffer; |
| surfaceCodecParams.dwOffset = 0; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeDistortionSurfaceCm]; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| // Setup references 1...n |
| // LIST 0 references |
| MOS_SURFACE refScaledSurface = *currScaledSurface; |
| for (uint8_t refIdx = 0; refIdx <= state->num_ref_idx_l0_active_minus1; refIdx++) |
| { |
| CODEC_PICTURE refPic = state->RefPicList[LIST_0][refIdx]; |
| |
| if (!CodecHal_PictureIsInvalid(refPic)) |
| { |
| if (refIdx == 0) |
| { |
| // Current Picture Y - VME |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = currScaledSurface; |
| surfaceCodecParams.dwOffset = isCurrBottomField ? currScaledBottomFieldOffset : 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeCurrForFwdRefCm]; |
| surfaceCodecParams.ucVDirection = currVDirection; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| bool isRefFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0; |
| bool isRefBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; |
| uint8_t refPicIdx = state->PicIdx[refPic.FrameIdx].ucPicIdx; |
| uint8_t scaledIdx = state->pRefList[refPicIdx]->ucScalingIdx; |
| if (state->b16xMeInUse) |
| { |
| MOS_SURFACE* p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx); |
| if (p16xSurface != nullptr) |
| { |
| refScaledSurface.OsResource = p16xSurface->OsResource; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); |
| } |
| } |
| else |
| { |
| MOS_SURFACE* p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx); |
| if (p4xSurface != nullptr) |
| { |
| refScaledSurface.OsResource = p4xSurface->OsResource; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); |
| } |
| } |
| uint32_t refScaledBottomFieldOffset = isRefBottomField ? currScaledBottomFieldOffset : 0; |
| |
| // L0 Reference Picture Y - VME |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = &refScaledSurface; |
| surfaceCodecParams.dwOffset = isRefBottomField ? refScaledBottomFieldOffset : 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeFwdRefIdx0Cm + (refIdx * 2)]; |
| surfaceCodecParams.ucVDirection = !isCurrFieldPicture ? CODECHAL_VDIRECTION_FRAME : |
| ((isRefBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| |
| //List1 |
| for (uint8_t refIdx = 0; refIdx <= state->num_ref_idx_l1_active_minus1; refIdx++) |
| { |
| CODEC_PICTURE refPic = state->RefPicList[LIST_1][refIdx]; |
| |
| if (!CodecHal_PictureIsInvalid(refPic)) |
| { |
| if (refIdx == 0) |
| { |
| // Current Picture Y - VME |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = currScaledSurface; |
| surfaceCodecParams.dwOffset = isCurrBottomField ? currScaledBottomFieldOffset : 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_CURR_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeCurrForBwdRefCm]; |
| surfaceCodecParams.ucVDirection = currVDirection; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| bool isRefFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0; |
| bool isRefBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0; |
| uint8_t refPicIdx = state->PicIdx[refPic.FrameIdx].ucPicIdx; |
| uint8_t scaledIdx = state->pRefList[refPicIdx]->ucScalingIdx; |
| if (state->b16xMeInUse) |
| { |
| MOS_SURFACE* p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx); |
| if (p16xSurface != nullptr) |
| { |
| refScaledSurface.OsResource = p16xSurface->OsResource; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); |
| } |
| } |
| else |
| { |
| MOS_SURFACE* p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx); |
| if (p4xSurface != nullptr) |
| { |
| refScaledSurface.OsResource = p4xSurface->OsResource; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface"); |
| } |
| } |
| |
| uint32_t refScaledBottomFieldOffset = isRefBottomField ? currScaledBottomFieldOffset : 0; |
| |
| // L1 Reference Picture Y - VME |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| surfaceCodecParams.bUseAdvState = true; |
| surfaceCodecParams.psSurface = &refScaledSurface; |
| surfaceCodecParams.dwOffset = isRefBottomField ? refScaledBottomFieldOffset : 0; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_REF_ENCODE].Value; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeBwdRefIdx0Cm + (refIdx * 2)]; |
| surfaceCodecParams.ucVDirection = !isCurrFieldPicture ? CODECHAL_VDIRECTION_FRAME : |
| ((isRefBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| } |
| |
| if (state->b4xMeInUse) |
| { |
| MOS_ZeroMemory(&surfaceCodecParams, sizeof(surfaceCodecParams)); |
| 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); |
| surfaceCodecParams.bIs2DSurface = false; |
| surfaceCodecParams.presBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx]; |
| surfaceCodecParams.dwBindingTableOffset = bindingTable->dwBindingTableEntries[HmeVdencStreaminOutputCm]; |
| surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value; |
| surfaceCodecParams.bIsWritable = true; |
| surfaceCodecParams.bRenderTarget = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState( |
| m_hwInterface, |
| cmdBuffer, |
| &surfaceCodecParams, |
| kernelState)); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::VdencHmeKernel( |
| VdencVmeState* state) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(state); |
| |
| PMHW_KERNEL_STATE kernelState = nullptr; |
| CODECHAL_MEDIA_STATE_TYPE encFunctionType; |
| if (state->b16xMeInUse) |
| { |
| kernelState = &m_vdencMeKernelState; |
| encFunctionType = CODECHAL_MEDIA_STATE_16X_ME; |
| } |
| else |
| { |
| kernelState = &m_vdencStreaminKernelState; |
| encFunctionType = CODECHAL_MEDIA_STATE_4X_ME; |
| } |
| |
| // If Single Task Phase is not enabled, use BT count for the kernel state. |
| if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported) |
| { |
| uint32_t maxBtCount = m_singleTaskPhaseSupported ? |
| m_maxBtCount : kernelState->KernelParams.iBTCount; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf( |
| m_stateHeapInterface, |
| maxBtCount)); |
| m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(maxBtCount); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); |
| } |
| |
| // Set up the DSH/SSH as normal |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AssignDshAndSshSpace( |
| m_stateHeapInterface, |
| kernelState, |
| false, |
| 0, |
| false, |
| m_storeData)); |
| |
| MHW_INTERFACE_DESCRIPTOR_PARAMS idParams; |
| MOS_ZeroMemory(&idParams, sizeof(idParams)); |
| idParams.pKernelState = kernelState; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetInterfaceDescriptor( |
| m_stateHeapInterface, |
| 1, |
| &idParams)); |
| |
| //Setup curbe for StreamIn Kernel |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VdencSetCurbeHmeKernel( |
| state)); |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_DSH_TYPE, |
| kernelState)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCurbe( |
| encFunctionType, |
| kernelState)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_ISH_TYPE, |
| kernelState)); |
| ) |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| SendKernelCmdsParams sendKernelCmdsParams = SendKernelCmdsParams(); |
| sendKernelCmdsParams.EncFunctionType = encFunctionType; |
| sendKernelCmdsParams.pKernelState = kernelState; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendGenericKernelCmds(&cmdBuffer, &sendKernelCmdsParams)); |
| |
| // Add binding table |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSetBindingTable( |
| m_stateHeapInterface, |
| kernelState)); |
| |
| uint32_t scalingFactor = (state->b16xMeInUse) ? SCALE_FACTOR_16x : SCALE_FACTOR_4x; |
| |
| VdencSendHmeSurfaces(state, &cmdBuffer); |
| |
| // Dump SSH for ME kernel |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion( |
| encFunctionType, |
| MHW_SSH_TYPE, |
| kernelState))); |
| |
| uint32_t resolutionX = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / scalingFactor); |
| uint32_t resolutionY = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scalingFactor); |
| |
| CODECHAL_WALKER_CODEC_PARAMS walkerCodecParams; |
| MOS_ZeroMemory(&walkerCodecParams, sizeof(walkerCodecParams)); |
| walkerCodecParams.WalkerMode = m_walkerMode; |
| walkerCodecParams.dwResolutionX = resolutionX; |
| walkerCodecParams.dwResolutionY = resolutionY; |
| walkerCodecParams.bNoDependency = true; |
| walkerCodecParams.bMbaff = state->bMbaff ? true : false; |
| walkerCodecParams.bGroupIdSelectSupported = m_groupIdSelectSupported; |
| walkerCodecParams.ucGroupId = m_groupId; |
| |
| MHW_WALKER_PARAMS walkerParams; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalInitMediaObjectWalkerParams( |
| m_hwInterface, |
| &walkerParams, |
| &walkerCodecParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObjectWalkerCmd( |
| &cmdBuffer, |
| &walkerParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, encFunctionType)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnSubmitBlocks( |
| m_stateHeapInterface, |
| kernelState)); |
| if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnUpdateGlobalCmdBufId( |
| m_stateHeapInterface)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| encFunctionType, |
| nullptr))); |
| |
| m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) |
| { |
| m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw); |
| m_lastTaskInPhase = false; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ConstructPakInsertObjBatchBuf( |
| PMOS_RESOURCE pakInsertObjBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (!pakInsertObjBuffer) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| CODECHAL_ENCODE_ASSERT(m_numNalUnit == 1); |
| |
| uint32_t nalUnitSize = m_nalUnitParams[0]->uiSize; |
| uint32_t nalUnitOffset = m_nalUnitParams[0]->uiOffset; |
| CODECHAL_ENCODE_ASSERT(nalUnitSize > 0 && nalUnitSize < CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, pakInsertObjBuffer, &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams; |
| MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams)); |
| pakInsertObjectParams.bEmulationByteBitsInsert = false; |
| pakInsertObjectParams.uiSkipEmulationCheckCount = m_nalUnitParams[0]->uiSkipEmulationCheckCount; |
| pakInsertObjectParams.pBsBuffer = &m_bsBuffer; |
| pakInsertObjectParams.dwBitSize = nalUnitSize * 8; |
| pakInsertObjectParams.dwOffset = nalUnitOffset; |
| pakInsertObjectParams.bEndOfSlice = false; |
| pakInsertObjectParams.bLastHeader = true; |
| |
| MOS_COMMAND_BUFFER constructedCmdBuf; |
| MOS_ZeroMemory(&constructedCmdBuf, sizeof(constructedCmdBuf)); |
| constructedCmdBuf.pCmdBase = (uint32_t *)data; |
| constructedCmdBuf.pCmdPtr = (uint32_t *)data; |
| constructedCmdBuf.iOffset = 0; |
| constructedCmdBuf.iRemaining = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPakInsertObject(&constructedCmdBuf, &pakInsertObjectParams)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr)); |
| |
| if (data) |
| { |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| pakInsertObjBuffer); |
| } |
| return eStatus; |
| } |
| |
| void CodechalVdencVp9State::PutDataForCompressedHdr( |
| CompressedHeader* compressedHdr, |
| uint32_t bit, |
| uint32_t prob, |
| uint32_t binIdx) |
| { |
| compressedHdr[binIdx].fields.valid = 1; |
| compressedHdr[binIdx].fields.bin_probdiff = 1; |
| compressedHdr[binIdx].fields.bin = bit; |
| compressedHdr[binIdx].fields.prob = (prob == 128) ? 0 : 1; |
| } |
| |
| // This function is NOT needed when HUC kernel is enabled. |
| // It only uses the default probablity and can NOT handle probability update! |
| MOS_STATUS CodechalVdencVp9State::RefreshFrameInternalBuffers() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_ASSERT(m_vp9PicParams->PicFlags.fields.refresh_frame_context == 0); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| bool keyFrame = !m_vp9PicParams->PicFlags.fields.frame_type; |
| bool isScaling = (m_oriFrameWidth == m_prevFrameInfo.FrameWidth) && |
| (m_oriFrameHeight == m_prevFrameInfo.FrameHeight) |
| ? false |
| : true; |
| bool resetSegIdBuf = keyFrame || isScaling || |
| m_vp9PicParams->PicFlags.fields.error_resilient_mode || |
| m_vp9PicParams->PicFlags.fields.intra_only; |
| |
| if (resetSegIdBuf) |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resSegmentIdBuffer, |
| &lockFlagsWriteOnly); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MOS_ZeroMemory(data, m_picSizeInSb * CODECHAL_CACHELINE_SIZE); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resSegmentIdBuffer)); |
| } |
| |
| //refresh inter probs in needed frame context buffers |
| bool clearAll = (keyFrame || m_vp9PicParams->PicFlags.fields.error_resilient_mode || |
| (m_vp9PicParams->PicFlags.fields.reset_frame_context == 3 && m_vp9PicParams->PicFlags.fields.intra_only)); |
| |
| bool clearSpecified = (m_vp9PicParams->PicFlags.fields.reset_frame_context == 2 && |
| m_vp9PicParams->PicFlags.fields.intra_only); |
| |
| MOS_STATUS status1 = MOS_STATUS_SUCCESS; |
| for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++) |
| { |
| if (clearAll || (clearSpecified && i == m_vp9PicParams->PicFlags.fields.frame_context_idx)) |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resProbBuffer[i], |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| status1 = ContextBufferInit(data, keyFrame || m_vp9PicParams->PicFlags.fields.intra_only); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resProbBuffer[i])); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(status1); |
| |
| m_clearAllToKey[i] = keyFrame || m_vp9PicParams->PicFlags.fields.intra_only; |
| if (i == 0) //reset this flag when Ctx buffer 0 is cleared. |
| { |
| m_isPreCtx0InterProbSaved = false; |
| } |
| } |
| else if (m_clearAllToKey[i]) // this buffer is inside inter frame, but its interProb has not been init to default inter type data. |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resProbBuffer[i], |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| 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. |
| { |
| status1 = CtxBufDiffInit(data, true); |
| } |
| else // set interprob to be inter type. |
| { |
| status1 = CtxBufDiffInit(data, false); |
| m_clearAllToKey[i] = false; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resProbBuffer[i])); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(status1); |
| } |
| 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. |
| { // in this case, only context buffer 0 will be temporally overwritten. |
| if (m_vp9PicParams->PicFlags.fields.intra_only) |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resProbBuffer[i], |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| if (!m_isPreCtx0InterProbSaved) // only when non intra-only -> intra-only need save InterProb, otherwise leave saved InterProb unchanged. |
| { |
| //save current interprob |
| 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)); |
| m_isPreCtx0InterProbSaved = true; |
| } |
| status1 = CtxBufDiffInit(data, true); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resProbBuffer[i])); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(status1); |
| } |
| else if (m_isPreCtx0InterProbSaved) |
| { |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resProbBuffer[i], |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| //reload former interprob |
| 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)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resProbBuffer[i])); |
| |
| m_isPreCtx0InterProbSaved = false; |
| } |
| } |
| } |
| |
| // compressed header |
| uint32_t index = 0; |
| CompressedHeader* compressedHdr = (CompressedHeader*)MOS_AllocAndZeroMemory(sizeof(CompressedHeader)* (PAK_COMPRESSED_HDR_SYNTAX_ELEMS + 1)); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(compressedHdr); |
| |
| if (!m_vp9PicParams->PicFlags.fields.LosslessFlag) |
| { |
| if (m_txMode == CODEC_VP9_TX_SELECTABLE) |
| { |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX); |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1); |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_SELECT_IDX); |
| } |
| else if (m_txMode == CODEC_VP9_TX_32X32) |
| { |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX); |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1); |
| PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_TX_MODE_SELECT_IDX); |
| } |
| else |
| { |
| PutDataForCompressedHdr(compressedHdr, (m_txMode & 0x02) >> 1, 128, PAK_TX_MODE_IDX); |
| PutDataForCompressedHdr(compressedHdr, (m_txMode & 0x01), 128, PAK_TX_MODE_IDX + 1); |
| } |
| |
| if (m_txMode == CODEC_VP9_TX_SELECTABLE) |
| { |
| index = PAK_TX_8x8_PROB_IDX; |
| for (auto i = 0; i < 2; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| |
| index = PAK_TX_16x16_PROB_IDX; |
| for (auto i = 0; i < 2; i++) |
| { |
| for (auto j = 0; j < 2; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| |
| index = PAK_TX_32x32_PROB_IDX; |
| for (auto i = 0; i < 2; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| } |
| } |
| |
| for (auto coeffSize = 0; coeffSize < 4; coeffSize++) |
| { |
| if (coeffSize > m_txMode) |
| { |
| continue; |
| } |
| |
| switch (coeffSize) |
| { |
| case 0: index = PAK_TX_4x4_COEFF_PROB_IDX; |
| break; |
| case 1: index = PAK_TX_8x8_COEFF_PROB_IDX; |
| break; |
| case 2: index = PAK_TX_16x16_COEFF_PROB_IDX; |
| break; |
| case 3: index = PAK_TX_32x32_COEFF_PROB_IDX; |
| break; |
| } |
| |
| PutDataForCompressedHdr(compressedHdr, 0, 128, index); |
| } |
| |
| PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX); |
| PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 2); |
| PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 4); |
| |
| if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only) |
| { |
| index = PAK_INTER_MODE_CTX_IDX; |
| for (auto i = 0; i < 7; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| |
| if (m_vp9PicParams->PicFlags.fields.mcomp_filter_type == CODEC_VP9_SWITCHABLE_FILTERS) |
| { |
| index = PAK_SWITCHABLE_FILTER_CTX_IDX; |
| for (auto i = 0; i < 4; i++) |
| { |
| for (auto j = 0; j < 2; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| } |
| |
| index = PAK_INTRA_INTER_CTX_IDX; |
| for (auto i = 0; i < 4; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| |
| bool allowComp = !( |
| (m_vp9PicParams->RefFlags.fields.LastRefSignBias && m_vp9PicParams->RefFlags.fields.GoldenRefSignBias && m_vp9PicParams->RefFlags.fields.AltRefSignBias) || |
| (!m_vp9PicParams->RefFlags.fields.LastRefSignBias && !m_vp9PicParams->RefFlags.fields.GoldenRefSignBias && !m_vp9PicParams->RefFlags.fields.AltRefSignBias)); |
| |
| if (allowComp) |
| { |
| if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode == PRED_MODE_HYBRID) |
| { |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX); |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX + 1); |
| index = PAK_HYBRID_PRED_CTX_IDX; |
| for (auto i = 0; i < 5; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| else if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode == PRED_MODE_COMPOUND) |
| { |
| PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX); |
| PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX + 1); |
| } |
| else |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX); |
| } |
| } |
| |
| if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode != PRED_MODE_COMPOUND) |
| { |
| index = PAK_SINGLE_REF_PRED_CTX_IDX; |
| for (auto i = 0; i < 5; i++) |
| { |
| for (auto j = 0; j < 2; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| } |
| |
| if (m_vp9PicParams->PicFlags.fields.comp_prediction_mode != PRED_MODE_SINGLE) |
| { |
| index = PAK_CMPUND_PRED_CTX_IDX; |
| for (auto i = 0; i < 5; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| |
| index = PAK_INTRA_MODE_PROB_CTX_IDX; |
| for (auto i = 0; i < 4; i++) |
| { |
| for (auto j = 0; j < 9; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| |
| index = PAK_PARTITION_PROB_IDX; |
| for (auto i = 0; i < 16; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 2; |
| } |
| } |
| |
| index = PAK_MVJOINTS_PROB_IDX; |
| for (auto i = 0; i < 3; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| |
| for (auto d = 0; d < 2; d++) |
| { |
| index = (d == 0) ? PAK_MVCOMP0_IDX : PAK_MVCOMP1_IDX; |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| for (auto i = 0; i < 10; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| for (auto i = 0; i < 10; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| } |
| |
| for (auto d = 0; d < 2; d++) |
| { |
| index = (d == 0) ? PAK_MVFRAC_COMP0_IDX : PAK_MVFRAC_COMP1_IDX; |
| for (auto i = 0; i < 3; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| for (auto i = 0; i < 3; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| for (auto i = 0; i < 3; i++) |
| { |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| } |
| } |
| |
| if (m_vp9PicParams->PicFlags.fields.allow_high_precision_mv) |
| { |
| for (auto d = 0; d < 2; d++) |
| { |
| index = (d == 0) ? PAK_MVHP_COMP0_IDX : PAK_MVHP_COMP1_IDX; |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| index += 8; |
| PutDataForCompressedHdr(compressedHdr, 0, 252, index); |
| } |
| } |
| } |
| |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resCompressedHeaderBuffer, |
| &lockFlagsWriteOnly); |
| if(data == nullptr) |
| { |
| MOS_FreeMemory(compressedHdr); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(nullptr); |
| } |
| |
| for (uint32_t i = 0; i < PAK_COMPRESSED_HDR_SYNTAX_ELEMS; i += 2) |
| { |
| data[i>>1] = (compressedHdr[i + 1].value << 0x04) | (compressedHdr[i].value); |
| } |
| |
| eStatus = (MOS_STATUS) m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resCompressedHeaderBuffer); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| MOS_FreeMemory(compressedHdr); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(eStatus); |
| } |
| |
| MOS_FreeMemory(compressedHdr); |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ExecutePictureLevel() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| // resize CommandBuffer Size for every BRC pass |
| if (!m_singleTaskPhaseSupported) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); |
| } |
| |
| PerfTagSetting perfTag; |
| CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE); |
| |
| if (m_currPass == 0) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPakInsertObjBatchBuf(&m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx])); |
| } |
| |
| // For VDENC dynamic scaling, here are the steps we need to process |
| // Pass 0. VDENC + PAK Pass |
| // a. If this is Dys + BRC case, then run BRC Pass 0 |
| // b. Ref frame scaling |
| // c. VDENC + PAK pass to stream out PakObjCmd |
| // Pass 1 -> Reset to Pass 0 so as to run HPU Pass 0 |
| // a. If this is Dys + BRC case, then run BRC Pass 1 |
| // b. Run HPU Pass 0 |
| // c. Lite Pass (Pak only multi pass enabled) to stream in |
| // PakObjCmd from previous pass |
| // Pass 1 -> Only run HPU Pass 1 to update the probabilities for |
| // next frame. Repak is disabled for performance reasons |
| if ( m_dysRefFrameFlags != DYS_REF_NONE) |
| { |
| if (m_currPass == 0) |
| { |
| if (m_dysVdencMultiPassEnabled) |
| { |
| if (Mos_ResourceIsNull(&m_resVdencDysPictureState2NdLevelBatchBuffer)) |
| { |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; |
| |
| MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; |
| allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; |
| allocParamsForBufferLinear.Format = Format_Buffer; |
| allocParamsForBufferLinear.dwBytes = m_vdencPicStateSecondLevelBatchBufferSize; |
| allocParamsForBufferLinear.pBufName = "VDEnc DYS Picture Second Level Batch Buffer"; |
| |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencDysPictureState2NdLevelBatchBuffer); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc DYS Picture Second Level Batch Buffer."); |
| return eStatus; |
| } |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); |
| } |
| } |
| else if (m_currPass == 1) |
| { |
| m_hucEnabled = m_dysHucEnabled; // recover huc state |
| m_vdencPakonlyMultipassEnabled = true; |
| m_dysRefFrameFlags = DYS_REF_NONE; |
| m_currPass = 0; // reset ucCurrPass = 0 to run the Huc |
| m_lastTaskInPhase = false; |
| } |
| } |
| else |
| { |
| if (IsFirstPass() && m_vdencBrcEnabled) |
| { |
| m_vdencPakObjCmdStreamOutEnabled = true; |
| m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface; |
| } |
| else |
| { |
| m_vdencPakObjCmdStreamOutEnabled = false; |
| } |
| } |
| |
| if ((m_dysRefFrameFlags != DYS_REF_NONE) && m_dysVdencMultiPassEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPicStateBatchBuf(&m_resVdencDysPictureState2NdLevelBatchBuffer)); |
| } |
| else |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPicStateBatchBuf(&m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex])); |
| } |
| |
| if (m_vdencBrcEnabled) |
| { |
| // Invoke BRC init/reset FW |
| if (m_brcInit || m_brcReset) |
| { |
| if (!m_singleTaskPhaseSupported) |
| { |
| //Reset earlier set PAK perf tag |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET); |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcInitReset()); |
| m_brcInit = m_brcReset = false; |
| } |
| // For multipass and singlepass+RePAK we call BRC update for all passes except last pass (RePAK) |
| // For single pass w/o RePAK (1 total pass) we call BRC update on one and only pass |
| if ((m_currPass < m_numPasses) || (m_currPass == 0 && m_numPasses == 0)) |
| { |
| bool origSingleTaskPhase = m_singleTaskPhaseSupported; |
| // If this is the case of Dynamic Scaling + BRC Pass 0' VDENC + Pak pass |
| // As a WA, Disable SingleTaskPhase before running 1st BRC update |
| // To run HPU0 on the next pass i.e Pak only pass, we make Pass 1 as Pass 0 in which case the |
| // BRC dmem buffer( resVdencBrcUpdateDmemBuffer[0] ) will get overridden if we do not submit BRC command now. |
| if (m_dysBrc && m_dysRefFrameFlags != DYS_REF_NONE) |
| { |
| m_singleTaskPhaseSupported = false; |
| } |
| if (!m_singleTaskPhaseSupported) |
| { |
| //Reset performance buffer used for BRC init |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE); |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcUpdate()); |
| |
| //Restore the original state of SingleTaskPhaseSupported flag |
| m_singleTaskPhaseSupported = origSingleTaskPhase; |
| } |
| } |
| |
| // run HuC_VP9Prob first pass (it runs in parallel with ENC) |
| if (m_hucEnabled) |
| { |
| if ((m_currPass == 0) || (m_currPass == m_numPasses)) // Before the first PAK pass and for RePak pass |
| { |
| if (!m_singleTaskPhaseSupported) |
| { |
| //Reset earlier set PAK perf tag |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| // Add Hpu tag here after added |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCVp9Prob()); |
| } |
| } |
| else |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(RefreshFrameInternalBuffers()); |
| } |
| |
| //Ref frame scaling |
| if (m_dysRefFrameFlags != DYS_REF_NONE && m_currPass == 0) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(DysRefFrames()); |
| |
| if (m_dysVdencMultiPassEnabled) |
| { |
| m_singleTaskPhaseSupported = true; |
| m_firstTaskInPhase = true; |
| m_vdencPakObjCmdStreamOutEnabled = true; |
| m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface; |
| } |
| else |
| { |
| m_hucEnabled = m_dysHucEnabled; // recover huc state |
| } |
| } |
| |
| // set HCP_SURFACE_STATE values |
| MHW_VDBOX_SURFACE_PARAMS surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID + 1]; |
| for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++) |
| { |
| MOS_ZeroMemory(&surfaceParams[i], sizeof(surfaceParams[i])); |
| surfaceParams[i].Mode = m_mode; |
| surfaceParams[i].ucSurfaceStateId = i; |
| surfaceParams[i].ChromaType = m_outputChromaFormat; |
| surfaceParams[i].bSrc8Pak10Mode = (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) && (!m_vp9SeqParams->SeqFlags.fields.SourceBitDepth); |
| |
| switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) |
| { |
| case VP9_ENCODED_BIT_DEPTH_10: //10 bit encoding |
| { |
| surfaceParams[i].ucBitDepthChromaMinus8 = 2; |
| surfaceParams[i].ucBitDepthLumaMinus8 = 2; |
| break; |
| } |
| default: |
| { |
| surfaceParams[i].ucBitDepthChromaMinus8 = 0; |
| surfaceParams[i].ucBitDepthLumaMinus8 = 0; |
| break; |
| } |
| } |
| } |
| |
| // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled |
| PMOS_SURFACE refSurface[3], refSurfaceNonScaled[3], dsRefSurface4x[3], dsRefSurface8x[3]; |
| for (auto i = 0; i < 3; i++) |
| { |
| refSurface[i] = refSurfaceNonScaled[i] = dsRefSurface4x[i] = dsRefSurface8x[i] = nullptr; |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetHcpSrcSurfaceParams(surfaceParams, refSurface, refSurfaceNonScaled, dsRefSurface4x, dsRefSurface8x)); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| if (!m_singleTaskPhaseSupported) |
| { |
| CODECHAL_ENCODE_SET_PERFTAG_INFO(perfTag, CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE); |
| } |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| // Send command buffer header at the beginning (OS dependent) |
| // frame tracking tag is only added in the last command buffer header |
| bool requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| } |
| |
| // Repak conditional batch buffer end based on repak flag written by Huc to HUC_STATUS regster |
| if (m_hucEnabled && (m_numPasses > 0) && (m_currPass == m_numPasses)) |
| { |
| // Insert conditional batch buffer end |
| // Success = bit 30 set to 1, Do RePAK = bit 31 set to 1, value is always 0; if 0 < memory, continue |
| MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams; |
| MOS_ZeroMemory( |
| &miConditionalBatchBufferEndParams, |
| sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS)); |
| |
| miConditionalBatchBufferEndParams.presSemaphoreBuffer = |
| &m_resHucPakMmioBuffer; |
| // Make the DisableCompareMask 0, so that the HW will do AND operation on DW0 with Mask DW1, refer to HuCVp9Prob() for the settings |
| // and compare the result against the Semaphore data which in our case dwValue = 0. |
| // If result > dwValue then continue execution otherwise terminate the batch buffer |
| miConditionalBatchBufferEndParams.bDisableCompareMask = false; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd( |
| &cmdBuffer, |
| &miConditionalBatchBufferEndParams)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); |
| |
| PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = nullptr; |
| // set HCP_PIPE_MODE_SELECT values |
| pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams(); |
| SetHcpPipeModeSelectParams(*pipeModeSelectParams); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams)); |
| |
| // This wait cmd is needed to make sure copy command is done as suggested by HW folk |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMfxWaitCmd(&cmdBuffer, nullptr, false)); |
| |
| // Decoded picture |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID])); |
| |
| // Source input |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID])); |
| |
| // Last reference picture |
| if (refSurface[0]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID])); |
| } |
| |
| // Golden reference picture |
| if (refSurface[1]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID])); |
| } |
| |
| // Alt reference picture |
| if (refSurface[2]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID])); |
| } |
| |
| // set HCP_PIPE_BUF_ADDR_STATE values |
| PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams = nullptr; |
| pipeBufAddrParams = CreateHcpPipeBufAddrParams(pipeBufAddrParams); |
| if (pipeBufAddrParams) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetHcpPipeBufAddrParams(*pipeBufAddrParams, refSurface, refSurfaceNonScaled, dsRefSurface4x, dsRefSurface8x)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPipeBufAddr(pipeBufAddrParams, refSurface, &cmdBuffer)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams)); |
| } |
| |
| // set HCP_IND_OBJ_BASE_ADDR_STATE values |
| MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; |
| SetHcpIndObjBaseAddrParams(indObjBaseAddrParams); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams)); |
| |
| m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencSrcSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID])); |
| if (m_pictureCodingType == I_TYPE) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID])); |
| } |
| else |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID])); |
| if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled) |
| { |
| if (m_refFrameFlags & 0x02) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID])); |
| } |
| if (m_refFrameFlags & 0x04) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID])); |
| } |
| } |
| } |
| |
| MHW_VDBOX_SURFACE_PARAMS dsSurfaceParams[2]; // 8x and 4x DS surfaces |
| SetHcpDsSurfaceParams(&dsSurfaceParams[0]); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencDsRefSurfaceStateCmd(&cmdBuffer, &dsSurfaceParams[0], 2)); |
| |
| if (pipeBufAddrParams) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams)); |
| MOS_Delete(pipeBufAddrParams); |
| pipeBufAddrParams = nullptr; |
| } |
| |
| MHW_BATCH_BUFFER secondLevelBatchBuffer; |
| MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer)); |
| secondLevelBatchBuffer.dwOffset = 0; |
| secondLevelBatchBuffer.bSecondLevel = true; |
| if (m_hucEnabled) |
| { |
| secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]; |
| } |
| else |
| { |
| if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled) |
| { |
| // For DyS + BRC case, we run BRC on Pass 0, so although we dont run HPU on Pass 0 |
| // (VDENC + PAK pass) we will still use the write buffer here |
| if (m_dysBrc) |
| { |
| secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferWrite[m_vdencPictureState2ndLevelBBIndex]; |
| } |
| else //CQP case for Pass 0 , HPU has not run yet.. so use this buffer |
| { |
| secondLevelBatchBuffer.OsResource = m_resVdencDysPictureState2NdLevelBatchBuffer; |
| } |
| } |
| else |
| { |
| secondLevelBatchBuffer.OsResource = m_resVdencPictureState2NdLevelBatchBufferRead[m_currPass][m_vdencPictureState2ndLevelBBIndex]; |
| } |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( |
| &cmdBuffer, |
| &secondLevelBatchBuffer)); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::Resize4x8xforDS(uint8_t bufIdx) |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| // calculate the expected 4x dimensions |
| uint32_t downscaledSurfaceWidth4x = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH; |
| uint32_t downscaledSurfaceHeight4x = ((m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT; |
| downscaledSurfaceHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1; |
| |
| // calculate the expected 8x dimensions |
| uint32_t downscaledSurfaceWidth8x = downscaledSurfaceWidth4x >> 1; |
| uint32_t downscaledSurfaceHeight8x = downscaledSurfaceHeight4x >> 1; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf); |
| |
| // get the 8x and 4x ds downscaled surfaces from tracked buffers |
| auto m_trackedBuf8xDsReconSurface = m_trackedBuf->Get8xDsReconSurface(bufIdx); |
| auto m_trackedBuf4xDsReconSurface = m_trackedBuf->Get4xDsReconSurface(bufIdx); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf8xDsReconSurface); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf4xDsReconSurface); |
| |
| // If any dimension of allocated surface is smaller, realloc needed |
| if (m_trackedBuf8xDsReconSurface->dwWidth < downscaledSurfaceWidth8x || m_trackedBuf8xDsReconSurface->dwHeight < downscaledSurfaceHeight8x) { |
| |
| // Get the previously assigned dimensions to make sure we do not lower any dimension |
| auto previous8xWidth = m_trackedBuf8xDsReconSurface->dwWidth; |
| auto previous8xHeight = m_trackedBuf8xDsReconSurface->dwHeight; |
| |
| auto new8xWidth = MOS_MAX(previous8xWidth, downscaledSurfaceWidth8x); |
| auto new8xHeight = MOS_MAX(previous8xHeight, downscaledSurfaceHeight8x); |
| |
| // Release the smaller resource |
| m_allocator->ReleaseResource(m_standard, ds8xRecon, bufIdx); |
| |
| // Re alloc larger resource |
| CODECHAL_ENCODE_CHK_NULL_RETURN( |
| m_trackedBuf8xDsReconSurface = (MOS_SURFACE*)m_allocator->AllocateResource( |
| m_standard, new8xWidth, new8xHeight, ds8xRecon, "ds8xRecon", bufIdx, false, Format_NV12, MOS_TILE_Y)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBuf8xDsReconSurface)); |
| } |
| |
| if (m_trackedBuf4xDsReconSurface->dwWidth < downscaledSurfaceWidth4x || m_trackedBuf4xDsReconSurface->dwHeight < downscaledSurfaceHeight4x) { |
| |
| // Get the previously assigned dimensions to make sure we do not lower any dimension |
| auto previous4xWidth = m_trackedBuf4xDsReconSurface->dwWidth; |
| auto previous4xHeight = m_trackedBuf4xDsReconSurface->dwHeight; |
| |
| auto new4xWidth = MOS_MAX(previous4xWidth, downscaledSurfaceWidth4x); |
| auto new4xHeight = MOS_MAX(previous4xHeight, downscaledSurfaceHeight4x); |
| |
| // Release the smaller resource |
| m_allocator->ReleaseResource(m_standard, ds4xRecon, bufIdx); |
| |
| // Re alloc larger resource |
| CODECHAL_ENCODE_CHK_NULL_RETURN( |
| m_trackedBuf4xDsReconSurface = (MOS_SURFACE*)m_allocator->AllocateResource( |
| m_standard, new4xWidth, new4xHeight, ds4xRecon, "ds4xRecon", bufIdx, false, Format_NV12, MOS_TILE_Y)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBuf4xDsReconSurface)); |
| } |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetHcpSrcSurfaceParams(MHW_VDBOX_SURFACE_PARAMS* surfaceParams, |
| PMOS_SURFACE* refSurface, |
| PMOS_SURFACE* refSurfaceNonScaled, |
| PMOS_SURFACE* dsRefSurface4x, |
| PMOS_SURFACE* dsRefSurface8x) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (m_pictureCodingType != I_TYPE) |
| { |
| uint8_t refPicIndex = 0, scalingIdx = 0; |
| if (m_refFrameFlags & 0x01) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.LastRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))); |
| refSurfaceNonScaled[0] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| refSurface[0] = (m_dysRefFrameFlags & DYS_REF_LAST) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[0]; |
| |
| scalingIdx = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx)); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf); |
| dsRefSurface4x[0] = m_trackedBuf->Get4xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[0])); |
| dsRefSurface8x[0] = m_trackedBuf->Get8xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[0])); |
| } |
| |
| if (m_refFrameFlags & 0x02) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.GoldenRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))); |
| refSurfaceNonScaled[1] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| refSurface[1] = (m_dysRefFrameFlags & DYS_REF_GOLDEN) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[1]; |
| |
| scalingIdx = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx)); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf); |
| dsRefSurface4x[1] = m_trackedBuf->Get4xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[1])); |
| dsRefSurface8x[1] = m_trackedBuf->Get8xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[1])); |
| } |
| |
| if (m_refFrameFlags & 0x04) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.AltRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))); |
| refSurfaceNonScaled[2] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| refSurface[2] = (m_dysRefFrameFlags & DYS_REF_ALT) ? &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sDysSurface) : refSurfaceNonScaled[2]; |
| |
| scalingIdx = m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->ucScalingIdx; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(Resize4x8xforDS(scalingIdx)); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBuf); |
| dsRefSurface4x[2] = m_trackedBuf->Get4xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface4x[2])); |
| dsRefSurface8x[2] = m_trackedBuf->Get8xDsReconSurface(scalingIdx); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, dsRefSurface8x[2])); |
| } |
| |
| if (!refSurface[0]) |
| { |
| refSurface[0] = (refSurface[1]) ? refSurface[1] : refSurface[2]; |
| refSurfaceNonScaled[0] = (refSurfaceNonScaled[1]) ? refSurfaceNonScaled[1] : refSurfaceNonScaled[2]; |
| dsRefSurface4x[0] = (dsRefSurface4x[1]) ? dsRefSurface4x[1] : dsRefSurface4x[2]; |
| dsRefSurface8x[0] = (dsRefSurface8x[1]) ? dsRefSurface8x[1] : dsRefSurface8x[2]; |
| } |
| |
| if (!refSurface[1]) |
| { |
| refSurface[1] = (refSurface[0]) ? refSurface[0] : refSurface[2]; |
| refSurfaceNonScaled[1] = (refSurfaceNonScaled[0]) ? refSurfaceNonScaled[0] : refSurfaceNonScaled[2]; |
| dsRefSurface4x[1] = (dsRefSurface4x[0]) ? dsRefSurface4x[0] : dsRefSurface4x[2]; |
| dsRefSurface8x[1] = (dsRefSurface8x[0]) ? dsRefSurface8x[0] : dsRefSurface8x[2]; |
| } |
| |
| if (!refSurface[2]) |
| { |
| refSurface[2] = (refSurface[0]) ? refSurface[0] : refSurface[1]; |
| refSurfaceNonScaled[2] = (refSurfaceNonScaled[0]) ? refSurfaceNonScaled[0] : refSurfaceNonScaled[1]; |
| dsRefSurface4x[2] = (dsRefSurface4x[0]) ? dsRefSurface4x[0] : dsRefSurface4x[1]; |
| dsRefSurface8x[2] = (dsRefSurface8x[0]) ? dsRefSurface8x[0] : dsRefSurface8x[1]; |
| } |
| |
| // Program Surface params for Reference surfaces |
| if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled) |
| { |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = refSurfaceNonScaled[0]; |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].bVdencDynamicScaling = true; |
| |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = refSurfaceNonScaled[1]; |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].bVdencDynamicScaling = true; |
| |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = refSurfaceNonScaled[2]; |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].bVdencDynamicScaling = true; |
| } |
| else |
| { |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = refSurface[0]; |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = refSurface[1]; |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = refSurface[2]; |
| } |
| |
| if (m_dysCurrFrameFlag) |
| { |
| if (m_dysVdencMultiPassEnabled) |
| { |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[0] ? refSurface[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[1] ? refSurface[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[2] ? refSurface[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| } |
| else |
| { |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurfaceNonScaled[0] ? refSurfaceNonScaled[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurfaceNonScaled[1] ? refSurfaceNonScaled[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurfaceNonScaled[2] ? refSurfaceNonScaled[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| } |
| } |
| else |
| { |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight = |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = m_rawSurfaceToPak->dwHeight; |
| } |
| } |
| |
| // Program Surface params for reconstructed surface |
| surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].psSurface = &m_reconSurface; |
| surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwReconSurfHeight = m_rawSurfaceToPak->dwHeight; |
| |
| // Program Surface params for source surface |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].psSurface = m_rawSurfaceToPak; |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].bDisplayFormatSwizzle = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle; |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualWidth = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualHeight = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH); |
| |
| return eStatus; |
| } |
| |
| void CodechalVdencVp9State::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams) |
| { |
| pipeModeSelectParams = {}; |
| pipeModeSelectParams.Mode = m_mode; |
| pipeModeSelectParams.bStreamOutEnabled = m_vdencBrcEnabled; |
| pipeModeSelectParams.bVdencEnabled = true; |
| pipeModeSelectParams.bVdencPakObjCmdStreamOutEnable = m_vdencPakObjCmdStreamOutEnabled; |
| pipeModeSelectParams.bTlbPrefetchEnable = true; |
| |
| // Add 1 to compensate for VdencPipeModeSelect params values |
| pipeModeSelectParams.ChromaType = m_vp9SeqParams->SeqFlags.fields.EncodedFormat + 1; |
| switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) |
| { |
| case VP9_ENCODED_BIT_DEPTH_10: |
| { |
| pipeModeSelectParams.ucVdencBitDepthMinus8 = 2; |
| break; |
| } |
| default: |
| { |
| pipeModeSelectParams.ucVdencBitDepthMinus8 = 0; |
| break; |
| } |
| } |
| } |
| |
| PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS CodechalVdencVp9State::CreateHcpPipeBufAddrParams(PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams) |
| { |
| pipeBufAddrParams = MOS_New(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS); |
| |
| return pipeBufAddrParams; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetPipeBufAddr( |
| PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams, |
| PMOS_SURFACE refSurface[3], |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState); |
| return m_mmcState->SetPipeBufAddr(pipeBufAddrParams, cmdBuffer); |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams, |
| PMOS_SURFACE* refSurface, |
| PMOS_SURFACE* refSurfaceNonScaled, |
| PMOS_SURFACE* dsRefSurface4x, |
| PMOS_SURFACE* dsRefSurface8x) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| pipeBufAddrParams = {}; |
| pipeBufAddrParams.Mode = m_mode; |
| pipeBufAddrParams.psPreDeblockSurface = &m_reconSurface; |
| pipeBufAddrParams.psPostDeblockSurface = &m_reconSurface; |
| pipeBufAddrParams.psRawSurface = m_rawSurfaceToPak; |
| |
| pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = |
| &m_resDeblockingFilterLineBuffer; |
| |
| pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer = |
| &m_resDeblockingFilterTileLineBuffer; |
| |
| pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer = |
| &m_resDeblockingFilterTileColumnBuffer; |
| |
| pipeBufAddrParams.presMetadataLineBuffer = &m_resMetadataLineBuffer; |
| pipeBufAddrParams.presMetadataTileLineBuffer = &m_resMetadataTileLineBuffer; |
| pipeBufAddrParams.presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer; |
| pipeBufAddrParams.presCurMvTempBuffer = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex); |
| |
| // 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. |
| uint8_t frameCtxIdx = 0; |
| if (m_hucEnabled && m_currPass == m_numPasses) |
| { |
| pipeBufAddrParams.presVp9ProbBuffer = &m_resHucProbOutputBuffer; |
| } |
| else |
| { |
| frameCtxIdx = m_vp9PicParams->PicFlags.fields.frame_context_idx; |
| CODECHAL_ENCODE_ASSERT(frameCtxIdx < CODEC_VP9_NUM_CONTEXTS); |
| pipeBufAddrParams.presVp9ProbBuffer = &m_resProbBuffer[frameCtxIdx]; |
| } |
| |
| pipeBufAddrParams.presVp9SegmentIdBuffer = &m_resSegmentIdBuffer; |
| pipeBufAddrParams.presHvdTileRowStoreBuffer = &m_resHvcTileRowstoreBuffer; |
| pipeBufAddrParams.ps4xDsSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER); |
| pipeBufAddrParams.ps8xDsSurface = m_trackedBuf->Get8xDsReconSurface(CODEC_CURR_TRACKED_BUFFER); |
| pipeBufAddrParams.presVdencIntraRowStoreScratchBuffer = &m_resVdencIntraRowStoreScratchBuffer; |
| pipeBufAddrParams.dwNumRefIdxL0ActiveMinus1 = (m_vp9PicParams->PicFlags.fields.frame_type) ? m_numRefFrames - 1 : 0; |
| pipeBufAddrParams.presVdencStreamOutBuffer = &m_resVdencBrcStatsBuffer; |
| pipeBufAddrParams.presStreamOutBuffer = nullptr; |
| pipeBufAddrParams.presFrameStatStreamOutBuffer = &m_resFrameStatStreamOutBuffer; |
| pipeBufAddrParams.presSseSrcPixelRowStoreBuffer = &m_resSseSrcPixelRowStoreBuffer; |
| pipeBufAddrParams.presVdencStreamInBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx]; |
| pipeBufAddrParams.presSegmentMapStreamOut = &m_resVdencSegmentMapStreamOut; |
| pipeBufAddrParams.presPakCuLevelStreamoutBuffer = |
| Mos_ResourceIsNull(&m_resPakcuLevelStreamoutData.sResource) ? nullptr : &m_resPakcuLevelStreamoutData.sResource; |
| if (m_dysRefFrameFlags != DYS_REF_NONE) |
| { |
| pipeBufAddrParams.presVdencPakObjCmdStreamOutBuffer = |
| (m_vdencPakObjCmdStreamOutEnabled) ? m_resVdencPakObjCmdStreamOutBuffer : nullptr; |
| } |
| else |
| { |
| pipeBufAddrParams.presVdencPakObjCmdStreamOutBuffer = m_resVdencPakObjCmdStreamOutBuffer = &m_resMbCodeSurface; |
| } |
| |
| if (m_pictureCodingType != I_TYPE) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(refSurface[i]); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dsRefSurface4x[i]); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(dsRefSurface8x[i]); |
| |
| pipeBufAddrParams.presReferences[i] = &refSurface[i]->OsResource; |
| pipeBufAddrParams.presVdencReferences[i] = &refSurface[i]->OsResource; |
| pipeBufAddrParams.presVdenc4xDsSurface[i] = &dsRefSurface4x[i]->OsResource; |
| pipeBufAddrParams.presVdenc8xDsSurface[i] = &dsRefSurface8x[i]->OsResource; |
| |
| if ((m_dysRefFrameFlags != DYS_REF_NONE) && !m_dysVdencMultiPassEnabled) |
| { |
| pipeBufAddrParams.presReferences[i + 4] = &refSurfaceNonScaled[i]->OsResource; |
| } |
| } |
| |
| pipeBufAddrParams.presColMvTempBuffer[0] = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex ^ 0x01); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::VerifyCommandBufferSize() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable()); |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::GetCommandBuffer( |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, cmdBuffer, 0)); |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ReturnCommandBuffer( |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, cmdBuffer, 0); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SubmitCommandBuffer( |
| PMOS_COMMAND_BUFFER cmdBuffer, |
| bool nullRendering) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, cmdBuffer, nullRendering)); |
| |
| return eStatus; |
| } |
| |
| void CodechalVdencVp9State::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams) |
| { |
| MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); |
| indObjBaseAddrParams.Mode = m_mode; |
| indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer; |
| indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound; |
| indObjBaseAddrParams.presProbabilityDeltaBuffer = &m_resProbabilityDeltaBuffer; |
| indObjBaseAddrParams.dwProbabilityDeltaSize = 29 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presCompressedHeaderBuffer = &m_resCompressedHeaderBuffer; |
| indObjBaseAddrParams.dwCompressedHeaderSize = 32 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presProbabilityCounterBuffer = &m_resProbabilityCounterBuffer; |
| indObjBaseAddrParams.dwProbabilityCounterOffset = 0; |
| indObjBaseAddrParams.dwProbabilityCounterSize = 193 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presTileRecordBuffer = &m_resTileRecordStrmOutBuffer; |
| indObjBaseAddrParams.dwTileRecordSize = m_picSizeInSb * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presCuStatsBuffer = &m_resCuStatsStrmOutBuffer; |
| indObjBaseAddrParams.dwCuStatsSize = MOS_ALIGN_CEIL(m_picSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE); |
| } |
| |
| void CodechalVdencVp9State::SetHcpDsSurfaceParams(MHW_VDBOX_SURFACE_PARAMS* dsSurfaceParams) |
| { |
| // 8xDS surface |
| MOS_ZeroMemory(&dsSurfaceParams[0], sizeof(MHW_VDBOX_SURFACE_PARAMS)); |
| dsSurfaceParams[0].Mode = m_mode; |
| dsSurfaceParams[0].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID; |
| dsSurfaceParams[0].psSurface = m_trackedBuf->Get8xDsReconSurface(CODEC_CURR_TRACKED_BUFFER); |
| // 4xDS Surface |
| MOS_ZeroMemory(&dsSurfaceParams[1], sizeof(MHW_VDBOX_SURFACE_PARAMS)); |
| dsSurfaceParams[1].Mode = m_mode; |
| dsSurfaceParams[1].ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID; |
| dsSurfaceParams[1].psSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER); |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::GetStatusReport( |
| EncodeStatus* encodeStatus, |
| EncodeStatusReport* encodeStatusReport) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatus); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(encodeStatusReport); |
| |
| encodeStatusReport->CodecStatus = CODECHAL_STATUS_SUCCESSFUL; |
| encodeStatusReport->bitstreamSize = |
| encodeStatus->dwMFCBitstreamByteCountPerFrame + encodeStatus->dwHeaderBytesInserted; |
| |
| encodeStatusReport->QpY = m_vp9PicParams->LumaACQIndex; |
| encodeStatusReport->NumberPasses = (uint8_t)encodeStatus->dwNumberPasses; |
| |
| if (m_brcEnabled) |
| { |
| MOS_LOCK_PARAMS lockFlagsReadOnly; |
| MOS_ZeroMemory(&lockFlagsReadOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsReadOnly.ReadOnly = 1; |
| |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer, &lockFlagsReadOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| HucBrcDataBuffer* hucData = (HucBrcDataBuffer*)data; |
| |
| encodeStatusReport->NextFrameWidthMinus1 = (uint16_t) hucData->DW5.NextFrameWidth - 1; |
| encodeStatusReport->NextFrameHeightMinus1 = (uint16_t) hucData->DW5.NextFrameHeight - 1; |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_brcBuffers.resBrcHucDataBuffer); |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ExecuteSliceLevel() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| MHW_BATCH_BUFFER secondLevelBatchBuffer; |
| MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer)); |
| secondLevelBatchBuffer.dwOffset = 0; |
| secondLevelBatchBuffer.bSecondLevel = true; |
| if (!m_hucEnabled) |
| { |
| secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx]; |
| } |
| else |
| { |
| secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderWriteBuffer; |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( |
| &cmdBuffer, |
| &secondLevelBatchBuffer)); |
| |
| MHW_VDBOX_VDENC_WEIGHT_OFFSET_PARAMS vdencWeightOffsetParams; |
| MOS_ZeroMemory(&vdencWeightOffsetParams, sizeof(vdencWeightOffsetParams)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWeightsOffsetsStateCmd(&cmdBuffer, nullptr, &vdencWeightOffsetParams)); |
| |
| MHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams; |
| vdencWalkerStateParams.Mode = CODECHAL_ENCODE_MODE_VP9; |
| vdencWalkerStateParams.pVp9EncPicParams = m_vp9PicParams; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWalkerStateCmd(&cmdBuffer, &vdencWalkerStateParams)); |
| |
| MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams; |
| MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams)); |
| // MFXPipeDone should not be set for tail insertion |
| vdPipelineFlushParams.Flags.bWaitDoneMFX = 1; |
| vdPipelineFlushParams.Flags.bWaitDoneHEVC = 1; |
| vdPipelineFlushParams.Flags.bFlushHEVC = 1; |
| vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(&cmdBuffer)); |
| |
| uint32_t offset = |
| (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + |
| m_encodeStatusBuf.dwNumPassesOffset + |
| sizeof(uint32_t) * 2; // encode status doesn't start until 3rd DW |
| |
| MHW_MI_STORE_DATA_PARAMS storeDataParams; |
| storeDataParams.pOsResource = &m_encodeStatusBuf.resStatusBuffer; |
| storeDataParams.dwResourceOffset = offset; |
| storeDataParams.dwValue = m_currPass + 1; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams)); |
| |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass)); |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| pakPassName.data()))); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if (!m_singleTaskPhaseSupported || m_lastTaskInPhase) |
| { |
| bool renderFlags; |
| |
| if (m_waitForEnc && |
| !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse)) |
| { |
| MOS_SYNC_PARAMS syncParams; |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| m_waitForEnc = false; |
| } |
| |
| renderFlags = m_videoContextUsesNullHw; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags)); |
| m_lastTaskInPhase = false; |
| |
| CODECHAL_DEBUG_TOOL( |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer( |
| m_resVdencPakObjCmdStreamOutBuffer, |
| CodechalDbgAttr::attrPakObjStreamout, |
| pakPassName.data(), |
| m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE, |
| 0, |
| CODECHAL_NUM_MEDIA_STATES)); |
| |
| if (m_vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| ; //CodecHal_DbgDumpEncodeVp9SegmentStreamout(m_debugInterface, m_encoder); |
| } if (m_mmcState) { |
| m_mmcState->UpdateUserFeatureKey(&m_reconSurface); |
| }); |
| } |
| |
| // Reset parameters for next PAK execution |
| if (m_currPass == m_numPasses) |
| { |
| if (m_vp9PicParams->PicFlags.fields.super_frame && m_tsEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructSuperFrame()); |
| } |
| |
| if (m_signalEnc && |
| !Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse)) |
| { |
| // Check if the signal obj count exceeds max value |
| MOS_SYNC_PARAMS syncParams; |
| if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED)) |
| { |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_renderContext; |
| syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| m_semaphoreObjCount--; |
| } |
| |
| // signal semaphore |
| syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams)); |
| m_semaphoreObjCount++; |
| } |
| |
| m_prevFrameInfo.KeyFrame = !m_vp9PicParams->PicFlags.fields.frame_type; |
| m_prevFrameInfo.IntraOnly = (m_vp9PicParams->PicFlags.fields.frame_type == CODEC_VP9_KEY_FRAME) || m_vp9PicParams->PicFlags.fields.intra_only; |
| m_prevFrameInfo.ShowFrame = m_vp9PicParams->PicFlags.fields.show_frame; |
| m_prevFrameInfo.FrameWidth = m_oriFrameWidth; |
| m_prevFrameInfo.FrameHeight = m_oriFrameHeight; |
| m_currMvTemporalBufferIndex ^= 0x01; |
| m_contextFrameTypes[m_vp9PicParams->PicFlags.fields.frame_context_idx] = m_vp9PicParams->PicFlags.fields.frame_type; |
| m_prevFrameSegEnabled = m_vp9PicParams->PicFlags.fields.segmentation_enabled; |
| |
| if (!m_singleTaskPhaseSupported) |
| { |
| m_osInterface->pfnResetPerfBufferID(m_osInterface); |
| } |
| |
| m_newPpsHeader = 0; |
| m_newSeqHeader = 0; |
| m_frameNum++; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::PakConstructPicStateBatchBuf( |
| PMOS_RESOURCE picStateBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(picStateBuffer); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, picStateBuffer, &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| // HCP_VP9_PIC_STATE |
| MHW_VDBOX_VP9_ENCODE_PIC_STATE picState; |
| MOS_ZeroMemory(&picState, sizeof(picState)); |
| picState.pVp9PicParams = m_vp9PicParams; |
| picState.pVp9SeqParams = m_vp9SeqParams; |
| picState.ppVp9RefList = &(m_refList[0]); |
| picState.PrevFrameParams.fields.KeyFrame = m_prevFrameInfo.KeyFrame; |
| picState.PrevFrameParams.fields.IntraOnly = m_prevFrameInfo.IntraOnly; |
| picState.PrevFrameParams.fields.Display = m_prevFrameInfo.ShowFrame; |
| picState.dwPrevFrmWidth = m_prevFrameInfo.FrameWidth; |
| picState.dwPrevFrmHeight = m_prevFrameInfo.FrameHeight; |
| picState.ucTxMode = m_txMode; |
| |
| for (auto i = 0; i < CODECHAL_ENCODE_VP9_BRC_MAX_NUM_OF_PASSES; i++) |
| { |
| picState.bNonFirstPassFlag = (i != 0) ? true : false; |
| |
| MOS_COMMAND_BUFFER constructedCmdBuf; |
| |
| constructedCmdBuf.pCmdBase = (uint32_t *)data; |
| constructedCmdBuf.pCmdPtr = (uint32_t *)(data + i * CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS); |
| constructedCmdBuf.iOffset = 0; |
| constructedCmdBuf.iRemaining = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9PicStateEncCmd(&constructedCmdBuf, nullptr, &picState)); |
| |
| // After adding pic State cmds in above function, pCmdPtr is not at the end of the picState Buffer, so adjusting it. |
| 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 |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&constructedCmdBuf, nullptr)); |
| } |
| |
| if (data) |
| { |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| picStateBuffer); |
| } |
| return eStatus; |
| } |
| |
| // This is used only for DynamicScaling |
| MOS_STATUS CodechalVdencVp9State::ExecuteDysPictureLevel() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()),"ERROR - vdbox index exceed the maximum"); |
| auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex); |
| |
| PerfTagSetting perfTag; |
| perfTag.Value = 0; |
| perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK; |
| perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE; |
| perfTag.PictureCodingType = m_pictureCodingType; |
| m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); |
| |
| // We only need to update Huc PAK insert object and picture state for the first pass |
| if (m_currPass == 0) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ConstructPakInsertObjBatchBuf(&m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx])); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PakConstructPicStateBatchBuf( |
| &m_brcBuffers.resPicStateBrcWriteHucReadBuffer)); |
| |
| } |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(GetCommandBuffer(&cmdBuffer)); |
| |
| if (!m_singleTaskPhaseSupported || m_firstTaskInPhase) |
| { |
| bool requestFrameTracking = false; |
| |
| // Send command buffer header at the beginning (OS dependent) |
| // frame tracking tag is only added in the last command buffer header |
| requestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : m_lastTaskInPhase; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking)); |
| } |
| |
| // Making sure ImgStatusCtrl is zeroed out before first PAK pass. HW supposedly does this before start of each frame. Remove this after confirming. |
| if (m_currPass == 0) |
| { |
| MHW_MI_LOAD_REGISTER_IMM_PARAMS miLoadRegImmParams; |
| MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams)); |
| miLoadRegImmParams.dwData = 0; |
| miLoadRegImmParams.dwRegister = mmioRegisters->hcpVp9EncImageStatusCtrlRegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiLoadRegisterImmCmd(&cmdBuffer, &miLoadRegImmParams)); |
| } |
| |
| // Read Image status before running PAK, to get correct cumulative delta applied for final pass. |
| if (m_currPass != m_numPasses) // Don't read it for Repak |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadImageStatus(&cmdBuffer)); |
| } |
| |
| //updating the numberofpakpasses in encode staus buffer. should not update for repak. |
| if (m_currPass < m_numPasses) |
| { |
| uint32_t offset = |
| (m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) + |
| m_encodeStatusBuf.dwNumPassesOffset + |
| sizeof(uint32_t)* 2; // encode status doesn't start until 3rd DW |
| |
| MHW_MI_STORE_DATA_PARAMS storeDataParams; |
| MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams)); |
| storeDataParams.pOsResource = &m_encodeStatusBuf.resStatusBuffer; |
| storeDataParams.dwResourceOffset = offset; |
| storeDataParams.dwValue = m_currPass + 1; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams)); |
| } |
| |
| if (!m_currPass && m_osInterface->bTagResourceSync) |
| { |
| // 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 |
| // which may be skipped in multi-pass PAK enabled case. The idea here is to insert the previous frame's tag at the beginning |
| // 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 |
| // as long as Dec/VP/Enc won't depend on this PAK so soon. |
| PMOS_RESOURCE globalGpuContextSyncTagBuffer = nullptr; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetGpuStatusBufferResource( |
| m_osInterface, |
| globalGpuContextSyncTagBuffer)); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(globalGpuContextSyncTagBuffer); |
| |
| uint32_t value = m_osInterface->pfnGetGpuStatusTag(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); |
| MHW_MI_STORE_DATA_PARAMS params; |
| params.pOsResource = globalGpuContextSyncTagBuffer; |
| params.dwResourceOffset = m_osInterface->pfnGetGpuStatusTagOffset(m_osInterface, m_osInterface->CurrentGpuContextOrdinal); |
| params.dwValue = (value > 0) ? (value - 1) : 0; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiStoreDataImmCmd(&cmdBuffer, ¶ms)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); |
| |
| // set HCP_PIPE_MODE_SELECT values |
| PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = nullptr; |
| pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams(); |
| if (pipeModeSelectParams) |
| { |
| pipeModeSelectParams->Mode = m_mode; |
| pipeModeSelectParams->bStreamOutEnabled = false; |
| pipeModeSelectParams->bVdencEnabled = false; |
| pipeModeSelectParams->ChromaType = m_vp9SeqParams->SeqFlags.fields.EncodedFormat; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams)); |
| m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams); |
| } |
| |
| // set HCP_SURFACE_STATE values |
| MHW_VDBOX_SURFACE_PARAMS surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID + 1]; |
| for (uint8_t i = 0; i <= CODECHAL_HCP_ALTREF_SURFACE_ID; i++) |
| { |
| MOS_ZeroMemory(&surfaceParams[i], sizeof(surfaceParams[i])); |
| surfaceParams[i].Mode = m_mode; |
| surfaceParams[i].ucSurfaceStateId = i; |
| surfaceParams[i].ChromaType = m_outputChromaFormat; |
| |
| switch (m_vp9SeqParams->SeqFlags.fields.EncodedBitDepth) |
| { |
| case VP9_ENCODED_BIT_DEPTH_10: //10 bit encoding |
| { |
| surfaceParams[i].ucBitDepthChromaMinus8 = 2; |
| surfaceParams[i].ucBitDepthLumaMinus8 = 2; |
| break; |
| } |
| default: |
| { |
| surfaceParams[i].ucBitDepthChromaMinus8 = 0; |
| surfaceParams[i].ucBitDepthLumaMinus8 = 0; |
| break; |
| } |
| } |
| } |
| |
| // For PAK engine, we do NOT use scaled reference images even if dynamic scaling is enabled |
| PMOS_SURFACE refSurface[3]; |
| for (auto i = 0; i < 3; i++) |
| { |
| refSurface[i] = nullptr; |
| } |
| |
| if (m_pictureCodingType != I_TYPE) |
| { |
| uint8_t refPicIndex; |
| if (m_refFrameFlags & 0x01) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.LastRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))); |
| refSurface[0] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| } |
| |
| if (m_refFrameFlags & 0x02) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.GoldenRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))); |
| refSurface[1] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| } |
| |
| if (m_refFrameFlags & 0x04) |
| { |
| refPicIndex = m_vp9PicParams->RefFlags.fields.AltRefIdx; |
| |
| CODECHAL_ENCODE_ASSERT((refPicIndex < CODEC_VP9_NUM_REF_FRAMES) && (!CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[refPicIndex]))) |
| refSurface[2] = &(m_refList[m_vp9PicParams->RefFrameList[refPicIndex].FrameIdx]->sRefBuffer); |
| } |
| |
| if (!refSurface[0]) |
| { |
| refSurface[0] = (refSurface[1]) ? refSurface[1] : refSurface[2]; |
| } |
| |
| if (!refSurface[1]) |
| { |
| refSurface[1] = (refSurface[0]) ? refSurface[0] : refSurface[2]; |
| } |
| |
| if (!refSurface[2]) |
| { |
| refSurface[2] = (refSurface[0]) ? refSurface[0] : refSurface[1]; |
| } |
| |
| // Program Surface params for Last/Golen/Alt Reference surface |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].psSurface = refSurface[0]; |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].psSurface = refSurface[1]; |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].psSurface = refSurface[2]; |
| |
| surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[0] ? refSurface[0]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[1] ? refSurface[1]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID].dwReconSurfHeight = MOS_ALIGN_CEIL((refSurface[2] ? refSurface[2]->dwHeight : 0), CODEC_VP9_MIN_BLOCK_WIDTH); |
| } |
| |
| // recon |
| surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].psSurface = &m_reconSurface; |
| surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID].dwReconSurfHeight = m_rawSurfaceToPak->dwHeight; |
| |
| // raw |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].psSurface = m_rawSurfaceToPak; |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].bDisplayFormatSwizzle = m_vp9SeqParams->SeqFlags.fields.DisplayFormatSwizzle; |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualWidth = MOS_ALIGN_CEIL(m_oriFrameWidth, CODEC_VP9_MIN_BLOCK_WIDTH); |
| surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID].dwActualHeight = MOS_ALIGN_CEIL(m_oriFrameHeight, CODEC_VP9_MIN_BLOCK_WIDTH); |
| |
| // Decodec picture |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID])); |
| |
| // Source input |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID])); |
| |
| // Last reference picture |
| if (refSurface[0]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_LAST_SURFACE_ID])); |
| } |
| |
| // Golden reference picture |
| if (refSurface[1]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_GOLDEN_SURFACE_ID])); |
| } |
| |
| // Alt reference picture |
| if (refSurface[2]) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &surfaceParams[CODECHAL_HCP_ALTREF_SURFACE_ID])); |
| } |
| |
| // set HCP_PIPE_BUF_ADDR_STATE values |
| PMHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams = nullptr; |
| pipeBufAddrParams = CreateHcpPipeBufAddrParams(pipeBufAddrParams); |
| if (pipeBufAddrParams) |
| { |
| pipeBufAddrParams->Mode = m_mode; |
| pipeBufAddrParams->psPreDeblockSurface = &m_reconSurface; |
| pipeBufAddrParams->psPostDeblockSurface = &m_reconSurface; |
| pipeBufAddrParams->psRawSurface = m_rawSurfaceToPak; |
| |
| pipeBufAddrParams->presStreamOutBuffer = nullptr; |
| pipeBufAddrParams->presMfdDeblockingFilterRowStoreScratchBuffer = |
| &m_resDeblockingFilterLineBuffer; |
| |
| pipeBufAddrParams->presDeblockingFilterTileRowStoreScratchBuffer = |
| &m_resDeblockingFilterTileLineBuffer; |
| |
| pipeBufAddrParams->presDeblockingFilterColumnRowStoreScratchBuffer = |
| &m_resDeblockingFilterTileColumnBuffer; |
| |
| pipeBufAddrParams->presMetadataLineBuffer = &m_resMetadataLineBuffer; |
| pipeBufAddrParams->presMetadataTileLineBuffer = &m_resMetadataTileLineBuffer; |
| pipeBufAddrParams->presMetadataTileColumnBuffer = &m_resMetadataTileColumnBuffer; |
| pipeBufAddrParams->presCurMvTempBuffer = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex); |
| if (m_pictureCodingType != I_TYPE) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| CODECHAL_ENCODE_CHK_NULL_RETURN(refSurface[i]); |
| pipeBufAddrParams->presReferences[i] = &refSurface[i]->OsResource; |
| } |
| } |
| |
| |
| pipeBufAddrParams->pRawSurfParam = &surfaceParams[CODECHAL_HCP_SRC_SURFACE_ID]; |
| pipeBufAddrParams->pDecodedReconParam = &surfaceParams[CODECHAL_HCP_DECODED_SURFACE_ID]; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPipeBufAddr(pipeBufAddrParams, refSurface, &cmdBuffer)); |
| |
| //Huc is disabled for ref frame scaling, use input region |
| uint8_t frameCtxIdx = m_vp9PicParams->PicFlags.fields.frame_context_idx; |
| CODECHAL_ENCODE_ASSERT(frameCtxIdx < CODEC_VP9_NUM_CONTEXTS); |
| pipeBufAddrParams->presVp9ProbBuffer = &m_resProbBuffer[frameCtxIdx]; |
| pipeBufAddrParams->presVp9SegmentIdBuffer = &m_resSegmentIdBuffer; |
| |
| if (m_pictureCodingType != I_TYPE) |
| { |
| pipeBufAddrParams->presColMvTempBuffer[0] = m_trackedBuf->GetMvTemporalBuffer(m_currMvTemporalBufferIndex ^ 0x01); |
| } |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpPipeBufAddrCmd(&cmdBuffer, pipeBufAddrParams)); |
| |
| MOS_Delete(pipeBufAddrParams); |
| } |
| |
| // set HCP_IND_OBJ_BASE_ADDR_STATE values |
| MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams; |
| MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams)); |
| indObjBaseAddrParams.Mode = m_mode; |
| indObjBaseAddrParams.presMvObjectBuffer = &m_resMbCodeSurface; |
| indObjBaseAddrParams.dwMvObjectOffset = m_mvOffset; |
| indObjBaseAddrParams.dwMvObjectSize = m_mbCodeSize - m_mvOffset; |
| indObjBaseAddrParams.presPakBaseObjectBuffer = &m_resBitstreamBuffer; |
| indObjBaseAddrParams.dwPakBaseObjectSize = m_bitstreamUpperBound; |
| indObjBaseAddrParams.presProbabilityDeltaBuffer = &m_resProbabilityDeltaBuffer; |
| indObjBaseAddrParams.dwProbabilityDeltaSize = 29 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presCompressedHeaderBuffer = &m_resCompressedHeaderBuffer; |
| indObjBaseAddrParams.dwCompressedHeaderSize = 32 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presProbabilityCounterBuffer = &m_resProbabilityCounterBuffer; |
| indObjBaseAddrParams.dwProbabilityCounterSize = 193 * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presTileRecordBuffer = &m_resTileRecordStrmOutBuffer; |
| indObjBaseAddrParams.dwTileRecordSize = m_picSizeInSb * CODECHAL_CACHELINE_SIZE; |
| indObjBaseAddrParams.presCuStatsBuffer = &m_resCuStatsStrmOutBuffer; |
| indObjBaseAddrParams.dwCuStatsSize = MOS_ALIGN_CEIL(m_picSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams)); |
| |
| // 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. |
| MHW_BATCH_BUFFER secondLevelBatchBuffer; |
| MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer)); |
| secondLevelBatchBuffer.dwOffset = (m_numPasses > 0) ? CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * (m_currPass % m_numPasses) : 0; |
| secondLevelBatchBuffer.bSecondLevel = true; |
| //As Huc is disabled for Ref frame scaling, use the ReadBuffer |
| secondLevelBatchBuffer.OsResource = m_brcBuffers.resPicStateBrcWriteHucReadBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( |
| &cmdBuffer, |
| &secondLevelBatchBuffer)); |
| |
| // HCP_VP9_SEGMENT_STATE |
| uint8_t segmentCount = (m_vp9PicParams->PicFlags.fields.segmentation_enabled) ? CODEC_VP9_MAX_SEGMENTS : 1; |
| |
| MHW_VDBOX_VP9_SEGMENT_STATE segmentState; |
| MOS_ZeroMemory(&segmentState, sizeof(segmentState)); |
| segmentState.Mode = m_mode; |
| segmentState.pVp9EncodeSegmentParams = m_vp9SegmentParams; |
| segmentState.ucQPIndexLumaAC = m_vp9PicParams->LumaACQIndex; |
| |
| // For BRC with segmentation, seg state commands for PAK are copied from BRC seg state buffer |
| // For CQP or BRC with no segmentation, PAK still needs seg state commands and driver prepares those commands. |
| segmentState.pbSegStateBufferPtr = nullptr; // Set this to nullptr, for commands to be prepared by driver |
| segmentState.pcucLfQpLookup = &LF_VALUE_QP_LOOKUP[0]; |
| for (uint8_t i = 0; i < segmentCount; i++) |
| { |
| segmentState.ucCurrentSegmentId = i; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hcpInterface->AddHcpVp9SegmentStateCmd(&cmdBuffer, nullptr, &segmentState)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ReturnCommandBuffer(&cmdBuffer)); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ExecuteDysSliceLevel() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_nalUnitParams); |
| |
| MOS_COMMAND_BUFFER cmdBuffer; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0)); |
| |
| MHW_BATCH_BUFFER secondLevelBatchBuffer; |
| MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(secondLevelBatchBuffer)); |
| secondLevelBatchBuffer.dwOffset = 0; |
| secondLevelBatchBuffer.bSecondLevel = true; |
| // This function is called only for Reference frame scaling for Dynamic Scaling feature |
| // Huc is disabled for ref frame scaling so we use on the ReadBuffer |
| secondLevelBatchBuffer.OsResource = m_resHucPakInsertUncompressedHeaderReadBuffer[m_currRecycledBufIdx]; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd( |
| &cmdBuffer, |
| &secondLevelBatchBuffer)); |
| |
| MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER)); |
| secondLevelBatchBuffer.OsResource = m_resMbCodeSurface; |
| secondLevelBatchBuffer.dwOffset = 0; |
| secondLevelBatchBuffer.bSecondLevel = true; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, &secondLevelBatchBuffer)); |
| |
| MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams; |
| MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams)); |
| // MFXPipeDone should not be set for tail insertion |
| vdPipelineFlushParams.Flags.bWaitDoneMFX = |
| (m_lastPicInStream || m_lastPicInSeq) ? 0 : 1; |
| vdPipelineFlushParams.Flags.bWaitDoneHEVC = 1; |
| vdPipelineFlushParams.Flags.bFlushHEVC = 1; |
| vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer)); |
| |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES)); |
| |
| if (m_currPass >= (m_numPasses - 1)) // Last pass and the one before last |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); |
| } |
| |
| std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_currPass)); |
| CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer( |
| &cmdBuffer, |
| CODECHAL_NUM_MEDIA_STATES, |
| pakPassName.data()))); |
| |
| m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0); |
| |
| if (m_waitForEnc && |
| !Mos_ResourceIsNull(&m_resSyncObjectRenderContextInUse)) |
| { |
| MOS_SYNC_PARAMS syncParams = g_cInitSyncParams; |
| syncParams.GpuContext = m_videoContext; |
| syncParams.presSyncResource = &m_resSyncObjectRenderContextInUse; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams)); |
| m_waitForEnc = false; |
| } |
| |
| if (m_currPass >= (m_numPasses - 1)) // Last pass and the one before last |
| { |
| bool renderFlags; |
| |
| renderFlags = m_videoContextUsesNullHw; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderFlags)); |
| } |
| |
| CODECHAL_DEBUG_TOOL( |
| if (m_vp9PicParams->PicFlags.fields.segmentation_enabled) { |
| ; //CodecHal_DbgDumpEncodeVp9SegmentStreamout(m_debugInterface, m_encoder); |
| } if (m_mmcState) { |
| m_mmcState->UpdateUserFeatureKey(&m_reconSurface); |
| }); |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::AllocateMbBrcSegMapSurface() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| //MBBRC segment map surface needs to be allocated when mbbrc is enabled as segment map will not be |
| //passed from APP when MBBRC is enabled |
| uint32_t picWidthInMb = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_maxPicWidth); |
| uint32_t picHeightInMb = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_maxPicHeight); |
| |
| m_mbSegmentMapSurface.TileType = MOS_TILE_LINEAR; |
| m_mbSegmentMapSurface.bArraySpacing = true; |
| m_mbSegmentMapSurface.Format = Format_Buffer_2D; |
| m_mbSegmentMapSurface.dwWidth = MOS_ALIGN_CEIL(picWidthInMb, 4); |
| m_mbSegmentMapSurface.dwHeight = picHeightInMb; |
| m_mbSegmentMapSurface.dwPitch = MOS_ALIGN_CEIL(picWidthInMb, 64); |
| |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; |
| MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| |
| allocParamsForBuffer2D.Type = MOS_GFXRES_2D; |
| allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; |
| allocParamsForBuffer2D.Format = Format_Buffer_2D; |
| allocParamsForBuffer2D.dwWidth = m_mbSegmentMapSurface.dwPitch; |
| allocParamsForBuffer2D.dwHeight = picHeightInMb; |
| allocParamsForBuffer2D.pBufName = "MBBRC driver Segment Map Surface"; |
| |
| uint32_t size = allocParamsForBuffer2D.dwWidth * allocParamsForBuffer2D.dwHeight; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer2D, |
| &m_mbSegmentMapSurface.OsResource)); |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &(m_mbSegmentMapSurface.OsResource), |
| &lockFlagsWriteOnly); |
| |
| if (data == nullptr) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock MBBRC driver segment map resource."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| MOS_ZeroMemory(data, size); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_mbSegmentMapSurface.OsResource); |
| |
| m_segmentMapAllocated = true; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetSequenceStructs() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (m_osInterface->osCpInterface->IsHMEnabled()) |
| { |
| m_advancedDshInUse = true; |
| } |
| |
| m_numPasses = m_hucEnabled ? CODECHAL_ENCODE_VP9_CQP_NUM_OF_PASSES - 1 : 0; |
| m_brcEnabled = CodecHalIsRateControlBrc(m_vp9SeqParams->RateControlMethod, CODECHAL_VP9); |
| if (m_brcEnabled) |
| { |
| m_brcReset = m_vp9SeqParams->SeqFlags.fields.bResetBRC; |
| m_vdencBrcEnabled = true; |
| m_numPasses = m_multipassBrcSupported ? CODECHAL_ENCODE_VP9_BRC_DEFAULT_NUM_OF_PASSES : CODECHAL_ENCODE_VP9_BRC_DEFAULT_NUM_OF_PASSES - 1; |
| } |
| |
| if (m_adaptiveRepakSupported) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateRePakThresholds()); |
| } |
| |
| m_tsEnabled = (m_vp9SeqParams->NumTemporalLayersMinus1 > 0) ? true : false; |
| |
| if (m_tsEnabled && m_brcEnabled) |
| { |
| // check base layer properties |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[0].uiNumerator > 0 && m_vp9SeqParams->FrameRate[0].uiDenominator > 0); |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[0] > 0); |
| |
| for (auto i = 1; i < m_vp9SeqParams->NumTemporalLayersMinus1 + 1; i += 1) |
| { |
| // check current layer properties |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[i].uiNumerator > 0 && m_vp9SeqParams->FrameRate[i].uiDenominator > 0); |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[i] > 0); |
| |
| // check current layer properties are bigger than previous layer (since current includes previous layer properties) |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[i].uiNumerator / m_vp9SeqParams->FrameRate[i].uiDenominator > |
| m_vp9SeqParams->FrameRate[i - 1].uiNumerator / m_vp9SeqParams->FrameRate[i - 1].uiDenominator); |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->TargetBitRate[i] > m_vp9SeqParams->TargetBitRate[i - 1]); |
| } |
| } |
| |
| if ((m_vp9SeqParams->SeqFlags.fields.MBBRC == MBBRC_ENABLED) || (m_vp9SeqParams->SeqFlags.fields.MBBRC == MBBRC_ENABLED_TU_DEPENDENCY)) |
| { |
| if (!m_segmentMapAllocated) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateMbBrcSegMapSurface()); |
| } |
| } |
| else |
| { |
| //Allocated Driver MbBrc Segment map resource needs to be deallocated when MBBRC is disabled. The reason being |
| //same segmnet map surface (sMbSegmentMapSurface) will be used in the driver referencing both the Application passed |
| //as well as Driver allocated resource for segmentmap depending on mbbrc disabled or enabled. |
| if (!Mos_ResourceIsNull(&m_mbSegmentMapSurface.OsResource) && m_segmentMapAllocated) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_mbSegmentMapSurface.OsResource); |
| } |
| |
| m_segmentMapAllocated = false; |
| } |
| |
| // if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer |
| m_gopIsIdrFrameOnly = (m_vp9SeqParams->GopPicSize == 1); |
| |
| // check output Chroma format |
| if (VP9_ENCODED_CHROMA_FORMAT_YUV420 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat) |
| { |
| m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV420; |
| } |
| else if (VP9_ENCODED_CHROMA_FORMAT_YUV422 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat) |
| { |
| m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV422; |
| } |
| else if (VP9_ENCODED_CHROMA_FORMAT_YUV444 == m_vp9SeqParams->SeqFlags.fields.EncodedFormat) |
| { |
| m_outputChromaFormat = HCP_CHROMA_FORMAT_YUV444; |
| } |
| else |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Invalid output chromat format in VP9 Seq param!"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetPictureStructs() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| //Enable only for TU1 |
| if (m_vp9SeqParams->TargetUsage != TU_QUALITY) |
| { |
| m_hmeEnabled = m_16xMeSupported = m_32xMeSupported = false; |
| m_16xMeEnabled = false; |
| } |
| |
| // setup internal parameters |
| // dwOriFrameWidth and dwOriFrameHeight are encoded resolutions which might be different from source resoultions if dynamic scaling is enabled |
| m_oriFrameWidth = m_vp9PicParams->SrcFrameWidthMinus1 + 1; |
| m_oriFrameHeight = m_vp9PicParams->SrcFrameHeightMinus1 + 1; |
| |
| if (m_oriFrameWidth == 0 || m_oriFrameWidth > m_maxPicWidth || |
| m_oriFrameHeight == 0 || m_oriFrameHeight > m_maxPicHeight) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| m_picWidthInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameWidth, CODEC_VP9_SUPER_BLOCK_WIDTH); |
| m_picHeightInSb = MOS_ROUNDUP_DIVIDE(m_oriFrameHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT); |
| m_picSizeInSb = m_picWidthInSb * m_picHeightInSb; |
| |
| m_picWidthInMb = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_oriFrameWidth); |
| m_picHeightInMb = (uint16_t)CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_oriFrameHeight); |
| m_frameWidth = m_picWidthInMb * CODECHAL_MACROBLOCK_WIDTH; |
| m_frameHeight = m_picHeightInMb * CODECHAL_MACROBLOCK_HEIGHT; |
| |
| // HME Scaling WxH |
| m_downscaledWidthInMb4x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_4x); |
| m_downscaledHeightInMb4x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_4x); |
| m_downscaledWidth4x = m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH; |
| m_downscaledHeight4x = m_downscaledHeightInMb4x * CODECHAL_MACROBLOCK_HEIGHT; |
| |
| // SuperHME Scaling WxH |
| m_downscaledWidthInMb16x = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_frameWidth / SCALE_FACTOR_16x); |
| m_downscaledHeightInMb16x = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameHeight / SCALE_FACTOR_16x); |
| m_downscaledWidth16x = m_downscaledWidthInMb16x * CODECHAL_MACROBLOCK_WIDTH; |
| m_downscaledHeight16x = m_downscaledHeightInMb16x * CODECHAL_MACROBLOCK_HEIGHT; |
| |
| m_frameFieldHeight = m_frameHeight; |
| m_frameFieldHeightInMb = m_picHeightInMb; |
| m_downscaledFrameFieldHeightInMb4x = m_downscaledHeightInMb4x; |
| m_downscaledFrameFieldHeightInMb16x = m_downscaledHeightInMb16x; |
| |
| MotionEstimationDisableCheck(); |
| |
| if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling) |
| { |
| m_rawSurface.dwWidth = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameWidthMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH); |
| m_rawSurface.dwHeight = MOS_ALIGN_CEIL(m_vp9PicParams->SrcFrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_HEIGHT); |
| } |
| |
| if (Mos_ResourceIsNull(&m_reconSurface.OsResource) && |
| (!m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef || m_codecFunction != CODECHAL_FUNCTION_ENC)) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| // Sync initialize |
| m_waitForEnc = false; |
| if ((m_firstFrame) || |
| (!m_brcEnabled && m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef) || |
| (!m_brcEnabled && (m_vp9PicParams->PicFlags.fields.frame_type == 0 || m_vp9PicParams->PicFlags.fields.intra_only))) |
| { |
| m_waitForPak = false; |
| } |
| else |
| { |
| m_waitForPak = true; |
| } |
| |
| m_signalEnc = false; |
| |
| uint8_t currRefIdx = m_vp9PicParams->CurrReconstructedPic.FrameIdx; |
| |
| m_dysRefFrameFlags = DYS_REF_NONE; |
| m_dysBrc = false; |
| m_dysCqp = false; |
| |
| // m_refFrameFlags is to indicate which frames to be used as reference |
| // m_refFrameFlags & 0x01 != 0: Last ref frames used as reference |
| // m_refFrameFlags & 0x02 != 0: Golden ref frames used as reference |
| // m_refFrameFlags & 0x04 != 0: Alternate ref frames used as reference |
| m_refFrameFlags = 0; |
| m_numRefFrames = 0; |
| m_lastRefPic = 0; |
| m_goldenRefPic = 0; |
| m_altRefPic = 0; |
| |
| uint8_t index = 0; |
| PCODEC_REF_LIST *refList = &m_refList[0]; |
| if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only) |
| { |
| m_refFrameFlags = m_vp9PicParams->RefFlags.fields.ref_frame_ctrl_l0 | m_vp9PicParams->RefFlags.fields.ref_frame_ctrl_l1; |
| |
| if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx])) |
| { |
| m_refFrameFlags &= ~0x1; |
| } |
| if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx])) |
| { |
| m_refFrameFlags &= ~0x2; |
| } |
| if (CodecHal_PictureIsInvalid(m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx])) |
| { |
| m_refFrameFlags &= ~0x4; |
| } |
| |
| //consilidate the reference flag, becasue two reference frame may have the same index |
| if ((m_refFrameFlags & 0x01) && |
| (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx)) |
| { |
| m_refFrameFlags &= ~0x2; //skip golden frame |
| } |
| if ((m_refFrameFlags & 0x01) && |
| (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx)) |
| { |
| m_refFrameFlags &= ~0x4; //skip alt frame |
| } |
| if ((m_refFrameFlags & 0x02) && |
| (m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx == m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx)) |
| { |
| m_refFrameFlags &= ~0x4; //skip alt frame |
| } |
| |
| if (m_refFrameFlags == 7 && !m_16xMeSupported) |
| { |
| // can support max 2 reference frames when SHME disabled, so ignore alt frame |
| m_refFrameFlags &= ~0x4; |
| } |
| |
| // MaxNum_Reference is 1 for TU7 |
| if (m_refFrameFlags != 1 && m_vp9SeqParams->TargetUsage == TU_PERFORMANCE) |
| { |
| m_refFrameFlags = 1; |
| } |
| |
| if (m_refFrameFlags == 0) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Ref list is empty!."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (m_refFrameFlags & 0x01) |
| { |
| index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.LastRefIdx].FrameIdx; |
| refList[index]->sRefBuffer = |
| m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer; |
| |
| m_lastRefPic = &refList[index]->sRefBuffer; |
| CodecHalGetResourceInfo(m_osInterface, m_lastRefPic); |
| m_lastRefPic->dwWidth = refList[index]->dwFrameWidth; |
| m_lastRefPic->dwHeight = refList[index]->dwFrameHeight; |
| m_numRefFrames++; |
| |
| if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling && |
| (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight)) |
| { |
| m_dysRefFrameFlags |= DYS_REF_LAST; |
| } |
| } |
| |
| if (m_refFrameFlags & 0x02) |
| { |
| index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.GoldenRefIdx].FrameIdx; |
| refList[index]->sRefBuffer = |
| m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer; |
| |
| m_goldenRefPic = &refList[index]->sRefBuffer; |
| CodecHalGetResourceInfo(m_osInterface, m_goldenRefPic); |
| m_goldenRefPic->dwWidth = refList[index]->dwFrameWidth; |
| m_goldenRefPic->dwHeight = refList[index]->dwFrameHeight; |
| m_numRefFrames++; |
| |
| if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling && |
| (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight)) |
| { |
| m_dysRefFrameFlags |= DYS_REF_GOLDEN; |
| } |
| } |
| |
| if (m_refFrameFlags & 0x04) |
| { |
| index = m_vp9PicParams->RefFrameList[m_vp9PicParams->RefFlags.fields.AltRefIdx].FrameIdx; |
| refList[index]->sRefBuffer = |
| m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef ? refList[index]->sRefRawBuffer : refList[index]->sRefReconBuffer; |
| |
| m_altRefPic = &refList[index]->sRefBuffer; |
| CodecHalGetResourceInfo(m_osInterface, m_altRefPic); |
| m_altRefPic->dwWidth = refList[index]->dwFrameWidth; |
| m_altRefPic->dwHeight = refList[index]->dwFrameHeight; |
| m_numRefFrames++; |
| |
| if (m_vp9SeqParams->SeqFlags.fields.EnableDynamicScaling && |
| (refList[index]->dwFrameWidth != m_oriFrameWidth || refList[index]->dwFrameHeight != m_oriFrameHeight)) |
| { |
| m_dysRefFrameFlags |= DYS_REF_ALT; |
| } |
| } |
| } |
| m_dysCurrFrameFlag = m_dysRefFrameFlags; |
| |
| refList[currRefIdx]->sRefReconBuffer = m_reconSurface; |
| refList[currRefIdx]->sRefRawBuffer = m_rawSurface; |
| refList[currRefIdx]->RefPic = m_vp9PicParams->CurrOriginalPic; |
| refList[currRefIdx]->bUsedAsRef = true; |
| refList[currRefIdx]->resBitstreamBuffer = m_resBitstreamBuffer; |
| refList[currRefIdx]->dwFrameWidth = m_oriFrameWidth; |
| refList[currRefIdx]->dwFrameHeight = m_oriFrameHeight; |
| |
| m_currOriginalPic = m_vp9PicParams->CurrOriginalPic; |
| m_currReconstructedPic = m_vp9PicParams->CurrReconstructedPic; |
| m_statusReportFeedbackNumber = m_vp9PicParams->StatusReportFeedbackNumber; |
| m_pictureCodingType = m_vp9PicParams->PicFlags.fields.frame_type == 0 ? I_TYPE : P_TYPE; |
| |
| PCODEC_PIC_ID picIdx = &m_picIdx[0]; |
| for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++) |
| { |
| picIdx[i].bValid = false; |
| } |
| if (m_vp9PicParams->PicFlags.fields.frame_type != 0 && !m_vp9PicParams->PicFlags.fields.intra_only) |
| { |
| for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++) |
| { |
| if (m_vp9PicParams->RefFrameList[i].PicFlags != PICTURE_INVALID) |
| { |
| index = m_vp9PicParams->RefFrameList[i].FrameIdx; |
| bool duplicatedIdx = false; |
| for (auto ii = 0; ii < i; ii++) |
| { |
| if (picIdx[ii].bValid && index == m_vp9PicParams->RefFrameList[ii].FrameIdx) |
| { |
| // we find the same FrameIdx in the ref_frame_list. Multiple reference frames are the same. |
| duplicatedIdx = true; |
| break; |
| } |
| } |
| if (duplicatedIdx) |
| { |
| continue; |
| } |
| |
| // this reference frame in unique. Save it into the full reference list with 127 items |
| refList[index]->RefPic.PicFlags = |
| CodecHal_CombinePictureFlags(refList[index]->RefPic, m_vp9PicParams->RefFrameList[i]); |
| |
| picIdx[i].bValid = true; |
| picIdx[i].ucPicIdx = index; |
| } |
| } |
| } |
| |
| // Save the current RefList |
| uint8_t ii = 0; |
| for (auto i = 0; i < CODEC_VP9_NUM_REF_FRAMES; i++) |
| { |
| if (picIdx[i].bValid) |
| { |
| refList[currRefIdx]->RefList[ii] = m_vp9PicParams->RefFrameList[i]; |
| ii++; |
| } |
| } |
| refList[currRefIdx]->ucNumRef = ii; |
| m_currRefList = refList[currRefIdx]; |
| |
| // the actual MbCode/MvData surface to be allocated later |
| m_trackedBuf->SetAllocationFlag(true); |
| |
| m_vdencPakonlyMultipassEnabled = false; |
| m_vdencPakObjCmdStreamOutEnabled = false; |
| |
| // In case there is overflow |
| if ((m_vp9PicParams->LumaACQIndex + m_vp9PicParams->LumaDCQIndexDelta) < 0) |
| { |
| m_vp9PicParams->LumaACQIndex = MOS_ABS(m_vp9PicParams->LumaDCQIndexDelta) + 1; |
| } |
| refList[currRefIdx]->ucQPValue[0] = m_vp9PicParams->LumaACQIndex + m_vp9PicParams->LumaDCQIndexDelta; |
| |
| m_txMode = CODEC_VP9_TX_SELECTABLE; |
| |
| // For VDEnc disable HME if HME hasn't been disabled by reg key AND TU != TU1 |
| m_hmeSupported = m_hmeSupported && (m_vp9SeqParams->TargetUsage == TU_QUALITY); |
| m_16xMeSupported = m_16xMeSupported && m_hmeSupported; |
| |
| // Enable HME/SHME for frame |
| m_hmeEnabled = m_hmeSupported && m_pictureCodingType != I_TYPE && !m_vp9PicParams->PicFlags.fields.intra_only; |
| m_16xMeEnabled = m_16xMeSupported && m_hmeEnabled; |
| |
| if (m_dysRefFrameFlags != DYS_REF_NONE && m_dysVdencMultiPassEnabled ) |
| { |
| if (!m_hucEnabled) |
| { |
| m_numPasses = m_dysRefFrameFlags != DYS_REF_NONE; |
| } |
| if (m_vdencBrcEnabled) |
| { |
| m_dysBrc = true; |
| //Reduce the total passes by 1, as m_currPass == 1 becomes m_currPass = 0 for Huc to run |
| m_numPasses = (m_numPasses > 0 ) ? m_numPasses - 1 : m_numPasses; |
| } |
| else |
| { |
| m_dysCqp = true; |
| } |
| } |
| |
| // We cannot use refresh_frame_context if HuC isn't enabled to update probs |
| if (m_vp9PicParams->PicFlags.fields.refresh_frame_context && !m_hucEnabled) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Refresh_frame_context cannot be enabled while HuC is disabled. HuC is needed for refresh_frame_context to be enabled."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::SetRowstoreCachingOffsets() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| if (m_vdencEnabled && |
| m_hwInterface->GetHcpInterface()->IsRowStoreCachingSupported()) |
| { |
| MHW_VDBOX_ROWSTORE_PARAMS rowStoreParams; |
| rowStoreParams.Mode = m_mode; |
| rowStoreParams.dwPicWidth = m_frameWidth; |
| rowStoreParams.ucChromaFormat = m_chromaFormat; |
| rowStoreParams.ucBitDepthMinus8 = m_bitDepth * 2; // 0(8bit) -> 0, 1(10bit)->2, 2(12bit)->4 |
| m_hwInterface->SetRowstoreCachingOffsets(&rowStoreParams); |
| } |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::InitializePicture(const EncoderParams& params) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| m_vp9SeqParams = (PCODEC_VP9_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams); |
| m_vp9PicParams = (PCODEC_VP9_ENCODE_PIC_PARAMS)(params.pPicParams); |
| m_nalUnitParams = params.ppNALUnitParams; |
| m_numNalUnit = params.uiNumNalUnits; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9SeqParams); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9PicParams); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_nalUnitParams); |
| |
| m_segmentMapProvided = params.bSegmentMapProvided && m_vp9PicParams->PicFlags.fields.segmentation_enabled; |
| // In MBBRC case, without a SegMap provided by the app, we need to set the SegMapUpdate ON |
| // as the Segmap is generated by HuC and it can be different for every frame |
| if (m_vp9PicParams->PicFlags.fields.segmentation_enabled && !params.bSegmentMapProvided) |
| { |
| m_vp9PicParams->PicFlags.fields.segmentation_update_map = 1; |
| } |
| |
| // For dynamic scaling, the SingleTaskPhaseSupported is set to true and it does not get restored |
| // to the original value after encoding of the frame. So need to restore to the original state |
| m_singleTaskPhaseSupported = m_storeSingleTaskPhaseSupported; |
| |
| m_mbBrcEnabled = false; |
| m_vp9SeqParams->SeqFlags.fields.MBBRC = MBBRC_DISABLED; |
| |
| // Filter level is decided by driver in VDEnc, app value is ignored |
| // Uncomment when PSNR thresholds are set properly |
| //pVp9PicParams->filter_level = CODECHAL_ENCODE_VP9_LF_VALUE_QP_LOOKUP[pVp9PicParams->LumaACQIndex]; |
| |
| // We do not support segmentation w/o seg map in CQP case, only support segmentation w/ seg map in CQP |
| // BRC/ACQP supports segmentation both w/ and w/o seg map |
| if (m_vp9PicParams->PicFlags.fields.segmentation_enabled && !params.bSegmentMapProvided && |
| m_vp9SeqParams->RateControlMethod == RATECONTROL_CQP) |
| { |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| // Need to index properly when more than one temporal layer is present. |
| CODECHAL_ENCODE_ASSERT(m_vp9SeqParams->FrameRate[0].uiDenominator > 0); |
| |
| uint32_t frameRate = m_vp9SeqParams->FrameRate[0].uiNumerator / m_vp9SeqParams->FrameRate[0].uiDenominator; |
| m_vp9SegmentParams = (PCODEC_VP9_ENCODE_SEGMENT_PARAMS)(params.pSegmentParams); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_vp9SegmentParams); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(PlatformCapabilityCheck()); |
| |
| if (m_newSeq) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs()); |
| } |
| |
| //when MBBRC is enabled App will not pass segment map. |
| if (!m_mbBrcEnabled) |
| { |
| m_mbStatsEnabled = false; |
| if (m_segmentMapProvided) |
| { |
| m_mbSegmentMapSurface = *(params.psMbSegmentMapSurface); |
| CodecHalGetResourceInfo(m_osInterface, &(m_mbSegmentMapSurface)); |
| } |
| } |
| else |
| { |
| //Kernel C model fixed Qindex delta's when MBBRC is enabled |
| int16_t segmentQIndexDelta[CODEC_VP9_MAX_SEGMENTS] = { 0, -8, -6, -4, -2, 2, 4, 6 }; |
| |
| for (uint8_t i = 0; i < CODEC_VP9_MAX_SEGMENTS; i++) |
| { |
| m_vp9SegmentParams->SegData[i].SegmentFlags.value = 0; |
| m_vp9SegmentParams->SegData[i].SegmentLFLevelDelta = 0; |
| m_vp9SegmentParams->SegData[i].SegmentQIndexDelta = segmentQIndexDelta[i]; |
| } |
| m_mbStatsEnabled = true; |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs()); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetRowstoreCachingOffsets()); |
| |
| m_pictureStatesSize = m_defaultPictureStatesSize; |
| m_picturePatchListSize = m_defaultPicturePatchListSize; |
| |
| m_hucCommandsSize = m_defaultHucCmdsSize; |
| |
| // Scaling occurs when HME is enabled |
| m_scalingEnabled = m_hmeSupported; |
| m_useRawForRef = m_vp9SeqParams->SeqFlags.fields.bUseRawReconRef; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(m_refList[m_currReconstructedPic.FrameIdx])); |
| |
| CODECHAL_DEBUG_TOOL( |
| m_debugInterface->m_currPic = m_vp9PicParams->CurrOriginalPic; |
| m_debugInterface->m_bufferDumpFrameNum = m_storeData; |
| m_debugInterface->m_frameType = m_pictureCodingType; |
| |
| if (m_newSeq) { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams( |
| m_vp9SeqParams)); |
| } |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams( |
| m_vp9PicParams)); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSegmentParams( |
| m_vp9SegmentParams));) |
| |
| CODECHAL_DEBUG_TOOL( |
| m_resVdencStatsBuffer = &(m_resVdencBrcStatsBuffer);) |
| |
| m_bitstreamUpperBound = params.dwBitstreamSize; |
| |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::AllocateResourcesBrc() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| // initiate allocation paramters and lock flags |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; |
| MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; |
| allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; |
| allocParamsForBufferLinear.Format = Format_Buffer; |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| // BRC history buffer |
| uint32_t size = m_brcHistoryBufferSize; |
| allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(size, CODECHAL_PAGE_SIZE) : size; |
| allocParamsForBufferLinear.pBufName = "BRC History Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resBrcHistoryBuffer)); |
| |
| // BRC Constant Data Buffer |
| allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? MOS_ALIGN_CEIL(m_brcConstantSurfaceSize, CODECHAL_PAGE_SIZE) : CODECHAL_ENCODE_VP9_BRC_CONSTANTSURFACE_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC Constant Data Buffer"; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resBrcConstantDataBuffer)); |
| |
| // PicState Brc read buffer |
| size = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * m_brcMaxNumPasses; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "BRC Pic State Read Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resPicStateBrcReadBuffer)); |
| |
| uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcReadBuffer, |
| &lockFlagsWriteOnly); |
| |
| if (data == nullptr) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC Pic State Read Buffer."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| MOS_ZeroMemory(data, size); |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcReadBuffer); |
| |
| // PicState Brc Write and Huc Read buffer |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "BRC Pic State Write Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resPicStateBrcWriteHucReadBuffer)); |
| |
| data = (uint8_t*)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcWriteHucReadBuffer, |
| &lockFlagsWriteOnly); |
| |
| if (data == nullptr) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock BRC Pic State Write Buffer."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| MOS_ZeroMemory(data, size); |
| m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcWriteHucReadBuffer); |
| |
| // PicState HuC Write buffer |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PIC_STATE_BUFFER_SIZE_PER_PASS * m_brcMaxNumPasses; |
| allocParamsForBufferLinear.pBufName = "BRC Huc Pic State Write Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resPicStateHucWriteBuffer)); |
| |
| // SegmentState Brc Read buffer |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC Segment State Read Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resSegmentStateBrcReadBuffer)); |
| |
| // SegmentState Brc Write buffer |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_SEGMENT_STATE_BUFFER_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC Segment State Write Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resSegmentStateBrcWriteBuffer)); |
| |
| // BRC Bitstream Size Data buffer |
| allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? |
| MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE, CODECHAL_PAGE_SIZE) : |
| CODECHAL_ENCODE_VP9_BRC_BITSTREAM_SIZE_BUFFER_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC Bitstream Size Data buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resBrcBitstreamSizeBuffer)); |
| |
| // BRC HuC Data Buffer |
| allocParamsForBufferLinear.dwBytes = m_vdencEnabled ? |
| MOS_ALIGN_CEIL(CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE, CODECHAL_PAGE_SIZE) : |
| CODECHAL_ENCODE_VP9_HUC_BRC_DATA_BUFFER_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC HuC Data Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resBrcHucDataBuffer)); |
| |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_BRC_MSDK_PAK_BUFFER_SIZE; |
| allocParamsForBufferLinear.pBufName = "BRC MSDK Buffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_brcBuffers.resBrcMsdkPakBuffer)); |
| |
| return eStatus; |
| } |
| |
| void CodechalVdencVp9State::ReleaseResourcesBrc() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHistoryBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resBrcHistoryBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcConstantDataBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resBrcConstantDataBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateBrcReadBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcReadBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateBrcWriteHucReadBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateBrcWriteHucReadBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resPicStateHucWriteBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resPicStateHucWriteBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resSegmentStateBrcReadBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resSegmentStateBrcReadBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resSegmentStateBrcWriteBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resSegmentStateBrcWriteBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcBitstreamSizeBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resBrcBitstreamSizeBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcHucDataBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resBrcHucDataBuffer); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_brcBuffers.resBrcMsdkPakBuffer)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_brcBuffers.resBrcMsdkPakBuffer); |
| } |
| |
| return; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::AllocateResources() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::AllocateResources()); |
| |
| // Application needs to pass the maxinum frame width/height |
| m_maxPicWidth = m_frameWidth; |
| m_maxPicHeight = m_frameHeight; |
| |
| uint32_t maxPicWidthInSb = MOS_ROUNDUP_DIVIDE(m_maxPicWidth, CODEC_VP9_SUPER_BLOCK_WIDTH); |
| uint32_t maxPicHeightInSb = MOS_ROUNDUP_DIVIDE(m_maxPicHeight, CODEC_VP9_SUPER_BLOCK_HEIGHT); |
| uint32_t maxPicSizeInSb = maxPicWidthInSb * maxPicHeightInSb; |
| uint32_t maxNumCuRecords = maxPicSizeInSb * 64; |
| |
| // initiate allocation paramters and lock flags |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; |
| MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; |
| allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; |
| allocParamsForBufferLinear.Format = Format_Buffer; |
| |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBuffer2D; |
| MOS_ZeroMemory(&allocParamsForBuffer2D, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBuffer2D.Type = MOS_GFXRES_2D; |
| allocParamsForBuffer2D.TileType = MOS_TILE_LINEAR; |
| allocParamsForBuffer2D.Format = Format_Buffer_2D; |
| |
| MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferNV12; |
| MOS_ZeroMemory(&allocParamsForBufferNV12, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| allocParamsForBufferNV12.Type = MOS_GFXRES_2D; |
| allocParamsForBufferNV12.TileType = MOS_TILE_Y; |
| allocParamsForBufferNV12.Format = Format_NV12; |
| |
| MOS_LOCK_PARAMS lockFlagsWriteOnly; |
| MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS)); |
| lockFlagsWriteOnly.WriteOnly = 1; |
| |
| // Allocate Ref Lists |
| CodecHalAllocateDataList( |
| m_refList, |
| m_numUncompressedSurface); |
| |
| if (m_pakEnabled) |
| { |
| // m_mvoffset looks not correct here, and corresponding setting of buffer offset in HCP_IND_OBJ, need to check with HW team. |
| // keep current logic unchanged but increase the buffer size for now in case regression before we know how to correctly program these. |
| 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 |
| |
| // 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) |
| // (2) CL alignment at end of every tile column for every SB of width |
| // as a result, increase the height by 1 for allocation purposes |
| uint32_t numOfLCU = maxPicSizeInSb + maxPicWidthInSb; |
| |
| //the following code used to calculate ulMBCodeSize: |
| //pakObjCmdStreamOutDataSize = 2*BYTES_PER_DWORD*(numOfLcu*NUM_PAK_DWS_PER_LCU + numOfLcu*maxNumOfCUperLCU*NUM_DWS_PER_CU); // Multiply by 2 for sideband |
| //const uint32_t maxNumOfCUperLCU = (64/8)*(64/8); |
| // NUM_PAK_DWS_PER_LCU 5 |
| // NUM_DWS_PER_CU 8 |
| m_mbCodeSize = MOS_ALIGN_CEIL(2 * sizeof(uint32_t) * numOfLCU * (5 + 64 * 8), CODECHAL_PAGE_SIZE); |
| |
| uint32_t formatMultiFactor = (m_chromaFormat == VP9_ENCODED_CHROMA_FORMAT_YUV444) ? 3 : 2; |
| formatMultiFactor *= (m_bitDepth == VP9_ENCODED_BIT_DEPTH_8) ? 1 : 2; |
| uint32_t size = (18 * formatMultiFactor) / 2; |
| // Deblocking filter line buffer |
| size = maxPicWidthInSb * size * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "DeblockingFilterLineBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resDeblockingFilterLineBuffer)); |
| |
| // Deblocking filter tile line buffer |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "DeblockingFilterTileLineBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resDeblockingFilterTileLineBuffer)); |
| |
| formatMultiFactor = m_chromaFormat == VP9_ENCODED_CHROMA_FORMAT_YUV444 ? 25 : 17; |
| size = formatMultiFactor * ((m_bitDepth == VP9_ENCODED_BIT_DEPTH_8) ? 1 : 2); |
| // Deblocking filter tile column buffer |
| size = maxPicHeightInSb * size * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "DeblockingFilterTileColumnBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resDeblockingFilterTileColumnBuffer)); |
| |
| // Metadata Line buffer |
| size = maxPicWidthInSb * 5 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "MetadataLineBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resMetadataLineBuffer)); |
| |
| // Metadata Tile Line buffer |
| size = maxPicWidthInSb * 5 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "MetadataTileLineBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resMetadataTileLineBuffer)); |
| |
| // Metadata Tile Column buffer |
| size = maxPicHeightInSb * 5 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "MetadataTileColumnBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resMetadataTileColumnBuffer)); |
| |
| // Current MV temporal buffer |
| size = maxPicSizeInSb * 9 * CODECHAL_CACHELINE_SIZE; |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_allocator->AllocateResource(m_standard, size, 1, mvTemporalBuffer, "mvTemporalBuffer", 0)); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_allocator->AllocateResource(m_standard, size, 1, mvTemporalBuffer, "mvTemporalBuffer", 1)); |
| |
| // Probability buffer |
| size = 32 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "ProbabilityBuffer"; |
| |
| for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resProbBuffer[i])); |
| } |
| |
| // Segment ID buffer |
| size = maxPicSizeInSb * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "SegmentIdBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resSegmentIdBuffer)); |
| |
| uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resSegmentIdBuffer, |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MOS_ZeroMemory(data, size); |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resSegmentIdBuffer); |
| |
| // Probability delta buffer |
| size = 29 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "ProbabilityDeltaBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resProbabilityDeltaBuffer)); |
| |
| // Compressed header buffer |
| size = 32 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "CompressedHeaderBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resCompressedHeaderBuffer)); |
| |
| // Probability counter buffer |
| allocParamsForBufferLinear.dwBytes = m_probabilityCounterBufferSize * m_maxTileNumber; |
| allocParamsForBufferLinear.pBufName = "ProbabilityCounterBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resProbabilityCounterBuffer)); |
| |
| // Tile record stream out buffer |
| size = maxPicSizeInSb * CODECHAL_CACHELINE_SIZE; // worst case: each SB is a tile |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "TileRecordStrmOutBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resTileRecordStrmOutBuffer)); |
| |
| // CU statistics stream out buffer |
| size = MOS_ALIGN_CEIL(maxPicSizeInSb * 64 * 8, CODECHAL_CACHELINE_SIZE); |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "CuStatsStrmOutBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resCuStatsStrmOutBuffer)); |
| |
| // HUC Prob DMEM buffer |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(MOS_MAX(sizeof(HucProbDmem), sizeof(HucProbDmem)), CODECHAL_CACHELINE_SIZE); |
| allocParamsForBufferLinear.pBufName = "HucProbDmemBuffer"; |
| for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucProbDmemBuffer[i][j])); |
| } |
| } |
| // Huc default prob buffer |
| allocParamsForBufferLinear.dwBytes = sizeof(Keyframe_Default_Probs)+sizeof(Inter_Default_Probs); |
| allocParamsForBufferLinear.pBufName = "HucDefaultProbBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucDefaultProbBuffer)); |
| |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resHucDefaultProbBuffer, |
| &lockFlagsWriteOnly); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(data); |
| |
| MOS_SecureMemcpy(data, sizeof(Keyframe_Default_Probs), |
| Keyframe_Default_Probs, sizeof(Keyframe_Default_Probs)); |
| MOS_SecureMemcpy(data + sizeof(Keyframe_Default_Probs), sizeof(Inter_Default_Probs), |
| Inter_Default_Probs, sizeof(Inter_Default_Probs)); |
| |
| m_osInterface->pfnUnlockResource(m_osInterface, &m_resHucDefaultProbBuffer); |
| |
| // Huc probability output buffer |
| allocParamsForBufferLinear.dwBytes = 32 * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.pBufName = "HucProbabilityOutputBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucProbOutputBuffer)); |
| |
| // Huc VP9 pak insert uncompressed header |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER; |
| allocParamsForBufferLinear.pBufName = "HucPakInsertUncompressedHeaderReadBuffer"; |
| |
| for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucPakInsertUncompressedHeaderReadBuffer[i])); |
| } |
| allocParamsForBufferLinear.dwBytes = CODECHAL_ENCODE_VP9_PAK_INSERT_UNCOMPRESSED_HEADER; |
| allocParamsForBufferLinear.pBufName = "HucPakInsertUncompressedHeaderWriteBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucPakInsertUncompressedHeaderWriteBuffer)); |
| |
| // Huc VP9 pak mmio buffer |
| allocParamsForBufferLinear.dwBytes = 4 * sizeof(uint32_t); |
| allocParamsForBufferLinear.pBufName = "HucPakMmioBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucPakMmioBuffer)); |
| |
| // Huc debug output buffer |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(1024 * sizeof(uint32_t), CODECHAL_PAGE_SIZE); |
| allocParamsForBufferLinear.pBufName = "HucDebugOutputBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHucDebugOutputBuffer)); |
| } |
| |
| if (m_encEnabled) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResourcesBrc()); |
| |
| if (m_hmeSupported) |
| { |
| MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(MOS_SURFACE)); |
| m_4xMeMvDataBuffer.TileType = MOS_TILE_LINEAR; |
| m_4xMeMvDataBuffer.bArraySpacing = true; |
| m_4xMeMvDataBuffer.Format = Format_Buffer_2D; |
| m_4xMeMvDataBuffer.dwWidth = m_downscaledWidthInMb4x * 32; |
| m_4xMeMvDataBuffer.dwHeight = m_downscaledHeightInMb4x * 4 * 10; |
| m_4xMeMvDataBuffer.dwPitch = MOS_ALIGN_CEIL(m_4xMeMvDataBuffer.dwWidth, 128); |
| |
| allocParamsForBuffer2D.dwWidth = m_4xMeMvDataBuffer.dwWidth; |
| allocParamsForBuffer2D.dwHeight = m_4xMeMvDataBuffer.dwHeight; |
| allocParamsForBuffer2D.pBufName = "4xME MV Data Buffer"; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer2D, |
| &m_4xMeMvDataBuffer.OsResource)); |
| |
| MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(MOS_SURFACE)); |
| m_4xMeDistortionBuffer.TileType = MOS_TILE_LINEAR; |
| m_4xMeDistortionBuffer.bArraySpacing = true; |
| m_4xMeDistortionBuffer.Format = Format_Buffer_2D; |
| m_4xMeDistortionBuffer.dwWidth = m_downscaledWidthInMb4x * 8; |
| m_4xMeDistortionBuffer.dwHeight = m_downscaledHeightInMb4x * 4 * 10; |
| m_4xMeDistortionBuffer.dwPitch = MOS_ALIGN_CEIL(m_4xMeDistortionBuffer.dwWidth, 128); |
| |
| allocParamsForBuffer2D.dwWidth = m_4xMeDistortionBuffer.dwWidth; |
| allocParamsForBuffer2D.dwHeight = m_4xMeDistortionBuffer.dwHeight; |
| allocParamsForBuffer2D.pBufName = "4xME Distortion Buffer"; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer2D, |
| &m_4xMeDistortionBuffer.OsResource)); |
| } |
| |
| if (m_16xMeSupported) |
| { |
| MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(MOS_SURFACE)); |
| m_16xMeMvDataBuffer.TileType = MOS_TILE_LINEAR; |
| m_16xMeMvDataBuffer.bArraySpacing = true; |
| m_16xMeMvDataBuffer.Format = Format_Buffer_2D; |
| |
| m_16xMeMvDataBuffer.dwWidth = MOS_ALIGN_CEIL((m_downscaledWidthInMb16x * 32), 64); |
| m_16xMeMvDataBuffer.dwHeight = m_downscaledHeightInMb16x * 4 * 10; |
| m_16xMeMvDataBuffer.dwPitch = MOS_ALIGN_CEIL(m_16xMeMvDataBuffer.dwWidth, 128); |
| |
| allocParamsForBuffer2D.dwWidth = m_4xMeMvDataBuffer.dwWidth; |
| allocParamsForBuffer2D.dwHeight = m_4xMeMvDataBuffer.dwHeight; |
| allocParamsForBuffer2D.pBufName = "16xME MV Data Buffer"; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer2D, |
| &m_16xMeMvDataBuffer.OsResource)); |
| } |
| |
| // intermediate surface to be used by the P kernel to help reduce number of SIC calls |
| MOS_ZeroMemory(&m_output16X16InterModes, sizeof(MOS_SURFACE)); |
| m_output16X16InterModes.TileType = MOS_TILE_LINEAR; |
| m_output16X16InterModes.bArraySpacing = true; |
| m_output16X16InterModes.Format = Format_Buffer_2D; |
| m_output16X16InterModes.dwWidth = 16 * m_picWidthInMb; |
| m_output16X16InterModes.dwHeight = 8 * m_picHeightInMb; |
| m_output16X16InterModes.dwPitch = MOS_ALIGN_CEIL(m_output16X16InterModes.dwWidth, 64); |
| |
| allocParamsForBuffer2D.dwWidth = m_output16X16InterModes.dwWidth; |
| allocParamsForBuffer2D.dwHeight = m_output16X16InterModes.dwHeight; |
| allocParamsForBuffer2D.pBufName = "Intermediate surface"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBuffer2D, |
| &m_output16X16InterModes.OsResource)); |
| |
| uint32_t size = 16 * m_picWidthInMb * m_picHeightInMb * sizeof(uint32_t); |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "Mode Decision Buffer"; |
| |
| for (auto i = 0; i < 2; i++) |
| { |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resModeDecision[i])); |
| } |
| } |
| |
| // VDENC Intra Row Store Scratch buffer |
| allocParamsForBufferLinear.dwBytes = m_picWidthInMb * CODECHAL_CACHELINE_SIZE; |
| allocParamsForBufferLinear.pBufName = "VDENC Intra Row Store Scratch Buffer"; |
| |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencIntraRowStoreScratchBuffer); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC Intra Row Store Scratch Buffer."); |
| return eStatus; |
| } |
| |
| // VDENC BRC Statistics buffer |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_maxTileNumber * m_vdencBrcStatsBufferSize, CODECHAL_PAGE_SIZE); |
| allocParamsForBufferLinear.pBufName = "VDENC BRC Statistics Buffer"; |
| |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencBrcStatsBuffer); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC Statistics Buffer\n", __FUNCTION__); |
| return eStatus; |
| } |
| |
| // HVC Tile Row Store Buffer |
| allocParamsForBufferLinear.dwBytes = CODECHAL_CACHELINE_SIZE * maxPicWidthInSb; |
| allocParamsForBufferLinear.pBufName = "HvcTileRowStoreBuffer"; |
| |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resHvcTileRowstoreBuffer); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate HVC Tile Row Store Buffer."); |
| return eStatus; |
| } |
| |
| // VDENC picture second level batch buffer |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencPicStateSecondLevelBatchBufferSize, CODECHAL_PAGE_SIZE); |
| allocParamsForBufferLinear.pBufName = "VDEnc Picture Second Level Batch Buffer Read"; |
| |
| for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencPictureState2NdLevelBatchBufferRead[j][i]); |
| } |
| } |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Picture Second Level Batch Buffer Read."); |
| return eStatus; |
| } |
| |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencPicStateSecondLevelBatchBufferSize, CODECHAL_PAGE_SIZE); |
| allocParamsForBufferLinear.pBufName = "VDEnc Picture Second Level Batch Buffer Write"; |
| |
| for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencPictureState2NdLevelBatchBufferWrite[i]); |
| } |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Picture Second Level Batch Buffer Write."); |
| return eStatus; |
| } |
| |
| // BRC init/reset DMEM |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucBrcInitDmem), CODECHAL_CACHELINE_SIZE); |
| allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer"; |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencBrcInitDmemBuffer); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC BRC Init DMEM Buffer\n"); |
| return eStatus; |
| } |
| |
| // BRC update DMEM |
| for (auto i = 0; i < 3; i++) |
| { |
| // BRC update DMEM |
| allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(sizeof(HucBrcUpdateDmem), CODECHAL_CACHELINE_SIZE); |
| allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer"; |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencBrcUpdateDmemBuffer[i]); |
| } |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC BRC Update DMEM Buffer\n"); |
| return eStatus; |
| } |
| |
| // This stream out/stream in buffer may need to be a separate buffer on HW, in which case |
| // we'll create 2 and ping-pong back and forth per-frame. For now, though, on simulation/SW, |
| // they can be the same buffer. |
| allocParamsForBufferLinear.dwBytes = CODECHAL_CACHELINE_SIZE * maxPicSizeInSb; |
| allocParamsForBufferLinear.pBufName = "VDEnc Segment Map Stream Out"; |
| |
| eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencSegmentMapStreamOut); |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDEnc Segment Map Stream Out Buffer."); |
| return eStatus; |
| } |
| |
| // Allocate Frame Statistics Streamout Data Destination Buffer |
| uint32_t size = MOS_ALIGN_CEIL(m_vdencBrcPakStatsBufferSize, CODECHAL_PAGE_SIZE); // Align to page is HuC requirement |
| allocParamsForBufferLinear.dwBytes = size * m_maxTileNumber; |
| allocParamsForBufferLinear.pBufName = "FrameStatStreamOutBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resFrameStatStreamOutBuffer), |
| "Failed to allocate VP9 FrameStatStreamOutBuffer"); |
| |
| uint8_t* data = nullptr; |
| CODECHAL_ENCODE_CHK_NULL_RETURN( |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resFrameStatStreamOutBuffer, |
| &lockFlagsWriteOnly)); |
| |
| MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resFrameStatStreamOutBuffer)); |
| |
| // Allocate SSE Source Pixel Row Store Buffer |
| m_sizeOfSseSrcPixelRowStoreBufferPerLcu = ((maxPicWidthInSb + 2) << 5) * CODECHAL_CACHELINE_SIZE; |
| size = m_sizeOfSseSrcPixelRowStoreBufferPerLcu * m_maxTileNumber; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "SseSrcPixelRowStoreBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resSseSrcPixelRowStoreBuffer), |
| "Failed to allocate VP9 SseSrcPixelRowStoreBuffer"); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN( |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resSseSrcPixelRowStoreBuffer, |
| &lockFlagsWriteOnly)); |
| |
| MOS_ZeroMemory(data, size); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resSseSrcPixelRowStoreBuffer)); |
| |
| // Allocate data extension buffer |
| size = CODECHAL_ENCODE_VP9_VDENC_DATA_EXTENSION_SIZE; |
| allocParamsForBufferLinear.dwBytes = size; |
| allocParamsForBufferLinear.pBufName = "DataExtensionBuffer"; |
| |
| CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource( |
| m_osInterface, |
| &allocParamsForBufferLinear, |
| &m_resVdencDataExtensionBuffer), |
| "Failed to allocate VP9 HuC data extension buffer"); |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN( |
| data = (uint8_t *)m_osInterface->pfnLockResource( |
| m_osInterface, |
| &m_resVdencDataExtensionBuffer, |
| &lockFlagsWriteOnly)); |
| |
| MOS_ZeroMemory(data, size); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource( |
| m_osInterface, |
| &m_resVdencDataExtensionBuffer)); |
| |
| if (m_hucCmdInitializer) |
| { |
| m_hucCmdInitializer->CmdInitializerAllocateResources(m_hwInterface); |
| } |
| |
| return eStatus; |
| } |
| |
| void CodechalVdencVp9State::FreeResources() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CodechalEncoderState::FreeResources(); |
| |
| PCODEC_REF_LIST *refList = &m_refList[0]; |
| |
| // Release Ref Lists |
| for (uint32_t i = 0; i < m_numUncompressedSurface; i++) |
| { |
| if (!Mos_ResourceIsNull(&refList[i]->sDysSurface.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &refList[i]->sDysSurface.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&refList[i]->sDys4xScaledSurface.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &refList[i]->sDys4xScaledSurface.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&refList[i]->sDys16xScaledSurface.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &refList[i]->sDys16xScaledSurface.OsResource); |
| } |
| } |
| |
| CodecHalFreeDataList(m_refList, m_numUncompressedSurface); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resDeblockingFilterLineBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resDeblockingFilterTileLineBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resDeblockingFilterTileColumnBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resMetadataLineBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resMetadataTileLineBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resMetadataTileColumnBuffer); |
| |
| for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resProbBuffer[i]); |
| } |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resSegmentIdBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resProbabilityDeltaBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resCompressedHeaderBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resProbabilityCounterBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resTileRecordStrmOutBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resCuStatsStrmOutBuffer); |
| |
| for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucProbDmemBuffer[i][j]); |
| } |
| } |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucPakMmioBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucDefaultProbBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucProbOutputBuffer); |
| for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++i) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucPakInsertUncompressedHeaderReadBuffer[i]); |
| } |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucPakInsertUncompressedHeaderWriteBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resHucDebugOutputBuffer); |
| |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resVdencDataExtensionBuffer); |
| |
| if (m_encEnabled) |
| { |
| ReleaseResourcesBrc(); |
| for (auto i = 0; i < 2; i++) |
| { |
| if (!Mos_ResourceIsNull(&m_resModeDecision[i])) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resModeDecision[i]); |
| } |
| } |
| |
| if (!Mos_ResourceIsNull(&m_output16X16InterModes.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_output16X16InterModes.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_4xMeMvDataBuffer.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_4xMeMvDataBuffer.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_4xMeDistortionBuffer.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_4xMeDistortionBuffer.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_16xMeMvDataBuffer.OsResource)) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_16xMeMvDataBuffer.OsResource); |
| } |
| |
| if (!Mos_ResourceIsNull(&m_mbSegmentMapSurface.OsResource) && m_segmentMapAllocated) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_mbSegmentMapSurface.OsResource); |
| } |
| } |
| |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencIntraRowStoreScratchBuffer); |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcStatsBuffer); |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resHvcTileRowstoreBuffer); |
| |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencDysPictureState2NdLevelBatchBuffer); |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencSegmentMapStreamOut); |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcInitDmemBuffer); |
| for (auto i = 0; i < 3; i++) |
| { |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[i]); |
| } |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resFrameStatStreamOutBuffer); |
| m_osInterface->pfnFreeResource(m_osInterface, &m_resSseSrcPixelRowStoreBuffer); |
| MOS_FreeMemory(m_mapBuffer); |
| |
| for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resVdencPictureState2NdLevelBatchBufferRead[j][i]); |
| } |
| m_osInterface->pfnFreeResource( |
| m_osInterface, |
| &m_resVdencPictureState2NdLevelBatchBufferWrite[i]); |
| } |
| if (m_hucCmdInitializer) |
| { |
| m_hucCmdInitializer->CmdInitializerFreeResources(); |
| MOS_Delete(m_hucCmdInitializer); |
| m_hucCmdInitializer = nullptr; |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (m_swBrcMode != nullptr) |
| { |
| bool result = MOS_FreeLibrary(m_swBrcMode) ? true : false; |
| CODECHAL_ENCODE_ASSERT(result == true); |
| m_swBrcMode = nullptr; |
| } |
| #endif |
| |
| return; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::CalculateVdencPictureStateCommandSize() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| MHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams; |
| uint32_t vdencPictureStatesSize = 0, vdencPicturePatchListSize = 0; |
| stateCmdSizeParams.bHucDummyStream = true; |
| m_hwInterface->GetHxxStateCommandSize( |
| CODECHAL_ENCODE_MODE_VP9, |
| &vdencPictureStatesSize, |
| &vdencPicturePatchListSize, |
| &stateCmdSizeParams); |
| |
| m_defaultPictureStatesSize += vdencPictureStatesSize; |
| m_defaultPicturePatchListSize += vdencPicturePatchListSize; |
| |
| m_hwInterface->GetVdencStateCommandsDataSize( |
| CODECHAL_ENCODE_MODE_VP9, |
| &vdencPictureStatesSize, |
| &vdencPicturePatchListSize); |
| |
| m_defaultPictureStatesSize += vdencPictureStatesSize; |
| m_defaultPicturePatchListSize += vdencPicturePatchListSize; |
| |
| //Set to max huc commands |
| uint32_t vdencHucStatesSize = 0, hucPatchListSize = 0; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetHucInterface()->GetHucStateCommandSize( |
| CODECHAL_ENCODE_MODE_VP9, (uint32_t*)&vdencHucStatesSize, (uint32_t*)&hucPatchListSize, &stateCmdSizeParams)); |
| m_defaultHucCmdsSize += m_defaultHucCmdsSize; |
| m_defaultHucPatchListSize += hucPatchListSize; |
| return eStatus; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::Initialize(CodechalSetting * settings) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| #ifndef _FULL_OPEN_SOURCE |
| if (m_cscDsState) |
| { |
| // support non-aligned and csc ds copy usages |
| m_cscDsState->EnableCopy(); |
| m_cscDsState->EnableColor(); |
| |
| // Temp WA until cscDs Codec/Platform LUT is completed |
| m_cscDsState->DisableCsc(); |
| } |
| #endif |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::Initialize(settings)); |
| #ifdef _MMC_SUPPORTED |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(InitMmcState()); |
| #endif |
| m_bitDepth = (settings->lumaChromaDepth & CODECHAL_LUMA_CHROMA_DEPTH_10_BITS) ? VP9_ENCODED_BIT_DEPTH_10 : VP9_ENCODED_BIT_DEPTH_8; |
| m_chromaFormat = settings->chromaFormat; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateVdencPictureStateCommandSize()); |
| |
| // Slice Level Commands |
| CODECHAL_ENCODE_CHK_STATUS_RETURN( |
| m_hwInterface->GetHxxPrimitiveCommandSize( |
| CODECHAL_ENCODE_MODE_VP9, |
| &m_sliceStatesSize, |
| &m_slicePatchListSize, |
| false)); |
| |
| m_hwInterface->GetVdencPictureSecondLevelCommandsSize( |
| CODECHAL_ENCODE_MODE_VP9, |
| &m_vdencPicStateSecondLevelBatchBufferSize); |
| |
| return eStatus; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Reports user feature keys used for VP9 encoding |
| //| Return: N/A |
| //------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::UserFeatureKeyReport() |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncoderState::UserFeatureKeyReport()) |
| |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_BRC_IN_USE_ID, m_brcEnabled, m_osInterface->pOsContext); |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_MULTIPASS_BRC_IN_USE_ID, m_multipassBrcSupported, m_osInterface->pOsContext); |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_ADAPTIVE_REPAK_IN_USE_ID, m_adaptiveRepakSupported, m_osInterface->pOsContext); |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_ME_ENABLE_ID, m_hmeSupported, m_osInterface->pOsContext); |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_16xME_ENABLE_ID, m_16xMeSupported, m_osInterface->pOsContext); |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VP9_ENCODE_HUC_ENABLE_ID, m_hucEnabled, m_osInterface->pOsContext); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| CodecHalEncodeWriteKey(__MEDIA_USER_FEATURE_VALUE_VDENC_IN_USE_ID, m_vdencEnabled, m_osInterface->pOsContext); |
| #endif |
| |
| return eStatus; |
| } |
| |
| //------------------------------------------------------------------------------ |
| //| Purpose: Retrieves the HCP registers and stores them in the status report |
| //| Return: N/A |
| //------------------------------------------------------------------------------ |
| MOS_STATUS CodechalVdencVp9State::ReadHcpStatus( |
| PMOS_COMMAND_BUFFER cmdBuffer) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| |
| CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer); |
| |
| CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()),"ERROR - vdbox index exceed the maximum"); |
| |
| EncodeStatusBuffer* encodeStatusBuf = &m_encodeStatusBuf; |
| uint32_t baseOffset = |
| (encodeStatusBuf->wCurrIndex * m_encodeStatusBuf.dwReportSize) + |
| sizeof(uint32_t)* 2; // encodeStatus is offset by 2 DWs in the resource |
| |
| MHW_MI_FLUSH_DW_PARAMS flushDwParams; |
| MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams)); |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams)); |
| |
| auto mmioRegisters = m_hcpInterface->GetMmioRegisters(m_vdboxIndex); |
| MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams; |
| MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams)); |
| miStoreRegMemParams.presStoreBuffer = &encodeStatusBuf->resStatusBuffer; |
| miStoreRegMemParams.dwOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset; |
| miStoreRegMemParams.dwRegister = mmioRegisters->hcpVp9EncBitstreamBytecountFrameRegOffset; |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams)); |
| |
| MHW_MI_COPY_MEM_MEM_PARAMS copyMemMemParams; |
| MOS_ZeroMemory(©MemMemParams , sizeof(copyMemMemParams)); |
| |
| copyMemMemParams.presSrc = &encodeStatusBuf->resStatusBuffer; |
| copyMemMemParams.dwSrcOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset; |
| copyMemMemParams.presDst = &m_brcBuffers.resBrcBitstreamSizeBuffer; |
| copyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(BRC_BITSTREAM_SIZE_BUFFER, dwHcpBitstreamByteCountFrame); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd( |
| cmdBuffer, |
| ©MemMemParams)); |
| |
| MOS_ZeroMemory(©MemMemParams, sizeof(copyMemMemParams)); |
| |
| // write frame size directly to huc second pass dmem buffer |
| // it is needed for correct pipeline synchronization and dmem initialization |
| copyMemMemParams.presSrc = &encodeStatusBuf->resStatusBuffer; |
| copyMemMemParams.dwSrcOffset = baseOffset + encodeStatusBuf->dwBSByteCountOffset; |
| // For BRC cases, do not overwrite the HPU probability in huc Dmen buffer in the last pass |
| copyMemMemParams.presDst = &m_resHucProbDmemBuffer[m_vdencBrcEnabled ? 2 : 1][m_currRecycledBufIdx]; |
| copyMemMemParams.dwDstOffset = CODECHAL_OFFSETOF(HucProbDmem, FrameSize); |
| |
| CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiCopyMemMemCmd( |
| cmdBuffer, |
| ©MemMemParams)); |
| |
| return eStatus; |
| } |
| |
| CodechalVdencVp9State::CodechalVdencVp9State( |
| CodechalHwInterface* hwInterface, |
| CodechalDebugInterface* debugInterface, |
| PCODECHAL_STANDARD_INFO standardInfo) |
| :CodechalEncoderState(hwInterface, debugInterface, standardInfo) |
| { |
| m_32xMeSupported = false; |
| |
| // VP9 uses a CM based down scale kernel |
| m_useCmScalingKernel = true; |
| m_interlacedFieldDisabled = true; |
| m_firstField = true; // each frame is treated as the first field |
| |
| // No field pictures in VP9 |
| m_verticalLineStride = CODECHAL_VLINESTRIDE_FRAME; |
| m_verticalLineStrideOffset = CODECHAL_VLINESTRIDEOFFSET_TOP_FIELD; |
| |
| // enable codec specific user feature key reporting |
| m_userFeatureKeyReport = true; |
| |
| m_codecGetStatusReportDefined = true; // Codec specific GetStatusReport is implemented. |
| |
| m_brcInit = true; |
| |
| MOS_ZeroMemory(&m_resDeblockingFilterLineBuffer, sizeof(m_resDeblockingFilterLineBuffer)); |
| MOS_ZeroMemory(&m_resDeblockingFilterTileLineBuffer, sizeof(m_resDeblockingFilterTileLineBuffer)); |
| MOS_ZeroMemory(&m_resDeblockingFilterTileColumnBuffer, sizeof(m_resDeblockingFilterTileColumnBuffer)); |
| MOS_ZeroMemory(&m_resMetadataLineBuffer, sizeof(m_resMetadataLineBuffer)); |
| MOS_ZeroMemory(&m_resMetadataTileLineBuffer, sizeof(m_resMetadataTileLineBuffer)); |
| MOS_ZeroMemory(&m_resMetadataTileColumnBuffer, sizeof(m_resMetadataTileColumnBuffer)); |
| |
| for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++) |
| { |
| MOS_ZeroMemory(&m_resProbBuffer[i], sizeof(m_resProbBuffer[i])); |
| } |
| MOS_ZeroMemory(&m_resSegmentIdBuffer, sizeof(m_resSegmentIdBuffer)); |
| MOS_ZeroMemory(&m_resHvcLineRowstoreBuffer, sizeof(m_resHvcLineRowstoreBuffer)); // Handle of HVC Line Row Store surface |
| MOS_ZeroMemory(&m_resHvcTileRowstoreBuffer, sizeof(m_resHvcTileRowstoreBuffer)); // Handle of HVC Tile Row Store surface |
| MOS_ZeroMemory(&m_resProbabilityDeltaBuffer, sizeof(m_resProbabilityDeltaBuffer)); |
| MOS_ZeroMemory(&m_resTileRecordStrmOutBuffer, sizeof(m_resTileRecordStrmOutBuffer)); |
| MOS_ZeroMemory(&m_resCuStatsStrmOutBuffer, sizeof(m_resCuStatsStrmOutBuffer)); |
| MOS_ZeroMemory(&m_resCompressedHeaderBuffer, sizeof(m_resCompressedHeaderBuffer)); |
| MOS_ZeroMemory(&m_resProbabilityCounterBuffer, sizeof(m_resProbabilityCounterBuffer)); |
| for (auto i = 0; i < 2; i++) |
| { |
| MOS_ZeroMemory(&m_resModeDecision[i], sizeof(m_resModeDecision[i])); |
| } |
| MOS_ZeroMemory(&m_resFrameStatStreamOutBuffer, sizeof(m_resFrameStatStreamOutBuffer)); |
| MOS_ZeroMemory(&m_resSseSrcPixelRowStoreBuffer, sizeof(m_resSseSrcPixelRowStoreBuffer)); |
| |
| MOS_ZeroMemory(&m_prevFrameInfo, sizeof(m_prevFrameInfo)); |
| |
| for (auto j = 0; j < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++j) |
| { |
| for (auto i = 0; i < 3; i++) |
| { |
| MOS_ZeroMemory(&m_resHucProbDmemBuffer[i][j], sizeof(m_resHucProbDmemBuffer[i][j])); |
| } |
| } |
| MOS_ZeroMemory(&m_resHucDefaultProbBuffer, sizeof(m_resHucDefaultProbBuffer)); |
| MOS_ZeroMemory(&m_resHucProbOutputBuffer, sizeof(m_resHucProbOutputBuffer)); |
| for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| MOS_ZeroMemory(&m_resHucPakInsertUncompressedHeaderReadBuffer[i], sizeof(m_resHucPakInsertUncompressedHeaderReadBuffer[i])); |
| } |
| MOS_ZeroMemory(&m_resHucPakInsertUncompressedHeaderWriteBuffer, sizeof(m_resHucPakInsertUncompressedHeaderWriteBuffer)); |
| MOS_ZeroMemory(&m_resHucPakMmioBuffer, sizeof(m_resHucPakMmioBuffer)); |
| MOS_ZeroMemory(&m_resHucDebugOutputBuffer, sizeof(m_resHucDebugOutputBuffer)); |
| MOS_ZeroMemory(&m_mbSegmentMapSurface, sizeof(m_mbSegmentMapSurface)); |
| MOS_ZeroMemory(&m_output16X16InterModes, sizeof(m_output16X16InterModes)); |
| |
| MOS_ZeroMemory(&m_4xMeMvDataBuffer, sizeof(m_4xMeMvDataBuffer)); |
| MOS_ZeroMemory(&m_16xMeMvDataBuffer, sizeof(m_16xMeMvDataBuffer)); |
| MOS_ZeroMemory(&m_4xMeDistortionBuffer, sizeof(m_4xMeDistortionBuffer)); |
| |
| MOS_ZeroMemory(&m_resVdencIntraRowStoreScratchBuffer, sizeof(m_resVdencIntraRowStoreScratchBuffer)); // Handle of intra row store surface |
| MOS_ZeroMemory(&m_resVdencBrcStatsBuffer, sizeof(m_resVdencBrcStatsBuffer)); |
| MOS_ZeroMemory(&m_resVdencSegmentMapStreamOut, sizeof(m_resVdencSegmentMapStreamOut)); |
| |
| for (auto i = 0; i < CODECHAL_VP9_ENCODE_RECYCLED_BUFFER_NUM; i++) |
| { |
| for (auto j = 0; j < 3; j++) |
| { |
| MOS_ZeroMemory(&m_resVdencPictureState2NdLevelBatchBufferRead[j][i], sizeof(m_resVdencPictureState2NdLevelBatchBufferRead[j][i])); |
| } |
| |
| MOS_ZeroMemory(&m_resVdencPictureState2NdLevelBatchBufferWrite[i], sizeof(m_resVdencPictureState2NdLevelBatchBufferWrite[i])); |
| } |
| |
| MOS_ZeroMemory(&m_resVdencDysPictureState2NdLevelBatchBuffer, sizeof(m_resVdencDysPictureState2NdLevelBatchBuffer)); |
| MOS_ZeroMemory(&m_resVdencBrcInitDmemBuffer, sizeof(m_resVdencBrcInitDmemBuffer)); |
| for (auto i = 0; i < 3; i++) |
| { |
| MOS_ZeroMemory(&m_resVdencBrcUpdateDmemBuffer[i], sizeof(m_resVdencBrcUpdateDmemBuffer[i])); |
| } |
| MOS_ZeroMemory(&m_resVdencDataExtensionBuffer, sizeof(m_resVdencDataExtensionBuffer)); |
| |
| MOS_ZeroMemory(&m_dysKernelState, sizeof(m_dysKernelState)); |
| |
| m_vdboxOneDefaultUsed = true; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::InitMmcState() |
| { |
| CODECHAL_ENCODE_FUNCTION_ENTER; |
| #ifdef _MMC_SUPPORTED |
| m_mmcState = MOS_New(CodechalMmcEncodeVp9, m_hwInterface, this); |
| CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState); |
| #endif |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::CtxBufDiffInit( |
| uint8_t *ctxBuffer, |
| bool setToKey) |
| { |
| int32_t i, j; |
| uint32_t byteCnt = CODEC_VP9_INTER_PROB_OFFSET; |
| //inter mode probs. have to be zeros for Key frame |
| for (i = 0; i < CODEC_VP9_INTER_MODE_CONTEXTS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_INTER_MODES - 1; j++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultInterModeProbs[i][j]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| } |
| //switchable interprediction probs |
| for (i = 0; i < CODEC_VP9_SWITCHABLE_FILTERS + 1; i++) |
| { |
| for (j = 0; j < CODEC_VP9_SWITCHABLE_FILTERS - 1; j++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultSwitchableInterpProb[i][j]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| } |
| //intra inter probs |
| for (i = 0; i < CODEC_VP9_INTRA_INTER_CONTEXTS; i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultIntraInterProb[i]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| //comp inter probs |
| for (i = 0; i < CODEC_VP9_COMP_INTER_CONTEXTS; i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultCompInterProb[i]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| //single ref probs |
| for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++) |
| { |
| for (j = 0; j < 2; j++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultSingleRefProb[i][j]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| } |
| //comp ref probs |
| for (i = 0; i < CODEC_VP9_REF_CONTEXTS; i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultCompRefProb[i]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| //y mode probs |
| for (i = 0; i < CODEC_VP9_BLOCK_SIZE_GROUPS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultIFYProb[i][j]; |
| } |
| else |
| { |
| //zeros for key frame, since HW will not use this buffer, but default right buffer. |
| byteCnt++; |
| } |
| } |
| } |
| //partition probs, key & intra-only frames use key type, other inter frames use inter type |
| for (i = 0; i < CODECHAL_VP9_PARTITION_CONTEXTS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_PARTITION_TYPES - 1; j++) |
| { |
| if (setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultKFPartitionProb[i][j]; |
| } |
| else |
| { |
| ctxBuffer[byteCnt++] = DefaultPartitionProb[i][j]; |
| } |
| } |
| } |
| //nmvc joints |
| for (i = 0; i < (CODEC_VP9_MV_JOINTS - 1); i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.joints[i]; |
| } |
| else |
| { |
| //zeros for key frame |
| byteCnt++; |
| } |
| } |
| //nmvc comps |
| for (i = 0; i < 2; i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].sign; |
| for (j = 0; j < (CODEC_VP9_MV_CLASSES - 1); j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].classes[j]; |
| } |
| for (j = 0; j < (CODECHAL_VP9_CLASS0_SIZE - 1); j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0[j]; |
| } |
| for (j = 0; j < CODECHAL_VP9_MV_OFFSET_BITS; j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].bits[j]; |
| } |
| } |
| else |
| { |
| byteCnt += 1; |
| byteCnt += (CODEC_VP9_MV_CLASSES - 1); |
| byteCnt += (CODECHAL_VP9_CLASS0_SIZE - 1); |
| byteCnt += (CODECHAL_VP9_MV_OFFSET_BITS); |
| } |
| } |
| for (i = 0; i < 2; i++) |
| { |
| if (!setToKey) |
| { |
| for (j = 0; j < CODECHAL_VP9_CLASS0_SIZE; j++) |
| { |
| for (int32_t k = 0; k < (CODEC_VP9_MV_FP_SIZE - 1); k++) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_fp[j][k]; |
| } |
| } |
| for (j = 0; j < (CODEC_VP9_MV_FP_SIZE - 1); j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].fp[j]; |
| } |
| } |
| else |
| { |
| byteCnt += (CODECHAL_VP9_CLASS0_SIZE * (CODEC_VP9_MV_FP_SIZE - 1)); |
| byteCnt += (CODEC_VP9_MV_FP_SIZE - 1); |
| } |
| } |
| for (i = 0; i < 2; i++) |
| { |
| if (!setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_hp; |
| ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].hp; |
| } |
| else |
| { |
| byteCnt += 2; |
| } |
| } |
| |
| //47 bytes of zeros |
| byteCnt += 47; |
| |
| //uv mode probs |
| for (i = 0; i < CODEC_VP9_INTRA_MODES; i++) |
| { |
| for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; j++) |
| { |
| if (setToKey) |
| { |
| ctxBuffer[byteCnt++] = DefaultKFUVModeProb[i][j]; |
| } |
| else |
| { |
| ctxBuffer[byteCnt++] = DefaultIFUVProbs[i][j]; |
| } |
| } |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::ContextBufferInit( |
| uint8_t *ctxBuffer, |
| bool setToKey) |
| { |
| |
| MOS_ZeroMemory(ctxBuffer, CODEC_VP9_SEG_PROB_OFFSET); |
| |
| int32_t i, j; |
| uint32_t byteCnt = 0; |
| //TX probs |
| for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_TX_SIZES - 3; j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultTxProbs.p8x8[i][j]; |
| } |
| } |
| for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_TX_SIZES - 2; j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultTxProbs.p16x16[i][j]; |
| } |
| } |
| for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; i++) |
| { |
| for (j = 0; j < CODEC_VP9_TX_SIZES - 1; j++) |
| { |
| ctxBuffer[byteCnt++] = DefaultTxProbs.p32x32[i][j]; |
| } |
| } |
| |
| //52 bytes of zeros |
| byteCnt += 52; |
| |
| uint8_t blocktype = 0; |
| uint8_t reftype = 0; |
| uint8_t coeffbands = 0; |
| uint8_t unConstrainedNodes = 0; |
| uint8_t prevCoefCtx = 0; |
| //coeff probs |
| for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++) |
| { |
| for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++) |
| { |
| for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++) |
| { |
| uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS; |
| for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++) |
| { |
| for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++) |
| { |
| ctxBuffer[byteCnt++] = DefaultCoefProbs4x4[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes]; |
| } |
| } |
| } |
| } |
| } |
| |
| for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++) |
| { |
| for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++) |
| { |
| for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++) |
| { |
| uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS; |
| for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++) |
| { |
| for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++) |
| { |
| ctxBuffer[byteCnt++] = DefaultCoefPprobs8x8[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes]; |
| } |
| } |
| } |
| } |
| } |
| |
| for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++) |
| { |
| for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++) |
| { |
| for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++) |
| { |
| uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS; |
| for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++) |
| { |
| for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++) |
| { |
| ctxBuffer[byteCnt++] = DefaultCoefProbs16x16[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes]; |
| } |
| } |
| } |
| } |
| } |
| |
| for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; blocktype++) |
| { |
| for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; reftype++) |
| { |
| for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; coeffbands++) |
| { |
| uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS; |
| for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; prevCoefCtx++) |
| { |
| for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; unConstrainedNodes++) |
| { |
| ctxBuffer[byteCnt++] = DefaultCoefProbs32x32[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes]; |
| } |
| } |
| } |
| } |
| } |
| |
| //16 bytes of zeros |
| byteCnt += 16; |
| |
| // mb skip probs |
| for (i = 0; i < CODEC_VP9_MBSKIP_CONTEXTS; i++) |
| { |
| ctxBuffer[byteCnt++] = DefaultMbskipProbs[i]; |
| } |
| |
| // populate prob values which are different between Key and Non-Key frame |
| CtxBufDiffInit(ctxBuffer, setToKey); |
| |
| //skip Seg tree/pred probs, updating not done in this function. |
| byteCnt = CODEC_VP9_SEG_PROB_OFFSET; |
| byteCnt += 7; |
| byteCnt += 3; |
| |
| //28 bytes of zeros |
| for (i = 0; i < 28; i++) |
| { |
| ctxBuffer[byteCnt++] = 0; |
| } |
| |
| //Just a check. |
| if (byteCnt > CODEC_VP9_PROB_MAX_NUM_ELEM) |
| { |
| CODECHAL_PUBLIC_ASSERTMESSAGE("Error: FrameContext array out-of-bounds, byteCnt = %d!\n", byteCnt); |
| return MOS_STATUS_NO_SPACE; |
| } |
| else |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| } |
| |
| #if USE_CODECHAL_DEBUG_TOOL |
| MOS_STATUS CodechalVdencVp9State::DumpSeqParams( |
| PCODEC_VP9_ENCODE_SEQUENCE_PARAMS seqParams) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSeqParams)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| CODECHAL_DEBUG_CHK_NULL(seqParams); |
| |
| std::ostringstream oss; |
| oss.setf(std::ios::showbase | std::ios::uppercase); |
| |
| oss << "# DDI Parameters:" << std::endl; |
| oss << "MaxFrameWidth = " << std::dec << +seqParams->wMaxFrameWidth << std::endl; |
| oss << "MaxFrameHeight = " << std::dec << +seqParams->wMaxFrameHeight << std::endl; |
| oss << "GopPicSize = " << std::dec << +seqParams->GopPicSize << std::endl; |
| oss << "TargetUsage = " << std::dec << +seqParams->TargetUsage << std::endl; |
| oss << "RateControlMethod = " << std::dec << +seqParams->RateControlMethod << std::endl; |
| |
| for (uint8_t i = 0; i < 8; i++) |
| { |
| oss << "TargetBitRate[" << +i << "] = " << std::dec << +seqParams->TargetBitRate[i] << std::endl; |
| } |
| oss << "MaxBitRate = " << std::dec << +seqParams->MaxBitRate << std::endl; |
| oss << "MinBitRate = " << std::dec << +seqParams->MinBitRate << std::endl; |
| oss << "InitVBVBufferFullnessInBit = " << +seqParams->InitVBVBufferFullnessInBit << std::endl; |
| oss << "VBVBufferSizeInBit = " << std::dec << +seqParams->VBVBufferSizeInBit << std::endl; |
| oss << "OptimalVBVBufferLevelInBit = " << std::dec << +seqParams->OptimalVBVBufferLevelInBit << std::endl; |
| oss << "UpperVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->UpperVBVBufferLevelThresholdInBit << std::endl; |
| oss << "LowerVBVBufferLevelThresholdInBit = " << std::dec << +seqParams->LowerVBVBufferLevelThresholdInBit << std::endl; |
| oss << "DisplayFormatSwizzle = " << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl; |
| // begining of union/struct |
| oss << "# bResetBRC = " << std::dec << +seqParams->SeqFlags.fields.bResetBRC << std::endl; |
| oss << "# bNoFrameHeaderInsertion = " << std::dec << +seqParams->SeqFlags.fields.bNoFrameHeaderInsertion << std::endl; |
| // Next 5 fields not currently implemented. nullptr output |
| oss << "# UseRawReconRef = " << std::dec << +seqParams->SeqFlags.fields.bUseRawReconRef << std::endl; |
| oss << "# MBBRC = " << std::dec << +seqParams->SeqFlags.fields.MBBRC << std::endl; |
| oss << "EnableDynamicScaling = " << std::dec << +seqParams->SeqFlags.fields.EnableDynamicScaling << std::endl; |
| oss << "SourceFormat = " << std::dec << +seqParams->SeqFlags.fields.SourceFormat << std::endl; |
| oss << "SourceBitDepth = " << std::dec << +seqParams->SeqFlags.fields.SourceBitDepth << std::endl; |
| oss << "EncodedFormat = " << std::dec << +seqParams->SeqFlags.fields.EncodedFormat << std::endl; |
| oss << "EncodedBitDepth = " << std::dec << +seqParams->SeqFlags.fields.EncodedBitDepth << std::endl; |
| oss << "DisplayFormatSwizzle = " << std::dec << +seqParams->SeqFlags.fields.DisplayFormatSwizzle << std::endl; |
| // end of union/struct |
| |
| oss << "UserMaxFrameSize = " << std::dec << +seqParams->UserMaxFrameSize << std::endl; |
| for (uint8_t i = 0; i < 8; i++) |
| { |
| oss << "FrameRateNumerator[" << +i << "] = " << std::dec << +seqParams->FrameRate[i].uiNumerator << std::endl; |
| oss << "FrameRateDenominator[" << +i << "] = " << std::dec << +seqParams->FrameRate[i].uiDenominator << std::endl; |
| } |
| |
| oss << "NumTemporalLayersMinus1 = " << std::dec << +seqParams->NumTemporalLayersMinus1 << std::endl; |
| |
| const char *fileName = m_debugInterface->CreateFileName( |
| "_DDIEnc", |
| CodechalDbgBufferType::bufSeqParams, |
| CodechalDbgExtType::txt); |
| |
| std::ofstream ofs(fileName, std::ios::out); |
| ofs << oss.str(); |
| ofs.close(); |
| |
| if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump)) |
| { |
| if (!m_debugInterface->m_ddiFileName.empty()) |
| { |
| std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app); |
| ofs << "SeqParamFile" |
| << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl; |
| ofs.close(); |
| } |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::DumpPicParams( |
| PCODEC_VP9_ENCODE_PIC_PARAMS picParams) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| CODECHAL_DEBUG_CHK_NULL(picParams); |
| |
| std::ostringstream oss; |
| oss.setf(std::ios::showbase | std::ios::uppercase); |
| |
| oss << "# DDI Parameters:" << std::endl; |
| oss << "SrcFrameHeightMinus1 = " << std::dec << +picParams->SrcFrameHeightMinus1 << std::endl; |
| oss << "SrcFrameWidthMinus1 = " << std::dec << +picParams->SrcFrameWidthMinus1 << std::endl; |
| oss << "CurrOriginalPic = " << std::dec << +picParams->CurrOriginalPic.FrameIdx << std::endl; |
| oss << "CurrReconstructedPic = " << std::dec << +picParams->CurrReconstructedPic.FrameIdx << std::endl; |
| |
| for (uint16_t i = 0; i < CODEC_VP9_NUM_REF_FRAMES; ++i) |
| { |
| oss << "RefFrameList[" << +i << "] = " << std::dec << +picParams->RefFrameList[i].FrameIdx << std::endl; |
| } |
| oss << "frame_type = " << std::dec << +picParams->PicFlags.fields.frame_type << std::endl; |
| oss << "show_frame = " << std::dec << +picParams->PicFlags.fields.show_frame << std::endl; |
| oss << "error_resilient_mode = " << std::dec << +picParams->PicFlags.fields.error_resilient_mode << std::endl; |
| oss << "intra_only = " << std::dec << +picParams->PicFlags.fields.intra_only << std::endl; |
| oss << "allow_high_precision_mv = " << std::dec << +picParams->PicFlags.fields.allow_high_precision_mv << std::endl; |
| oss << "mcomp_filter_type = " << std::dec << +picParams->PicFlags.fields.mcomp_filter_type << std::endl; |
| oss << "frame_parallel_decoding_mode = " << std::dec << +picParams->PicFlags.fields.frame_parallel_decoding_mode << std::endl; |
| oss << "segmentation_enabled = " << std::dec << +picParams->PicFlags.fields.segmentation_enabled << std::endl; |
| oss << "segmentation_temporal_update = " << std::dec << +picParams->PicFlags.fields.segmentation_temporal_update << std::endl; |
| oss << "segmentation_update_map = " << std::dec << +picParams->PicFlags.fields.segmentation_update_map << std::endl; |
| oss << "reset_frame_context = " << std::dec << +picParams->PicFlags.fields.reset_frame_context << std::endl; |
| oss << "refresh_frame_context = " << std::dec << +picParams->PicFlags.fields.refresh_frame_context << std::endl; |
| oss << "frame_context_idx = " << std::dec << +picParams->PicFlags.fields.frame_context_idx << std::endl; |
| oss << "LosslessFlag = " << std::dec << +picParams->PicFlags.fields.LosslessFlag << std::endl; |
| oss << "comp_prediction_mode = " << std::dec << +picParams->PicFlags.fields.comp_prediction_mode << std::endl; |
| oss << "super_frame = " << std::dec << +picParams->PicFlags.fields.super_frame << std::endl; |
| oss << "seg_id_block_size = " << std::dec << +picParams->PicFlags.fields.seg_id_block_size << std::endl; |
| oss << "seg_update_data = " << std::dec << +picParams->PicFlags.fields.seg_update_data << std::endl; |
| oss << "LastRefIdx = " << std::dec << +picParams->RefFlags.fields.LastRefIdx << std::endl; |
| oss << "LastRefSignBias = " << std::dec << +picParams->RefFlags.fields.LastRefSignBias << std::endl; |
| oss << "GoldenRefIdx = " << std::dec << +picParams->RefFlags.fields.GoldenRefIdx << std::endl; |
| oss << "GoldenRefSignBias = " << std::dec << +picParams->RefFlags.fields.GoldenRefSignBias << std::endl; |
| oss << "AltRefIdx = " << std::dec << +picParams->RefFlags.fields.AltRefIdx << std::endl; |
| oss << "AltRefSignBias = " << std::dec << +picParams->RefFlags.fields.AltRefSignBias << std::endl; |
| oss << "ref_frame_ctrl_l0 = " << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l0 << std::endl; |
| oss << "ref_frame_ctrl_l1 = " << std::dec << +picParams->RefFlags.fields.ref_frame_ctrl_l1 << std::endl; |
| oss << "refresh_frame_flags = " << std::dec << +picParams->RefFlags.fields.refresh_frame_flags << std::endl; |
| oss << "LumaACQIndex = " << std::dec << +picParams->LumaACQIndex << std::endl; |
| oss << "LumaDCQIndexDelta = " << std::dec << +picParams->LumaDCQIndexDelta << std::endl; |
| oss << "ChromaACQIndexDelta = " << std::dec << +picParams->ChromaACQIndexDelta << std::endl; |
| oss << "ChromaDCQIndexDelta = " << std::dec << +picParams->ChromaDCQIndexDelta << std::endl; |
| oss << "filter_level = " << std::dec << +picParams->filter_level << std::endl; |
| oss << "sharpness_level = " << std::dec << +picParams->sharpness_level << std::endl; |
| |
| for (uint8_t i = 0; i < 4; ++i) |
| { |
| oss << "LFRefDelta[" << +i << "] = " << std::dec << +picParams->LFRefDelta[i] << std::endl; |
| } |
| |
| for (uint8_t i = 0; i < 2; ++i) |
| { |
| oss << "LFModeDelta[" << +i << "] = " << std::dec << +picParams->LFModeDelta[i] << std::endl; |
| } |
| |
| oss << "BitOffsetForLFRefDelta = " << std::dec << +picParams->BitOffsetForLFRefDelta << std::endl; |
| oss << "BitOffsetForLFModeDelta = " << std::dec << +picParams->BitOffsetForLFModeDelta << std::endl; |
| oss << "BitOffsetForLFLevel = " << std::dec << +picParams->BitOffsetForLFLevel << std::endl; |
| oss << "BitOffsetForQIndex = " << std::dec << +picParams->BitOffsetForQIndex << std::endl; |
| oss << "BitOffsetForFirstPartitionSize = " << std::dec << +picParams->BitOffsetForFirstPartitionSize << std::endl; |
| oss << "BitOffsetForSegmentation = " << std::dec << +picParams->BitOffsetForSegmentation << std::endl; |
| oss << "BitSizeForSegmentation = " << std::dec << +picParams->BitSizeForSegmentation << std::endl; |
| oss << "log2_tile_rows = " << std::dec << +picParams->log2_tile_rows << std::endl; |
| oss << "log2_tile_columns = " << std::dec << +picParams->log2_tile_columns << std::endl; |
| oss << "temporal_id = " << std::dec << +picParams->temporal_id << std::endl; |
| oss << "StatusReportFeedbackNumber = " << std::dec << +picParams->StatusReportFeedbackNumber << std::endl; |
| oss << "SkipFrameFlag = " << std::dec << +picParams->SkipFrameFlag << std::endl; |
| oss << "NumSkipFrames = " << std::dec << +picParams->NumSkipFrames << std::endl; |
| oss << "SizeSkipFrames = " << std::dec << +picParams->SizeSkipFrames << std::endl; |
| |
| const char *fileName = m_debugInterface->CreateFileName( |
| "_DDIEnc", |
| CodechalDbgBufferType::bufPicParams, |
| CodechalDbgExtType::txt); |
| |
| std::ofstream ofs(fileName, std::ios::out); |
| ofs << oss.str(); |
| ofs.close(); |
| |
| if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump)) |
| { |
| if (!m_debugInterface->m_ddiFileName.empty()) |
| { |
| std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app); |
| ofs << "PicNum" |
| << " = " << m_debugInterface->m_bufferDumpFrameNum << std::endl; |
| ofs << "PicParamFile" |
| << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl; |
| ofs.close(); |
| } |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS CodechalVdencVp9State::DumpSegmentParams( |
| PCODEC_VP9_ENCODE_SEGMENT_PARAMS segmentParams) |
| { |
| CODECHAL_DEBUG_FUNCTION_ENTER; |
| |
| if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSegmentParams)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| CODECHAL_DEBUG_CHK_NULL(segmentParams); |
| |
| std::ostringstream oss; |
| oss.setf(std::ios::showbase | std::ios::uppercase); |
| |
| for (uint8_t i = 0; i < 8; ++i) |
| { |
| oss << "Segment_id = " << std::dec << +i << std::endl; |
| oss << "SegmentReferenceEnabled = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled << std::endl; |
| oss << "SegmentReference = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentReference << std::endl; |
| oss << "SegmentSkipped = " << std::dec << +segmentParams->SegData[i].SegmentFlags.fields.SegmentSkipped << std::endl; |
| oss << "SegmentLFLevelDelta = " << std::dec << +segmentParams->SegData[i].SegmentLFLevelDelta << std::endl; |
| oss << "SegmentQIndexDelta = " << std::dec << +segmentParams->SegData[i].SegmentQIndexDelta << std::endl; |
| } |
| |
| if (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDriverUltDump)) |
| { |
| if (!m_debugInterface->m_ddiFileName.empty()) |
| { |
| std::ofstream ofs(m_debugInterface->m_ddiFileName, std::ios::app); |
| ofs << "SegmentParamFileParamFile" |
| << " = \"" << m_debugInterface->m_fileName << "\"" << std::endl; |
| ofs.close(); |
| } |
| } |
| |
| const char *fileName = m_debugInterface->CreateFileName( |
| "_DDIEnc", |
| CodechalDbgBufferType::bufSegmentParams, |
| CodechalDbgExtType::txt); |
| |
| std::ofstream ofs(fileName, std::ios::out); |
| ofs << oss.str(); |
| ofs.close(); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| #endif |