blob: 614dad87461c1bee890b3a45c6bdc9cbd13dfb92 [file] [log] [blame]
/*
* Copyright (c) 2011-2021, 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.
*/
//!
//! \file codechal_vdenc_avc.cpp
//! \brief This file implements the base C++ class/interface for AVC VDENC encoding
//! to be used across CODECHAL components.
//!
#include "codechal_vdenc_avc.h"
#include "hal_oca_interface.h"
#define CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE 128
#define CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE 52
#define CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE 10240 // 10K is just estimation
#define CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING 3
#define CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD 22
#define CODECHAL_ENCODE_AVC_HME_FIRST_STEP 0
#define CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP 1
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x 1
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x 2
#define CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x 2
#define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x 1
#define CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x 0
#define CODECHAL_ENCODE_VDENC_IMG_STATE_CMD_SIZE 140
#define CODECHAL_ENCODE_MI_BATCH_BUFFER_END_CMD_SIZE 4
typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME
{
CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE = 0,
CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE = 1,
CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE = 1,
CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE = 2,
CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION = 3,
CODECHAL_ENCODE_AVC_ME_RESERVED0 = 4,
CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF = 5,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0 = 6,
CODECHAL_ENCODE_AVC_ME_RESERVED1 = 7,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1 = 8,
CODECHAL_ENCODE_AVC_ME_RESERVED2 = 9,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2 = 10,
CODECHAL_ENCODE_AVC_ME_RESERVED3 = 11,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3 = 12,
CODECHAL_ENCODE_AVC_ME_RESERVED4 = 13,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4 = 14,
CODECHAL_ENCODE_AVC_ME_RESERVED5 = 15,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5 = 16,
CODECHAL_ENCODE_AVC_ME_RESERVED6 = 17,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6 = 18,
CODECHAL_ENCODE_AVC_ME_RESERVED7 = 19,
CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7 = 20,
CODECHAL_ENCODE_AVC_ME_RESERVED8 = 21,
CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF = 22,
CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0 = 23,
CODECHAL_ENCODE_AVC_ME_RESERVED9 = 24,
CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1 = 25,
CODECHAL_ENCODE_AVC_ME_VDENC_STREAMIN = 26,
CODECHAL_ENCODE_AVC_ME_NUM_SURFACES = 27
} CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_ME;
// binding table for State Content Detection
typedef enum _CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON
{
CODECHAL_ENCODE_AVC_SFD_VDENC_INPUT_IMAGE_STATE_COMMON = 0,
CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON = 1,
CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON = 2,
CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON = 3,
CODECHAL_ENCODE_AVC_SFD_VDENC_OUTPUT_IMAGE_STATE_COMMON = 4,
CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES = 5
} CODECHAL_ENCODE_AVC_BINDING_TABLE_OFFSET_SFD_COMMON;
const uint32_t CodechalVdencAvcState::AVC_Mode_Cost[2][12][CODEC_AVC_NUM_QP] =
{
//INTRASLICE
{
//LUTMODE_INTRA_NONPRED
{
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, //QP=[0 ~12]
16,
18,
22,
24,
13,
15,
16,
18,
13,
15,
15,
12,
14, //QP=[13~25]
12,
12,
10,
10,
11,
10,
10,
10,
9,
9,
8,
8,
8, //QP=[26~38]
8,
8,
8,
8,
8,
8,
8,
8,
7,
7,
7,
7,
7, //QP=[39~51]
},
//LUTMODE_INTRA_16x16, LUTMODE_INTRA
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[13~25]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[26~38]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[39~51]
},
//LUTMODE_INTRA_8x8
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
1,
1,
1, //QP=[13~25]
1,
1,
1,
1,
1,
4,
4,
4,
4,
6,
6,
6,
6, //QP=[26~38]
6,
6,
6,
6,
6,
6,
6,
6,
7,
7,
7,
7,
7, //QP=[39~51]
},
//LUTMODE_INTRA_4x4
{
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, //QP=[0 ~12]
64,
72,
80,
88,
48,
56,
64,
72,
53,
59,
64,
56,
64, //QP=[13~25]
57,
64,
58,
55,
64,
64,
64,
64,
59,
59,
60,
57,
50, //QP=[26~38]
46,
42,
38,
34,
31,
27,
23,
22,
19,
18,
16,
14,
13, //QP=[39~51]
},
//LUTMODE_INTER_16x8, LUTMODE_INTER_8x16
{
0,
},
//LUTMODE_INTER_8x8q
{
0,
},
//LUTMODE_INTER_8x4q, LUTMODE_INTER_4x8q, LUTMODE_INTER_16x8_FIELD
{
0,
},
//LUTMODE_INTER_4x4q, LUTMODE_INTER_8x8_FIELD
{
0,
},
//LUTMODE_INTER_16x16, LUTMODE_INTER
{
0,
},
//LUTMODE_INTER_BWD
{
0,
},
//LUTMODE_REF_ID
{
0,
},
//LUTMODE_INTRA_CHROMA
{
0,
},
},
//PREDSLICE
{
//LUTMODE_INTRA_NONPRED
{
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, //QP=[0 ~12]
7,
8,
9,
10,
5,
6,
7,
8,
6,
7,
7,
7,
7, //QP=[13~25]
6,
7,
7,
6,
7,
7,
7,
7,
7,
7,
7,
7,
7, //QP=[26~38]
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7, //QP=[39~51]
},
{
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, //QP=[0 ~12]
24,
28,
31,
35,
19,
21,
24,
28,
20,
24,
25,
21,
24, //QP=[13~25]
24,
24,
24,
21,
24,
24,
26,
24,
24,
24,
24,
24,
24, //QP=[26~38]
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24, //QP=[39~51]
},
//LUTMODE_INTRA_8x8
{
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, //QP=[0 ~12]
28,
32,
36,
40,
22,
26,
28,
32,
24,
26,
30,
26,
28, //QP=[13~25]
26,
28,
26,
26,
30,
28,
28,
28,
26,
28,
28,
26,
28, //QP=[26~38]
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28, //QP=[39~51]
},
//LUTMODE_INTRA_4x4
{
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, //QP=[0 ~12]
72,
80,
88,
104,
56,
64,
72,
80,
58,
68,
76,
64,
68, //QP=[13~25]
64,
68,
68,
64,
70,
70,
70,
70,
68,
68,
68,
68,
68, //QP=[26~38]
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68, //QP=[39~51]
},
//LUTMODE_INTER_16x8, LUTMODE_INTER_8x16
{
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, //QP=[0 ~12]
8,
9,
11,
12,
6,
7,
9,
10,
7,
8,
9,
8,
9, //QP=[13~25]
8,
9,
8,
8,
9,
9,
9,
9,
8,
8,
8,
8,
8, //QP=[26~38]
8,
8,
8,
9,
9,
9,
9,
9,
9,
9,
9,
9,
9, //QP=[39~51]
},
//LUTMODE_INTER_8x8q
{
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, //QP=[0 ~12]
2,
3,
3,
3,
2,
2,
2,
3,
2,
2,
2,
2,
3, //QP=[13~25]
2,
2,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3, //QP=[26~38]
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3, //QP=[39~51]
},
//LUTMODE_INTER_8x4q, LUTMODE_INTER_4x8q, LUTMODE_INTER_16x8_FIELD
{
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[0 ~12]
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5, //QP=[13~25]
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5, //QP=[26~38]
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5,
5, //QP=[39~51]
},
//LUTMODE_INTER_4x4q, LUTMODE_INTER_8x8_FIELD
{
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, //QP=[0 ~12]
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7, //QP=[13~25]
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7, //QP=[26~38]
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7, //QP=[39~51]
},
//LUTMODE_INTER_16x16, LUTMODE_INTER
{
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //QP=[0 ~12]
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6, //QP=[13~25]
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6, //QP=[26~38]
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6,
6, //QP=[39~51]
},
//LUTMODE_INTER_BWD
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[13~25]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[26~38]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[39~51]
},
//LUTMODE_REF_ID
{
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, //QP=[0 ~12]
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4, //QP=[13~25]
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4, //QP=[26~38]
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4, //QP=[39~51]
},
//LUTMODE_INTRA_CHROMA
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //QP=[0 ~12]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[13~25]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[26~38]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[39~51]
},
},
};
const int8_t CodechalVdencAvcState::BRC_UPD_GlobalRateQPAdjTabI_U8[64] =
{
48,
40,
32,
24,
16,
8,
0,
-8,
40,
32,
24,
16,
8,
0,
-8,
-16,
32,
24,
16,
8,
0,
-8,
-16,
-24,
24,
16,
8,
0,
-8,
-16,
-24,
-32,
16,
8,
0,
-8,
-16,
-24,
-32,
-40,
8,
0,
-8,
-16,
-24,
-32,
-40,
-48,
0,
-8,
-16,
-24,
-32,
-40,
-48,
-56,
48,
40,
32,
24,
16,
8,
0,
-8,
};
const int8_t CodechalVdencAvcState::BRC_UPD_GlobalRateQPAdjTabP_U8[64] =
{
48, 40, 32, 24, 16, 8, 0, -8, 40, 32, 24, 16, 8, 0, -8, -16, 16, 8, 8, 4, -8, -16, -16, -24, 8, 0, 0, -8, -16, -16, -16, -24, 8, 0, 0, -24, -32, -32, -32, -48, 0, -16, -16, -24, -32, -48, -56, -64, -8, -16, -32, -32, -48, -48, -56, -64, -16, -32, -48, -48, -48, -56, -64, -80};
// P picture global rate QP Adjustment table for sliding window BRC
const int8_t CodechalVdencAvcState::BRC_UPD_SlWinGlobalRateQPAdjTabP_U8[64] =
{
48,
40,
32,
24,
16,
8,
0,
-8,
40,
32,
24,
16,
8,
0,
-8,
-16,
16,
8,
8,
4,
-8,
-16,
-16,
-24,
8,
0,
0,
-8,
-16,
-16,
-16,
-24,
8,
0,
0,
-24,
-32,
-32,
-32,
-48,
0,
-16,
-24,
-32,
-40,
-56,
-64,
-72,
-8,
-16,
-32,
-40,
-48,
-56,
-64,
-64,
-16,
-32,
-48,
-48,
-48,
-56,
-64,
-80,
};
const int8_t CodechalVdencAvcState::BRC_UPD_GlobalRateQPAdjTabB_U8[64] =
{
48, 40, 32, 24, 16, 8, 0, -8, 40, 32, 24, 16, 8, 0, -8, -16, 32, 24, 16, 8, 0, -8, -16, -24, 24, 16, 8, 0, -8, -8, -16, -24, 16, 8, 0, 0, -8, -16, -24, -32, 16, 8, 0, 0, -8, -16, -24, -32, 0, -8, -8, -16, -32, -48, -56, -64, 0, -8, -8, -16, -32, -48, -56, -64};
const uint8_t CodechalVdencAvcState::BRC_UPD_DistThreshldI_U8[10] =
{
2, 4, 8, 12, 19, 32, 64, 128, 0, 0};
const uint8_t CodechalVdencAvcState::BRC_UPD_DistThreshldP_U8[10] =
{
2, 4, 8, 12, 19, 32, 64, 128, 0, 0};
const int8_t CodechalVdencAvcState::CBR_UPD_DistQPAdjTabI_U8[81] =
{
0,
0,
0,
0,
0,
3,
4,
6,
8,
0,
0,
0,
0,
0,
2,
3,
5,
7,
-1,
0,
0,
0,
0,
2,
2,
4,
5,
-1,
-1,
0,
0,
0,
1,
2,
2,
4,
-2,
-2,
-1,
0,
0,
0,
1,
2,
4,
-2,
-2,
-1,
0,
0,
0,
1,
2,
4,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
5,
-3,
-2,
-1,
-1,
0,
0,
2,
4,
7,
-4,
-3,
-2,
-1,
0,
1,
3,
5,
8,
};
const int8_t CodechalVdencAvcState::CBR_UPD_DistQPAdjTabP_U8[81] =
{
-1,
0,
0,
0,
0,
1,
1,
2,
3,
-1,
-1,
0,
0,
0,
1,
1,
2,
3,
-2,
-1,
-1,
0,
0,
1,
1,
2,
3,
-3,
-2,
-2,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
};
const int8_t CodechalVdencAvcState::CBR_UPD_DistQPAdjTabB_U8[81] =
{
0,
0,
0,
0,
0,
2,
3,
3,
4,
0,
0,
0,
0,
0,
2,
3,
3,
4,
-1,
0,
0,
0,
0,
2,
2,
3,
3,
-1,
-1,
0,
0,
0,
1,
2,
2,
2,
-1,
-1,
-1,
0,
0,
0,
1,
2,
2,
-2,
-1,
-1,
0,
0,
0,
0,
1,
2,
-2,
-1,
-1,
-1,
0,
0,
0,
1,
3,
-2,
-2,
-1,
-1,
0,
0,
1,
1,
3,
-2,
-2,
-1,
-1,
0,
1,
1,
2,
4,
};
const int8_t CodechalVdencAvcState::VBR_UPD_DistQPAdjTabI_U8[81] =
{
0,
0,
0,
0,
0,
3,
4,
6,
8,
0,
0,
0,
0,
0,
2,
3,
5,
7,
-1,
0,
0,
0,
0,
2,
2,
4,
5,
-1,
-1,
0,
0,
0,
1,
2,
2,
4,
-2,
-2,
-1,
0,
0,
0,
1,
2,
4,
-2,
-2,
-1,
0,
0,
0,
1,
2,
4,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
5,
-3,
-2,
-1,
-1,
0,
0,
2,
4,
7,
-4,
-3,
-2,
-1,
0,
1,
3,
5,
8,
};
const int8_t CodechalVdencAvcState::VBR_UPD_DistQPAdjTabP_U8[81] =
{
-1,
0,
0,
0,
0,
1,
1,
2,
3,
-1,
-1,
0,
0,
0,
1,
1,
2,
3,
-2,
-1,
-1,
0,
0,
1,
1,
2,
3,
-3,
-2,
-2,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
-3,
-2,
-1,
-1,
0,
0,
1,
2,
3,
};
const int8_t CodechalVdencAvcState::VBR_UPD_DistQPAdjTabB_U8[81] =
{
0,
0,
0,
0,
0,
2,
3,
3,
4,
0,
0,
0,
0,
0,
2,
3,
3,
4,
-1,
0,
0,
0,
0,
2,
2,
3,
3,
-1,
-1,
0,
0,
0,
1,
2,
2,
2,
-1,
-1,
-1,
0,
0,
0,
1,
2,
2,
-2,
-1,
-1,
0,
0,
0,
0,
1,
2,
-2,
-1,
-1,
-1,
0,
0,
0,
1,
3,
-2,
-2,
-1,
-1,
0,
0,
1,
1,
3,
-2,
-2,
-1,
-1,
0,
1,
1,
2,
4,
};
const int8_t CodechalVdencAvcState::CBR_UPD_FrmSzAdjTabI_S8[72] =
{
-4,
-20,
-28,
-36,
-40,
-44,
-48,
-80,
0,
-8,
-12,
-20,
-24,
-28,
-32,
-36,
0,
0,
-8,
-16,
-20,
-24,
-28,
-32,
8,
4,
0,
0,
-8,
-16,
-24,
-28,
32,
24,
16,
2,
-4,
-8,
-16,
-20,
36,
32,
28,
16,
8,
0,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::CBR_UPD_FrmSzAdjTabP_S8[72] =
{
-8,
-24,
-32,
-44,
-48,
-56,
-64,
-80,
-8,
-16,
-32,
-40,
-44,
-52,
-56,
-64,
0,
0,
-16,
-28,
-36,
-40,
-44,
-48,
8,
4,
0,
0,
-8,
-16,
-24,
-36,
20,
12,
4,
0,
-8,
-8,
-8,
-16,
24,
16,
8,
8,
8,
0,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::CBR_UPD_FrmSzAdjTabB_S8[72] =
{
0,
-4,
-8,
-16,
-24,
-32,
-40,
-48,
1,
0,
-4,
-8,
-16,
-24,
-32,
-40,
4,
2,
0,
-1,
-3,
-8,
-16,
-24,
8,
4,
2,
0,
-1,
-4,
-8,
-16,
20,
16,
4,
0,
-1,
-4,
-8,
-16,
24,
20,
16,
8,
4,
0,
-4,
-8,
28,
24,
20,
16,
8,
4,
0,
-8,
32,
24,
20,
16,
8,
4,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::VBR_UPD_FrmSzAdjTabI_S8[72] =
{
-4,
-20,
-28,
-36,
-40,
-44,
-48,
-80,
0,
-8,
-12,
-20,
-24,
-28,
-32,
-36,
0,
0,
-8,
-16,
-20,
-24,
-28,
-32,
8,
4,
0,
0,
-8,
-16,
-24,
-28,
32,
24,
16,
2,
-4,
-8,
-16,
-20,
36,
32,
28,
16,
8,
0,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::VBR_UPD_FrmSzAdjTabP_S8[72] =
{
-8,
-24,
-32,
-44,
-48,
-56,
-64,
-80,
-8,
-16,
-32,
-40,
-44,
-52,
-56,
-64,
0,
0,
-16,
-28,
-36,
-40,
-44,
-48,
8,
4,
0,
0,
-8,
-16,
-24,
-36,
20,
12,
4,
0,
-8,
-8,
-8,
-16,
24,
16,
8,
8,
8,
0,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::VBR_UPD_FrmSzAdjTabB_S8[72] =
{
0,
-4,
-8,
-16,
-24,
-32,
-40,
-48,
1,
0,
-4,
-8,
-16,
-24,
-32,
-40,
4,
2,
0,
-1,
-3,
-8,
-16,
-24,
8,
4,
2,
0,
-1,
-4,
-8,
-16,
20,
16,
4,
0,
-1,
-4,
-8,
-16,
24,
20,
16,
8,
4,
0,
-4,
-8,
28,
24,
20,
16,
8,
4,
0,
-8,
32,
24,
20,
16,
8,
4,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::QVBR_UPD_FrmSzAdjTabP_S8[72] =
{
-8,
-24,
-32,
-44,
-48,
-56,
-64,
-80,
-8,
-16,
-32,
-40,
-44,
-52,
-56,
-64,
0,
0,
-16,
-28,
-36,
-40,
-44,
-48,
16,
16,
8,
0,
-8,
-16,
-24,
-36,
20,
16,
8,
0,
-8,
-8,
-8,
-16,
24,
16,
8,
8,
8,
0,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::LOW_DELAY_UPD_FrmSzAdjTabI_S8[72] =
{
0,
0,
-8,
-12,
-16,
-20,
-28,
-36,
0,
0,
-4,
-8,
-12,
-16,
-24,
-32,
4,
2,
0,
-1,
-3,
-8,
-16,
-24,
8,
4,
2,
0,
-1,
-4,
-8,
-16,
20,
16,
4,
0,
-1,
-4,
-8,
-16,
24,
20,
16,
8,
4,
0,
-4,
-8,
28,
24,
20,
16,
8,
4,
0,
-8,
32,
24,
20,
16,
8,
4,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::LOW_DELAY_UPD_FrmSzAdjTabP_S8[72] =
{
-8,
-24,
-32,
-40,
-44,
-48,
-52,
-80,
-8,
-16,
-32,
-40,
-40,
-44,
-44,
-56,
0,
0,
-12,
-20,
-24,
-28,
-32,
-36,
8,
4,
0,
0,
-8,
-16,
-24,
-32,
32,
16,
8,
4,
-4,
-8,
-16,
-20,
36,
24,
16,
8,
4,
-2,
-4,
-8,
40,
36,
24,
20,
16,
8,
0,
-8,
48,
40,
28,
24,
20,
12,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const int8_t CodechalVdencAvcState::LOW_DELAY_UPD_FrmSzAdjTabB_S8[72] =
{
0,
-4,
-8,
-16,
-24,
-32,
-40,
-48,
1,
0,
-4,
-8,
-16,
-24,
-32,
-40,
4,
2,
0,
-1,
-3,
-8,
-16,
-24,
8,
4,
2,
0,
-1,
-4,
-8,
-16,
20,
16,
4,
0,
-1,
-4,
-8,
-16,
24,
20,
16,
8,
4,
0,
-4,
-8,
28,
24,
20,
16,
8,
4,
0,
-8,
32,
24,
20,
16,
8,
4,
0,
-4,
64,
48,
28,
20,
16,
12,
8,
4,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzMinTabP_U8[9] =
{
1, 2, 4, 6, 8, 10, 16, 16, 16};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzMinTabI_U8[9] =
{
1, 2, 4, 8, 16, 20, 24, 32, 36};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzMaxTabP_U8[9] =
{
48, 64, 80, 96, 112, 128, 144, 160, 160};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzMaxTabI_U8[9] =
{
48, 64, 80, 96, 112, 128, 144, 160, 160};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzSCGTabP_U8[9] =
{
4, 8, 12, 16, 20, 24, 24, 0, 0};
const uint8_t CodechalVdencAvcState::BRC_UPD_FrmSzSCGTabI_U8[9] =
{
4, 8, 12, 16, 20, 24, 24, 0, 0};
// Cost Table 14*42 = 588 bytes
const uint8_t CodechalVdencAvcState::BRC_UPD_I_IntraNonPred[42] =
{
0x0e, 0x0e, 0x0e, 0x18, 0x19, 0x1b, 0x1c, 0x0d, 0x0f, 0x18, 0x19, 0x0d, 0x0f, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07};
const uint8_t CodechalVdencAvcState::BRC_UPD_I_Intra8x8[42] =
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x01,
0x04,
0x04,
0x04,
0x04,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x07,
0x07,
0x07,
0x07,
0x07,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_I_Intra4x4[42] =
{
0x2e, 0x2e, 0x2e, 0x38, 0x39, 0x3a, 0x3b, 0x2c, 0x2e, 0x38, 0x39, 0x2d, 0x2f, 0x38, 0x2e, 0x38, 0x2e, 0x38, 0x2f, 0x2e, 0x38, 0x38, 0x38, 0x38, 0x2f, 0x2f, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x1e, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x0e, 0x0d};
const uint8_t CodechalVdencAvcState::BRC_UPD_I_IntraChroma[42] =
{
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};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_IntraNonPred[42] =
{
0x06, 0x06, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x05, 0x06, 0x07, 0x08, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Intra16x16[42] =
{
0x1b, 0x1b, 0x1b, 0x1c, 0x1e, 0x28, 0x29, 0x1a, 0x1b, 0x1c, 0x1e, 0x1a, 0x1c, 0x1d, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1c, 0x1c, 0x1d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Intra8x8[42] =
{
0x1d,
0x1d,
0x1d,
0x1e,
0x28,
0x29,
0x2a,
0x1b,
0x1d,
0x1e,
0x28,
0x1c,
0x1d,
0x1f,
0x1d,
0x1e,
0x1d,
0x1e,
0x1d,
0x1d,
0x1f,
0x1e,
0x1e,
0x1e,
0x1d,
0x1e,
0x1e,
0x1d,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
0x1e,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Intra4x4[42] =
{
0x38,
0x38,
0x38,
0x39,
0x3a,
0x3b,
0x3d,
0x2e,
0x38,
0x39,
0x3a,
0x2f,
0x39,
0x3a,
0x38,
0x39,
0x38,
0x39,
0x39,
0x38,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
0x39,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Inter16x8[42] =
{
0x07,
0x07,
0x07,
0x08,
0x09,
0x0b,
0x0c,
0x06,
0x07,
0x09,
0x0a,
0x07,
0x08,
0x09,
0x08,
0x09,
0x08,
0x09,
0x08,
0x08,
0x09,
0x09,
0x09,
0x09,
0x08,
0x08,
0x08,
0x08,
0x08,
0x08,
0x08,
0x08,
0x09,
0x09,
0x09,
0x09,
0x09,
0x09,
0x09,
0x09,
0x09,
0x09,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Inter8x8[42] =
{
0x02,
0x02,
0x02,
0x02,
0x03,
0x03,
0x03,
0x02,
0x02,
0x02,
0x03,
0x02,
0x02,
0x02,
0x02,
0x03,
0x02,
0x02,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
0x03,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_Inter16x16[42] =
{
0x05,
0x05,
0x05,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
0x06,
};
const uint8_t CodechalVdencAvcState::BRC_UPD_P_RefId[42] =
{
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04};
const bool CodechalVdencAvcState::SHMEEnabled[NUM_VDENC_TARGET_USAGE_MODES] =
{
0, 1, 1, 0, 0, 0, 0, 0};
const bool CodechalVdencAvcState::UHMEEnabled[NUM_VDENC_TARGET_USAGE_MODES] =
{
0, 1, 1, 0, 0, 0, 0, 0};
const uint8_t CodechalVdencAvcState::AdaptiveInterRoundingPWithoutB[CODEC_AVC_NUM_QP] =
{
//QP = 0 1 2 3 4 5 6 7 8 9 10 11 12
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3, //QP=[0~12]
3,
3,
3,
3,
3,
3,
3,
3,
1,
0,
0,
0,
0, //QP=[13~25]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[26~38]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0 //QP=[39~51]
};
const uint8_t CodechalVdencAvcState::AdaptiveInterRoundingP[CODEC_AVC_NUM_QP] =
{
//QP = 0 1 2 3 4 5 6 7 8 9 10 11 12
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4, //QP=[0~12]
4,
4,
4,
4,
4,
3,
3,
3,
3,
3,
3,
3,
3, //QP=[13~25]
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3, //QP=[26~38]
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3,
3 //QP=[39~51]
};
const uint32_t CodechalVdencAvcState::InterRoundingP[NUM_TARGET_USAGE_MODES] =
{
0, 3, 3, 3, 3, 3, 3, 3};
const uint32_t CodechalVdencAvcState::InterRoundingB[NUM_TARGET_USAGE_MODES] =
{
0, 0, 0, 0, 0, 0, 0, 0};
const uint32_t CodechalVdencAvcState::InterRoundingBRef[NUM_TARGET_USAGE_MODES] =
{
0, 2, 2, 2, 2, 2, 2, 2};
const uint8_t CodechalVdencAvcState::AdaptiveInterRoundingB[CODEC_AVC_NUM_QP] =
{
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, //QP=[0~12]
4,
3,
3,
3,
3,
3,
3,
0,
0,
0,
0,
0,
0, //QP=[13~25]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, //QP=[26~38]
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0 //QP=[39~51]
};
/* real thresholds are computed as multiplication on -50 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshI0_FP_NEG[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.80, 0.60, 0.34, 0.2};
/* real thresholds are computed as multiplication on 50 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshI0_FP_POS[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.2, 0.4, 0.66, 0.9};
/* real thresholds are computed as multiplication on 50 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshPB0_FP_NEG[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.90, 0.66, 0.46, 0.3};
/* real thresholds are computed as multiplication on 50 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshPB0_FP_POS[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.3, 0.46, 0.70, 0.90};
/* real negative thresholds are computed as multiplication on -50 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshVBR0_NEG[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.90, 0.70, 0.50, 0.3};
/* positive thresholds are computed as multiplication on 100 and casting to int */
const double CodechalVdencAvcState::BRC_DevThreshVBR0_POS[CODECHAL_VDENC_AVC_N_DEV_THRESHLDS / 2] =
{
0.4, 0.5, 0.75, 0.90};
const int8_t CodechalVdencAvcState::BRC_LowDelay_DevThreshPB0_S8[8] =
{
-45, -33, -23, -15, -8, 0, 15, 25};
const int8_t CodechalVdencAvcState::BRC_LowDelay_DevThreshI0_S8[8] =
{
-40, -30, -17, -10, -5, 0, 10, 20};
const int8_t CodechalVdencAvcState::BRC_LowDelay_DevThreshVBR0_S8[8] =
{
-45, -35, -25, -15, -8, 0, 20, 40};
const int8_t CodechalVdencAvcState::BRC_INIT_DistQPDelta_I8[4] =
{
-5, -2, 2, 5};
const uint8_t CodechalVdencAvcState::BRC_EstRateThreshP0_U8[7] =
{
4, 8, 12, 16, 20, 24, 28};
const uint8_t CodechalVdencAvcState::BRC_EstRateThreshI0_U8[7] =
{
4, 8, 12, 16, 20, 24, 28};
const uint16_t CodechalVdencAvcState::BRC_UPD_start_global_adjust_frame[4] =
{
10, 50, 100, 150};
const uint8_t CodechalVdencAvcState::BRC_UPD_global_rate_ratio_threshold[7] =
{
80, 90, 95, 101, 105, 115, 130};
// global rate ratio threshold table for sliding window BRC
const uint8_t CodechalVdencAvcState::BRC_UPD_slwin_global_rate_ratio_threshold[7] =
{
80, 90, 95, 101, 105, 110, 120};
const uint8_t CodechalVdencAvcState::BRC_UPD_start_global_adjust_mult[5] =
{
1, 1, 3, 2, 1};
const uint8_t CodechalVdencAvcState::BRC_UPD_start_global_adjust_div[5] =
{
40, 5, 5, 3, 1};
const uint16_t CodechalVdencAvcState::SliceSizeThrsholdsP[52] = // slice size threshold delta for P frame targeted for 99% compliance
{
1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, //[ 0- 9]
1400, 1400, 1400, 1400, 1400, 1400, 1400, 1250, 1100, 950, //[10-19]
850, 750, 650, 600, 550, 525, 500, 450, 400, 390, //[20-29]
380, 300, 300, 300, 250, 200, 175, 150, 150, 150, //[30-39]
150, 100, 100, 100, 100, 100, 100, 100, 100, 100, //[40-49]
100, 100 //[50-51]
};
const uint16_t CodechalVdencAvcState::SliceSizeThrsholdsI[52] = // slice size threshold delta for I frame targeted for 99% compliance
{
1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, //[ 0- 9]
1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1400, 1350, //[10-19]
1300, 1300, 1200, 1155, 1120, 1075, 1000, 975, 950, 800, //[20-29]
750, 650, 600, 550, 500, 450, 400, 350, 300, 300, //[30-39]
300, 250, 200, 200, 200, 200, 200, 200, 200, 200, //[40-49]
200, 200 //[50-51]
};
const int8_t CodechalVdencAvcState::BRC_UPD_global_rate_ratio_threshold_qp[8] =
{
-3, -2, -1, 0, 1, 1, 2, 3};
const uint8_t CodechalVdencAvcState::MaxRefIdx0[NUM_VDENC_TARGET_USAGE_MODES] =
{
0, 2, 2, 1, 1, 1, 0, 0};
const uint32_t CodechalVdencAvcState::TrellisQuantizationRounding[NUM_VDENC_TARGET_USAGE_MODES] =
{
0, 7, 7, 7, 7, 7, 7, 0};
const bool CodechalVdencAvcState::TrellisQuantizationEnable[NUM_VDENC_TARGET_USAGE_MODES] =
{
0, 0, 0, 0, 0, 0, 0, 0};
MOS_STATUS CodechalVdencAvcState::ComputeBRCInitQP(
PCODEC_AVC_ENCODE_SEQUENCE_PARAMS seqParams,
int32_t * initQP)
{
const float x0 = 0, y0 = 1.19f, x1 = 1.75f, y1 = 1.75f;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint32_t frameSize;
int32_t QP, deltaQ;
CODECHAL_ENCODE_CHK_NULL_RETURN(seqParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(initQP);
// InitQPIP calculation
frameSize = ((m_frameWidth * m_frameHeight * 3) >> 1);
QP = (int32_t)(1. / 1.2 * pow(10.0, (log10(frameSize * 2. / 3. * ((float)seqParams->FramesPer100Sec) / ((float)(seqParams->TargetBitRate) * 100)) - x0) * (y1 - y0) / (x1 - x0) + y0) + 0.5);
QP += 2;
//add additional change based on buffer size. It is especially useful for low delay
deltaQ = (int32_t)(9 - (seqParams->VBVBufferSizeInBit * ((float)seqParams->FramesPer100Sec) / ((float)(seqParams->TargetBitRate) * 100)));
QP += deltaQ < 0 ? 0 : deltaQ;
QP = CodecHal_Clip3(CODECHAL_ENCODE_AVC_BRC_MIN_QP, CODECHAL_ENCODE_AVC_MAX_SLICE_QP, QP);
QP--;
if (QP < 0)
QP = 1;
*initQP = QP;
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::AvcVdencStoreHuCStatus2Register(
CodechalHwInterface *hwInterface,
PMOS_COMMAND_BUFFER cmdBuffer)
{
MhwMiInterface * miInterface;
MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
MHW_MI_STORE_DATA_PARAMS storeDataParams;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface);
CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface->GetMiInterface());
miInterface = hwInterface->GetMiInterface();
// Write HUC_STATUS2 mask - bit 6 - valid IMEM loaded
MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
storeDataParams.pOsResource = &m_resHucStatus2Buffer;
storeDataParams.dwResourceOffset = 0;
storeDataParams.dwValue = hwInterface->GetHucInterface()->GetHucStatus2ImemLoadedMask();
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
// Store HUC_STATUS2 register
MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
storeRegParams.presStoreBuffer = &m_resHucStatus2Buffer;
storeRegParams.dwOffset = sizeof(uint32_t);
CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
storeRegParams.dwRegister = hwInterface->GetHucInterface()->GetMmioRegisters(m_vdboxIndex)->hucStatus2RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &storeRegParams));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetTLBAllocation(
PMOS_COMMAND_BUFFER cmdBuffer,
PTLBAllocationParams params)
{
MhwMiInterface * miInterface;
MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
MHW_MI_LOAD_REGISTER_IMM_PARAMS miLoadRegImmParams;
MmioRegistersMfx * mmioRegisters;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(params);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->presTlbMmioBuffer);
miInterface = m_hwInterface->GetMiInterface();
CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
mmioRegisters = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
// Save MFX_LRA_0/1/2 registers to a temp buffer so we can restore registers after frame encoding
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = params->presTlbMmioBuffer;
miStoreRegMemParams.dwOffset = 0;
miStoreRegMemParams.dwRegister = mmioRegisters->mfxLra0RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
miStoreRegMemParams.dwOffset = sizeof(uint32_t);
miStoreRegMemParams.dwRegister = mmioRegisters->mfxLra1RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
miStoreRegMemParams.dwOffset = 2 * sizeof(uint32_t);
miStoreRegMemParams.dwRegister = mmioRegisters->mfxLra2RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
// Update MFX_LRA_0/1/2 registers to set TBL for VMC=240
// =======================================================
// Clients LRA LRA range Min LRA range Max
// =======================================================
// VMXRA + VMC LRA0 0 239
// VMX LRA1 240 245
// BSP LRA2 246 250
// VCR + VCS LRA3 251 255
// =======================================================
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->mfxLra0RegOffset;
miLoadRegImmParams.dwData = (params->dwMmioMfxLra0Override > 0) ? params->dwMmioMfxLra0Override : CODECHAL_VDENC_AVC_MMIO_MFX_LRA_0_VMC240;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->mfxLra1RegOffset;
miLoadRegImmParams.dwData = (params->dwMmioMfxLra1Override > 0) ? params->dwMmioMfxLra1Override : CODECHAL_VDENC_AVC_MMIO_MFX_LRA_1_VMC240;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->mfxLra2RegOffset;
miLoadRegImmParams.dwData = (params->dwMmioMfxLra2Override > 0) ? params->dwMmioMfxLra2Override : CODECHAL_VDENC_AVC_MMIO_MFX_LRA_2_VMC240;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::RestoreTLBAllocation(
PMOS_COMMAND_BUFFER cmdBuffer,
PMOS_RESOURCE tlbMmioBuffer)
{
MhwMiInterface * miInterface;
MHW_MI_LOAD_REGISTER_MEM_PARAMS miLoadRegMemParams;
MmioRegistersMfx * mmioRegisters;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(tlbMmioBuffer);
miInterface = m_hwInterface->GetMiInterface();
CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
mmioRegisters = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
// Restore MFX_LRA_0/1/2 registers
miLoadRegMemParams.presStoreBuffer = tlbMmioBuffer;
miLoadRegMemParams.dwOffset = 0;
miLoadRegMemParams.dwRegister = mmioRegisters->mfxLra0RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegMemParams.dwOffset = sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->mfxLra1RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegMemParams.dwOffset = 2 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->mfxLra2RegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
return eStatus;
}
CodechalVdencAvcState::CodechalVdencAvcState(
CodechalHwInterface * hwInterface,
CodechalDebugInterface *debugInterface,
PCODECHAL_STANDARD_INFO standardInfo) : CodechalEncodeAvcBase(hwInterface, debugInterface, standardInfo)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
InitializeDataMember();
// Setup initial data
m_brcInit = true;
// enable codec specific user feature key reporting for AVC
m_userFeatureKeyReport = true;
m_swBrcMode = nullptr;
m_cmKernelEnable = true;
m_brcRoiSupported = true;
m_nonNativeBrcRoiSupported = false;
if (m_cmKernelEnable)
{
m_useCmScalingKernel = 1;
}
MOS_ZeroMemory(&m_vdencIntraRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_pakStatsBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_vdencStatsBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_pakStatsBufferFull, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_vdencTlbMmioBuffer, sizeof(MOS_RESOURCE));
}
CodechalVdencAvcState::~CodechalVdencAvcState()
{
CODECHAL_ENCODE_FUNCTION_ENTER;
m_osInterface->pfnFreeResource(m_osInterface, &m_vdencIntraRowStoreScratchBuffer);
m_osInterface->pfnFreeResource(m_osInterface, &m_vdencStatsBuffer);
m_osInterface->pfnFreeResource(m_osInterface, &m_pakStatsBuffer);
m_osInterface->pfnFreeResource(m_osInterface, &m_pakStatsBufferFull);
m_osInterface->pfnFreeResource(m_osInterface, &m_vdencTlbMmioBuffer);
if (m_vdencBrcImgStatAllocated)
{
for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
Mhw_FreeBb(m_osInterface, &m_batchBufferForVdencImgStat[i], nullptr);
}
}
else
{
Mhw_FreeBb(m_osInterface, &m_batchBufferForVdencImgStat[0], nullptr);
}
if (m_seiData.pSEIBuffer)
{
MOS_FreeMemory(m_seiData.pSEIBuffer);
m_seiData.pSEIBuffer = nullptr;
}
MOS_Delete(m_sfdKernelState);
m_sfdKernelState = nullptr;
if (m_pakEnabled)
{
// release skip frame copy buffer
m_osInterface->pfnFreeResource(m_osInterface, &m_resSkipFrameBuffer);
}
// SFD surfaces
{
// SFD output buffer
for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
m_osInterface->pfnFreeResource(
m_osInterface,
&m_resSfdOutputBuffer[i]);
}
m_osInterface->pfnFreeResource(
m_osInterface,
&m_resSfdCostTablePFrameBuffer);
m_osInterface->pfnFreeResource(
m_osInterface,
&m_resSfdCostTableBFrameBuffer);
}
if (m_swBrcMode != nullptr)
{
m_osInterface->pfnFreeLibrary(m_swBrcMode);
m_swBrcMode = nullptr;
}
for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
for (uint32_t j = 0; j < CODECHAL_VDENC_BRC_NUM_OF_PASSES; j++)
{
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[i][j]);
}
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcInitDmemBuffer[i]);
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcImageStatesReadBuffer[i]);
if (m_nonNativeBrcRoiSupported)
{
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcRoiBuffer[i]);
}
}
for (uint32_t i = 0; i < CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM; i++)
{
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcConstDataBuffer[i]);
}
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcHistoryBuffer);
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencSfdImageStateReadBuffer);
m_osInterface->pfnFreeResource(m_osInterface, &m_resVdencBrcDbgBuffer);
}
MOS_STATUS CodechalVdencAvcState::Initialize(CodechalSetting *settings)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_STATUS statusKey = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(settings);
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize(settings));
if (m_cscDsState)
{
// for AVC: the Ds+Copy kernel is by default used to do CSC and copy
// non-aligned surface
m_cscDsState->EnableCopy();
m_cscDsState->EnableColor();
m_cscDsState->EnableSfc();
}
MOS_USER_FEATURE_VALUE_DATA userFeatureData;
#if (_DEBUG || _RELEASE_INTERNAL)
/*MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (userFeatureData.i32Data)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnLoadLibrary(m_osInterface, CODECHAL_DBG_STRING_SWAVCBRCLIBRARY, &m_swBrcMode));
}*/
// SW BRC DLL Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_BRC_SOFTWARE_IN_USE_ID, (m_swBrcMode == nullptr) ? false : true, m_osInterface->pOsContext);
#endif // (_DEBUG || _RELEASE_INTERNAL)
if (m_codecFunction != CODECHAL_FUNCTION_PAK)
{
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
statusKey = MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_ME_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (statusKey == MOS_STATUS_SUCCESS)
{
m_hmeSupported = (userFeatureData.u32Data) ? true : false;
}
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
statusKey = MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_16xME_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (statusKey == MOS_STATUS_SUCCESS)
{
m_16xMeSupported = (userFeatureData.i32Data) ? true : false;
}
#ifndef _FULL_OPEN_SOURCE
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_staticFrameDetectionEnable = (userFeatureData.i32Data) ? true : false;
#endif
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_FORCE_TO_SKIP_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_forceToSkipEnable = (userFeatureData.u32Data) ? true : false;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_SLIDING_WINDOW_SIZE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_slidingWindowSize = userFeatureData.u32Data;
m_groupIdSelectSupported = 0; // Disabled by default for AVC for now
#if (_DEBUG || _RELEASE_INTERNAL)
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_GROUP_ID_SELECT_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_groupIdSelectSupported = (userFeatureData.i32Data) ? true : false;
#endif
m_groupId = 0; // default value for group ID = 0
#if (_DEBUG || _RELEASE_INTERNAL)
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_GROUP_ID_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_groupId = (uint8_t)userFeatureData.i32Data;
#endif
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_CRE_PREFETCH_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_crePrefetchEnable = userFeatureData.bData == 1;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_SINGLE_PASS_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_vdencSinglePassEnable = userFeatureData.bData == 1;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_TLB_PREFETCH_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_tlbPrefetchEnable = userFeatureData.bData == 1;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_TLB_ALLOCATION_WA_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (userFeatureData.u32Data == 0) // MFX_LRA_0/1/2 offsets might not be available
{
MEDIA_WR_WA(m_waTable, WaTlbAllocationForAvcVdenc, false);
}
if (MEDIA_IS_WA(m_waTable, WaTlbAllocationForAvcVdenc))
{
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_MMIO_MFX_LRA_0_OVERRIDE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_mmioMfxLra0Override = userFeatureData.u32Data;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_MMIO_MFX_LRA_1_OVERRIDE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_mmioMfxLra1Override = userFeatureData.u32Data;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_MMIO_MFX_LRA_2_OVERRIDE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_mmioMfxLra2Override = userFeatureData.u32Data;
}
}
#if (_DEBUG || _RELEASE_INTERNAL)
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_PERMB_STREAMOUT_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_perMBStreamOutEnable = (userFeatureData.u32Data) ? true : false;
#endif
// Initialize hardware resources for the current Os/Platform
CODECHAL_ENCODE_CHK_STATUS_RETURN(InitializeState());
MotionEstimationDisableCheck();
CODECHAL_ENCODE_CHK_STATUS_RETURN(Initialize());
// common function for all codecs needed
if (m_cscDsState && m_hwInterface->UsesRenderEngine(m_codecFunction, m_standard))
{
if (m_hmeSupported)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateMe());
}
if (m_singleTaskPhaseSupported)
{
uint32_t i;
uint32_t scalingBtCount, meBtCount, mbEncBtCount, brcBtCount, encOneBtCount, encTwoBtCount;
scalingBtCount = MOS_ALIGN_CEIL(
m_scaling4xKernelStates[0].KernelParams.iBTCount,
m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
meBtCount = MOS_ALIGN_CEIL(
m_hmeKernel ? m_hmeKernel->GetBTCount() : m_meKernelStates[0].KernelParams.iBTCount,
m_stateHeapInterface->pStateHeapInterface->GetBtIdxAlignment());
mbEncBtCount = 0;
brcBtCount = 0;
encOneBtCount = scalingBtCount + meBtCount;
encOneBtCount += (m_16xMeSupported) ? encOneBtCount : 0;
encOneBtCount += (m_32xMeSupported) ? encOneBtCount : 0;
encTwoBtCount = mbEncBtCount + brcBtCount;
m_maxBtCount = MOS_MAX(encOneBtCount, encTwoBtCount);
}
}
// Picture Level Commands
m_hwInterface->GetMfxStateCommandsDataSize(
CODECHAL_ENCODE_MODE_AVC,
&m_pictureStatesSize,
&m_picturePatchListSize,
false);
// Slice Level Commands
m_hwInterface->GetMfxPrimitiveCommandsDataSize(
CODECHAL_ENCODE_MODE_AVC,
&m_sliceStatesSize,
&m_slicePatchListSize,
false);
CODECHAL_ENCODE_CHK_STATUS_RETURN(CalculateVdencCommandsSize());
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::CalculateVdencCommandsSize()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
PMHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams = CreateMhwVdboxStateCmdsizeParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(stateCmdSizeParams);
uint32_t vdencPictureStatesSize, vdencPicturePatchListSize;
uint32_t vdencSliceStatesSize, vdencSlicePatchListSize;
m_hwInterface->GetHxxStateCommandSize(
CODECHAL_ENCODE_MODE_AVC,
&vdencPictureStatesSize,
&vdencPicturePatchListSize,
stateCmdSizeParams);
MOS_Delete(stateCmdSizeParams);
m_pictureStatesSize += vdencPictureStatesSize;
m_picturePatchListSize += vdencPicturePatchListSize;
// Picture Level Commands
m_hwInterface->GetVdencStateCommandsDataSize(
CODECHAL_ENCODE_MODE_AVC,
&vdencPictureStatesSize,
&vdencPicturePatchListSize);
m_pictureStatesSize += vdencPictureStatesSize;
m_picturePatchListSize += vdencPicturePatchListSize;
// Slice Level Commands
m_hwInterface->GetVdencPrimitiveCommandsDataSize(
CODECHAL_ENCODE_MODE_AVC,
&vdencSliceStatesSize,
&vdencSlicePatchListSize
);
m_sliceStatesSize += vdencSliceStatesSize;
m_slicePatchListSize += vdencSlicePatchListSize;
return eStatus;
}
void CodechalVdencAvcState::InitializeDataMember()
{
CODECHAL_ENCODE_FUNCTION_ENTER;
// SEI
MOS_ZeroMemory(&m_seiData, sizeof(m_seiData));
m_seiDataOffset = false;
m_seiParamBuffer = nullptr;
m_brcInit = false;
m_brcReset = false;
m_mbBrcEnabled = false;
m_mbBrcUserFeatureKeyControl = false;
m_dBrcTargetSize = 0.0f;
m_trellis = false;
m_acceleratorHeaderPackingCaps = false; //flag set by driver from driver caps
m_dBrcInitCurrentTargetBufFullInBits = 0;
m_dBrcInitResetInputBitsPerFrame = 0;
m_brcInitResetBufSizeInBits = false;
m_brcInitPreviousTargetBufFullInBits = false;
// Below values will be set if qp control params are sent by app
m_minMaxQpControlEnabled = false; // Flag to indicate if min/max QP feature is enabled or not.
m_iMinQp = 0;
m_iMaxQp = 0;
m_pMinQp = 0;
m_pMaxQp = 0;
m_pFrameMinMaxQpControl = false; // Indicates min/max QP values for P-frames are set separately or not.
m_skipFrameBufferSize = false; // size of skip frame packed data
MOS_ZeroMemory(&m_resSkipFrameBuffer, sizeof(MOS_RESOURCE)); // copy skip frame packed data from DDI
// VDENC BRC Buffers
MOS_ZeroMemory(&m_resVdencBrcUpdateDmemBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM * CODECHAL_VDENC_BRC_NUM_OF_PASSES);
MOS_ZeroMemory(&m_resVdencBrcInitDmemBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);
MOS_ZeroMemory(&m_resVdencBrcImageStatesReadBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);
MOS_ZeroMemory(&m_resVdencBrcConstDataBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM);
MOS_ZeroMemory(&m_resVdencBrcHistoryBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_resVdencBrcRoiBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);
MOS_ZeroMemory(&m_resVdencBrcDbgBuffer, sizeof(MOS_RESOURCE));
// Static frame detection
m_staticFrameDetectionEnable = false; // Static frame detection enable
MOS_ZeroMemory(&m_resSfdOutputBuffer, sizeof(MOS_RESOURCE) * CODECHAL_ENCODE_RECYCLED_BUFFER_NUM);
MOS_ZeroMemory(&m_resSfdCostTablePFrameBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_resSfdCostTableBFrameBuffer, sizeof(MOS_RESOURCE));
MOS_ZeroMemory(&m_resVdencSfdImageStateReadBuffer, sizeof(MOS_RESOURCE));
m_sfdKernelState = nullptr;
// Generation Specific Support Flags & User Feature Key Reads
m_mbBrcSupportCaps = 0;
m_ftqEnable = false; // FTQEnable
m_skipBiasAdjustmentSupported = false; // SkipBiasAdjustment support for P frame
m_sliceLevelReportSupported = false; // Slice Level Report support
m_brcRoiSupported = false;
m_brcMotionAdaptiveEnable = false;
m_brcAdaptiveRegionBoostSupported = false;
m_brcAdaptiveRegionBoostEnable = false;
m_roundingInterEnable = false;
m_adaptiveRoundingInterEnable = false;
m_roundingInterP = false;
MOS_ZeroMemory(m_vdEncModeCost, 12 * sizeof(uint8_t));
MOS_ZeroMemory(m_vdEncMvCost, 8 * sizeof(uint8_t));
MOS_ZeroMemory(m_vdEncHmeMvCost, 8 * sizeof(uint8_t));
m_slidingWindowSize = false;
m_forceToSkipEnable = false;
m_vdencBrcInitDmemBufferSize = false;
m_vdencBrcUpdateDmemBufferSize = false;
m_vdencStaticFrame = false;
m_vdencStaticRegionPct = false;
m_perMBStreamOutEnable = false;
m_vdencSSCThrsTblI = SliceSizeThrsholdsI;
m_vdencSSCThrsTblP = SliceSizeThrsholdsP;
}
MOS_STATUS CodechalVdencAvcState::InitializeState()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_STATUS statusKey = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
MOS_USER_FEATURE_VALUE_DATA userFeatureData;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_SINGLE_TASK_PHASE_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_singleTaskPhaseSupported = (userFeatureData.i32Data) ? true : false;
// Set interleaved scaling output to support PAFF.
m_fieldScalingOutputInterleaved = true;
if (m_encEnabled)
{
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_FTQ_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_ftqEnable = (userFeatureData.i32Data) ? true : false;
m_mbBrcSupportCaps = 1;
if (m_mbBrcSupportCaps)
{
// If the MBBRC user feature key does not exist, MBBRC will be set in SPS parsing
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_MB_BRC_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (userFeatureData.i32Data == 0 || userFeatureData.i32Data == 1)
{
m_mbBrcUserFeatureKeyControl = true;
m_mbBrcEnabled = userFeatureData.i32Data ? true : false;
}
}
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
statusKey = MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ENCODE_32xME_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
if (statusKey == MOS_STATUS_SUCCESS)
{
m_32xMeSupported = (userFeatureData.i32Data) ? true : false;
}
}
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_roundingInterEnable = (userFeatureData.i32Data) ? true : false;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
userFeatureData.i32Data = CODECHAL_ENCODE_AVC_INVALID_ROUNDING;
userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ROUNDING_INTER_P_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_roundingInterP = userFeatureData.i32Data;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
userFeatureData.i32Data = 1;
userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_ADAPTIVE_ROUNDING_INTER_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_adaptiveRoundingInterEnable = (userFeatureData.i32Data) ? true : false;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_AVC_SKIP_BIAS_ADJUSTMENT_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_skipBiasAdjustmentSupported = (userFeatureData.i32Data) ? true : false;
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
userFeatureData.i32Data = MHW_VDBOX_VDENC_DYNAMIC_SLICE_WA_COUNT;
userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_TAIL_INSERTION_DELAY_COUNT_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_vdencFlushDelayCount = (userFeatureData.i32Data);
MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
MOS_UserFeature_ReadValue_ID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_VDENC_BRC_MOTION_ADAPTIVE_ENABLE_ID,
&userFeatureData,
m_osInterface->pOsContext);
m_brcMotionAdaptiveEnable = (userFeatureData.i32Data) ? true : false;
m_vdencBrcStatsBufferSize = AVC_BRC_STATS_BUF_SIZE;
m_vdencBrcPakStatsBufferSize = AVC_BRC_PAK_STATS_BUF_SIZE;
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::ValidateNumReferences(PCODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS params)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_NULL_RETURN(params);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->pSeqParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->pAvcSliceParams);
uint8_t numRefIdx0MinusOne = params->pAvcSliceParams->num_ref_idx_l0_active_minus1;
uint8_t numRefIdx1MinusOne = params->pAvcSliceParams->num_ref_idx_l1_active_minus1;
// Nothing to do here if numRefIdx = 0 and frame encoded
if (numRefIdx0MinusOne == 0 && !CodecHal_PictureIsField(params->pPicParams->CurrOriginalPic))
{
if (params->wPictureCodingType == P_TYPE ||
(params->wPictureCodingType == B_TYPE && numRefIdx1MinusOne == 0))
{
return eStatus;
}
}
if (params->wPictureCodingType == P_TYPE)
{
uint8_t maxPNumRefIdx0MinusOne = MaxRefIdx0[params->pSeqParams->TargetUsage];
if (numRefIdx0MinusOne > maxPNumRefIdx0MinusOne)
{
CODECHAL_ENCODE_NORMALMESSAGE("Invalid active reference list size.");
numRefIdx0MinusOne = maxPNumRefIdx0MinusOne;
}
numRefIdx1MinusOne = 0;
}
// Override number of references used by VME. PAK uses value from DDI (num_ref_idx_l*_active_minus1_from_DDI)
params->pAvcSliceParams->num_ref_idx_l0_active_minus1 = numRefIdx0MinusOne;
params->pAvcSliceParams->num_ref_idx_l1_active_minus1 = numRefIdx1MinusOne;
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetRounding(PCODECHAL_ENCODE_AVC_ROUNDING_PARAMS param, PMHW_VDBOX_AVC_SLICE_STATE sliceState)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
if (param != nullptr && param->bEnableCustomRoudingIntra)
{
sliceState->dwRoundingIntraValue = param->dwRoundingIntra;
}
else
{
sliceState->dwRoundingIntraValue = 5;
}
if (param != nullptr && param->bEnableCustomRoudingInter)
{
sliceState->bRoundingInterEnable = true;
sliceState->dwRoundingValue = param->dwRoundingInter;
}
else
{
sliceState->bRoundingInterEnable = m_roundingInterEnable;
CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState);
CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSeqParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcPicParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState->pEncodeAvcSliceParams);
auto avcSeqParams = sliceState->pEncodeAvcSeqParams;
auto avcPicParams = sliceState->pEncodeAvcPicParams;
auto avcSliceParams = sliceState->pEncodeAvcSliceParams;
uint8_t sliceQP = avcPicParams->pic_init_qp_minus26 + 26 + avcSliceParams->slice_qp_delta;
switch (Slice_Type[avcSliceParams->slice_type])
{
case SLICE_P:
if (m_roundingInterP == CODECHAL_ENCODE_AVC_INVALID_ROUNDING)
{
// Adaptive Rounding is only used in CQP case
if (m_adaptiveRoundingInterEnable && !m_vdencBrcEnabled)
{
// If IPPP scenario
if (avcSeqParams->GopRefDist == 1)
{
sliceState->dwRoundingValue = CodechalVdencAvcState::AdaptiveInterRoundingPWithoutB[sliceQP];
}
else
{
sliceState->dwRoundingValue = CodechalVdencAvcState::AdaptiveInterRoundingP[sliceQP];
}
}
else
{
sliceState->dwRoundingValue = CodechalVdencAvcState::InterRoundingP[avcSeqParams->TargetUsage];
}
}
else
{
sliceState->dwRoundingValue = m_roundingInterP;
}
break;
case SLICE_B:
if (m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef)
{
sliceState->dwRoundingValue = InterRoundingBRef[avcSeqParams->TargetUsage];
}
else
{
if (m_adaptiveRoundingInterEnable && !m_vdencBrcEnabled)
{
sliceState->dwRoundingValue = AdaptiveInterRoundingB[sliceQP];
}
else
{
sliceState->dwRoundingValue = InterRoundingB[avcSeqParams->TargetUsage];
}
}
break;
default:
// do nothing
break;
}
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::GetSkipBiasAdjustment(uint8_t sliceQP, uint16_t gopRefDist, bool *skipBiasAdjustmentEnable)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_NULL_RETURN(skipBiasAdjustmentEnable);
// Determine if SkipBiasAdjustment should be enabled for P picture
// 1. No B frame 2. Qp >= 22 3. CQP mode
*skipBiasAdjustmentEnable = m_skipBiasAdjustmentSupported && (m_pictureCodingType == P_TYPE) && (gopRefDist == 1) && (sliceQP >= CODECHAL_ENCODE_AVC_SKIP_BIAS_ADJUSTMENT_QP_THRESHOLD);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::GetHmeSupportedBasedOnTU(HmeLevel hmeLevel, bool *supported)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_NULL_RETURN(supported);
switch (hmeLevel)
{
case HME_LEVEL_4x:
//HME always supported
*supported = true;
break;
case HME_LEVEL_16x:
*supported = SHMEEnabled[m_targetUsage & 0x7] ? true : false;
break;
case HME_LEVEL_32x:
*supported = UHMEEnabled[m_targetUsage & 0x7] ? true : false;
break;
default:
CODECHAL_ENCODE_ASSERTMESSAGE("Invalid hme Level");
eStatus = MOS_STATUS_INVALID_PARAMETER;
break;
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::InitKernelStateSFD()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
uint8_t *kernelBinary;
uint32_t kernelSize;
uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid;
MOS_STATUS status = CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize);
CODECHAL_ENCODE_CHK_STATUS_RETURN(status);
CODECHAL_KERNEL_HEADER currKrnHeader;
CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize(
kernelBinary,
ENC_SFD,
0,
&currKrnHeader,
&kernelSize));
auto kernelStatePtr = m_sfdKernelState;
kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_SFD_NUM_SURFACES;
kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON);
kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
kernelStatePtr->KernelParams.iIdCount = 1;
kernelStatePtr->KernelParams.iInlineDataLength = 0;
kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
kernelStatePtr->KernelParams.pBinary =
kernelBinary +
(currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
kernelStatePtr->KernelParams.iSize = kernelSize;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
m_stateHeapInterface,
kernelStatePtr->KernelParams.iBTCount,
&kernelStatePtr->dwSshSize,
&kernelStatePtr->dwBindingTableSize));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetCurbeSFD(PCODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS params)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_NULL_RETURN(params);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->pKernelState);
CODECHAL_ENCODE_AVC_SFD_CURBE_COMMON curbe;
MOS_ZeroMemory(&curbe, sizeof(curbe));
curbe.DW0.EnableIntraCostScalingForStaticFrame = 1;
curbe.DW0.EnableAdaptiveMvStreamIn = 0; // VDEnc
curbe.DW0.StreamInType = 7; // VDEnc
curbe.DW0.SliceType = (m_pictureCodingType + 1) % 3;
curbe.DW0.BRCModeEnable = (m_vdencBrcEnabled != 0);
curbe.DW0.VDEncModeDisable = false;
curbe.DW1.HMEStreamInRefCost = 5;
curbe.DW1.NumOfRefs = m_avcSliceParams->num_ref_idx_l0_active_minus1; // VDEnc
curbe.DW1.QPValue = m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta;
// SFD kernel requires to round-down to 4-MB aligned
curbe.DW2.FrameHeightInMBs = (m_oriFrameHeight / CODECHAL_MACROBLOCK_HEIGHT >> 2) << 2;
curbe.DW2.FrameWidthInMBs = (m_oriFrameWidth / CODECHAL_MACROBLOCK_WIDTH >> 2) << 2;
curbe.DW3.LargeMvThresh = 128;
uint32_t totalMb = curbe.DW2.FrameWidthInMBs * curbe.DW2.FrameHeightInMBs;
curbe.DW4.TotalLargeMvThreshold = totalMb / 100;
curbe.DW5.ZMVThreshold = 4;
curbe.DW6.TotalZMVThreshold = totalMb * m_avcPicParam->dwZMvThreshold / 100;
curbe.DW7.MinDistThreshold = 10;
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(curbe.CostTable, CODEC_AVC_NUM_QP * sizeof(uint8_t), m_codechalEncodeAvcSfdCostTableVdEnc, CODEC_AVC_NUM_QP * sizeof(uint8_t)),
"Failed to copy VDEnc SFD cost table");
curbe.DW21.ActualHeightInMB = curbe.DW2.FrameHeightInMBs;
curbe.DW21.ActualWidthInMB = curbe.DW2.FrameWidthInMBs;
curbe.DW24.VDEncInputImagStateIndex = CODECHAL_ENCODE_AVC_SFD_VDENC_INPUT_IMAGE_STATE_COMMON;
curbe.DW26.MVDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON;
curbe.DW27.InterDistortionSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON;
curbe.DW28.OutputDataSurfaceIndex = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON;
curbe.DW29.VDEncOutputImagStateIndex = CODECHAL_ENCODE_AVC_SFD_VDENC_OUTPUT_IMAGE_STATE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
&curbe,
params->pKernelState->dwCurbeOffset,
sizeof(curbe)));
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateSfdParam(
&curbe));)
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetSequenceStructs()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);
auto seqParams = m_avcSeqParam;
if (m_targetUsageOverride)
{
seqParams->TargetUsage = m_targetUsageOverride;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSequenceStructs());
// App does tail insertion in VDEnc dynamic slice non-CP case
m_vdencNoTailInsertion =
seqParams->EnableSliceLevelRateCtrl &&
(!m_osInterface->osCpInterface->IsCpEnabled());
// If 16xMe is supported then check if it is supported in the TU settings
if (m_16xMeSupported)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_16x, &m_16xMeSupported));
}
// If 32xMe is supported then check if it is supported in the TU settings
if (m_32xMeSupported)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(GetHmeSupportedBasedOnTU(HME_LEVEL_32x, &m_32xMeSupported));
}
if (m_firstFrame)
{
m_oriFrameHeight = seqParams->FrameHeight;
m_oriFrameWidth = seqParams->FrameWidth;
}
// check if there is a dynamic resolution change
if ((m_oriFrameHeight && (m_oriFrameHeight != seqParams->FrameHeight)) ||
(m_oriFrameWidth && (m_oriFrameWidth != seqParams->FrameWidth)))
{
m_resolutionChanged = true;
m_oriFrameHeight = seqParams->FrameHeight;
m_oriFrameWidth = seqParams->FrameWidth;
// Need to call BRCInit instead of BRCReset for dynamic resolution change
m_brcInit = true;
}
else
{
m_resolutionChanged = false;
}
// HuC based BRC should be used when 1) BRC is requested by App and 2) HuC FW is loaded and HuC is enabled for use.
if (CodecHalIsRateControlBrc(seqParams->RateControlMethod, CODECHAL_AVC))
{
if (!MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrEnableMediaKernels))
{
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_STATUS_UNKNOWN, "Failed to load HuC firmware!");
}
m_vdencBrcEnabled = MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrEnableMediaKernels);
}
if (m_mbBrcSupportCaps && (m_vdencBrcEnabled))
{
// control MBBRC if the user feature key does not exist
if (!m_mbBrcUserFeatureKeyControl)
{
if (seqParams->RateControlMethod == RATECONTROL_ICQ || seqParams->RateControlMethod == RATECONTROL_QVBR)
{
// If the rate control method is ICQ or QVBR then enable MBBRC by default for all TUs and ignore the app input
m_mbBrcEnabled = true;
CODECHAL_ENCODE_NORMALMESSAGE("MBBRC enabled with rate control = %d", seqParams->RateControlMethod);
}
else if (seqParams->RateControlMethod == RATECONTROL_VCM)
{
// If the rate control method is VCM then disable MBBRC by default for all TUs and ignore the app input
m_mbBrcEnabled = false;
}
else
{
switch (seqParams->MBBRC)
{
case mbBrcInternal:
m_mbBrcEnabled = true;
break;
case mbBrcDisabled:
m_mbBrcEnabled = false;
break;
case mbBrcEnabled:
m_mbBrcEnabled = true;
break;
}
}
}
}
m_trellis = seqParams->Trellis;
// Simple check for BRC parameters; if error, disable BRC and continue encoding
if ((m_vdencBrcEnabled) &&
((((!seqParams->InitVBVBufferFullnessInBit ||
!seqParams->VBVBufferSizeInBit ||
!seqParams->MaxBitRate) &&
(seqParams->RateControlMethod != RATECONTROL_AVBR)) ||
!seqParams->TargetBitRate ||
!seqParams->FramesPer100Sec) &&
seqParams->RateControlMethod != RATECONTROL_ICQ))
{
CODECHAL_ENCODE_ASSERTMESSAGE("Fatal error in AVC Encoding BRC parameters.");
CODECHAL_ENCODE_ASSERTMESSAGE("RateControlMethod = %d, InitVBVBufferFullnessInBit = %d, VBVBufferSizeInBit = %d, MaxBitRate = %d, TargetBitRate = %d, FramesPer100Sec = %d",
seqParams->RateControlMethod,
seqParams->InitVBVBufferFullnessInBit,
seqParams->VBVBufferSizeInBit,
seqParams->MaxBitRate,
seqParams->TargetBitRate,
seqParams->FramesPer100Sec);
m_vdencBrcEnabled = false;
}
// BRC Init or Reset
if (seqParams->bInitBRC)
{
m_brcInit = seqParams->bInitBRC;
}
else
{
m_brcReset = seqParams->bResetBRC;
}
if (seqParams->RateControlMethod == RATECONTROL_ICQ)
{
if (seqParams->ICQQualityFactor < CODECHAL_ENCODE_AVC_MIN_ICQ_QUALITYFACTOR ||
seqParams->ICQQualityFactor > CODECHAL_ENCODE_AVC_MAX_ICQ_QUALITYFACTOR)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Invalid ICQ Quality Factor input\n");
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
}
if (seqParams->EnableSliceLevelRateCtrl)
{
m_waReadVDEncOverflowStatus = MEDIA_IS_WA(m_hwInterface->GetWaTable(), WaReadVDEncOverflowStatus);
}
// if GOP structure is I-frame only, we use 3 non-ref slots for tracked buffer
m_gopIsIdrFrameOnly = (seqParams->GopPicSize == 1 && seqParams->GopRefDist == 0);
// Set sliding window size to one second by default, up to 60
if (m_slidingWindowSize == 0)
{
m_slidingWindowSize = MOS_MIN((uint32_t)(seqParams->FramesPer100Sec / 100), 60);
}
m_maxNumSlicesAllowed = CodecHalAvcEncode_GetMaxNumSlicesAllowed(
(CODEC_AVC_PROFILE_IDC)(seqParams->Profile),
(CODEC_AVC_LEVEL_IDC)(seqParams->Level),
seqParams->FramesPer100Sec);
m_lookaheadDepth = seqParams->LookaheadDepth;
if (m_lookaheadDepth > 0)
{
uint64_t targetBitRate = (uint64_t)seqParams->TargetBitRate;
if ((seqParams->FramesPer100Sec < 100) || ((targetBitRate * 100) < seqParams->FramesPer100Sec))
{
CODECHAL_ENCODE_ASSERTMESSAGE("Invalid FrameRate or TargetBitRate in lookahead pass!");
return MOS_STATUS_INVALID_PARAMETER;
}
m_averageFrameSize = (uint32_t)(targetBitRate * 100 / seqParams->FramesPer100Sec);
if (seqParams->VBVBufferSizeInBit < seqParams->InitVBVBufferFullnessInBit)
{
CODECHAL_ENCODE_ASSERTMESSAGE("VBVBufferSizeInBit is less than InitVBVBufferFullnessInBit\n");
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
if (m_targetBufferFulness == 0)
{
m_targetBufferFulness = seqParams->VBVBufferSizeInBit - seqParams->InitVBVBufferFullnessInBit;
}
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetPictureStructs()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
auto picParams = m_avcPicParam;
auto seqParams = m_avcSeqParam;
auto avcRefList = &m_refList[0];
auto avcPicIdx = &m_picIdx[0];
uint8_t prevRefIdx = m_currReconstructedPic.FrameIdx;
uint8_t currRefIdx = picParams->CurrReconstructedPic.FrameIdx;
int16_t prevFrameNum = m_frameNum;
int16_t currFrameNum = picParams->frame_num;
if (m_firstFrame)
{
m_oriFieldCodingFlag = picParams->FieldCodingFlag;
}
if (Mos_ResourceIsNull(&m_reconSurface.OsResource) &&
(!picParams->UserFlags.bUseRawPicForRef || m_codecFunction != CODECHAL_FUNCTION_ENC))
{
return MOS_STATUS_INVALID_PARAMETER;
}
// Sync initialize
if ((m_firstFrame) ||
(picParams->UserFlags.bUseRawPicForRef) || // No need to wait for previous PAK if reconstructed pic is not used as reference (but RAW pic is used for ref)
((picParams->CodingType == I_TYPE)) || // No need to wait for I-Frames
((currFrameNum == prevFrameNum) &&
CodecHal_PictureIsFrame(picParams->CurrOriginalPic)) || // No need to wait if current and previous pics have same frame numbers (Same reference list is used for two pictures with same frame numbers)
(!avcRefList[prevRefIdx]->bUsedAsRef &&
CodecHal_PictureIsField(picParams->CurrOriginalPic)))
{
m_waitForPak = false;
}
else
{
m_waitForPak = true;
}
m_signalEnc = false;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetPictureStructs());
m_hwInterface->GetMfxInterface()->SetBrcNumPakPasses(GetNumBrcPakPasses(picParams->BRCPrecision));
if (m_vdencBrcEnabled)
{
m_numPasses = CODECHAL_VDENC_BRC_NUM_OF_PASSES - 1; // 2-pass VDEnc BRC
if (picParams->BRCPrecision == 1)
{
m_vdencSinglePassEnable = true;
m_numPasses = 0;
}
}
else
{
// legacy AVC : 1 original plus extra to handle IPCM MBs
// VDENC : single PAK pass
m_numPasses = (CODECHAL_VDENC_AVC_CQP_NUM_OF_PASSES - 1);
}
if (seqParams->RateControlMethod == RATECONTROL_VCM && m_pictureCodingType == B_TYPE)
{
CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support B-frames\n");
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
if (seqParams->RateControlMethod == RATECONTROL_VCM && (picParams->FieldCodingFlag || picParams->FieldFrameCodingFlag))
{
CODECHAL_ENCODE_ASSERTMESSAGE("VCM BRC mode does not support interlaced\n");
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
if (picParams->FieldCodingFlag || picParams->FieldFrameCodingFlag)
{
CODECHAL_ENCODE_ASSERTMESSAGE("VDEnc does not support interlaced picture\n");
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
avcRefList[currRefIdx]->pRefPicSelectListEntry = nullptr;
if (m_brcAdaptiveRegionBoostSupported && m_avcPicParam->TargetFrameSize && !m_lookaheadDepth)
{ // Adaptive region boost is enabled for TCBRC only
m_brcAdaptiveRegionBoostEnable = true;
m_vdencStreamInEnabled = true;
} else
{
m_brcAdaptiveRegionBoostEnable = false;
}
if (!m_brcAdaptiveRegionBoostEnable && m_avcPicParam->NumDirtyROI) // ROI is not supported with ARB now
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupDirtyROI(
&(m_resVdencStreamInBuffer[m_currRecycledBufIdx])));
}
if (!m_brcAdaptiveRegionBoostEnable && m_avcPicParam->NumROI) // ROI is not supported with ARB now
{
m_avcPicParam->bNativeROI = ProcessRoiDeltaQp();
if (m_vdencBrcEnabled && !m_avcPicParam->bNativeROI)
{
if (!m_nonNativeBrcRoiSupported)
{
MOS_OS_ASSERTMESSAGE("Non native ROIs are not supported on this platform with BRC");
return MOS_STATUS_INVALID_PARAMETER;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupBrcROIBuffer(
m_avcPicParam,
&(m_resVdencBrcRoiBuffer[m_currRecycledBufIdx])));
}
else
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupROIStreamIn(
m_avcPicParam,
m_avcSliceParams,
&(m_resVdencStreamInBuffer[m_currRecycledBufIdx])));
}
}
if(m_avcPicParam->ForceSkip.Enable && (m_pictureCodingType != I_TYPE))
{
m_avcPicParam->ForceSkip.Enable = 1;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupForceSkipStreamIn(
m_avcPicParam,
&(m_resVdencStreamInBuffer[m_currRecycledBufIdx])));
}
else
m_avcPicParam->ForceSkip.Enable = 0;
if ((m_lookaheadDepth > 0) && (m_prevTargetFrameSize > 0))
{
int64_t targetBufferFulness = (int64_t)m_targetBufferFulness;
targetBufferFulness += (int64_t)(m_prevTargetFrameSize << 3) - (int64_t)m_averageFrameSize;
m_targetBufferFulness = targetBufferFulness < 0 ?
0 : (targetBufferFulness > 0xFFFFFFFF ? 0xFFFFFFFF : (uint32_t)targetBufferFulness);
}
m_prevTargetFrameSize = m_avcPicParam->TargetFrameSize;
if (m_brcAdaptiveRegionBoostEnable)
{
uint16_t rowOffset[8] = {0, 3, 5, 2, 7, 4, 1, 6};
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetupRegionBoosting(&(m_resVdencStreamInBuffer[m_currRecycledBufIdx]), rowOffset[(m_storeData - 1) & 7]));
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetSliceStructs()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
auto slcParams = m_avcSliceParams;
auto seqParams = m_avcSeqParam;
auto picParams = m_avcPicParam;
if (m_pictureCodingType != I_TYPE)
{
CODECHAL_ENCODE_AVC_VALIDATE_NUM_REFS_PARAMS validateNumRefsParams;
validateNumRefsParams.pSeqParams = seqParams;
validateNumRefsParams.pPicParams = picParams;
validateNumRefsParams.pAvcSliceParams = slcParams;
validateNumRefsParams.wPictureCodingType = m_pictureCodingType;
validateNumRefsParams.wPicHeightInMB = m_picHeightInMb;
validateNumRefsParams.wFrameFieldHeightInMB = m_frameFieldHeightInMb;
validateNumRefsParams.bFirstFieldIPic = m_firstFieldIdrPic;
validateNumRefsParams.bVDEncEnabled = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(ValidateNumReferences(&validateNumRefsParams));
}
else
{
slcParams->num_ref_idx_l0_active_minus1 = 0;
slcParams->num_ref_idx_l1_active_minus1 = 0;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::SetSliceStructs());
if (eStatus == MOS_STATUS_INVALID_PARAMETER)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Invalid slice parameters.");
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SendSFDSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, PCODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS params)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(params);
// VDEnc input/output image state (CQP mode)
CODECHAL_SURFACE_CODEC_PARAMS surfaceCodecParams;
auto kernelState = params->pKernelState;
if (params->bVdencActive && !params->bVdencBrcEnabled)
{
CODECHAL_ENCODE_CHK_NULL_RETURN(params->presVDEncImageStateInputBuffer);
MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
surfaceCodecParams.presBuffer = params->presVDEncImageStateInputBuffer;
surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(m_hwInterface->m_vdencBrcImgStateBufferSize);
surfaceCodecParams.dwOffset = 0;
surfaceCodecParams.bRenderTarget = false;
surfaceCodecParams.bIsWritable = false;
surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE].Value;
surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_VDENC_INPUT_IMAGE_STATE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceCodecParams,
kernelState));
CODECHAL_ENCODE_CHK_NULL_RETURN(params->presVDEncImageStateOutputBuffer);
surfaceCodecParams.presBuffer = params->presVDEncImageStateOutputBuffer;
surfaceCodecParams.bRenderTarget = true;
surfaceCodecParams.bIsWritable = true;
surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_VDENC_IMAGESTATE_ENCODE].Value;
surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_VDENC_OUTPUT_IMAGE_STATE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceCodecParams,
kernelState));
}
// HME MV Data surface
CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeMvDataSurface);
MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
surfaceCodecParams.bIs2DSurface = true;
surfaceCodecParams.bMediaBlockRW = true;
surfaceCodecParams.psSurface = params->psMeMvDataSurface;
surfaceCodecParams.dwOffset = params->dwMeMvBottomFieldOffset;
surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_MV_DATA_SURFACE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceCodecParams,
kernelState));
// HME distortion surface
CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionSurface);
MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
surfaceCodecParams.bIs2DSurface = true;
surfaceCodecParams.bMediaBlockRW = true;
surfaceCodecParams.psSurface = params->psMeDistortionSurface;
surfaceCodecParams.dwOffset = params->dwMeDistortionBottomFieldOffset;
surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_INTER_DISTORTION_SURFACE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceCodecParams,
kernelState));
// output buffer
CODECHAL_ENCODE_CHK_NULL_RETURN(params->presOutputBuffer);
MOS_ZeroMemory(&surfaceCodecParams, sizeof(CODECHAL_SURFACE_CODEC_PARAMS));
surfaceCodecParams.presBuffer = params->presOutputBuffer;
surfaceCodecParams.dwSize = MOS_BYTES_TO_DWORDS(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE);
surfaceCodecParams.dwOffset = 0;
surfaceCodecParams.bRenderTarget = true;
surfaceCodecParams.bIsWritable = true;
surfaceCodecParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
surfaceCodecParams.dwBindingTableOffset = CODECHAL_ENCODE_AVC_SFD_OUTPUT_DATA_SURFACE_COMMON;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceCodecParams,
kernelState));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SFDKernel()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
if (!m_sfdKernelState)
{
CODECHAL_ENCODE_CHK_NULL_RETURN(m_sfdKernelState = MOS_New(MHW_KERNEL_STATE));
CODECHAL_ENCODE_CHK_STATUS_RETURN(InitKernelStateSFD());
}
PerfTagSetting perfTag;
perfTag.Value = 0;
perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
perfTag.CallType = m_singleTaskPhaseSupported ? CODECHAL_ENCODE_PERFTAG_CALL_SCALING_KERNEL : CODECHAL_ENCODE_PERFTAG_CALL_SFD_KERNEL;
perfTag.PictureCodingType = m_pictureCodingType;
m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
// set function type and kernel state pointer
auto encFunctionType = CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION;
auto kernelState = m_sfdKernelState;
// If Single Task Phase is not enabled, use BT count for the kernel state.
if (m_firstTaskInPhase == true || !m_singleTaskPhaseSupported)
{
uint32_t dwMaxBtCount = m_singleTaskPhaseSupported ? m_maxBtCount : kernelState->KernelParams.iBTCount;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnRequestSshSpaceForCmdBuf(
m_stateHeapInterface,
dwMaxBtCount));
m_vmeStatesSize = m_hwInterface->GetKernelLoadCommandSize(dwMaxBtCount);
CODECHAL_ENCODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
}
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));
// set-up SFD Curbe
CODECHAL_ENCODE_AVC_SFD_CURBE_PARAMS sfdcurbeParams;
MOS_ZeroMemory(&sfdcurbeParams, sizeof(sfdcurbeParams));
sfdcurbeParams.pKernelState = kernelState;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCurbeSFD(&sfdcurbeParams));
// dump DSH/Curbe/ISH
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));
if (!m_vdencBrcEnabled)
{
//Set VDENC image state command in VDENC buffer for CQP mode
PMHW_VDBOX_AVC_IMG_PARAMS imageStateParams = CreateMhwVdboxAvcImgParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(imageStateParams);
imageStateParams->pEncodeAvcPicParams = m_avcPicParam;
imageStateParams->pEncodeAvcSeqParams = m_avcSeqParam;
imageStateParams->pEncodeAvcSliceParams = m_avcSliceParams;
imageStateParams->wPicWidthInMb = m_picWidthInMb;
imageStateParams->wPicHeightInMb = m_picHeightInMb;
imageStateParams->wSlcHeightInMb = m_sliceHeight;
imageStateParams->dwMaxVmvR = CodecHalAvcEncode_GetMaxVmvR(m_avcSeqParam->Level);
imageStateParams->bVdencBRCEnabled = m_vdencBrcEnabled;
imageStateParams->bVdencStreamInEnabled = m_vdencStreamInEnabled;
imageStateParams->bCrePrefetchEnable = m_crePrefetchEnable;
if (m_avcSeqParam->EnableSliceLevelRateCtrl)
{
uint8_t qpY = m_avcPicParam->QpY;
imageStateParams->dwMbSlcThresholdValue = CODECHAL_VDENC_AVC_MB_SLICE_TRHESHOLD;
imageStateParams->dwVdencSliceMinusBytes = (m_pictureCodingType == I_TYPE) ? m_vdencSSCThrsTblI[qpY] : m_vdencSSCThrsTblP[qpY];
}
imageStateParams->pVDEncModeCost = m_vdencModeCostTbl;
imageStateParams->pVDEncHmeMvCost = m_vdencHmeMvCostTbl;
imageStateParams->pVDEncMvCost = m_vdencMvCostTbl;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AddVdencSfdImgBuffer(
&m_resVdencSfdImageStateReadBuffer, imageStateParams));
MOS_Delete(imageStateParams);
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateEncParam(
0,
nullptr));)
}
// Add surface states
CODECHAL_ENCODE_AVC_SFD_SURFACE_PARAMS sfdsurfaceParams;
MOS_ZeroMemory(&sfdsurfaceParams, sizeof(sfdsurfaceParams));
sfdsurfaceParams.dwDownscaledWidthInMb4x = m_downscaledWidthInMb4x;
sfdsurfaceParams.dwDownscaledHeightInMb4x = m_downscaledFrameFieldHeightInMb4x;
sfdsurfaceParams.psMeMvDataSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
sfdsurfaceParams.dwMeMvBottomFieldOffset = m_hmeKernel ? m_hmeKernel->Get4xMeMvBottomFieldOffset() : (uint32_t)m_meMvBottomFieldOffset;
sfdsurfaceParams.psMeDistortionSurface = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer;
sfdsurfaceParams.dwMeDistortionBottomFieldOffset = m_hmeKernel ? m_hmeKernel->GetDistortionBottomFieldOffset() : (uint32_t)m_meDistortionBottomFieldOffset;
sfdsurfaceParams.bVdencActive = true;
sfdsurfaceParams.bVdencBrcEnabled = m_vdencBrcEnabled;
sfdsurfaceParams.presOutputBuffer = &m_resSfdOutputBuffer[m_currRecycledBufIdx];
sfdsurfaceParams.pKernelState = kernelState;
if (!m_vdencBrcEnabled)
{
sfdsurfaceParams.presVDEncImageStateInputBuffer = &m_resVdencSfdImageStateReadBuffer;
sfdsurfaceParams.presVDEncImageStateOutputBuffer = &m_batchBufferForVdencImgStat[m_currRecycledBufIdx].OsResource;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSFDSurfaces(
&cmdBuffer,
&sfdsurfaceParams));
// dump SSH
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpKernelRegion(
encFunctionType,
MHW_SSH_TYPE,
kernelState));)
HalOcaInterface::TraceMessage(cmdBuffer, *m_osInterface->pOsContext, __FUNCTION__, sizeof(__FUNCTION__));
HalOcaInterface::OnDispatch(cmdBuffer, *m_osInterface->pOsContext, *m_miInterface, *m_renderEngineInterface->GetMmioRegisters());
MHW_MEDIA_OBJECT_PARAMS mediaObjectParams;
MediaObjectInlineData mediaObjectInlineData;
MOS_ZeroMemory(&mediaObjectParams, sizeof(mediaObjectParams));
MOS_ZeroMemory(&mediaObjectInlineData, sizeof(mediaObjectInlineData));
mediaObjectParams.pInlineData = &mediaObjectInlineData;
mediaObjectParams.dwInlineDataSize = sizeof(mediaObjectInlineData);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_renderEngineInterface->AddMediaObject(
&cmdBuffer,
nullptr,
&mediaObjectParams));
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));)
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->UpdateSSEuForCmdBuffer(&cmdBuffer, m_singleTaskPhaseSupported, m_lastTaskInPhase));
m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
{
HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_renderContextUsesNullHw);
m_lastTaskInPhase = false;
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetupROIStreamIn(
PCODEC_AVC_ENCODE_PIC_PARAMS picParams,
PCODEC_AVC_ENCODE_SLICE_PARAMS slcParams,
PMOS_RESOURCE vdencStreamIn)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(picParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencStreamIn);
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
CODECHAL_VDENC_STREAMIN_STATE *pData = (CODECHAL_VDENC_STREAMIN_STATE *)m_osInterface->pfnLockResource(
m_osInterface,
vdencStreamIn,
&lockFlags);
CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
MOS_ZeroMemory(pData, m_picHeightInMb * m_picWidthInMb * CODECHAL_VDENC_STREAMIN_STATE::byteSize);
m_vdencStreamInEnabled = true;
// legacy AVC ROI[n]->VDEnc ROI[n+1], ROI 1 has higher priority than 2 and so on
if (picParams->bNativeROI)
{
for (int32_t i = picParams->NumROI - 1; i >= 0; i--)
{
int32_t dqpidx = -1;
for (int32_t j = 0; j < m_maxNumNativeRoi; j++)
{
if (m_avcPicParam->ROIDistinctDeltaQp[j] == m_avcPicParam->ROI[i].PriorityLevelOrDQp)
{
dqpidx = j;
break;
}
}
CODECHAL_ENCODE_CHK_COND_RETURN(dqpidx == -1, "Max number of supported different dQP for ROI is %u", m_maxNumNativeRoi);
uint32_t curX, curY;
for (curY = picParams->ROI[i].Top; curY < picParams->ROI[i].Bottom; curY++)
{
for (curX = picParams->ROI[i].Left; curX < picParams->ROI[i].Right; curX++)
{
(pData + (m_picWidthInMb * curY + curX))->DW0.RegionOfInterestRoiSelection = dqpidx + 1; //Shift ROI by 1
}
}
}
}
else
{
int8_t qpPrimeY = (int8_t)CodecHal_Clip3(10, 51, picParams->QpY + slcParams->slice_qp_delta);
for (int32_t i = 0; i < m_picHeightInMb * m_picWidthInMb; i++)
{
(pData + i)->DW1.Qpprimey = qpPrimeY;
}
for (int32_t i = picParams->NumROI - 1; i >= 0; i--)
{
uint32_t curX, curY;
int8_t newQp = (int8_t)CodecHal_Clip3(10, 51, qpPrimeY + picParams->ROI[i].PriorityLevelOrDQp);
for (curY = picParams->ROI[i].Top; curY < picParams->ROI[i].Bottom; curY++)
{
for (curX = picParams->ROI[i].Left; curX < picParams->ROI[i].Right; curX++)
{
(pData + (m_picWidthInMb * curY + curX))->DW1.Qpprimey = newQp;
}
}
}
}
m_osInterface->pfnUnlockResource(
m_osInterface,
vdencStreamIn);
return eStatus;
}
bool CodechalVdencAvcState::ProcessRoiDeltaQp()
{
CODECHAL_ENCODE_FUNCTION_ENTER;
// Intialize ROIDistinctDeltaQp to be min expected delta qp, setting to -128
// Check if forceQp is needed or not
// forceQp is enabled if there are greater than 3 distinct delta qps or if the deltaqp is beyond range (-8, 7)
for (auto k = 0; k < m_maxNumRoi; k++)
{
m_avcPicParam->ROIDistinctDeltaQp[k] = -128;
}
int32_t numQp = 0;
for (int32_t i = 0; i < m_avcPicParam->NumROI; i++)
{
bool dqpNew = true;
//Get distinct delta Qps among all ROI regions, index 0 having the lowest delta qp
int32_t k = numQp - 1;
for (; k >= 0; k--)
{
if (m_avcPicParam->ROI[i].PriorityLevelOrDQp == m_avcPicParam->ROIDistinctDeltaQp[k] ||
m_avcPicParam->ROI[i].PriorityLevelOrDQp == 0)
{
dqpNew = false;
break;
}
else if (m_avcPicParam->ROI[i].PriorityLevelOrDQp < m_avcPicParam->ROIDistinctDeltaQp[k])
{
continue;
}
else
{
break;
}
}
if (dqpNew)
{
for (int32_t j = numQp - 1; (j >= k + 1 && j >= 0); j--)
{
m_avcPicParam->ROIDistinctDeltaQp[j + 1] = m_avcPicParam->ROIDistinctDeltaQp[j];
}
m_avcPicParam->ROIDistinctDeltaQp[k + 1] = m_avcPicParam->ROI[i].PriorityLevelOrDQp;
numQp++;
}
}
//Set the ROI DeltaQp to zero for remaining array elements
for (auto k = numQp; k < m_maxNumRoi; k++)
{
m_avcPicParam->ROIDistinctDeltaQp[k] = 0;
}
m_avcPicParam->NumROIDistinctDeltaQp = (int8_t)numQp;
bool bIsNativeROI = (!(numQp > m_maxNumNativeRoi || m_avcPicParam->ROIDistinctDeltaQp[0] < -8 || m_avcPicParam->ROIDistinctDeltaQp[numQp - 1] > 7));
bool bIsNativeROIAllowed = !m_vdencBrcEnabled || m_mbBrcEnabled; // BRC native ROI require MBBRC on
// return whether is native ROI or not
return bIsNativeROI && bIsNativeROIAllowed;
}
MOS_STATUS CodechalVdencAvcState::SetupDirtyROI(PMOS_RESOURCE vdencStreamIn)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencStreamIn);
m_vdencStaticFrame = false;
m_vdencStaticRegionPct = 0;
//Dirty ROI feature just for p frame
if (m_pictureCodingType != P_TYPE)
{
return eStatus;
}
//Dirty ROI feature just for the previous frame reference
auto ppsIdx = m_avcSliceParams->pic_parameter_set_id;
auto refPicListIdx = m_avcSliceParams[ppsIdx].RefPicList[0][0].FrameIdx;
auto refFrameListIdx = m_avcPicParam[ppsIdx].RefFrameList[refPicListIdx].FrameIdx;
if (m_prevReconFrameIdx != refFrameListIdx)
{
return eStatus;
}
auto picParams = m_avcPicParam;
CODECHAL_ENCODE_CHK_NULL_RETURN(picParams);
// calculate the non-dirty percentage
uint16_t staticArea = m_picHeightInMb * m_picWidthInMb;
for (int32_t i = picParams->NumDirtyROI - 1; i >= 0; i--)
{
staticArea -= (picParams->DirtyROI[i].Right - picParams->DirtyROI[i].Left) *
(picParams->DirtyROI[i].Bottom - picParams->DirtyROI[i].Top);
}
uint16_t staticRegionPct = (MOS_MAX(0, staticArea * 256)) / (m_picHeightInMb * m_picWidthInMb);
m_vdencStaticFrame = staticRegionPct > (uint16_t)(CODECHAL_VDENC_AVC_STATIC_FRAME_ZMV_PERCENT * 256 / 100.0);
m_vdencStaticRegionPct = staticRegionPct;
//BRC + MBQP => streamIn
if (m_vdencBrcEnabled && m_mbBrcEnabled)
{
m_vdencStreamInEnabled = true;
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
auto pData = (CODECHAL_VDENC_STREAMIN_STATE *)m_osInterface->pfnLockResource(
m_osInterface,
vdencStreamIn,
&lockFlags);
CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
MOS_ZeroMemory(pData, m_picHeightInMb * m_picWidthInMb * CODECHAL_VDENC_STREAMIN_STATE::byteSize);
for (int32_t i = picParams->NumDirtyROI - 1; i >= 0; i--)
{
for (uint32_t curY = picParams->DirtyROI[i].Top; curY < picParams->DirtyROI[i].Bottom; curY++)
{
for (uint32_t curX = picParams->DirtyROI[i].Left; curX < picParams->DirtyROI[i].Right; curX++)
{
(pData + (m_picWidthInMb * curY + curX))->DW0.RegionOfInterestRoiSelection = 1;
}
}
}
m_osInterface->pfnUnlockResource(
m_osInterface,
vdencStreamIn);
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetupBrcROIBuffer(PCODEC_AVC_ENCODE_PIC_PARAMS picParams, PMOS_RESOURCE brcRoiBuffer)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(picParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(brcRoiBuffer);
m_vdencStreamInEnabled = true;
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
int8_t* pData = (int8_t*)m_osInterface->pfnLockResource(
m_osInterface,
&m_resVdencBrcRoiBuffer[m_currRecycledBufIdx],
&lockFlags);
CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
MOS_ZeroMemory(pData, m_picHeightInMb * m_picWidthInMb);
for (int32_t i = picParams->NumROI - 1; i >= 0; i--)
{
int32_t dqpidx = -1;
for (int32_t j = 0; j < m_maxNumBrcRoi; j++)
{
if (m_avcPicParam->ROIDistinctDeltaQp[j] == m_avcPicParam->ROI[i].PriorityLevelOrDQp)
{
dqpidx = j;
break;
}
}
CODECHAL_ENCODE_CHK_COND_RETURN(dqpidx == -1, "Max number of supported different dQP for ROI is %u", m_maxNumBrcRoi);
uint32_t curX, curY;
for (curY = picParams->ROI[i].Top; curY < picParams->ROI[i].Bottom; curY++)
{
for (curX = picParams->ROI[i].Left; curX < picParams->ROI[i].Right; curX++)
{
*(pData + (m_picWidthInMb * curY + curX)) = dqpidx + 1; // Shift ROI by 1
}
}
}
m_osInterface->pfnUnlockResource(
m_osInterface,
&m_resVdencBrcRoiBuffer[m_currRecycledBufIdx]);
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::SetupForceSkipStreamIn(PCODEC_AVC_ENCODE_PIC_PARAMS picParams, PMOS_RESOURCE vdencStreamIn)
{
int32_t i;
uint32_t uiCurX, uiCurY;
//PVDENC_STREAMIN_STATE_CMD pData;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint32_t CleanHorizontalStartMB = (picParams->ForceSkip.Xpos >> 4);
uint32_t CleanHorizontalEndMB = (picParams->ForceSkip.Xpos + picParams->ForceSkip.Width) >> 4;
uint32_t CleanVerticalStartMB = (picParams->ForceSkip.Ypos >> 4);
uint32_t CleanVerticalEndMB = (picParams->ForceSkip.Ypos + picParams->ForceSkip.Height) >> 4;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(picParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencStreamIn);
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
CODECHAL_VDENC_STREAMIN_STATE *pData = (CODECHAL_VDENC_STREAMIN_STATE*)m_osInterface->pfnLockResource(
m_osInterface,
vdencStreamIn,
&lockFlags);
CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
MOS_ZeroMemory(pData, m_picHeightInMb * m_picWidthInMb * CODECHAL_VDENC_STREAMIN_STATE::byteSize);
for (uint16_t i = 0; i < m_picHeightInMb * m_picWidthInMb; i++)
{
uint32_t XPosInMbs = (i % m_picWidthInMb);
uint32_t YPosInMbs = (i / m_picWidthInMb);
if (XPosInMbs < CleanHorizontalStartMB || YPosInMbs < CleanVerticalStartMB
|| XPosInMbs >= CleanHorizontalEndMB || YPosInMbs >= CleanVerticalEndMB)
{
pData->DW0.Forceskip = true;
}
else
{
pData->DW0.Forceskip = false;
}
pData++;
}
m_osInterface->pfnUnlockResource(
m_osInterface,
vdencStreamIn);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetupRegionBoosting(PMOS_RESOURCE vdencStreamIn, uint16_t boostIndex)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencStreamIn);
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
CODECHAL_VDENC_STREAMIN_STATE *pData = (CODECHAL_VDENC_STREAMIN_STATE *)m_osInterface->pfnLockResource(
m_osInterface,
vdencStreamIn,
&lockFlags);
CODECHAL_ENCODE_CHK_NULL_RETURN(pData);
MOS_ZeroMemory(pData, m_picHeightInMb * m_picWidthInMb * CODECHAL_VDENC_STREAMIN_STATE::byteSize);
for (uint16_t y = 0; y < m_picHeightInMb; y++)
{
if ((y & 7) == boostIndex)
{
for (uint16_t x = 0; x < m_picWidthInMb; x++)
{
pData->DW0.RegionOfInterestRoiSelection = 1;
pData++;
}
}
else
{
pData += m_picWidthInMb;
}
}
m_osInterface->pfnUnlockResource(
m_osInterface,
vdencStreamIn);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::StoreHucErrorStatus(
MmioRegistersHuc* mmioRegisters,
PMOS_COMMAND_BUFFER cmdBuffer,
bool addToEncodeStatus)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(mmioRegisters);
CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
// 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_AVC_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 CodechalVdencAvcState::HuCBrcInitReset()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
auto mmioRegisters = m_hucInterface->GetMmioRegisters(m_vdboxIndex);
auto avcSeqParams = m_avcSeqParam;
MOS_COMMAND_BUFFER cmdBuffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
if (!m_singleTaskPhaseSupported || m_firstTaskInPhase)
{
MHW_MI_MMIOREGISTERS mmioRegister;
bool validMmio = m_mfxInterface->ConvertToMiRegister(m_vdboxIndex, mmioRegister);
// Send command buffer header at the beginning (OS dependent)
bool bRequestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
&cmdBuffer, bRequestFrameTracking, validMmio ? &mmioRegister: nullptr));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectStartCmd((void*)this, m_osInterface, m_miInterface, &cmdBuffer));
// load kernel from WOPCM into L2 storage RAM
MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
MOS_ZeroMemory(&imemParams, sizeof(imemParams));
imemParams.dwKernelDescriptor = m_vdboxHucVdencBrcInitKernelDescriptor;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams));
// pipe mode select
PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(pipeModeSelectParams);
pipeModeSelectParams->Mode = m_mode;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams));
m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetDmemHuCBrcInitReset());
// set HuC DMEM param
MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
dmemParams.presHucDataSource = &m_resVdencBrcInitDmemBuffer[m_currRecycledBufIdx];
dmemParams.dwDataLength = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams));
MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
virtualAddrParams.regionParams[0].presRegion = &m_resVdencBrcHistoryBuffer;
virtualAddrParams.regionParams[0].isWritable = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcDummyStreamObject(&cmdBuffer));
// 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_ENCODE_CHK_STATUS_RETURN(AvcVdencStoreHuCStatus2Register(m_hwInterface, &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));
// Collect HuC Init/Reset kernel performance data
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectEndCmd((void*)this, m_osInterface, m_miInterface, &cmdBuffer));
// Handle HUC_STATUS error codes
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHucOutputRegistersHandling(mmioRegisters, &cmdBuffer, true));
if (!m_singleTaskPhaseSupported && (m_osInterface->bNoParsingAssistanceInKmd))
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
}
if (!m_singleTaskPhaseSupported)
{
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
&cmdBuffer,
CODECHAL_NUM_MEDIA_STATES,
"BRCINIT"));
)
}
m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
if (!m_singleTaskPhaseSupported)
{
bool renderingFlags = m_videoContextUsesNullHw;
HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags));
}
CODECHAL_DEBUG_TOOL(DumpHucBrcInit());
m_firstTaskInPhase = false;
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::HuCBrcUpdate()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
auto mmioRegisters = m_hucInterface->GetMmioRegisters(m_vdboxIndex);
auto avcSeqParams = m_avcSeqParam;
auto avcPicParams = m_avcPicParam;
MOS_COMMAND_BUFFER cmdBuffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
if (!m_singleTaskPhaseSupported || (m_firstTaskInPhase && !m_brcInit))
{
MHW_MI_MMIOREGISTERS mmioRegister;
bool validMmio = m_mfxInterface->ConvertToMiRegister(m_vdboxIndex, mmioRegister);
// Send command buffer header at the beginning (OS dependent)
bool bRequestFrameTracking = m_singleTaskPhaseSupported ? m_firstTaskInPhase : 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(
SendPrologWithFrameTracking(&cmdBuffer, bRequestFrameTracking, validMmio ? &mmioRegister : nullptr));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectStartCmd((void*)this, m_osInterface, m_miInterface, &cmdBuffer));
if (m_brcInit || m_brcReset)
{
// Insert conditional batch buffer end for HuC valid IMEM loaded check
MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
MOS_ZeroMemory(
&miConditionalBatchBufferEndParams,
sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
miConditionalBatchBufferEndParams.presSemaphoreBuffer =
&m_resHucStatus2Buffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
&cmdBuffer,
&miConditionalBatchBufferEndParams));
}
// Update HuC DMEM data from other HW buffer if needed
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddMiStoreForHWOutputToHucDmem(&cmdBuffer));
//Set MFX/VDENC image state command in VDENC BRC buffer
PMHW_VDBOX_AVC_IMG_PARAMS imageStateParams = CreateMhwVdboxAvcImgParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(imageStateParams);
SetMfxAvcImgStateParams(*imageStateParams);
imageStateParams->bVdencBRCEnabled = 1;
imageStateParams->bSliceSizeStreamOutEnabled = m_sliceSizeStreamoutSupported;
if (avcSeqParams->EnableSliceLevelRateCtrl)
{
uint8_t qpY = m_avcPicParam->QpY;
imageStateParams->dwMbSlcThresholdValue = CODECHAL_VDENC_AVC_MB_SLICE_TRHESHOLD;
imageStateParams->dwVdencSliceMinusBytes = (m_pictureCodingType == I_TYPE) ? m_vdencSSCThrsTblI[qpY] : m_vdencSSCThrsTblP[qpY];
}
if (m_minMaxQpControlEnabled)
{
// Convert range [1,51] to [10,51] for VDEnc due to HW limitation
if (m_pictureCodingType == I_TYPE)
{
imageStateParams->pEncodeAvcPicParams->ucMaximumQP = MOS_MAX(m_iMaxQp, 10);
imageStateParams->pEncodeAvcPicParams->ucMinimumQP = MOS_MAX(m_iMinQp, 10);
}
else if (m_pictureCodingType == P_TYPE)
{
imageStateParams->pEncodeAvcPicParams->ucMaximumQP = MOS_MAX(m_pMaxQp, 10);
imageStateParams->pEncodeAvcPicParams->ucMinimumQP = MOS_MAX(m_pMinQp, 10);
}
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddVdencBrcImgBuffer(
&m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx],
imageStateParams));
MOS_Delete(imageStateParams);
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
nullptr,
nullptr));
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateEncParam(
0,
nullptr));)
// load kernel from WOPCM into L2 storage RAM
MHW_VDBOX_HUC_IMEM_STATE_PARAMS imemParams;
MOS_ZeroMemory(&imemParams, sizeof(imemParams));
imemParams.dwKernelDescriptor = m_vdboxHucVdencBrcUpdateKernelDescriptor;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucImemStateCmd(&cmdBuffer, &imemParams));
// pipe mode select
PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(pipeModeSelectParams);
pipeModeSelectParams->Mode = m_mode;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams));
m_vdencInterface->ReleaseMhwVdboxPipeModeSelectParams(pipeModeSelectParams);
// DMEM set
SetDmemHuCBrcUpdate();
MHW_VDBOX_HUC_DMEM_STATE_PARAMS dmemParams;
MOS_ZeroMemory(&dmemParams, sizeof(dmemParams));
dmemParams.presHucDataSource = &(m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][m_currPass]);
dmemParams.dwDataLength = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE);
dmemParams.dwDmemOffset = HUC_DMEM_OFFSET_RTOS_GEMS;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucDmemStateCmd(&cmdBuffer, &dmemParams));
// Set Const Data buffer
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetConstDataHuCBrcUpdate());
// Add Virtual addr
MHW_VDBOX_HUC_VIRTUAL_ADDR_PARAMS virtualAddrParams;
MOS_ZeroMemory(&virtualAddrParams, sizeof(virtualAddrParams));
// Input regions
virtualAddrParams.regionParams[1].presRegion = &m_vdencStatsBuffer;
virtualAddrParams.regionParams[2].presRegion = &m_pakStatsBuffer;
virtualAddrParams.regionParams[3].presRegion = &m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx];
if (m_staticFrameDetectionInUse)
{
virtualAddrParams.regionParams[4].presRegion = &m_resSfdOutputBuffer[m_currRecycledBufIdx];
}
virtualAddrParams.regionParams[5].presRegion = &m_resVdencBrcConstDataBuffer[GetCurrConstDataBufIdx()];
if (m_nonNativeBrcRoiSupported && m_avcPicParam->NumROI && !m_avcPicParam->bNativeROI) // Only for BRC non-native ROI
{
if (m_osInterface->osCpInterface != nullptr && m_osInterface->osCpInterface->IsCpEnabled())
{
CODECHAL_ENCODE_ASSERTMESSAGE("Non-native BRC ROI doesn't supports in CP case");
return MOS_STATUS_UNIMPLEMENTED;
}
virtualAddrParams.regionParams[8].presRegion = &m_resVdencBrcRoiBuffer[m_currRecycledBufIdx];
virtualAddrParams.regionParams[9].presRegion = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
}
// Output regions
virtualAddrParams.regionParams[0].presRegion = &m_resVdencBrcHistoryBuffer;
virtualAddrParams.regionParams[0].isWritable = true;
virtualAddrParams.regionParams[6].presRegion = &m_batchBufferForVdencImgStat[0].OsResource;
virtualAddrParams.regionParams[6].isWritable = true;
if (m_nonNativeBrcRoiSupported && m_avcPicParam->NumROI && !m_avcPicParam->bNativeROI) // Only for BRC non-native ROI
{
if (m_osInterface->osCpInterface != nullptr && m_osInterface->osCpInterface->IsCpEnabled())
{
CODECHAL_ENCODE_ASSERTMESSAGE("Non-native BRC ROI doesn't supports in CP case");
return MOS_STATUS_UNIMPLEMENTED;
}
virtualAddrParams.regionParams[10].presRegion = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
virtualAddrParams.regionParams[10].isWritable = true;
}
// region 15 always in clear
virtualAddrParams.regionParams[15].presRegion = &m_resVdencBrcDbgBuffer;
if (m_sliceSizeStreamoutSupported)
{
virtualAddrParams.regionParams[7].presRegion = &m_pakSliceSizeStreamoutBuffer;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucVirtualAddrStateCmd(&cmdBuffer, &virtualAddrParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcDummyStreamObject(&cmdBuffer));
// 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_ENCODE_CHK_STATUS_RETURN(AvcVdencStoreHuCStatus2Register(m_hwInterface, &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
MHW_MI_STORE_DATA_PARAMS storeDataParams;
MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
storeDataParams.pOsResource = &m_resPakMmioBuffer;
storeDataParams.dwResourceOffset = sizeof(uint32_t);
storeDataParams.dwValue = CODECHAL_VDENC_AVC_BRC_HUC_STATUS_REENCODE_MASK;
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_resPakMmioBuffer;
storeRegParams.dwOffset = 0;
storeRegParams.dwRegister = mmioRegisters->hucStatusRegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(&cmdBuffer, &storeRegParams));
// Collect HuC Update kernel performance data
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectEndCmd((void*)this, m_osInterface, m_miInterface, &cmdBuffer));
// Handle HUC_STATUS error codes
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHucOutputRegistersHandling(mmioRegisters, &cmdBuffer, true));
if ((!m_singleTaskPhaseSupported) && (m_osInterface->bNoParsingAssistanceInKmd))
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
}
CODECHAL_DEBUG_TOOL(DumpHucBrcUpdate(true));
if (!m_singleTaskPhaseSupported)
{
std::string pak_pass = "BRCUPDATE_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,
pak_pass.data()));
)
}
m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
if (!m_singleTaskPhaseSupported)
{
bool renderingFlags = m_videoContextUsesNullHw;
HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, renderingFlags));
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::LoadCosts(uint16_t pictureCodingType, uint8_t qp)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_ASSERT(qp < CODEC_AVC_NUM_QP);
MOS_ZeroMemory(m_vdEncModeCost, 12);
MOS_ZeroMemory(m_vdEncMvCost, 8);
MOS_ZeroMemory(m_vdEncHmeMvCost, 8);
m_vdEncModeCost[LutMode_INTRA_NONPRED] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTRA_NONPRED][qp]), 0x6f);
m_vdEncModeCost[LutMode_INTRA_16x16] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTRA_16x16][qp]), 0x8f);
m_vdEncModeCost[LutMode_INTRA_8x8] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTRA_8x8][qp]), 0x8f);
m_vdEncModeCost[LutMode_INTRA_4x4] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTRA_4x4][qp]), 0x8f);
if (pictureCodingType == P_TYPE)
{
// adjustment due to dirty ROI
if (m_vdencStaticFrame)
{
uint32_t temp = AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTRA_16x16][qp];
temp = (uint32_t)(temp * CODECHAL_VDENC_AVC_STATIC_FRAME_INTRACOSTSCLRatioP / 100.0 + 0.5);
m_vdEncModeCost[LutMode_INTRA_16x16] = Map44LutValue(temp, 0x8f);
}
m_vdEncModeCost[LutMode_INTER_16x16] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTER_16x16][qp]), 0x8f);
m_vdEncModeCost[LutMode_INTER_16x8] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTER_16x8][qp]), 0x8f);
m_vdEncModeCost[LutMode_INTER_8x8q] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTER_8x8q][qp]), 0x6f);
m_vdEncModeCost[LutMode_INTER_8x4q] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTER_8x4q][qp]), 0x6f);
m_vdEncModeCost[LutMode_INTER_4x4q] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_INTER_4x4q][qp]), 0x6f);
m_vdEncModeCost[LutMode_REF_ID] = Map44LutValue((uint32_t)(AVC_Mode_Cost[pictureCodingType - 1][LutMode_REF_ID][qp]), 0x6f);
CODECHAL_ENCODE_CHK_STATUS_RETURN(LoadMvCost(qp));
CODECHAL_ENCODE_CHK_STATUS_RETURN(LoadHmeMvCost(qp));
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::HuCBrcDummyStreamObject(PMOS_COMMAND_BUFFER cmdBuffer)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
// pass dummy buffer by Ind Obj Addr command
MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjParams;
MOS_ZeroMemory(&indObjParams, sizeof(indObjParams));
indObjParams.presDataBuffer = &m_resVdencBrcDbgBuffer;
indObjParams.dwDataSize = 1;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucIndObjBaseAddrStateCmd(cmdBuffer, &indObjParams));
MHW_VDBOX_HUC_STREAM_OBJ_PARAMS streamObjParams;
MOS_ZeroMemory(&streamObjParams, sizeof(streamObjParams));
streamObjParams.dwIndStreamInLength = 1;
streamObjParams.bHucProcessing = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hucInterface->AddHucStreamObjectCmd(cmdBuffer, &streamObjParams));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetConstDataHuCBrcUpdate()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
// Set VDENC BRC constant buffer, data remains the same till BRC Init is called
if (m_brcInit)
{
MOS_LOCK_PARAMS lockFlagsWriteOnly;
for (uint8_t picType = 0; picType < CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM; picType++)
{
auto hucConstData = (uint8_t*)m_osInterface->pfnLockResource(
m_osInterface, &m_resVdencBrcConstDataBuffer[picType], &lockFlagsWriteOnly);
CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
FillHucConstData(hucConstData, picType);
m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcConstDataBuffer[picType]);
}
}
if (m_vdencStaticFrame)
{
MOS_LOCK_PARAMS lockFlagsWriteOnly;
auto hucConstData = (PAVCVdencBRCCostantData)m_osInterface->pfnLockResource(
m_osInterface, &m_resVdencBrcConstDataBuffer[GetCurrConstDataBufIdx()], &lockFlagsWriteOnly);
CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
// adjustment due to dirty ROI
for (int j = 0; j < 42; j++)
{
uint32_t temp = AVC_Mode_Cost[1][LutMode_INTRA_16x16][10 + j];
temp = (uint32_t)(temp * CODECHAL_VDENC_AVC_STATIC_FRAME_INTRACOSTSCLRatioP / 100.0 + 0.5);
hucConstData->UPD_P_Intra16x16[j] = Map44LutValue(temp, 0x8f);
}
m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcConstDataBuffer[GetCurrConstDataBufIdx()]);
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::InitializePicture(const EncoderParams &params)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
auto ppsidx = ((PCODEC_AVC_ENCODE_SLICE_PARAMS)(params.pSliceParams))->pic_parameter_set_id;
auto spsidx = ((PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams))->seq_parameter_set_id;
if (ppsidx >= CODEC_AVC_MAX_PPS_NUM || spsidx >= CODEC_AVC_MAX_SPS_NUM)
{
//should never happen
return MOS_STATUS_UNKNOWN;
}
m_madEnabled = params.bMADEnabled;
m_avcSeqParams[spsidx] = (PCODEC_AVC_ENCODE_SEQUENCE_PARAMS)(params.pSeqParams);
m_avcPicParams[ppsidx] = (PCODEC_AVC_ENCODE_PIC_PARAMS)(params.pPicParams);
m_avcQCParams = (PCODECHAL_ENCODE_AVC_QUALITY_CTRL_PARAMS)params.pAVCQCParams;
m_avcRoundingParams = (PCODECHAL_ENCODE_AVC_ROUNDING_PARAMS)params.pAVCRoundingParams;
m_avcSeqParam = m_avcSeqParams[spsidx];
m_avcPicParam = m_avcPicParams[ppsidx];
m_avcVuiParams = (PCODECHAL_ENCODE_AVC_VUI_PARAMS)params.pVuiParams;
m_avcSliceParams = (PCODEC_AVC_ENCODE_SLICE_PARAMS)params.pSliceParams;
m_avcFeiPicParams = (CodecEncodeAvcFeiPicParams *)params.pFeiPicParams;
m_avcIQMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)params.pIQMatrixBuffer;
m_avcIQWeightScaleLists = (PCODEC_AVC_ENCODE_IQ_WEIGTHSCALE_LISTS)params.pIQWeightScaleLists;
m_nalUnitParams = params.ppNALUnitParams;
m_sliceStructCaps = params.uiSlcStructCaps;
m_skipFrameFlag = m_avcPicParam->SkipFrameFlag;
// Picture and slice header packing flag from DDI caps
m_acceleratorHeaderPackingCaps = params.bAcceleratorHeaderPackingCaps;
CODECHAL_ENCODE_CHK_NULL_RETURN(m_avcIQMatrixParams);
// so far this only applies to AVC
// can move to MotionEstimationDisableCheck() if the logic applies to other codecs later
if (m_avcQCParams)
{
// disable 4x/16x/32 HME if DDI wants to do so, enabling logic is not affected
if (m_avcQCParams->HMEDisable)
{
m_hmeSupported = false;
m_16xMeSupported = false;
m_32xMeSupported = false;
}
else if (m_avcQCParams->SuperHMEDisable)
{
m_16xMeSupported = false;
m_32xMeSupported = false;
}
else if (m_avcQCParams->UltraHMEDisable)
{
m_32xMeSupported = false;
}
}
// Sei for AVC
if (params.pSeiData != nullptr)
{
if (params.pSeiData->dwSEIBufSize > 0) // sei is present
{
if (params.pSeiData->dwSEIBufSize > m_seiData.dwSEIBufSize)
{
// Destroy and re-allocate
if (m_seiData.pSEIBuffer)
{
MOS_FreeMemory(m_seiData.pSEIBuffer);
m_seiData.pSEIBuffer = nullptr;
}
m_seiData.dwSEIBufSize = params.pSeiData->dwSEIBufSize;
m_seiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(m_seiData.dwSEIBufSize);
CODECHAL_ENCODE_CHK_NULL_RETURN(m_seiData.pSEIBuffer);
}
m_seiParamBuffer = params.pSeiParamBuffer;
m_seiDataOffset = params.dwSEIDataOffset;
m_seiData.newSEIData = params.pSeiData->newSEIData;
m_seiData.dwSEIDataSize = params.pSeiData->dwSEIDataSize;
eStatus = MOS_SecureMemcpy(m_seiData.pSEIBuffer,
m_seiData.dwSEIDataSize,
(m_seiParamBuffer + m_seiDataOffset),
m_seiData.dwSEIDataSize);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
return eStatus;
}
}
m_extraPictureStatesSize = m_seiData.dwSEIDataSize;
}
m_deblockingEnabled = 0;
for (uint32_t i = 0; i < m_numSlices; i++)
{
if (m_avcSliceParams[i].disable_deblocking_filter_idc != 1)
{
m_deblockingEnabled = 1;
break;
}
}
if (m_newSeq)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSequenceStructs());
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetPictureStructs());
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceStructs());
m_scalingEnabled = m_16xMeSupported;
m_useRawForRef = m_userFlags.bUseRawPicForRef;
CODECHAL_DEBUG_TOOL(
m_debugInterface->m_currPic = m_avcPicParam->CurrOriginalPic;
m_debugInterface->m_bufferDumpFrameNum = m_storeData;
m_debugInterface->m_frameType = m_pictureCodingType;
if (m_newSeq) {
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSeqParams(
m_avcSeqParam,
m_avcIQMatrixParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateConstParam());
}
if (m_newVuiData) {
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpVuiParams(
m_avcVuiParams));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpPicParams(
m_avcPicParam,
m_avcIQMatrixParams));
for (uint32_t i = 0; i < m_numSlices; i++) {
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpSliceParams(
&m_avcSliceParams[i],
m_avcPicParam));
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateDdiParam(
m_avcSeqParam,
m_avcPicParam,
&m_avcSliceParams[i]));
}
// BRC non-native ROI dump as HuC_region8[in], HuC_region9[in] and HuC_region10[out]
if (m_avcPicParam->NumROI && (!m_vdencBrcEnabled || m_avcPicParam->bNativeROI) ||
m_avcPicParam->NumDirtyROI || m_encodeParams.bMbQpDataEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&(m_resVdencStreamInBuffer[m_currRecycledBufIdx]),
CodechalDbgAttr::attrStreamIn,
m_encodeParams.bMbQpDataEnabled ? "_MBQP" : "_ROI",
m_picWidthInMb * m_picHeightInMb * CODECHAL_CACHELINE_SIZE,
0,
CODECHAL_NUM_MEDIA_STATES));
})
// Set min/max QP values in AVC State based on frame type if atleast one of them is non-zero
if (m_avcPicParam->ucMinimumQP || m_avcPicParam->ucMaximumQP)
{
m_minMaxQpControlEnabled = true;
if (m_avcPicParam->CodingType == I_TYPE)
{
m_iMaxQp = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51); // Clamp to the max QP to [1, 51] . Zero is not used by our Kernel.
m_iMinQp = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), m_iMaxQp); // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
if (!m_pFrameMinMaxQpControl)
{
m_pMinQp = m_iMinQp;
m_pMaxQp = m_iMaxQp;
}
}
else if (m_avcPicParam->CodingType == P_TYPE)
{
m_pFrameMinMaxQpControl = true;
m_pMaxQp = MOS_MIN(MOS_MAX(m_avcPicParam->ucMaximumQP, 1), 51); // Clamp to the max QP to [1, 51]. Zero is not used by our Kernel.
m_pMinQp = MOS_MIN(MOS_MAX(m_avcPicParam->ucMinimumQP, 1), m_pMaxQp); // Clamp the min QP to [1, maxQP] to make sure minQP <= maxQP
}
// Zero out the QP values, so we don't update the AVCState settings until new values are sent in MiscParamsRC
m_avcPicParam->ucMinimumQP = 0;
m_avcPicParam->ucMaximumQP = 0;
}
if (m_codecFunction != CODECHAL_FUNCTION_ENC && !m_userFlags.bDisableAcceleratorHeaderPacking && m_acceleratorHeaderPackingCaps)
{
CODECHAL_ENCODE_AVC_PACK_PIC_HEADER_PARAMS packPicHeaderParams;
packPicHeaderParams.pBsBuffer = &m_bsBuffer;
packPicHeaderParams.pPicParams = m_avcPicParam;
packPicHeaderParams.pSeqParams = m_avcSeqParam;
packPicHeaderParams.pAvcVuiParams = m_avcVuiParams;
packPicHeaderParams.pAvcIQMatrixParams = m_avcIQMatrixParams;
packPicHeaderParams.ppNALUnitParams = m_nalUnitParams;
packPicHeaderParams.pSeiData = &m_seiData;
packPicHeaderParams.dwFrameHeight = m_frameHeight;
packPicHeaderParams.dwOriFrameHeight = m_oriFrameHeight;
packPicHeaderParams.wPictureCodingType = m_avcPicParam->CodingType;
packPicHeaderParams.bNewSeq = m_newSeq;
packPicHeaderParams.pbNewPPSHeader = &m_newPpsHeader;
packPicHeaderParams.pbNewSeqHeader = &m_newSeqHeader;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackPictureHeader(&packPicHeaderParams));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetStatusReportParams(m_refList[m_currReconstructedPic.FrameIdx]));
m_bitstreamUpperBound = m_encodeParams.dwBitstreamSize;
uint8_t sliceQP = m_avcPicParam->pic_init_qp_minus26 + 26 + m_avcSliceParams->slice_qp_delta;
CODECHAL_ENCODE_CHK_STATUS_RETURN(GetSkipBiasAdjustment(sliceQP, m_avcSeqParam->GopRefDist, &m_skipBiasAdjustmentEnable));
// Determine if Trellis Quantization should be enabled
MOS_ZeroMemory(&m_trellisQuantParams, sizeof(m_trellisQuantParams));
// Trellis must remain switched off if it is explicitly disabled or picture is encoded with CAVLC
if (!(m_trellis & trellisDisabled) && m_avcPicParam->entropy_coding_mode_flag)
{
if (m_trellis == trellisInternal)
{
CODECHAL_ENCODE_AVC_TQ_INPUT_PARAMS tqInputParams;
tqInputParams.ucQP = sliceQP;
tqInputParams.ucTargetUsage = m_avcSeqParam->TargetUsage;
tqInputParams.wPictureCodingType = m_pictureCodingType;
tqInputParams.bBrcEnabled = false;
tqInputParams.bVdEncEnabled = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(GetTrellisQuantization(
&tqInputParams,
&m_trellisQuantParams));
}
else if ((m_pictureCodingType == I_TYPE && (m_trellis & trellisEnabledI)) ||
(m_pictureCodingType == P_TYPE && (m_trellis & trellisEnabledP)) ||
(m_pictureCodingType == B_TYPE && (m_trellis & trellisEnabledB)))
{
m_trellisQuantParams.dwTqEnabled = true;
m_trellisQuantParams.dwTqRounding = CODECHAL_ENCODE_AVC_DEFAULT_TRELLIS_QUANT_ROUNDING;
}
}
m_resVdencStatsBuffer = &(m_vdencStatsBuffer);
m_resPakStatsBuffer = &(m_pakStatsBuffer);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::ExecuteKernelFunctions()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
if (!m_cscDsState)
{
return eStatus;
}
if (m_avcPicParam->bRepeatFrame)
{
m_cscDsState->ResetCscFlag();
m_rawSurfaceToEnc = &m_prevRawSurface;
m_rawSurfaceToPak = &m_prevRawSurface;
}
// SHME and CSC require calling EU kernels
if (!(m_16xMeSupported || m_cscDsState->RequireCsc()))
{
return eStatus;
}
CODECHAL_DEBUG_TOOL(
if (MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrFlatPhysCCS))
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBltOutput(
m_rawSurfaceToEnc,
CodechalDbgAttr::attrDecodeBltOutput))
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
m_rawSurfaceToEnc,
CodechalDbgAttr::attrEncodeRawInputSurface,
"SrcSurf"))
CODECHAL_DEBUG_TOOL(m_debugInterface->DumpSurfaceInfo(m_rawSurfaceToEnc, "RawSurfaceToEnc")));
m_firstTaskInPhase = true;
if (!m_avcPicParam->bRepeatFrame &&
((m_rawSurfaceToEnc->Format == Format_A8R8G8B8) || m_rawSurfaceToEnc->Format == Format_A8B8G8R8))
{
m_pollingSyncEnabled = m_avcPicParam->bEnableSync;
m_syncMarkerOffset = m_rawSurfaceToEnc->dwPitch * m_avcPicParam->SyncMarkerY + m_avcPicParam->SyncMarkerX * 4;
if ((m_avcPicParam->SyncMarkerSize >= 4) && (m_avcPicParam->pSyncMarkerValue != nullptr))
{
// driver only uses the lower 4 bytes as marker for now, as MI_SEMAPHORE_WAIT only supports 32-bit semaphore data.
m_syncMarkerValue = *((uint32_t *)m_avcPicParam->pSyncMarkerValue);
}
else // application is not sending valid marker, use default value.
{
m_syncMarkerValue = 0x01234501;
}
}
else
{
m_pollingSyncEnabled = false;
}
if (m_cscDsState->RequireCopyOnly())
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->RawSurfaceMediaCopy(m_rawSurfaceToEnc->Format));
return eStatus;
}
if (m_cscDsState->UseSfc() && m_cscDsState->RequireCsc())
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->CscUsingSfc(m_avcSeqParam->InputColorSpace));
return eStatus;
}
UpdateSSDSliceCount();
// Csc, Downscaling, and/or 10-bit to 8-bit conversion
CodechalEncodeCscDs::KernelParams cscScalingKernelParams;
MOS_ZeroMemory(&cscScalingKernelParams, sizeof(cscScalingKernelParams));
cscScalingKernelParams.bLastTaskInPhaseCSC = !m_scalingEnabled;
cscScalingKernelParams.bLastTaskInPhase4xDS = false;
cscScalingKernelParams.bLastTaskInPhase16xDS = !(m_32xMeSupported || m_pictureCodingType != I_TYPE);
cscScalingKernelParams.bLastTaskInPhase32xDS = m_pictureCodingType == I_TYPE;
cscScalingKernelParams.inputColorSpace = m_avcSeqParam->InputColorSpace;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->KernelFunctions(&cscScalingKernelParams));
if (!m_16xMeSupported)
{
// for 4xME VDEnc used its internal 4x scaled surface, no more operation needed
return eStatus;
}
// Static frame detection
// no need to call for I-frame
m_staticFrameDetectionInUse = m_staticFrameDetectionEnable && m_hmeEnabled;
CODECHAL_ENCODE_CHK_STATUS_RETURN(ExecuteMeKernel());
// call SFD kernel after HME in same command buffer
if (m_staticFrameDetectionInUse)
{
// Load VDEnc Costs
CODECHAL_ENCODE_CHK_STATUS_RETURN(LoadCosts(m_avcPicParam->CodingType,
m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta));
m_vdencHmeMvCostTbl = m_vdEncHmeMvCost;
m_vdencModeCostTbl = m_vdEncModeCost;
m_vdencMvCostTbl = m_vdEncMvCost;
m_lastTaskInPhase = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SFDKernel());
}
CODECHAL_DEBUG_TOOL(
CODECHAL_ME_OUTPUT_PARAMS meOutputParams;
MOS_ZeroMemory(&meOutputParams, sizeof(meOutputParams));
meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me16xMvDataBuffer) : &m_16xMeMvDataBuffer;
meOutputParams.b16xMeInUse = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&meOutputParams.psMeMvBuffer->OsResource,
CodechalDbgAttr::attrOutput,
"MvData",
meOutputParams.psMeMvBuffer->dwHeight * meOutputParams.psMeMvBuffer->dwPitch,
m_hmeKernel ? m_hmeKernel->Get16xMeMvBottomFieldOffset() : (uint32_t)m_meMv16xBottomFieldOffset,
CODECHAL_MEDIA_STATE_16X_ME));
meOutputParams.pResVdenStreamInBuffer = &(m_resVdencStreamInBuffer[m_currRecycledBufIdx]);
meOutputParams.psMeMvBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xMvDataBuffer) : &m_4xMeMvDataBuffer;
meOutputParams.psMeDistortionBuffer = m_hmeKernel ? m_hmeKernel->GetSurface(CodechalKernelHme::SurfaceId::me4xDistortionBuffer) : &m_4xMeDistortionBuffer;
meOutputParams.b16xMeInUse = false;
meOutputParams.bVdencStreamInInUse = true;
if (m_vdencStreamInEnabled) {
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_resVdencStreamInBuffer[m_currRecycledBufIdx],
CodechalDbgAttr::attrOutput,
"MvData",
m_picWidthInMb * m_picHeightInMb * CODECHAL_CACHELINE_SIZE,
0,
CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN));
}
if (m_staticFrameDetectionInUse) {
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_resSfdOutputBuffer[m_currRecycledBufIdx],
CodechalDbgAttr::attrOutput,
"Out",
SFD_OUTPUT_BUFFER_SIZE,
0,
CODECHAL_MEDIA_STATE_STATIC_FRAME_DETECTION));
}
);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SendPrologWithFrameTracking(
PMOS_COMMAND_BUFFER cmdBuffer,
bool frameTracking,
MHW_MI_MMIOREGISTERS *mmioRegister)
{
// Set flag bIsMdfLoad in remote gaming scenario to boost GPU frequency for low latency
cmdBuffer->Attributes.bFrequencyBoost = (m_avcSeqParam->ScenarioInfo == ESCENARIO_REMOTEGAMING);
return CodechalEncoderState::SendPrologWithFrameTracking(cmdBuffer, frameTracking, mmioRegister);
}
MOS_STATUS CodechalVdencAvcState::ExecutePictureLevel()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
#if MHW_HWCMDPARSER_ENABLED
char frameType = '\0';
switch (m_avcPicParam->CodingType)
{
case I_TYPE:
frameType = 'I';
break;
case P_TYPE:
frameType = 'P';
break;
case B_TYPE:
frameType = m_avcPicParam->RefPicFlag ? 'B' : 'b';
break;
}
auto instance = mhw::HwcmdParser::GetInstance();
if (instance)
{
instance->UpdateFrameInfo(frameType);
}
#endif
MHW_BATCH_BUFFER batchBuffer;
MOS_ZeroMemory(&batchBuffer, sizeof(batchBuffer));
batchBuffer.dwOffset = m_currPass * BRC_IMG_STATE_SIZE_PER_PASS;
batchBuffer.bSecondLevel = true;
CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS encodePictureLevelParams;
MOS_ZeroMemory(&encodePictureLevelParams, sizeof(encodePictureLevelParams));
encodePictureLevelParams.psPreDeblockSurface = &m_reconSurface;
encodePictureLevelParams.psPostDeblockSurface = &m_reconSurface;
encodePictureLevelParams.bBrcEnabled = false;
encodePictureLevelParams.pImgStateBatchBuffer = &batchBuffer;
bool suppressReconPic =
((!m_refList[m_currReconstructedPic.FrameIdx]->bUsedAsRef) && m_suppressReconPicSupported);
encodePictureLevelParams.bDeblockerStreamOutEnable = 0;
encodePictureLevelParams.bPreDeblockOutEnable = !m_deblockingEnabled && !suppressReconPic;
encodePictureLevelParams.bPostDeblockOutEnable = m_deblockingEnabled && !suppressReconPic;
encodePictureLevelParams.bPerMBStreamOutEnable = m_perMBStreamOutEnable;
if (!m_staticFrameDetectionInUse)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(LoadCosts(m_avcPicParam->CodingType,
m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta));
m_vdencHmeMvCostTbl = m_vdEncHmeMvCost;
m_vdencModeCostTbl = m_vdEncModeCost;
m_vdencMvCostTbl = m_vdEncMvCost;
}
// VDEnc HuC BRC
if (m_vdencBrcEnabled)
{
PerfTagSetting perfTag;
perfTag.Value = 0;
perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
perfTag.CallType = CODECHAL_ENCODE_PERFTAG_CALL_BRC_INIT_RESET;
perfTag.PictureCodingType = m_pictureCodingType;
m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
SetBufferToStorePakStatistics();
// Invoke BRC init/reset FW
if (m_brcInit || m_brcReset)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcInitReset());
}
perfTag.CallType = m_currPass == 0 ? CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE : CODECHAL_ENCODE_PERFTAG_CALL_BRC_UPDATE_SECOND_PASS;
m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
// Invoke BRC update FW
CODECHAL_ENCODE_CHK_STATUS_RETURN(HuCBrcUpdate());
m_brcInit = m_brcReset = false;
}
PerfTagSetting perfTag;
perfTag.Value = 0;
perfTag.Mode = (uint16_t)m_mode & CODECHAL_ENCODE_MODE_BIT_MASK;
perfTag.CallType = m_currPass == 0 ? CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE : CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE_SECOND_PASS;
perfTag.PictureCodingType = m_pictureCodingType;
m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value);
MOS_COMMAND_BUFFER cmdBuffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
// PAK cmd buffer header insertion for 1) non STF 2) STF (except VDEnc BRC case inserted in HuC cmd buffer)
if (!m_singleTaskPhaseSupported || (m_firstTaskInPhase && (!m_vdencBrcEnabled)))
{
bool requestFrameTracking = false;
m_hwInterface->m_numRequestedEuSlices = ((m_frameHeight * m_frameWidth) >= m_ssdResolutionThreshold &&
m_targetUsage <= m_ssdTargetUsageThreshold)
? m_sliceShutdownRequestState
: m_sliceShutdownDefaultState;
MHW_MI_MMIOREGISTERS mmioRegister;
bool validMmio = m_mfxInterface->ConvertToMiRegister(m_vdboxIndex, mmioRegister);
// 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, validMmio ? &mmioRegister : nullptr));
m_hwInterface->m_numRequestedEuSlices = CODECHAL_SLICE_SHUTDOWN_DEFAULT;
}
// Set TBL distribution to VMC = 240 for VDEnc performance
if (MEDIA_IS_WA(m_waTable, WaTlbAllocationForAvcVdenc) &&
(!m_singleTaskPhaseSupported || !m_currPass))
{
TLBAllocationParams tlbAllocationParams;
tlbAllocationParams.presTlbMmioBuffer = &m_vdencTlbMmioBuffer;
tlbAllocationParams.dwMmioMfxLra0Override = m_mmioMfxLra0Override;
tlbAllocationParams.dwMmioMfxLra1Override = m_mmioMfxLra1Override;
tlbAllocationParams.dwMmioMfxLra2Override = m_mmioMfxLra2Override;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetTLBAllocation(&cmdBuffer, &tlbAllocationParams));
}
MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS miConditionalBatchBufferEndParams;
if (m_vdencBrcEnabled && !m_swBrcMode)
{
// Insert conditional batch buffer end for HuC valid IMEM loaded check
MOS_ZeroMemory(&miConditionalBatchBufferEndParams, sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_resHucStatus2Buffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(
m_miInterface->AddMiConditionalBatchBufferEndCmd(
&cmdBuffer,
&miConditionalBatchBufferEndParams));
}
if (m_currPass)
{
if (m_inlineEncodeStatusUpdate && m_vdencBrcEnabled)
{
// inc dwStoreData conditionaly
UpdateEncodeStatus(&cmdBuffer, false);
}
// Insert conditional batch buffer end
MOS_ZeroMemory(&miConditionalBatchBufferEndParams, sizeof(MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS));
if (!m_vdencBrcEnabled)
{
miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_encodeStatusBuf.resStatusBuffer;
miConditionalBatchBufferEndParams.dwOffset =
(m_encodeStatusBuf.wCurrIndex * m_encodeStatusBuf.dwReportSize) +
m_encodeStatusBuf.dwImageStatusMaskOffset + (sizeof(uint32_t) * 2);
}
else
{
// VDENC uses HuC BRC FW generated semaphore for conditional 2nd pass
miConditionalBatchBufferEndParams.presSemaphoreBuffer = &m_resPakMmioBuffer;
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
&cmdBuffer,
&miConditionalBatchBufferEndParams));
}
if (!m_currPass && m_osInterface->bTagResourceSync)
{
// This is a short term solution 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_HW_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_HW_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &params));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencControlStateCmd(&cmdBuffer));
// set MFX_SURFACE_STATE values
// Ref surface
MHW_VDBOX_SURFACE_PARAMS reconSurfaceParams;
MOS_ZeroMemory(&reconSurfaceParams, sizeof(reconSurfaceParams));
reconSurfaceParams.Mode = m_mode;
reconSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_REF_SURFACE_ID;
reconSurfaceParams.psSurface = &m_reconSurface;
CODECHAL_DEBUG_TOOL(m_debugInterface->DumpSurfaceInfo(&m_reconSurface, "ReconSurface"));
// Src surface
MHW_VDBOX_SURFACE_PARAMS surfaceParams;
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.Mode = m_mode;
surfaceParams.ucSurfaceStateId = CODECHAL_MFX_SRC_SURFACE_ID;
surfaceParams.psSurface = m_rawSurfaceToPak;
surfaceParams.dwActualHeight = m_avcSeqParam->FrameHeight;
surfaceParams.dwActualWidth = m_avcSeqParam->FrameWidth;
surfaceParams.bDisplayFormatSwizzle = m_avcPicParam->bDisplayFormatSwizzle;
surfaceParams.bColorSpaceSelection = (m_avcSeqParam->InputColorSpace == ECOLORSPACE_P709) ? 1 : 0;
CODECHAL_DEBUG_TOOL(m_debugInterface->DumpSurfaceInfo(m_rawSurfaceToPak, "RawSurfaceToPak"));
MHW_VDBOX_PIPE_BUF_ADDR_PARAMS pipeBufAddrParams;
pipeBufAddrParams.pRawSurfParam = &surfaceParams;
pipeBufAddrParams.pDecodedReconParam = &reconSurfaceParams;
SetMfxPipeBufAddrStateParams(encodePictureLevelParams, pipeBufAddrParams);
CODECHAL_ENCODE_CHK_NULL_RETURN(m_mmcState);
m_mmcState->SetPipeBufAddr(&pipeBufAddrParams, &cmdBuffer);
PMHW_VDBOX_PIPE_MODE_SELECT_PARAMS pipeModeSelectParams = m_vdencInterface->CreateMhwVdboxPipeModeSelectParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(pipeModeSelectParams);
SetMfxPipeModeSelectParams(encodePictureLevelParams, *pipeModeSelectParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(&cmdBuffer, pipeModeSelectParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &reconSurfaceParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &surfaceParams));
// 4xDS surface
MHW_VDBOX_SURFACE_PARAMS dsSurfaceParams;
MOS_ZeroMemory(&dsSurfaceParams, sizeof(dsSurfaceParams));
dsSurfaceParams.Mode = m_mode;
dsSurfaceParams.ucSurfaceStateId = CODECHAL_MFX_DSRECON_SURFACE_ID;
dsSurfaceParams.psSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
CODECHAL_DEBUG_TOOL(m_debugInterface->DumpSurfaceInfo(dsSurfaceParams.psSurface, "4xDsReconSurface"));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &dsSurfaceParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
SetMfxIndObjBaseAddrStateParams(indObjBaseAddrParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS bspBufBaseAddrParams;
SetMfxBspBufBaseAddrStateParams(bspBufBaseAddrParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &bspBufBaseAddrParams));
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_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencRefSurfaceStateCmd(&cmdBuffer, &reconSurfaceParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencDsRefSurfaceStateCmd(&cmdBuffer, &dsSurfaceParams, 1));
// PerfMode is enabled only on BXT, KBL+, replace all 4x Ds refs with the 1st L0 ref
if (m_vdencInterface->IsPerfModeSupported() && m_perfModeEnabled[m_avcSeqParam->TargetUsage] &&
pipeBufAddrParams.dwNumRefIdxL0ActiveMinus1 == 0)
{
pipeBufAddrParams.dwNumRefIdxL0ActiveMinus1 = 1;
pipeBufAddrParams.presVdencReferences[1] = nullptr;
pipeBufAddrParams.presVdenc4xDsSurface[1] = pipeBufAddrParams.presVdenc4xDsSurface[0];
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencPipeBufAddrCmd(&cmdBuffer, &pipeBufAddrParams));
MHW_VDBOX_VDENC_CQPT_STATE_PARAMS vdencCQPTStateParams;
SetVdencCqptStateParams(vdencCQPTStateParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencConstQPStateCmd(&cmdBuffer, &vdencCQPTStateParams));
if (encodePictureLevelParams.bBrcEnabled && m_avcSeqParam->RateControlMethod != RATECONTROL_ICQ)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
&cmdBuffer,
encodePictureLevelParams.pImgStateBatchBuffer));
}
else
{
//Set MFX_AVC_IMG_STATE command
PMHW_VDBOX_AVC_IMG_PARAMS imageStateParams = CreateMhwVdboxAvcImgParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(imageStateParams);
SetMfxAvcImgStateParams(*imageStateParams);
PMHW_BATCH_BUFFER secondLevelBatchBufferUsed = nullptr;
// VDENC CQP case
if (!m_vdencBrcEnabled)
{
// VDENC case uses multiple buffers for concurrency between SFD and VDENC
secondLevelBatchBufferUsed = &(m_batchBufferForVdencImgStat[m_currRecycledBufIdx]);
if (!m_staticFrameDetectionInUse)
{
// CQP case, driver programs the 2nd Level BB
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_LockBb(m_osInterface, secondLevelBatchBufferUsed));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(nullptr, secondLevelBatchBufferUsed, imageStateParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencAvcCostStateCmd(nullptr, secondLevelBatchBufferUsed, imageStateParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencImgStateCmd(nullptr, secondLevelBatchBufferUsed, imageStateParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(nullptr, secondLevelBatchBufferUsed));
#if MHW_HWCMDPARSER_ENABLED
auto instance = mhw::HwcmdParser::GetInstance();
if (instance)
{
instance->ParseCmdBuf((uint32_t *)(secondLevelBatchBufferUsed->pData),
secondLevelBatchBufferUsed->iCurrent / sizeof(uint32_t));
}
#endif
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
nullptr,
secondLevelBatchBufferUsed));
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateEncParam(
0,
nullptr));
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpEncodeImgStats(nullptr));)
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb(m_osInterface, secondLevelBatchBufferUsed, true));
}
else
{
// SFD enabled, SFD kernel updates VDENC IMG STATE
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(&cmdBuffer, nullptr, imageStateParams));
#if (_DEBUG || _RELEASE_INTERNAL)
secondLevelBatchBufferUsed->iLastCurrent = CODECHAL_ENCODE_VDENC_IMG_STATE_CMD_SIZE + CODECHAL_ENCODE_MI_BATCH_BUFFER_END_CMD_SIZE;
#endif
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulatePakParam(
&cmdBuffer,
nullptr));
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpEncodeImgStats(&cmdBuffer));)
}
}
else
{
// current location to add cmds in 2nd level batch buffer
m_batchBufferForVdencImgStat[0].iCurrent = 0;
// reset starting location (offset) executing 2nd level batch buffer for each frame & each pass
m_batchBufferForVdencImgStat[0].dwOffset = 0;
secondLevelBatchBufferUsed = &(m_batchBufferForVdencImgStat[0]);
}
MOS_Delete(imageStateParams);
HalOcaInterface::OnSubLevelBBStart(cmdBuffer, *m_osInterface->pOsContext,&secondLevelBatchBufferUsed->OsResource, 0, true, 0);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(&cmdBuffer, secondLevelBatchBufferUsed));
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
secondLevelBatchBufferUsed,
CODECHAL_MEDIA_STATE_ENC_NORMAL,
nullptr));)
}
MHW_VDBOX_QM_PARAMS qmParams;
MHW_VDBOX_QM_PARAMS fqmParams;
SetMfxQmStateParams(qmParams, fqmParams);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxFqmCmd(&cmdBuffer, &fqmParams));
if (m_pictureCodingType == B_TYPE)
{
// Add AVC Direct Mode command
MHW_VDBOX_AVC_DIRECTMODE_PARAMS directmodeParams;
MOS_ZeroMemory(&directmodeParams, sizeof(directmodeParams));
directmodeParams.CurrPic = m_avcPicParam->CurrReconstructedPic;
directmodeParams.isEncode = true;
directmodeParams.uiUsedForReferenceFlags = 0xFFFFFFFF;
directmodeParams.pAvcPicIdx = &(m_picIdx[0]);
directmodeParams.avcRefList = (void**)m_refList;
directmodeParams.bPicIdRemappingInUse = false;
directmodeParams.bDisableDmvBuffers = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(&cmdBuffer, &directmodeParams));
}
m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::ExecuteSliceLevel()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface->osCpInterface);
auto cpInterface = m_hwInterface->GetCpInterface();
auto avcSlcParams = m_avcSliceParams;
auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id];
auto avcSeqParams = m_avcSeqParams[avcPicParams->seq_parameter_set_id];
auto slcData = m_slcData;
// *** Temporarily commented until ULT fully support multislice ROW mode
// For use with the single task phase implementation
//if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
//{
// uint32_t numSlc = (m_frameFieldHeightInMb + m_sliceHeight - 1) / m_sliceHeight;
// if (numSlc != m_numSlices)
// {
// return MOS_STATUS_INVALID_PARAMETER;
// }
//}
bool useBatchBufferForPakSlices = false;
if (m_singleTaskPhaseSupported && m_singleTaskPhaseSupportedInPak)
{
if (m_currPass == 0)
{
// The same buffer is used for all slices for all passes.
uint32_t batchBufferForPakSlicesSize =
(m_numPasses + 1) * m_numSlices * m_pakSliceSize;
if (batchBufferForPakSlicesSize >
(uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize)
{
if (m_batchBufferForPakSlices[m_currRecycledBufIdx].iSize)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(ReleaseBatchBufferForPakSlices(m_currRecycledBufIdx));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateBatchBufferForPakSlices(
m_numSlices,
m_numPasses,
m_currRecycledBufIdx));
}
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_LockBb(
m_osInterface,
&m_batchBufferForPakSlices[m_currRecycledBufIdx]));
useBatchBufferForPakSlices = true;
}
MOS_COMMAND_BUFFER cmdBuffer;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
if (m_osInterface->osCpInterface->IsCpEnabled())
{
MHW_CP_SLICE_INFO_PARAMS sliceInfoParam;
sliceInfoParam.bLastPass = (m_currPass == m_numPasses) ? true : false;
CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->SetMfxProtectionState(false, &cmdBuffer, nullptr, &sliceInfoParam));
CODECHAL_ENCODE_CHK_STATUS_RETURN(cpInterface->UpdateParams(false));
}
avcSlcParams = m_avcSliceParams;
CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS packSlcHeaderParams = {};
MHW_VDBOX_AVC_SLICE_STATE sliceState = {};
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetCommonSliceState(packSlcHeaderParams, sliceState));
MHW_VDBOX_VD_PIPE_FLUSH_PARAMS vdPipelineFlushParams;
for (uint16_t slcCount = 0; slcCount < m_numSlices; slcCount++)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSliceState(packSlcHeaderParams, sliceState, slcCount));
CODECHAL_ENCODE_CHK_STATUS_RETURN(SendSlice(&cmdBuffer, &sliceState));
// Add dumps for 2nd level batch buffer
if (sliceState.bSingleTaskPhaseSupported && !sliceState.bVdencInUse)
{
CODECHAL_ENCODE_CHK_NULL_RETURN(sliceState.pBatchBufferForPakSlices);
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
sliceState.pBatchBufferForPakSlices,
CODECHAL_MEDIA_STATE_ENC_NORMAL,
nullptr));)
}
// For SKL, only the 1st slice state should be programmed for VDENC
if (!m_hwInterface->m_isVdencSuperSliceEnabled)
{
break;
}
else // For CNL slice state is programmed per Super slice
{
MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams));
// MfxPipeDone should be set for all super slices except the last super slice and should not be set for tail insertion.
vdPipelineFlushParams.Flags.bWaitDoneMFX =
(slcCount == (m_numSlices)-1) ? ((m_lastPicInStream || m_lastPicInSeq) ? 0 : 1) : 1;
vdPipelineFlushParams.Flags.bWaitDoneVDENC = 1;
vdPipelineFlushParams.Flags.bFlushVDENC = 1;
vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams));
//Do not send MI_FLUSH for last Super slice now
if (slcCount != ((m_numSlices)-1))
{
// Send MI_FLUSH for every Super slice
MHW_MI_FLUSH_DW_PARAMS flushDwParams;
MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
&cmdBuffer,
&flushDwParams));
}
}
}
if (useBatchBufferForPakSlices)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
m_osInterface,
&m_batchBufferForPakSlices[m_currRecycledBufIdx],
m_lastTaskInPhase));
}
//Send VDENC WALKER cmd per every frame for SKL
if (!m_hwInterface->m_isVdencSuperSliceEnabled)
{
PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams = CreateMhwVdboxVdencWalkerStateParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencWalkerStateParams);
vdencWalkerStateParams->Mode = CODECHAL_ENCODE_MODE_AVC;
vdencWalkerStateParams->pAvcSeqParams = avcSeqParams;
vdencWalkerStateParams->pAvcSlcParams = avcSlcParams;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWalkerStateCmd(&cmdBuffer, vdencWalkerStateParams));
MOS_Delete(vdencWalkerStateParams);
MOS_ZeroMemory(&vdPipelineFlushParams, sizeof(vdPipelineFlushParams));
// MFXPipeDone should not be set for tail insertion
vdPipelineFlushParams.Flags.bWaitDoneMFX =
(m_lastPicInStream || m_lastPicInSeq) ? 0 : 1;
vdPipelineFlushParams.Flags.bWaitDoneVDENC = 1;
vdPipelineFlushParams.Flags.bFlushVDENC = 1;
vdPipelineFlushParams.Flags.bWaitDoneVDCmdMsgParser = 1;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdPipelineFlushCmd(&cmdBuffer, &vdPipelineFlushParams));
}
// Insert end of sequence/stream if set
if (m_lastPicInStream || m_lastPicInSeq)
{
MHW_VDBOX_PAK_INSERT_PARAMS pakInsertObjectParams;
MOS_ZeroMemory(&pakInsertObjectParams, sizeof(pakInsertObjectParams));
pakInsertObjectParams.bLastPicInSeq = m_lastPicInSeq;
pakInsertObjectParams.bLastPicInStream = m_lastPicInStream;
pakInsertObjectParams.dwBitSize = 32; // use dwBitSize for SrcDataEndingBitInclusion
if (m_lastPicInSeq)
{
pakInsertObjectParams.dwLastPicInSeqData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSEQ << 24);
}
if (m_lastPicInStream)
{
pakInsertObjectParams.dwLastPicInStreamData = (uint32_t)((1 << 16) | CODECHAL_ENCODE_AVC_NAL_UT_EOSTREAM << 24);
}
pakInsertObjectParams.bHeaderLengthExcludeFrmSize = true;
if (pakInsertObjectParams.bEmulationByteBitsInsert)
{
//Does not matter here, but keeping for consistency
CODECHAL_ENCODE_ASSERTMESSAGE("The emulation prevention bytes are not inserted by the app and are requested to be inserted by HW.");
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPakInsertObject(&cmdBuffer, nullptr, &pakInsertObjectParams));
}
if (m_hwInterface->m_isVdencSuperSliceEnabled)
{
// Send MI_FLUSH with bVideoPipelineCacheInvalidate set to true for last Super slice
MHW_MI_FLUSH_DW_PARAMS flushDwParams;
MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
flushDwParams.bVideoPipelineCacheInvalidate = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
&cmdBuffer,
&flushDwParams));
}
// On-demand sync for VDEnc StreamIn surface and CSC surface
if (m_cscDsState && m_currPass == 0)
{
if (m_cscDsState->RequireCsc())
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscDsState->WaitCscSurface(m_videoContext, true));
}
if (m_16xMeSupported)
{
auto syncParams = g_cInitSyncParams;
syncParams.GpuContext = m_videoContext;
syncParams.bReadOnly = true;
syncParams.presSyncResource = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
}
}
// Prepare MetaData
if ((m_presMetadataBuffer != nullptr) && (m_currPass == m_numPasses))
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(PrepareHWMetaData(m_presMetadataBuffer, &m_pakSliceSizeStreamoutBuffer, &cmdBuffer));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(&cmdBuffer));
if (m_vdencBrcEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(StoreNumPasses(
&(m_encodeStatusBuf),
m_miInterface,
&cmdBuffer,
m_currPass));
}
#if USE_CODECHAL_DEBUG_TOOL
if (m_vdencBrcEnabled && m_enableFakeHrdSize)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(ModifyEncodedFrameSizeWithFakeHeaderSize( &cmdBuffer));
}
#endif
CODECHAL_ENCODE_CHK_STATUS_RETURN(EndStatusReport(&cmdBuffer, CODECHAL_NUM_MEDIA_STATES));
if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
}
std::string pak_pass = "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,
pak_pass.data()));
//CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
// m_debugInterface,
// &cmdBuffer));
)
#if MHW_HWCMDPARSER_ENABLED
auto instance = mhw::HwcmdParser::GetInstance();
if (instance)
{
instance->ParseCmdBuf(cmdBuffer.pCmdBase, cmdBuffer.iOffset / sizeof(uint32_t));
}
#endif
m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
bool renderingFlags = m_videoContextUsesNullHw;
if (!m_singleTaskPhaseSupported || m_lastTaskInPhase)
{
// Restore TLB allocation
if (MEDIA_IS_WA(m_waTable, WaTlbAllocationForAvcVdenc))
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(RestoreTLBAllocation(&cmdBuffer, &m_vdencTlbMmioBuffer));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(SubmitCommandBuffer(&cmdBuffer, renderingFlags));
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER),
CodechalDbgAttr::attrReconstructedSurface,
"4XScaling"))
if (avcSlcParams->slice_type == SLICE_P || avcSlcParams->slice_type == SLICE_SP
|| avcSlcParams->slice_type == SLICE_B)
{
for (int i = 0; i < (avcSlcParams->num_ref_idx_l0_active_minus1 + 1); i++)
{
std::string refSurfName = "4XScaling_RefL0[" + std::to_string(static_cast<uint32_t>(i)) + "]";
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
(m_trackedBuf->Get4xDsReconSurface(m_refList[m_avcSliceParams->RefPicList[0][i].FrameIdx]->ucScalingIdx)),
CodechalDbgAttr::attrReconstructedSurface,
refSurfName.c_str()))
}
}
if (MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrFlatPhysCCS)){
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBltOutput(
&m_reconSurface,
CodechalDbgAttr::attrDecodeBltOutput))}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
&m_reconSurface,
CodechalDbgAttr::attrReconstructedSurface,
"ReconSurf")))
CODECHAL_DEBUG_TOOL(
if (m_mmcState) {
m_mmcState->UpdateUserFeatureKey(&m_reconSurface);
})
if (m_sliceSizeStreamoutSupported)
{
CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_pakSliceSizeStreamoutBuffer,
CodechalDbgAttr::attrOutput,
"SliceSizeStreamout",
CODECHAL_ENCODE_SLICESIZE_BUF_SIZE,
0,
CODECHAL_NUM_MEDIA_STATES)));
}
if ((m_currPass == m_numPasses) &&
m_signalEnc &&
!Mos_ResourceIsNull(&m_resSyncObjectVideoContextInUse))
{
// Check if the signal obj count exceeds max value
if (m_semaphoreObjCount == MOS_MIN(m_semaphoreMaxCount, MOS_MAX_OBJECT_SIGNALED))
{
auto 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
auto syncParams = g_cInitSyncParams;
syncParams.GpuContext = m_videoContext;
syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
m_semaphoreObjCount++;
}
}
CODECHAL_DEBUG_TOOL(
// here add the dump buffer for PAK statistics.
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_pakStatsBufferFull,
CodechalDbgAttr::attrInput,
"MB and FrameLevel PAK staistics vdenc",
m_vdencBrcPakStatsBufferSize + m_picWidthInMb * m_picHeightInMb * 64, //size
0, //offset
CODECHAL_MEDIA_STATE_16X_ME));
)
if (m_vdencBrcEnabled)
{
CODECHAL_DEBUG_TOOL(DumpHucBrcUpdate(false));
CODECHAL_DEBUG_TOOL(DumpEncodeImgStats(nullptr));
}
// Reset parameters for next PAK execution
if (m_currPass == m_numPasses)
{
if (!m_singleTaskPhaseSupported)
{
m_osInterface->pfnResetPerfBufferID(m_osInterface);
}
m_newPpsHeader = 0;
m_newSeqHeader = 0;
}
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateSliceStateParam(
m_adaptiveRoundingInterEnable,
&sliceState));
CODECHAL_ENCODE_CHK_STATUS_RETURN(DumpFrameParFile());)
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::AddVdencWalkerStateCmd(
PMOS_COMMAND_BUFFER cmdBuffer)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams = CreateMhwVdboxVdencWalkerStateParams();
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencWalkerStateParams);
auto avcSlcParams = m_avcSliceParams;
auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id];
auto avcSeqParams = m_avcSeqParams[avcPicParams->seq_parameter_set_id];
vdencWalkerStateParams->Mode = CODECHAL_ENCODE_MODE_AVC;
vdencWalkerStateParams->pAvcSeqParams = avcSeqParams;
vdencWalkerStateParams->pAvcSlcParams = m_avcSliceParams;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_vdencInterface->AddVdencWalkerStateCmd(cmdBuffer, vdencWalkerStateParams));
MOS_Delete(vdencWalkerStateParams);
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::UserFeatureKeyReport()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::UserFeatureKeyReport());
// AVC HME Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_ME_IN_USE_ID, m_hmeSupported, m_osInterface->pOsContext);
// AVC SuperHME Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_16xME_IN_USE_ID, m_16xMeSupported, m_osInterface->pOsContext);
// AVC UltraHME Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_32xME_IN_USE_ID, m_32xMeSupported, m_osInterface->pOsContext);
// AVC RateControl Method Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_ENCODE_RATECONTROL_METHOD_ID, m_avcSeqParam->RateControlMethod, m_osInterface->pOsContext);
// Static frame detection Enable Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_STATIC_FRAME_DETECTION_ENABLE_ID, m_staticFrameDetectionEnable, m_osInterface->pOsContext);
// AVC FTQ Reporting
#if (_DEBUG || _RELEASE_INTERNAL)
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_AVC_FTQ_IN_USE_ID, m_ftqEnable, m_osInterface->pOsContext);
// VDENC Reporting
CodecHalEncode_WriteKey(__MEDIA_USER_FEATURE_VALUE_VDENC_IN_USE_ID, true, m_osInterface->pOsContext);
#endif // _DEBUG || _RELEASE_INTERNAL
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::AllocateResources()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CodechalEncodeAvcBase::AllocateResources();
// Allocate SEI buffer
m_seiData.pSEIBuffer = (uint8_t *)MOS_AllocAndZeroMemory(CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE);
if (m_seiData.pSEIBuffer == nullptr)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate SEI Buffer.");
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
m_seiData.dwSEIBufSize = CODECHAL_ENCODE_AVC_SEI_BUFFER_SIZE;
// initiate allocation parameters 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;
// initiate allocation parameters
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;
if (m_pakEnabled)
{
// Allocate skip frame copy buffer
allocParamsForBufferLinear.dwBytes = m_skipFrameBufferSize = CODECHAL_PAGE_SIZE;
allocParamsForBufferLinear.pBufName = "Skip Frame Copy Buffer";
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resSkipFrameBuffer),
"Failed to allocate Skip Frame Copy Buffer\n");
}
if (m_staticFrameDetectionEnable)
{
// SFD output buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE, CODECHAL_CACHELINE_SIZE);
allocParamsForBufferLinear.pBufName = "Static frame detection output buffer";
// VDENC case needs a set of buffers for concurrency between SFD and HuC BRC FW
for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resSfdOutputBuffer[i]),
"Failed to allocate static frame detection output buffer\n");
}
// SFD P-frame cost table buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE, CODECHAL_CACHELINE_SIZE);
allocParamsForBufferLinear.pBufName = "SFD P-frame cost table buffer";
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resSfdCostTablePFrameBuffer),
"Failed to allocate SFD P-frame cost table buffer\n");
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resSfdCostTableBFrameBuffer),
"Failed to allocate SFD B-frame cost table buffer\n");
// copy SFD P-frame cost table
uint8_t *data;
if (nullptr == (data = (uint8_t *)m_osInterface->pfnLockResource(
m_osInterface,
&m_resSfdCostTablePFrameBuffer,
&lockFlagsWriteOnly)))
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD P-frame cost table Buffer.");
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data,
CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE * sizeof(uint8_t),
m_codechalEncodeAvcSfdCostTablePFrame,
CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE * sizeof(uint8_t)),
"Failed to copy SFD P-frame cost table");
m_osInterface->pfnUnlockResource(m_osInterface, &m_resSfdCostTablePFrameBuffer);
// copy SFD B-frame cost table
if (nullptr == (data = (uint8_t *)m_osInterface->pfnLockResource(
m_osInterface,
&m_resSfdCostTableBFrameBuffer,
&lockFlagsWriteOnly)))
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock SFD B-frame cost table Buffer.");
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(data,
CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE * sizeof(uint8_t),
m_codechalEncodeAvcSfdCostTableBFrame,
CODECHAL_ENCODE_AVC_SFD_COST_TABLE_BUFFER_SIZE * sizeof(uint8_t)),
"Failed to copy SFD B-frame cost table");
m_osInterface->pfnUnlockResource(m_osInterface, &m_resSfdCostTableBFrameBuffer);
}
// VDENC BRC buffer allocation
for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
// BRC update DMEM
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcUpdateDmemBufferSize, CODECHAL_CACHELINE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BrcUpdate DmemBuffer";
for (uint32_t j = 0; j < CODECHAL_VDENC_BRC_NUM_OF_PASSES; j++)
{
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcUpdateDmemBuffer[i][j]);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC Update DMEM Buffer\n", __FUNCTION__);
return eStatus;
}
uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
m_osInterface,
&(m_resVdencBrcUpdateDmemBuffer[i][j]),
&lockFlagsWriteOnly);
if (data == nullptr)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock VDEnc BRC Update DMEM Buffer.");
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes);
m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcUpdateDmemBuffer[i][j]);
}
// BRC init/reset DMEM
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcInitDmemBufferSize, CODECHAL_CACHELINE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BrcInit DmemBuffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcInitDmemBuffer[i]);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC Init DMEM Buffer\n", __FUNCTION__);
return eStatus;
}
// VDENC IMG STATE read buffer
allocParamsForBufferLinear.dwBytes = GetVdencBRCImgStateBufferSize();
allocParamsForBufferLinear.pBufName = "VDENC BRC IMG State Read Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcImageStatesReadBuffer[i]);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC IMG State Read Buffer\n", __FUNCTION__);
return eStatus;
}
}
// Const Data buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(GetBRCCostantDataSize(), CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC Const Data Buffer";
for (uint32_t i = 0; i < CODECHAL_ENCODE_VDENC_BRC_CONST_BUFFER_NUM; i++)
{
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcConstDataBuffer[i]),
"%s: Failed to allocate 's'", __FUNCTION__, allocParamsForBufferLinear.pBufName);
uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
m_osInterface,
&m_resVdencBrcConstDataBuffer[i],
&lockFlagsWriteOnly);
if (data == nullptr)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock '%s'", allocParamsForBufferLinear.pBufName);
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes);
m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcConstDataBuffer[i]);
}
// BRC history buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_VDENC_AVC_BRC_HISTORY_BUF_SIZE, CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC History Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcHistoryBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC History Buffer\n", __FUNCTION__);
return eStatus;
}
if (!m_vdencBrcEnabled && m_staticFrameDetectionEnable)
{
// SFD VDENC IMG STATE input buffer (CQP mode)
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_hwInterface->m_vdencBrcImgStateBufferSize, CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC IMG SFD input Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencSfdImageStateReadBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC IMG SFD input Buffer\n", __FUNCTION__);
return eStatus;
}
}
if (m_nonNativeBrcRoiSupported)
{
// BRC ROI Buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_picWidthInMb * m_picHeightInMb, MHW_CACHELINE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC ROI Buffer";
for (uint32_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
CODECHAL_ENCODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcRoiBuffer[i]),
"%s: Failed to allocate '%s'\n", __FUNCTION__, allocParamsForBufferLinear.pBufName);
uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource(
m_osInterface,
&(m_resVdencBrcRoiBuffer[i]),
&lockFlagsWriteOnly);
if (data == nullptr)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to Lock '%s'.", allocParamsForBufferLinear.pBufName);
eStatus = MOS_STATUS_UNKNOWN;
return eStatus;
}
MOS_ZeroMemory(data, allocParamsForBufferLinear.dwBytes);
m_osInterface->pfnUnlockResource(m_osInterface, &m_resVdencBrcRoiBuffer[i]);
}
}
// Debug buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(CODECHAL_VDENC_AVC_BRC_DEBUG_BUF_SIZE, CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC Debug Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_resVdencBrcDbgBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC Debug Buffer\n", __FUNCTION__);
return eStatus;
}
// VDENC Intra Row Store Scratch buffer
// 1 cacheline per MB
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_vdencIntraRowStoreScratchBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to allocate VDENC Intra Row Store Scratch Buffer.");
return eStatus;
}
// VDENC Statistics buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcStatsBufferSize, CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC Statistics Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_vdencStatsBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate BRC VDENC Statistics Buffer\n", __FUNCTION__);
return eStatus;
}
// PAK Statistics buffer
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(m_vdencBrcPakStatsBufferSize, CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC BRC PAK Statistics Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_pakStatsBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC PAK Statistics Buffer\n", __FUNCTION__);
return eStatus;
}
// Here allocate the buffer for MB+FrameLevel PAK statistics.
uint32_t size = m_vdencBrcPakStatsBufferSize + m_picWidthInMb*m_picHeightInMb*64;
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(size, CODECHAL_PAGE_SIZE);
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_pakStatsBufferFull);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC BRC PerMB and framel level PAK Statistics Buffer\n", __FUNCTION__);
return eStatus;
}
// VDENC uses second level batch buffer for image state cmds
if (!m_vdencBrcEnabled)
{
// CQP mode needs a set of buffers for concurrency between SFD and VDEnc
for (uint8_t i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; i++)
{
MOS_ZeroMemory(
&m_batchBufferForVdencImgStat[i],
sizeof(m_batchBufferForVdencImgStat[i]));
m_batchBufferForVdencImgStat[i].bSecondLevel = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
m_osInterface,
&m_batchBufferForVdencImgStat[i],
nullptr,
m_hwInterface->m_vdencBrcImgStateBufferSize));
}
m_vdencBrcImgStatAllocated = true;
}
else
{
MOS_ZeroMemory(
&m_batchBufferForVdencImgStat[0],
sizeof(m_batchBufferForVdencImgStat[0]));
m_batchBufferForVdencImgStat[0].bSecondLevel = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(Mhw_AllocateBb(
m_osInterface,
&m_batchBufferForVdencImgStat[0],
nullptr,
GetVdencBRCImgStateBufferSize()));
}
// Buffer to store VDEnc TLB MMIO values (registers MFX_LRA_0/1/2)
allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(3 * sizeof(uint32_t), CODECHAL_PAGE_SIZE);
allocParamsForBufferLinear.pBufName = "VDENC TLB MMIO Buffer";
eStatus = (MOS_STATUS)m_osInterface->pfnAllocateResource(
m_osInterface,
&allocParamsForBufferLinear,
&m_vdencTlbMmioBuffer);
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("%s: Failed to allocate VDENC TLB MMIO Buffer\n", __FUNCTION__);
return eStatus;
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::Initialize()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodechalEncodeAvcBase::Initialize());
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::InitKernelStateMe()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
uint8_t *kernelBinary;
uint32_t kernelSize;
uint32_t kuid = m_useCommonKernel ? m_kuidCommon : m_kuid;
MOS_STATUS status = CodecHalGetKernelBinaryAndSize(m_kernelBase, kuid, &kernelBinary, &kernelSize);
CODECHAL_ENCODE_CHK_STATUS_RETURN(status);
for (auto krnStateIdx = 0; krnStateIdx < 2; krnStateIdx++)
{
CODECHAL_KERNEL_HEADER currKrnHeader;
auto kernelStatePtr = &m_meKernelStates[krnStateIdx];
auto EncOperation = (krnStateIdx > 0) ? VDENC_ME : ENC_ME;
CODECHAL_ENCODE_CHK_STATUS_RETURN(pfnGetKernelHeaderAndSize(
kernelBinary,
EncOperation,
(EncOperation == VDENC_ME) ? 0 : krnStateIdx,
&currKrnHeader,
&kernelSize));
kernelStatePtr->KernelParams.iBTCount = CODECHAL_ENCODE_AVC_ME_NUM_SURFACES;
kernelStatePtr->KernelParams.iThreadCount = m_renderEngineInterface->GetHwCaps()->dwMaxThreads;
kernelStatePtr->KernelParams.iCurbeLength = sizeof(CODECHAL_ENCODE_AVC_ME_CURBE);
kernelStatePtr->KernelParams.iBlockWidth = CODECHAL_MACROBLOCK_WIDTH;
kernelStatePtr->KernelParams.iBlockHeight = CODECHAL_MACROBLOCK_HEIGHT;
kernelStatePtr->KernelParams.iIdCount = 1;
kernelStatePtr->dwCurbeOffset = m_stateHeapInterface->pStateHeapInterface->GetSizeofCmdInterfaceDescriptorData();
kernelStatePtr->KernelParams.pBinary =
kernelBinary +
(currKrnHeader.KernelStartPointer << MHW_KERNEL_OFFSET_SHIFT);
kernelStatePtr->KernelParams.iSize = kernelSize;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_stateHeapInterface->pfnCalculateSshAndBtSizesRequested(
m_stateHeapInterface,
kernelStatePtr->KernelParams.iBTCount,
&kernelStatePtr->dwSshSize,
&kernelStatePtr->dwBindingTableSize));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->MhwInitISH(m_stateHeapInterface, kernelStatePtr));
if (m_noMeKernelForPFrame)
{
m_meKernelStates[1] = m_meKernelStates[0];
break;
}
}
// Until a better way can be found, maintain old binding table structures
auto bindingTable = &m_meBindingTable;
bindingTable->dwMEMVDataSurface = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE;
bindingTable->dw16xMEMVDataSurface = CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE;
bindingTable->dw32xMEMVDataSurface = CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE;
bindingTable->dwMEDist = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE;
bindingTable->dwMEBRCDist = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION;
bindingTable->dwMECurrForFwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF;
bindingTable->dwMEFwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX0;
bindingTable->dwMEFwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX1;
bindingTable->dwMEFwdRefPicIdx[2] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX2;
bindingTable->dwMEFwdRefPicIdx[3] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX3;
bindingTable->dwMEFwdRefPicIdx[4] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX4;
bindingTable->dwMEFwdRefPicIdx[5] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX5;
bindingTable->dwMEFwdRefPicIdx[6] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX6;
bindingTable->dwMEFwdRefPicIdx[7] = CODECHAL_ENCODE_AVC_ME_FWD_REF_IDX7;
bindingTable->dwMECurrForBwdRef = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF;
bindingTable->dwMEBwdRefPicIdx[0] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX0;
bindingTable->dwMEBwdRefPicIdx[1] = CODECHAL_ENCODE_AVC_ME_BWD_REF_IDX1;
bindingTable->dwVdencStreamInSurface = CODECHAL_ENCODE_AVC_ME_VDENC_STREAMIN;
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetCurbeMe(MeCurbeParams *params)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_ASSERT(m_avcSeqParam->TargetUsage <= NUM_TARGET_USAGE_MODES);
auto slcParams = m_avcSliceParams;
auto framePicture = CodecHal_PictureIsFrame(m_avcPicParam->CurrOriginalPic);
auto qpPrimeY =
(m_avcPicParam->pic_init_qp_minus26 + 26) +
m_avcSliceParams->slice_qp_delta;
auto mvShiftFactor = 0;
auto prevMvReadPosFactor = 0;
bool useMvFromPrevStep, writeDistortions;
uint32_t scaleFactor;
switch (params->hmeLvl)
{
case HME_LEVEL_32x:
useMvFromPrevStep = CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
writeDistortions = false;
scaleFactor = SCALE_FACTOR_32x;
mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_32x;
break;
case HME_LEVEL_16x:
useMvFromPrevStep = (m_32xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
writeDistortions = false;
scaleFactor = SCALE_FACTOR_16x;
mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_16x;
prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_16x;
break;
case HME_LEVEL_4x:
useMvFromPrevStep = (m_16xMeEnabled) ? CODECHAL_ENCODE_AVC_HME_FOLLOWING_STEP : CODECHAL_ENCODE_AVC_HME_FIRST_STEP;
writeDistortions = true;
scaleFactor = SCALE_FACTOR_4x;
mvShiftFactor = CODECHAL_ENCODE_AVC_MV_SHIFT_FACTOR_4x;
prevMvReadPosFactor = CODECHAL_ENCODE_AVC_PREV_MV_READ_POSITION_4x;
break;
default:
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
break;
}
CODECHAL_ENCODE_AVC_ME_CURBE cmd;
CODECHAL_ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(
&cmd,
sizeof(CODECHAL_ENCODE_AVC_ME_CURBE),
g_cInit_CODECHAL_ENCODE_AVC_ME_CURBE,
sizeof(CODECHAL_ENCODE_AVC_ME_CURBE)));
cmd.DW3.SubPelMode = 3;
if (m_fieldScalingOutputInterleaved)
{
cmd.DW3.SrcAccess =
cmd.DW3.RefAccess = CodecHal_PictureIsField(m_avcPicParam->CurrOriginalPic) ? 1 : 0;
cmd.DW7.SrcFieldPolarity = CodecHal_PictureIsBottomField(m_avcPicParam->CurrOriginalPic) ? 1 : 0;
}
cmd.DW4.PictureHeightMinus1 = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight / scaleFactor) - 1;
cmd.DW4.PictureWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth / scaleFactor);
cmd.DW5.QpPrimeY = qpPrimeY;
cmd.DW6.WriteDistortions = writeDistortions;
cmd.DW6.UseMvFromPrevStep = useMvFromPrevStep;
cmd.DW6.SuperCombineDist = m_superCombineDistGeneric[m_avcSeqParam->TargetUsage];
cmd.DW6.MaxVmvR = (framePicture) ? CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) * 4 : (CodecHalAvcEncode_GetMaxMvLen(m_avcSeqParam->Level) >> 1) * 4;
if (m_pictureCodingType == B_TYPE)
{
// This field is irrelevant since we are not using the bi-direct search.
// set it to 32
cmd.DW1.BiWeight = 32;
cmd.DW13.NumRefIdxL1MinusOne =
m_avcSliceParams->num_ref_idx_l1_active_minus1;
}
if (m_pictureCodingType == P_TYPE ||
m_pictureCodingType == B_TYPE)
{
if (m_16xMeSupported)
{
cmd.DW30.ActualMBHeight = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameFieldHeight);
cmd.DW30.ActualMBWidth = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(m_frameWidth);
}
cmd.DW13.NumRefIdxL0MinusOne =
m_avcSliceParams->num_ref_idx_l0_active_minus1;
}
cmd.DW13.RefStreaminCost = 5;
// This flag is to indicate the ROI source type instead of indicating ROI is enabled or not
cmd.DW13.ROIEnable = 0;
if (!framePicture)
{
if (m_pictureCodingType != I_TYPE)
{
cmd.DW14.List0RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_0);
cmd.DW14.List0RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_1);
cmd.DW14.List0RefID2FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_2);
cmd.DW14.List0RefID3FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_3);
cmd.DW14.List0RefID4FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_4);
cmd.DW14.List0RefID5FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_5);
cmd.DW14.List0RefID6FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_6);
cmd.DW14.List0RefID7FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_0, CODECHAL_ENCODE_REF_ID_7);
}
if (m_pictureCodingType == B_TYPE)
{
cmd.DW14.List1RefID0FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_0);
cmd.DW14.List1RefID1FieldParity = CodecHalAvcEncode_GetFieldParity(slcParams, LIST_1, CODECHAL_ENCODE_REF_ID_1);
}
}
cmd.DW15.MvShiftFactor = mvShiftFactor;
cmd.DW15.PrevMvReadPosFactor = prevMvReadPosFactor;
// r3 & r4
uint8_t tu = m_avcSeqParam->TargetUsage;
uint8_t ucMeMethod = m_meMethodTable ? // use the ME table dependent on prototype or codec standard
m_meMethodTable[tu]
: m_meMethodGeneric[tu];
uint8_t tableIdx = 0;
eStatus = MOS_SecureMemcpy(&(cmd.SPDelta), 14 * sizeof(uint32_t), m_encodeSearchPath[tableIdx][ucMeMethod], 14 * sizeof(uint32_t));
if (eStatus != MOS_STATUS_SUCCESS)
{
CODECHAL_ENCODE_ASSERTMESSAGE("Failed to copy memory.");
return eStatus;
}
// r5
cmd.DW32._4xMeMvOutputDataSurfIndex = CODECHAL_ENCODE_AVC_ME_MV_DATA_SURFACE;
cmd.DW33._16xOr32xMeMvInputDataSurfIndex = (params->hmeLvl == HME_LEVEL_32x) ? CODECHAL_ENCODE_AVC_32xME_MV_DATA_SURFACE : CODECHAL_ENCODE_AVC_16xME_MV_DATA_SURFACE;
cmd.DW34._4xMeOutputDistSurfIndex = CODECHAL_ENCODE_AVC_ME_DISTORTION_SURFACE;
cmd.DW35._4xMeOutputBrcDistSurfIndex = CODECHAL_ENCODE_AVC_ME_BRC_DISTORTION;
cmd.DW36.VMEFwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_FWD_REF;
cmd.DW37.VMEBwdInterPredictionSurfIndex = CODECHAL_ENCODE_AVC_ME_CURR_FOR_BWD_REF;
cmd.DW38.VDEncStreamInSurfIndex = CODECHAL_ENCODE_AVC_ME_VDENC_STREAMIN;
CODECHAL_ENCODE_CHK_STATUS_RETURN(params->pKernelState->m_dshRegion.AddData(
&cmd,
params->pKernelState->dwCurbeOffset,
sizeof(cmd)));
CODECHAL_DEBUG_TOOL(
CODECHAL_ENCODE_CHK_STATUS_RETURN(PopulateHmeParam(m_16xMeEnabled, m_32xMeEnabled, ucMeMethod, &cmd));)
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SendMeSurfaces(PMOS_COMMAND_BUFFER cmdBuffer, MeSurfaceParams *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->pKernelState);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->pCurrOriginalPic);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps4xMeMvDataBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeDistortionBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(params->psMeVdencStreamInBuffer);
CODECHAL_MEDIA_STATE_TYPE encMediaStateType;
encMediaStateType = (params->b32xMeInUse) ? CODECHAL_MEDIA_STATE_32X_ME : params->b16xMeInUse ? CODECHAL_MEDIA_STATE_16X_ME : CODECHAL_MEDIA_STATE_4X_ME;
if (params->bVdencStreamInEnabled && encMediaStateType == CODECHAL_MEDIA_STATE_4X_ME)
{
encMediaStateType = CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN;
}
CODECHAL_ENCODE_CHK_NULL_RETURN(params->pMeBindingTable);
auto meBindingTable = params->pMeBindingTable;
auto currFieldPicture = CodecHal_PictureIsField(*(params->pCurrOriginalPic)) ? 1 : 0;
auto currBottomField = CodecHal_PictureIsBottomField(*(params->pCurrOriginalPic)) ? 1 : 0;
uint8_t ucCurrVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((currBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
PMOS_SURFACE currScaledSurface = nullptr, meMvDataBuffer = nullptr;
uint32_t meMvBottomFieldOffset = 0, currScaledBottomFieldOffset = 0, refScaledBottomFieldOffset = 0;
if (params->b32xMeInUse)
{
CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps32xMeMvDataBuffer);
currScaledSurface = m_trackedBuf->Get32xDsSurface(CODEC_CURR_TRACKED_BUFFER);
meMvDataBuffer = params->ps32xMeMvDataBuffer;
meMvBottomFieldOffset = params->dw32xMeMvBottomFieldOffset;
currScaledBottomFieldOffset = params->dw32xScaledBottomFieldOffset;
}
else if (params->b16xMeInUse)
{
CODECHAL_ENCODE_CHK_NULL_RETURN(params->ps16xMeMvDataBuffer);
currScaledSurface = m_trackedBuf->Get16xDsSurface(CODEC_CURR_TRACKED_BUFFER);
meMvDataBuffer = params->ps16xMeMvDataBuffer;
meMvBottomFieldOffset = params->dw16xMeMvBottomFieldOffset;
currScaledBottomFieldOffset = params->dw16xScaledBottomFieldOffset;
}
else
{
currScaledSurface = m_trackedBuf->Get4xDsSurface(CODEC_CURR_TRACKED_BUFFER);
meMvDataBuffer = params->ps4xMeMvDataBuffer;
meMvBottomFieldOffset = params->dw4xMeMvBottomFieldOffset;
currScaledBottomFieldOffset = params->dw4xScaledBottomFieldOffset;
}
// Reference height and width information should be taken from the current scaled surface rather
// than from the reference scaled surface in the case of PAFF.
auto refScaledSurface = *currScaledSurface;
auto width = MOS_ALIGN_CEIL(params->dwDownscaledWidthInMb * 32, 64);
auto height = params->dwDownscaledHeightInMb * 4 * CODECHAL_ENCODE_ME_DATA_SIZE_MULTIPLIER;
// Force the values
meMvDataBuffer->dwWidth = width;
meMvDataBuffer->dwHeight = height;
meMvDataBuffer->dwPitch = width;
CODECHAL_SURFACE_CODEC_PARAMS surfaceParams;
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bIs2DSurface = true;
surfaceParams.bMediaBlockRW = true;
surfaceParams.psSurface = meMvDataBuffer;
surfaceParams.dwOffset = meMvBottomFieldOffset;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMEMVDataSurface;
surfaceParams.bIsWritable = true;
surfaceParams.bRenderTarget = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
if (params->b16xMeInUse && params->b32xMeEnabled)
{
// Pass 32x MV to 16x ME operation
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bIs2DSurface = true;
surfaceParams.bMediaBlockRW = true;
surfaceParams.psSurface = params->ps32xMeMvDataBuffer;
surfaceParams.dwOffset =
currBottomField ? params->dw32xMeMvBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dw32xMEMVDataSurface;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
else if (!params->b32xMeInUse && params->b16xMeEnabled)
{
// Pass 16x MV to 4x ME operation
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bIs2DSurface = true;
surfaceParams.bMediaBlockRW = true;
surfaceParams.psSurface = params->ps16xMeMvDataBuffer;
surfaceParams.dwOffset =
currBottomField ? params->dw16xMeMvBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_MV_DATA_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dw16xMEMVDataSurface;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
// Insert Distortion buffers only for 4xMe case
if (!params->b32xMeInUse && !params->b16xMeInUse)
{
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bIs2DSurface = true;
surfaceParams.bMediaBlockRW = true;
surfaceParams.psSurface = params->psMeDistortionBuffer;
surfaceParams.dwOffset = params->dwMeDistortionBottomFieldOffset;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMEDist;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_ME_DISTORTION_ENCODE].Value;
surfaceParams.bIsWritable = true;
surfaceParams.bRenderTarget = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
// Setup references 1...n
// LIST 0 references
uint8_t refPicIdx;
CODEC_PICTURE refPic;
bool refFieldPicture, refBottomField;
for (uint8_t refIdx = 0; refIdx <= params->dwNumRefIdxL0ActiveMinus1; refIdx++)
{
refPic = params->pL0RefFrameList[refIdx];
if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid)
{
if (refIdx == 0)
{
// Current Picture Y - VME
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bUseAdvState = true;
surfaceParams.psSurface = currScaledSurface;
surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForFwdRef;
surfaceParams.ucVDirection = ucCurrVDirection;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0;
refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx;
uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx;
if (params->b32xMeInUse)
{
MOS_SURFACE *p32xSurface = m_trackedBuf->Get32xDsSurface(scaledIdx);
if (p32xSurface != nullptr)
{
refScaledSurface.OsResource = p32xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
else if (params->b16xMeInUse)
{
MOS_SURFACE *p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx);
if (p16xSurface != nullptr)
{
refScaledSurface.OsResource = p16xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
else
{
MOS_SURFACE *p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx);
if (p4xSurface != nullptr)
{
refScaledSurface.OsResource = p4xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
// L0 Reference Picture Y - VME
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bUseAdvState = true;
surfaceParams.psSurface = &refScaledSurface;
surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMEFwdRefPicIdx[refIdx];
surfaceParams.ucVDirection = !currFieldPicture ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
}
// Setup references 1...n
// LIST 1 references
for (uint8_t refIdx = 0; refIdx <= params->dwNumRefIdxL1ActiveMinus1; refIdx++)
{
refPic = params->pL1RefFrameList[refIdx];
if (!CodecHal_PictureIsInvalid(refPic) && params->pPicIdx[refPic.FrameIdx].bValid)
{
if (refIdx == 0)
{
// Current Picture Y - VME
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bUseAdvState = true;
surfaceParams.psSurface = currScaledSurface;
surfaceParams.dwOffset = currBottomField ? currScaledBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMECurrForBwdRef;
surfaceParams.ucVDirection = ucCurrVDirection;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
refFieldPicture = CodecHal_PictureIsField(refPic) ? 1 : 0;
refBottomField = (CodecHal_PictureIsBottomField(refPic)) ? 1 : 0;
refPicIdx = params->pPicIdx[refPic.FrameIdx].ucPicIdx;
uint8_t scaledIdx = params->ppRefList[refPicIdx]->ucScalingIdx;
if (params->b32xMeInUse)
{
MOS_SURFACE *p32xSurface = m_trackedBuf->Get32xDsSurface(scaledIdx);
if (p32xSurface != nullptr)
{
refScaledSurface.OsResource = p32xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
else if (params->b16xMeInUse)
{
MOS_SURFACE *p16xSurface = m_trackedBuf->Get16xDsSurface(scaledIdx);
if (p16xSurface != nullptr)
{
refScaledSurface.OsResource = p16xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
else
{
MOS_SURFACE *p4xSurface = m_trackedBuf->Get4xDsSurface(scaledIdx);
if (p4xSurface != nullptr)
{
refScaledSurface.OsResource = p4xSurface->OsResource;
}
else
{
CODECHAL_ENCODE_ASSERTMESSAGE("NULL pointer of DsSurface");
}
refScaledBottomFieldOffset = refBottomField ? currScaledBottomFieldOffset : 0;
}
// L1 Reference Picture Y - VME
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.bUseAdvState = true;
surfaceParams.psSurface = &refScaledSurface;
surfaceParams.dwOffset = refBottomField ? refScaledBottomFieldOffset : 0;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_HME_DOWNSAMPLED_ENCODE].Value;
surfaceParams.dwBindingTableOffset = meBindingTable->dwMEBwdRefPicIdx[refIdx];
surfaceParams.ucVDirection = (!currFieldPicture) ? CODECHAL_VDIRECTION_FRAME : ((refBottomField) ? CODECHAL_VDIRECTION_BOT_FIELD : CODECHAL_VDIRECTION_TOP_FIELD);
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
}
if (encMediaStateType == CODECHAL_MEDIA_STATE_ME_VDENC_STREAMIN)
{
MOS_ZeroMemory(&surfaceParams, sizeof(surfaceParams));
surfaceParams.dwSize = params->dwVDEncStreamInSurfaceSize;
surfaceParams.bIs2DSurface = false;
surfaceParams.presBuffer = params->psMeVdencStreamInBuffer;
surfaceParams.dwBindingTableOffset = meBindingTable->dwVdencStreamInSurface;
surfaceParams.dwCacheabilityControl = m_hwInterface->GetCacheabilitySettings()[MOS_CODEC_RESOURCE_USAGE_SURFACE_BRC_ME_DISTORTION_ENCODE].Value;
surfaceParams.bIsWritable = true;
surfaceParams.bRenderTarget = true;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalSetRcsSurfaceState(
m_hwInterface,
cmdBuffer,
&surfaceParams,
params->pKernelState));
}
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::SetMfxPipeBufAddrStateParams(
CODECHAL_ENCODE_AVC_GENERIC_PICTURE_LEVEL_PARAMS genericParam,
MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & param)
{
MOS_STATUS eStatus = CodechalEncodeAvcBase::SetMfxPipeBufAddrStateParams(genericParam, param);
param.ps4xDsSurface = m_trackedBuf->Get4xDsReconSurface(CODEC_CURR_TRACKED_BUFFER);
param.presVdencIntraRowStoreScratchBuffer = &m_vdencIntraRowStoreScratchBuffer;
param.presVdencStreamOutBuffer = &m_vdencStatsBuffer;
if (m_perMBStreamOutEnable)
{
// Using frame and PerMB level buffer to get PerMB StreamOut PAK Statistic.
param.presStreamOutBuffer = &m_pakStatsBufferFull;
}
else
{
param.presStreamOutBuffer = &m_pakStatsBuffer;
}
param.dwNumRefIdxL0ActiveMinus1 = m_avcSliceParams->num_ref_idx_l0_active_minus1;
param.dwNumRefIdxL1ActiveMinus1 = m_avcSliceParams->num_ref_idx_l1_active_minus1;
param.oneOnOneMapping = m_oneOnOneMapping;
if (m_pictureCodingType != I_TYPE)
{
// populate the RefPic and DS surface so pfnAddVdencPipeBufAddrCmd() can directly use them
auto l0RefFrameList = m_avcSliceParams->RefPicList[LIST_0];
for (uint8_t refIdx = 0; refIdx <= m_avcSliceParams->num_ref_idx_l0_active_minus1; refIdx++)
{
auto refPic = l0RefFrameList[refIdx];
if (!CodecHal_PictureIsInvalid(refPic) && m_picIdx[refPic.FrameIdx].bValid)
{
// L0 references
auto refPicIdx = m_picIdx[refPic.FrameIdx].ucPicIdx;
param.presVdencReferences[refIdx] = &m_refList[refPicIdx]->sRefReconBuffer.OsResource;
param.presVdenc4xDsSurface[refIdx] =
&(m_trackedBuf->Get4xDsReconSurface(m_refList[refPicIdx]->ucScalingIdx))->OsResource;
}
}
}
if (m_vdencStreamInEnabled)
param.presVdencStreamInBuffer = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
return eStatus;
}
void CodechalVdencAvcState::SetVdencCqptStateParams(MHW_VDBOX_VDENC_CQPT_STATE_PARAMS &param)
{
MOS_ZeroMemory(&param, sizeof(param));
param.wPictureCodingType = m_pictureCodingType;
param.bFTQEnabled = m_vdencInterface->VdencFTQEnabled(m_avcSeqParam->TargetUsage);
param.bTransform8x8Flag = m_avcPicParam->transform_8x8_mode_flag;
}
void CodechalVdencAvcState::SetMfxAvcImgStateParams(MHW_VDBOX_AVC_IMG_PARAMS &param)
{
CodechalEncodeAvcBase::SetMfxAvcImgStateParams(param);
if (m_avcSeqParam->EnableSliceLevelRateCtrl)
{
uint8_t qpY = m_avcPicParam->QpY;
param.dwMbSlcThresholdValue = CODECHAL_VDENC_AVC_MB_SLICE_TRHESHOLD;
param.dwVdencSliceMinusBytes = (m_pictureCodingType == I_TYPE) ? m_vdencSSCThrsTblI[qpY] : m_vdencSSCThrsTblP[qpY];
}
if (MEDIA_IS_WA(m_waTable, WaEnableOnlyASteppingFeatures))
{
param.bRollingIRestrictFracCand = true;
}
param.bVdencEnabled = true;
param.pVDEncModeCost = m_vdencModeCostTbl;
param.pVDEncHmeMvCost = m_vdencHmeMvCostTbl;
param.pVDEncMvCost = m_vdencMvCostTbl;
param.bVDEncPerfModeEnabled =
m_vdencInterface->IsPerfModeSupported() && m_perfModeEnabled[m_avcSeqParam->TargetUsage];
}
PMHW_VDBOX_STATE_CMDSIZE_PARAMS CodechalVdencAvcState::CreateMhwVdboxStateCmdsizeParams()
{
PMHW_VDBOX_STATE_CMDSIZE_PARAMS stateCmdSizeParams = MOS_New(MHW_VDBOX_STATE_CMDSIZE_PARAMS);
return stateCmdSizeParams;
}
PMHW_VDBOX_AVC_IMG_PARAMS CodechalVdencAvcState::CreateMhwVdboxAvcImgParams()
{
PMHW_VDBOX_AVC_IMG_PARAMS avcImgParams = MOS_New(MHW_VDBOX_AVC_IMG_PARAMS);
return avcImgParams;
}
PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS CodechalVdencAvcState::CreateMhwVdboxVdencWalkerStateParams()
{
PMHW_VDBOX_VDENC_WALKER_STATE_PARAMS vdencWalkerStateParams = MOS_New(MHW_VDBOX_VDENC_WALKER_STATE_PARAMS);
return vdencWalkerStateParams;
}
MOS_STATUS CodechalVdencAvcState::FillHucConstData(uint8_t *data, uint8_t /*picType*/)
{
auto hucConstData = (PAVCVdencBRCCostantData)data;
auto avcSeqParams = m_avcSeqParam;
CODECHAL_ENCODE_CHK_NULL_RETURN(hucConstData);
MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabI_U8, 64 * sizeof(uint8_t), (void *)BRC_UPD_GlobalRateQPAdjTabI_U8, 64 * sizeof(uint8_t));
if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_LOW) // Sliding Window BRC
{
MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t), (void *)BRC_UPD_SlWinGlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t));
}
else
{
MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t), (void *)BRC_UPD_GlobalRateQPAdjTabP_U8, 64 * sizeof(uint8_t));
}
MOS_SecureMemcpy(hucConstData->UPD_GlobalRateQPAdjTabB_U8, 64 * sizeof(uint8_t), (void *)BRC_UPD_GlobalRateQPAdjTabB_U8, 64 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistThreshldI_U8, 10 * sizeof(uint8_t), (void *)BRC_UPD_DistThreshldI_U8, 10 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistThreshldP_U8, 10 * sizeof(uint8_t), (void *)BRC_UPD_DistThreshldP_U8, 10 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistThreshldB_U8, 10 * sizeof(uint8_t), (void *)BRC_UPD_DistThreshldP_U8, 10 * sizeof(uint8_t));
if (avcSeqParams->RateControlMethod == RATECONTROL_CBR)
{
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabI_U8, 81 * sizeof(uint8_t), (void *)CBR_UPD_DistQPAdjTabI_U8, 81 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabP_U8, 81 * sizeof(uint8_t), (void *)CBR_UPD_DistQPAdjTabP_U8, 81 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabB_U8, 81 * sizeof(uint8_t), (void *)CBR_UPD_DistQPAdjTabB_U8, 81 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t), (void *)CBR_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t), (void *)CBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t), (void *)CBR_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
}
else
{
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabI_U8, 81 * sizeof(uint8_t), (void *)VBR_UPD_DistQPAdjTabI_U8, 81 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabP_U8, 81 * sizeof(uint8_t), (void *)VBR_UPD_DistQPAdjTabP_U8, 81 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_DistQPAdjTabB_U8, 81 * sizeof(uint8_t), (void *)VBR_UPD_DistQPAdjTabB_U8, 81 * sizeof(int8_t));
if (avcSeqParams->FrameSizeTolerance == EFRAMESIZETOL_EXTREMELY_LOW) // Low Delay Mode
{
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t), (void *)LOW_DELAY_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t), (void *)LOW_DELAY_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t), (void *)LOW_DELAY_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
}
else
{
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabI_S8, 72 * sizeof(uint8_t), (void *)VBR_UPD_FrmSzAdjTabI_S8, 72 * sizeof(int8_t));
if (avcSeqParams->RateControlMethod == RATECONTROL_QVBR)
{
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t), (void *)QVBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
}
else
{
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabP_S8, 72 * sizeof(uint8_t), (void *)VBR_UPD_FrmSzAdjTabP_S8, 72 * sizeof(int8_t));
}
MOS_SecureMemcpy(hucConstData->UPD_BufRateAdjTabB_S8, 72 * sizeof(uint8_t), (void *)VBR_UPD_FrmSzAdjTabB_S8, 72 * sizeof(int8_t));
}
}
MOS_SecureMemcpy(hucConstData->UPD_FrmSzMinTabP_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzMinTabP_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_FrmSzMinTabI_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzMinTabI_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_FrmSzMaxTabP_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzMaxTabP_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_FrmSzMaxTabI_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzMaxTabI_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_FrmSzSCGTabP_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzSCGTabP_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_FrmSzSCGTabI_U8, 9 * sizeof(uint8_t), (void *)BRC_UPD_FrmSzSCGTabI_U8, 9 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_I_IntraNonPred, 42 * sizeof(uint8_t), (void *)BRC_UPD_I_IntraNonPred, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_I_Intra8x8, 42 * sizeof(uint8_t), (void *)BRC_UPD_I_Intra8x8, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_I_Intra4x4, 42 * sizeof(uint8_t), (void *)BRC_UPD_I_Intra4x4, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_IntraNonPred, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_IntraNonPred, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Intra16x16, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Intra16x16, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Intra8x8, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Intra8x8, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Intra4x4, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Intra4x4, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Inter16x8, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Inter16x8, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Inter8x8, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Inter8x8, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_Inter16x16, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_Inter16x16, 42 * sizeof(uint8_t));
MOS_SecureMemcpy(hucConstData->UPD_P_RefId, 42 * sizeof(uint8_t), (void *)BRC_UPD_P_RefId, 42 * sizeof(uint8_t));
CODECHAL_ENCODE_CHK_STATUS_RETURN(LoadHmeMvCostTable(avcSeqParams, hucConstData->UPD_HMEMVCost));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::ExecuteMeKernel()
{
if (m_hmeEnabled)
{
if (m_16xMeEnabled)
{
m_lastTaskInPhase = false;
if (m_32xMeEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMeKernel(nullptr, HME_LEVEL_32x));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMeKernel(nullptr, HME_LEVEL_16x));
}
// On-demand sync for VDEnc SHME StreamIn surface
auto syncParams = g_cInitSyncParams;
syncParams.GpuContext = m_renderContext;
syncParams.presSyncResource = &m_resVdencStreamInBuffer[m_currRecycledBufIdx];
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
// HME StreamIn
m_lastTaskInPhase = !m_staticFrameDetectionInUse;
CODECHAL_ENCODE_CHK_STATUS_RETURN(EncodeMeKernel(nullptr, HME_LEVEL_4x));
m_vdencStreamInEnabled = true;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::PrepareHWMetaData(
PMOS_RESOURCE presMetadataBuffer,
PMOS_RESOURCE presSliceSizeStreamoutBuffer,
PMOS_COMMAND_BUFFER cmdBuffer)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
if (!presMetadataBuffer)
{
return eStatus;
}
// get access to the MMIO registers
CODECHAL_ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
MmioRegistersMfx *mmioRegisters = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
MHW_MI_STORE_DATA_PARAMS storeDataParams;
MOS_ZeroMemory(&storeDataParams, sizeof(storeDataParams));
storeDataParams.pOsResource = presMetadataBuffer;
storeDataParams.dwResourceOffset = m_metaDataOffset.dwEncodeErrorFlags;
storeDataParams.dwValue = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
storeDataParams.dwResourceOffset = m_metaDataOffset.dwWrittenSubregionsCount;
storeDataParams.dwValue = m_numSlices;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
MHW_MI_LOAD_REGISTER_MEM_PARAMS miLoadRegMemParams;
MHW_MI_LOAD_REGISTER_IMM_PARAMS miLoadRegImmParams;
MHW_MI_MATH_PARAMS miMathParams;
MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParams;
for (uint16_t slcCount = 0; slcCount < m_numSlices; ++slcCount)
{
uint32_t subRegionStartOffset = m_metaDataOffset.dwMetaDataSize + slcCount * m_metaDataOffset.dwMetaDataSubRegionSize;
storeDataParams.dwResourceOffset = subRegionStartOffset + m_metaDataOffset.dwbStartOffset;
storeDataParams.dwValue = 0; //m_slcData[slcCount].SliceOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
storeDataParams.dwResourceOffset = subRegionStartOffset + m_metaDataOffset.dwbHeaderSize;
storeDataParams.dwValue = m_slcData[slcCount].BitSize;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
// reg0Lo = (SlcCount)thSliceSize con (slcCount-1)thSliceSize
miLoadRegMemParams.presStoreBuffer = presSliceSizeStreamoutBuffer;
miLoadRegMemParams.dwOffset = (slcCount / 2) * 4;
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister0HiOffset;
miLoadRegImmParams.dwData = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
// reg4Lo = mask
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = (slcCount & 1) ? 0xFFFF0000 : 0x0000FFFF;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
MHW_MI_ALU_PARAMS aluParams[4 + 16 * 4];
int aluCount = 0;
// load SrcA, reg0
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// load SrcB, reg4
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG4;
++aluCount;
// and SrcA, SrcB
aluParams[aluCount].AluOpcode = MHW_MI_ALU_AND;
++aluCount;
// >> 16
if (slcCount & 1)
{
for (int i = 0; i < 16; ++i)
{
// store reg0, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG0;
aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
++aluCount;
// load SrcA, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// load SrcB, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// add SrcA, SrcB
aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
++aluCount;
}
}
// store reg0, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG0;
aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
++aluCount;
miMathParams.dwNumAluParams = aluCount;
miMathParams.pAluPayload = aluParams;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiMathCmd(cmdBuffer, &miMathParams));
// Store from reg0Lo/Hi to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = presMetadataBuffer;
miStoreRegMemParams.dwOffset = subRegionStartOffset + m_metaDataOffset.dwbSize;
miStoreRegMemParams.dwRegister = (slcCount & 1) ? mmioRegisters->generalPurposeRegister0HiOffset : mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
MHW_MI_FLUSH_DW_PARAMS flushDwParams;
MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
cmdBuffer,
&flushDwParams));
}
// Special processing for one slice case (to avoid limitations for multi-slice configuration)
// It is a temporary solution. Need to implement programming via mfcBitstreamBytecountSliceRegOffset register
// But it is possible to use this programming for slice conformance feature in the future
if (m_numSlices == 1)
{
MHW_MI_STORE_REGISTER_MEM_PARAMS miStoreRegMemParamsAVC;
MOS_ZeroMemory(&miStoreRegMemParamsAVC, sizeof(miStoreRegMemParamsAVC));
miStoreRegMemParamsAVC.presStoreBuffer = presMetadataBuffer;
miStoreRegMemParamsAVC.dwOffset = m_metaDataOffset.dwMetaDataSize + m_metaDataOffset.dwbSize; // overwrite
miStoreRegMemParamsAVC.dwRegister = mmioRegisters->mfcBitstreamBytecountFrameRegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParamsAVC));
}
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodedBitstreamWrittenBytesCount;
miStoreRegMemParams.dwRegister = mmioRegisters->mfcBitstreamBytecountFrameRegOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
// Statistics
// Average QP
if (m_avcSeqParam->RateControlMethod == RATECONTROL_CQP)
{
storeDataParams.dwResourceOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwAverageQP;
storeDataParams.dwValue = m_avcPicParam->QpY + m_avcSliceParams->slice_qp_delta;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
}
else
{
CODECHAL_ENCODE_NORMALMESSAGE("RC mode is temporarily not supported");
}
MOS_RESOURCE *pPakFrameStat = (m_perMBStreamOutEnable) ? &m_pakStatsBufferFull : &m_pakStatsBuffer; //& m_resFrameStatStreamOutBuffer; or m_pakStatsBuffer
MHW_MI_LOAD_REGISTER_REG_PARAMS miLoadRegRegParams;
MHW_MI_FLUSH_DW_PARAMS flushDwParams;
MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
/*** Intra/Inter/Skip statistics counted by number of MBs (not sub-blocks) ***/
/*** Intra16x16 + Intra8x8 + Intra4x4 ***/
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = 0xFFFF0000;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
// DW4 Intra16x16:Intra8x8
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 4 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister0HiOffset;
miLoadRegImmParams.dwData = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
MOS_ZeroMemory(&miMathParams, sizeof(miMathParams));
MHW_MI_ALU_PARAMS aluParams[4 + 16 * 4];
int aluCount;
auto Reg0OpReg4ToReg0 = [&](MHW_MI_ALU_OPCODE opCode) {
aluCount = 0;
// load SrcA, reg0
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// load SrcB, reg4
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG4;
++aluCount;
// and SrcA, SrcB
aluParams[aluCount].AluOpcode = opCode;
++aluCount;
// store reg0, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG0;
aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
++aluCount;
miMathParams.dwNumAluParams = aluCount;
miMathParams.pAluPayload = aluParams;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiMathCmd(cmdBuffer, &miMathParams));
return MOS_STATUS_SUCCESS;
};
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_AND)); // reg0 0:0:intra16x16:0
// DW5 Intra4x4:Inter16x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 5 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
miLoadRegImmParams.dwData = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams)); // reg4 0:0:intra4x4:inter16x16(garb)
auto AddHighShortsOfReg0Reg4ToReg0 = [&]() {
aluCount = 0;
// load SrcA, reg0
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// load SrcB, reg4
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG4;
++aluCount;
// add SrcA, SrcB
aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
++aluCount;
// ACCU keeps now 0:0:reg0+reg4:0
// 16bit shift left
for (int i = 0; i < 16; ++i)
{
// store reg0, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG0;
aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
++aluCount;
// load SrcA, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCA;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// load SrcB, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_LOAD;
aluParams[aluCount].Operand1 = MHW_MI_ALU_SRCB;
aluParams[aluCount].Operand2 = MHW_MI_ALU_GPREG0;
++aluCount;
// add SrcA, SrcB
aluParams[aluCount].AluOpcode = MHW_MI_ALU_ADD;
++aluCount;
}
// store reg0, accu
aluParams[aluCount].AluOpcode = MHW_MI_ALU_STORE;
aluParams[aluCount].Operand1 = MHW_MI_ALU_GPREG0;
aluParams[aluCount].Operand2 = MHW_MI_ALU_ACCU;
++aluCount;
miMathParams.dwNumAluParams = aluCount;
miMathParams.pAluPayload = aluParams;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiMathCmd(cmdBuffer, &miMathParams));
// move from reg0hi to reg0lo
MOS_ZeroMemory(&miLoadRegRegParams, sizeof(miLoadRegRegParams));
miLoadRegRegParams.dwSrcRegister = mmioRegisters->generalPurposeRegister0HiOffset;
miLoadRegRegParams.dwDstRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &miLoadRegRegParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister0HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
return MOS_STATUS_SUCCESS;
};
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHighShortsOfReg0Reg4ToReg0()); // reg0 0:0:(Intra4x4+Intra16x16).hi:(Intra4x4+Intra16x16).lo
// Temp store from reg0 to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwIntraCodingUnitsCount;
miStoreRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
// DW4 Intra16x16:Intra8x8
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 4 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = 0x0000FFFF;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_AND)); // reg0 0:0:0:Intra8x8
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
miLoadRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miLoadRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwIntraCodingUnitsCount;
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_ADD));
// Store from reg0 to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwIntraCodingUnitsCount;
miStoreRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
/*** Inter16x16 + Inter16x8 + Inter8x16 + Intra8x8 ***/
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = 0xFFFF0000;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
// DW6 Inter16x8:Inter8x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 6 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister0HiOffset;
miLoadRegImmParams.dwData = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_AND)); // reg0 0:0:inter16x8:0
// DW7 Inter8x8:InterSkip16x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 7 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
miLoadRegImmParams.dwData = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams)); // reg4 0:0:inter8x8:0
CODECHAL_ENCODE_CHK_STATUS_RETURN(AddHighShortsOfReg0Reg4ToReg0()); // reg0 0:0:(Inter16x8+Inter8x8).hi:(Inter16x8+Inter8x8).lo;
// Temp store from reg0 to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwInterCodingUnitsCount;
miStoreRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
// DW6 Inter16x8:Inter8x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 6 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
// DW5 Intra4x4 : Inter16x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 5 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = 0x0000FFFF;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_AND)); // reg0 0:Inter8x16:0:Inter16x16
// move from reg0hi to reg4lo
MOS_ZeroMemory(&miLoadRegRegParams, sizeof(miLoadRegRegParams));
miLoadRegRegParams.dwSrcRegister = mmioRegisters->generalPurposeRegister0HiOffset;
miLoadRegRegParams.dwDstRegister = mmioRegisters->generalPurposeRegister4LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterRegCmd(cmdBuffer, &miLoadRegRegParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_ADD)); // reg0 0:0:(Inter8x16+Inter16x16).hi::(Inter8x16+Inter16x16).hi
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
miLoadRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miLoadRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwInterCodingUnitsCount;
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_ADD));
// Store from reg0 to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwInterCodingUnitsCount;
miStoreRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
/*** Inter skip 16x16 ***/
MOS_ZeroMemory(&miLoadRegImmParams, sizeof(miLoadRegImmParams));
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4LoOffset;
miLoadRegImmParams.dwData = 0x0000FFFF;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
miLoadRegImmParams.dwData = 0;
miLoadRegImmParams.dwRegister = mmioRegisters->generalPurposeRegister4HiOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(cmdBuffer, &miLoadRegImmParams));
MOS_ZeroMemory(&miLoadRegMemParams, sizeof(miLoadRegMemParams));
// DW7 Inter8x8:InterSkip16x16
miLoadRegMemParams.presStoreBuffer = pPakFrameStat;
miLoadRegMemParams.dwOffset = 7 * sizeof(uint32_t);
miLoadRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(cmdBuffer, &miLoadRegMemParams));
CODECHAL_ENCODE_CHK_STATUS_RETURN(Reg0OpReg4ToReg0(MHW_MI_ALU_AND));
// Store from reg0 to presMetadataBuffer
MOS_ZeroMemory(&miStoreRegMemParams, sizeof(miStoreRegMemParams));
miStoreRegMemParams.presStoreBuffer = m_presMetadataBuffer;
miStoreRegMemParams.dwOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwSkipCodingUnitsCount;
miStoreRegMemParams.dwRegister = mmioRegisters->generalPurposeRegister0LoOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(cmdBuffer, &miStoreRegMemParams));
// Average MV_X/MV_Y, report (0,0) as temp solution, later may need kernel involved
storeDataParams.dwResourceOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwAverageMotionEstimationXDirection;
storeDataParams.dwValue = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
storeDataParams.dwResourceOffset = m_metaDataOffset.dwEncodeStats + m_metaDataOffset.dwAverageMotionEstimationYDirection;
storeDataParams.dwValue = 0;
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(cmdBuffer, &storeDataParams));
return eStatus;
}
MOS_STATUS CodechalVdencAvcState::AddVdencBrcImgBuffer(
PMOS_RESOURCE vdencBrcImgBuffer,
PMHW_VDBOX_AVC_IMG_PARAMS params)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_ENCODE_CHK_NULL_RETURN(vdencBrcImgBuffer);
CODECHAL_ENCODE_CHK_NULL_RETURN(params);
CODECHAL_ENCODE_CHK_NULL_RETURN(m_hwInterface);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->AddVdencBrcImgBuffer(
vdencBrcImgBuffer,
params));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::SetCommonSliceState(
CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
MHW_VDBOX_AVC_SLICE_STATE & sliceState)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
auto avcSlcParams = m_avcSliceParams;
auto avcPicParams = m_avcPicParams[avcSlcParams->pic_parameter_set_id];
MOS_ZeroMemory(&packSlcHeaderParams, sizeof(packSlcHeaderParams));
packSlcHeaderParams.pBsBuffer = &m_bsBuffer;
packSlcHeaderParams.pPicParams = avcPicParams;
packSlcHeaderParams.pSeqParams = m_avcSeqParam;
packSlcHeaderParams.ppRefList = &(m_refList[0]);
packSlcHeaderParams.CurrPic = m_currOriginalPic;
packSlcHeaderParams.CurrReconPic = m_currReconstructedPic;
packSlcHeaderParams.UserFlags = m_userFlags;
packSlcHeaderParams.NalUnitType = m_nalUnitType;
packSlcHeaderParams.wPictureCodingType = m_pictureCodingType;
packSlcHeaderParams.bVdencEnabled = true;
MOS_ZeroMemory(&sliceState, sizeof(sliceState));
sliceState.presDataBuffer = &m_resMbCodeSurface;
sliceState.pAvcPicIdx = &(m_picIdx[0]);
sliceState.pEncodeAvcSeqParams = m_avcSeqParam;
sliceState.pEncodeAvcPicParams = avcPicParams;
sliceState.pBsBuffer = &m_bsBuffer;
sliceState.ppNalUnitParams = m_nalUnitParams;
sliceState.bBrcEnabled = false;
// Disable Panic mode when min/max QP control is on. kernel may disable it, but disable in driver also.
sliceState.bRCPanicEnable = m_panicEnable && (!m_minMaxQpControlEnabled);
sliceState.bAcceleratorHeaderPackingCaps = m_encodeParams.bAcceleratorHeaderPackingCaps;
sliceState.wFrameFieldHeightInMB = m_frameFieldHeightInMb;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::SetSliceState(
CODECHAL_ENCODE_AVC_PACK_SLC_HEADER_PARAMS &packSlcHeaderParams,
MHW_VDBOX_AVC_SLICE_STATE & sliceState,
uint16_t slcIdx)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
auto avcSlcParams = m_avcSliceParams;
auto slcData = m_slcData;
if (m_currPass == 0)
{
packSlcHeaderParams.pAvcSliceParams = &avcSlcParams[slcIdx];
if (m_acceleratorHeaderPackingCaps)
{
slcData[slcIdx].SliceOffset = m_bsBuffer.SliceOffset;
CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalAvcEncode_PackSliceHeader(&packSlcHeaderParams));
slcData[slcIdx].BitSize = m_bsBuffer.BitSize;
}
if (m_sliceStructCaps != CODECHAL_SLICE_STRUCT_ARBITRARYMBSLICE)
{
slcData[slcIdx].CmdOffset = slcIdx * m_sliceHeight * m_picWidthInMb * 16 * 4;
}
else
{
slcData[slcIdx].CmdOffset = packSlcHeaderParams.pAvcSliceParams->first_mb_in_slice * 16 * 4;
}
}
sliceState.pEncodeAvcSliceParams = &avcSlcParams[slcIdx];
sliceState.dwDataBufferOffset =
m_slcData[slcIdx].CmdOffset + m_mbcodeBottomFieldOffset;
sliceState.dwOffset = slcData[slcIdx].SliceOffset;
sliceState.dwLength = slcData[slcIdx].BitSize;
sliceState.uiSkipEmulationCheckCount = slcData[slcIdx].SkipEmulationByteCount;
sliceState.dwSliceIndex = slcIdx;
sliceState.bFirstPass = (m_currPass == 0);
sliceState.bLastPass = (m_currPass == m_numPasses);
sliceState.bInsertBeforeSliceHeaders = (slcIdx == 0);
sliceState.bVdencInUse = true;
// App handles tail insertion for VDEnc dynamic slice in non-cp case
sliceState.bVdencNoTailInsertion = m_vdencNoTailInsertion;
uint32_t batchBufferForPakSlicesStartOffset =
(uint32_t)m_batchBufferForPakSlices[m_currRecycledBufIdx].iCurrent;
if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingIntra)
{
sliceState.dwRoundingIntraValue = m_avcRoundingParams->dwRoundingIntra;
}
else
{
sliceState.dwRoundingIntraValue = 5;
}
if (m_avcRoundingParams != nullptr && m_avcRoundingParams->bEnableCustomRoudingInter)
{
sliceState.bRoundingInterEnable = true;
sliceState.dwRoundingValue = m_avcRoundingParams->dwRoundingInter;
}
else
{
sliceState.bRoundingInterEnable = m_roundingInterEnable;
CODECHAL_ENCODE_CHK_STATUS_RETURN(SetRounding(m_avcRoundingParams, &sliceState));
}
sliceState.oneOnOneMapping = m_oneOnOneMapping;
return MOS_STATUS_SUCCESS;
}
void CodechalVdencAvcState::SetBufferToStorePakStatistics()
{
CODECHAL_ENCODE_FUNCTION_ENTER;
// Set HuC DMEM buffers which need to be updated.
// They are first pass of next frame and next pass of current frame, as the 2nd VDEnc+PAK pass may not be triggered.
uint32_t nextRecycledBufIdx = (m_currRecycledBufIdx + 1) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM;
uint32_t nextPass = (m_currPass + 1) % CODECHAL_VDENC_BRC_NUM_OF_PASSES;
m_resVdencBrcUpdateDmemBufferPtr[0] = &m_resVdencBrcUpdateDmemBuffer[nextRecycledBufIdx][0];
if (m_lastTaskInPhase)
{
// last pass of current frame, no next pass
m_resVdencBrcUpdateDmemBufferPtr[1] = nullptr;
}
else
{
m_resVdencBrcUpdateDmemBufferPtr[1] = &m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][nextPass];
}
}
uint32_t CodechalVdencAvcState::GetCurrConstDataBufIdx()
{
return m_avcPicParam->CodingType - 1;
}
#if USE_CODECHAL_DEBUG_TOOL
MOS_STATUS CodechalVdencAvcState::DumpHucBrcInit()
{
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
&m_resVdencBrcInitDmemBuffer[m_currRecycledBufIdx],
m_vdencBrcInitDmemBufferSize,
m_currPass,
hucRegionDumpInit));
// History Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcHistoryBuffer,
0,
CODECHAL_VDENC_AVC_BRC_HISTORY_BUF_SIZE,
0,
"_History",
0,
m_currPass,
hucRegionDumpInit));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::DumpHucBrcUpdate(bool isInput)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
if (isInput)
{
//HUC DMEM dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucDmem(
&m_resVdencBrcUpdateDmemBuffer[m_currRecycledBufIdx][m_currPass],
m_vdencBrcUpdateDmemBufferSize,
m_currPass,
hucRegionDumpUpdate));
// Constant Data Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcConstDataBuffer[GetCurrConstDataBufIdx()],
0,
GetBRCCostantDataSize(),
5,
"_ConstData",
isInput,
m_currPass,
hucRegionDumpUpdate));
// VDENC Statistics Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_vdencStatsBuffer,
0,
m_vdencBrcStatsBufferSize,
1,
"_VdencStats",
isInput,
m_currPass,
hucRegionDumpUpdate));
// PAK Statistics Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_pakStatsBuffer,
0,
m_vdencBrcPakStatsBufferSize,
2,
"_PakStats",
isInput,
m_currPass,
hucRegionDumpUpdate));
// VDENC Img State Read Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcImageStatesReadBuffer[m_currRecycledBufIdx],
0,
GetVdencBRCImgStateBufferSize(),
3,
"_ImageStateRead",
isInput,
m_currPass,
hucRegionDumpUpdate));
// SFD output buffer dump
if (m_staticFrameDetectionInUse)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resSfdOutputBuffer[m_currRecycledBufIdx],
0,
sizeof(CODECHAL_ENCODE_AVC_SFD_OUTPUT_BUFFER_SIZE_COMMON),
4,
"_SfdOutput",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
// Slice size Buffer dump
if (m_sliceSizeStreamoutSupported)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_pakSliceSizeStreamoutBuffer,
0,
CODECHAL_ENCODE_SLICESIZE_BUF_SIZE,
7,
"_SliceSizeStreamOut",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
// BRC non-native ROI
if (m_avcPicParam->NumROI && !m_avcPicParam->bNativeROI && m_vdencBrcEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcRoiBuffer[m_currRecycledBufIdx],
0,
m_picWidthInMb * m_picHeightInMb,
8,
"_BrcROI_idxs",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
// VDEnc StreamIn
if (m_avcPicParam->NumROI && !m_avcPicParam->bNativeROI && m_vdencBrcEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencStreamInBuffer[m_currRecycledBufIdx],
0,
m_picWidthInMb * m_picHeightInMb * CODECHAL_CACHELINE_SIZE,
9,
"_VDEnc_StreamIn",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
}
else
{
// History Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcHistoryBuffer,
0,
CODECHAL_VDENC_AVC_BRC_HISTORY_BUF_SIZE,
0,
"_History",
isInput,
m_currPass,
hucRegionDumpUpdate));
// VDENC Img State Write Buffer dump
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_batchBufferForVdencImgStat[0].OsResource,
0,
GetVdencBRCImgStateBufferSize(),
6,
"_ImageStateWrite",
isInput,
m_currPass,
hucRegionDumpUpdate));
// VDEnc StreamIn
if (m_avcPicParam->NumROI && !m_avcPicParam->bNativeROI && m_vdencBrcEnabled)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencStreamInBuffer[m_currRecycledBufIdx],
0,
m_picWidthInMb * m_picHeightInMb * CODECHAL_CACHELINE_SIZE,
10,
"_VDEnc_StreamIn",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpHucRegion(
&m_resVdencBrcDbgBuffer,
0,
CODECHAL_VDENC_AVC_BRC_DEBUG_BUF_SIZE,
15,
"_Debug",
isInput,
m_currPass,
hucRegionDumpUpdate));
}
return MOS_STATUS_SUCCESS;
}
uint32_t CodechalVdencAvcState::GetPakVDEncPassDumpSize()
{
return m_mfxInterface->GetAvcImgStateSize() + m_vdencInterface->GetVdencAvcCostStateSize() + m_vdencInterface->GetVdencAvcImgStateSize();
}
MOS_STATUS CodechalVdencAvcState::DumpEncodeImgStats(
PMOS_COMMAND_BUFFER cmdbuffer)
{
CODECHAL_DEBUG_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrImageState))
{
return MOS_STATUS_SUCCESS;
}
uint32_t size = GetPakVDEncPassDumpSize();
std::string SurfName = "Pak_VDEnc_Pass[" + std::to_string(static_cast<uint32_t>(m_currPass)) + "]";
// MFX_AVC_IMG_STATE
if (m_vdencBrcEnabled)
{
// BRC case: both MFX_AVC_IMG_STATE and VDENC_IMG_STATE are updated by HuC FW
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_batchBufferForVdencImgStat[0].OsResource,
CodechalDbgAttr::attrImageState,
SurfName.c_str(),
size,
0,
CODECHAL_NUM_MEDIA_STATES));
}
else
{
// CQP case: updated by driver or SFD kernel
if (!m_staticFrameDetectionInUse)
{
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
&m_batchBufferForVdencImgStat[m_currRecycledBufIdx].OsResource,
CodechalDbgAttr::attrImageState,
SurfName.c_str(),
size,
0,
CODECHAL_NUM_MEDIA_STATES));
}
else
{
if (!cmdbuffer->pCmdPtr)
{
return MOS_STATUS_INVALID_PARAMETER;
}
uint8_t *data = (uint8_t *)MOS_AllocAndZeroMemory(size);
CODECHAL_DEBUG_CHK_NULL(data);
// MFX AVC IMG STATE is updated by driver
uint8_t *mfxData = (uint8_t *)(cmdbuffer->pCmdPtr - (m_mfxInterface->GetAvcImgStateSize() / sizeof(uint32_t)));
CODECHAL_DEBUG_CHK_NULL(mfxData);
MOS_SecureMemcpy(data, m_mfxInterface->GetAvcImgStateSize(), mfxData, m_mfxInterface->GetAvcImgStateSize());
// VDENC IMG STATE is updated by SFD kernel
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.ReadOnly = 1;
uint8_t *vdencData = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, &m_batchBufferForVdencImgStat[m_currRecycledBufIdx].OsResource, &lockFlags);
CODECHAL_DEBUG_CHK_NULL(vdencData);
MOS_SecureMemcpy((data + m_mfxInterface->GetAvcImgStateSize()), m_vdencInterface->GetVdencAvcImgStateSize(), vdencData, m_vdencInterface->GetVdencAvcImgStateSize());
m_osInterface->pfnUnlockResource(m_osInterface, &m_batchBufferForVdencImgStat[m_currRecycledBufIdx].OsResource);
CODECHAL_ENCODE_CHK_STATUS_RETURN(m_debugInterface->DumpData(
data,
size,
CodechalDbgAttr::attrImageState,
SurfName.c_str()));
MOS_FreeMemory(data);
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::PopulateHmeParam(
bool is16xMeEnabled,
bool is32xMeEnabled,
uint8_t meMethod,
void * cmd)
{
CODECHAL_DEBUG_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
{
return MOS_STATUS_SUCCESS;
}
CODECHAL_ENCODE_AVC_ME_CURBE *curbe = (CODECHAL_ENCODE_AVC_ME_CURBE *)cmd;
if (m_pictureCodingType == P_TYPE)
{
m_avcPar->SuperHME = is16xMeEnabled;
m_avcPar->UltraHME = is32xMeEnabled;
m_avcPar->SuperCombineDist = curbe->DW6.SuperCombineDist;
m_avcPar->StreamInEnable = is16xMeEnabled;
m_avcPar->StreamInL0FromNewRef = is16xMeEnabled ? 7 : 0;
m_avcPar->StreamInL1FromNewRef = 0;
m_avcPar->MEMethod = meMethod;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::DumpFrameParFile()
{
CODECHAL_DEBUG_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
{
return MOS_STATUS_SUCCESS;
}
std::ostringstream oss;
oss.setf(std::ios::showbase | std::ios::uppercase);
if (m_pictureCodingType == I_TYPE)
{
// I Slice Parameters
// DDI Params
oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl;
oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl;
oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl;
oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl;
oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl;
oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl;
oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl;
oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl;
oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl;
oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl;
oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl;
oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl;
oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl;
oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl;
oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl;
oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl;
oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl;
oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl;
oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl;
oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl;
oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl;
oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl;
oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl;
if (m_avcPar->NumP == 0) // There's no P frame
{
oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
}
oss << "SliceMode = " << std::dec << +m_avcPar->SliceMode << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "MaxNumSlicesCheckEnable = 1" << std::endl;
}
// DS Params
oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl;
// BRC init Params
oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl;
oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl;
oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl;
oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl;
oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl;
oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl;
oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl;
oss << "SlidingWindowRCEnable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl;
oss << "SlidingWindowSize = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl;
oss << "SlidingWindowMaxRateRatio = " << std::dec << +m_avcPar->SlidingWindowMaxRateRatio << std::endl;
oss << "LowDelayGoldenFrameBoost = " << std::dec << +m_avcPar->LowDelayGoldenFrameBoost << std::endl;
oss << "TopQPDeltaThrforAdaptive2Pass = " << std::dec << +m_avcPar->TopQPDeltaThrforAdaptive2Pass << std::endl;
oss << "BotQPDeltaThrforAdaptive2Pass = " << std::dec << +m_avcPar->BotQPDeltaThrforAdaptive2Pass << std::endl;
oss << "TopFrmSzPctThrforAdaptive2Pass = " << std::dec << +m_avcPar->TopFrmSzPctThrforAdaptive2Pass << std::endl;
oss << "BotFrmSzPctThrforAdaptive2Pass = " << std::dec << +m_avcPar->BotFrmSzPctThrforAdaptive2Pass << std::endl;
oss << "MBHeaderCompensation = " << std::dec << +m_avcPar->MBHeaderCompensation << std::endl;
oss << "QPSelectMethodforFirstPass = " << std::dec << +m_avcPar->QPSelectMethodforFirstPass << std::endl;
oss << "MBQpCtrl = " << std::dec << +m_avcPar->MBQpCtrl << std::endl;
oss << "QPMax = " << std::dec << +m_avcPar->QPMax << std::endl;
oss << "QPMin = " << std::dec << +m_avcPar->QPMin << std::endl;
oss << "HrdConformanceCheckDisable = " << std::dec << +m_avcPar->HrdConformanceCheckDisable << std::endl;
oss << "ICQReEncode = " << std::dec << +m_avcPar->ICQReEncode << std::endl;
oss << "AdaptiveCostAdjustEnable = " << std::dec << +m_avcPar->AdaptiveCostAdjustEnable << std::endl;
oss << "AdaptiveHMEExtension = " << std::dec << +m_avcPar->AdaptiveHMEExtension << std::endl;
oss << "StreamInStaticRegion = " << std::dec << +m_avcPar->StreamInStaticRegion << std::endl;
oss << "ScenarioInfo = " << std::dec << +m_avcPar->ScenarioInfo << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "SliceSizeWA = " << std::dec << +m_avcPar->SliceSizeWA << std::endl;
}
// BRC frame update Params
oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl;
oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl;
oss << "SceneChgDetectEn = " << std::dec << +m_avcPar->SceneChgDetectEn << std::endl;
oss << "SceneChgPrevIntraPctThresh = " << std::dec << +m_avcPar->SceneChgPrevIntraPctThresh << std::endl;
oss << "SceneChgCurIntraPctThresh = " << std::dec << +m_avcPar->SceneChgCurIntraPctThresh << std::endl;
oss << "SceneChgWidth0 = " << std::dec << +m_avcPar->SceneChgWidth0 << std::endl;
oss << "SceneChgWidth1 = " << std::dec << +m_avcPar->SceneChgWidth1 << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "SliceSizeThr = " << std::dec << +m_avcPar->SliceSizeThr << std::endl;
oss << "SliceMaxSize = " << std::dec << +m_avcPar->SliceMaxSize << std::endl;
}
// Enc Params
oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl;
oss << "VDEncPerfMode = " << std::dec << +m_avcPar->VDEncPerfMode << std::endl;
// PAK Params
oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl;
oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl;
oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl;
oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl;
oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl;
oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl;
oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl;
oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl;
if (m_avcPar->NumP == 0) // There's no P frame
{
oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
}
oss << "VDEncMode = 1" << std::endl;
oss << "EnableExternalCost = 0" << std::endl;
oss << "EnableNewCost = 1" << std::endl;
oss << "BestDistQPDelta0 = 0" << std::endl;
oss << "BestDistQPDelta1 = 0" << std::endl;
oss << "BestDistQPDelta2 = 0" << std::endl;
oss << "BestDistQPDelta3 = 0" << std::endl;
oss << "BestIntra4x4QPDelta = 0" << std::endl;
oss << "BestIntra8x8QPDelta = 0" << std::endl;
oss << "BestIntra16x16QPDelta = 0" << std::endl;
}
else if (m_pictureCodingType == P_TYPE)
{
// P Slice Parameters
// DDI Params
oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl;
oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl;
oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
if (m_avcPar->NumB == 0) // There's no B frame
{
oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
}
oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl;
if (m_avcPar->WeightedPred)
{
oss << "EnableWeightPredictionDetection = 1" << std::endl;
oss << "FadeDetectionMethod = 1" << std::endl;
}
oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl;
oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl;
oss << "StaticFrameZMVPercent = " << std::dec << +m_avcPar->StaticFrameZMVPercent << std::endl;
oss << "HME0XOffset = " << std::dec << +m_avcPar->hme0XOffset << std::endl;
oss << "HME0YOffset = " << std::dec << +m_avcPar->hme0YOffset << std::endl;
oss << "HME1XOffset = " << std::dec << +m_avcPar->hme1XOffset << std::endl;
oss << "HME1YOffset = " << std::dec << +m_avcPar->hme1YOffset << std::endl;
// HME Params
oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl;
oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl;
oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl;
oss << "StreamInEnable = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInEnable : m_avcPar->StreamInEnable) << std::endl;
oss << "StreamInL0FromNewRef = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInL0FromNewRef : m_avcPar->StreamInL0FromNewRef) << std::endl;
oss << "StreamInL1FromNewRef = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInL1FromNewRef : m_avcPar->StreamInL1FromNewRef) << std::endl;
oss << "MEMethod = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->meMethod : m_avcPar->MEMethod) << std::endl;
// Enc Params
oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl;
oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl;
oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl;
oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl;
oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl;
oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl;
if (m_avcPar->EnableIntraCostScalingForStaticFrame)
{
oss << "IntraCostUpdateMethod = 3" << std::endl;
}
oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl;
oss << "VdencExtPakObjDisable = " << std::dec << +m_avcPar->VdencExtPakObjDisable << std::endl;
oss << "PPMVDisable = " << std::dec << +m_avcPar->PPMVDisable << std::endl;
oss << "AdaptiveMvStreamIn = " << std::dec << +m_avcPar->AdaptiveMvStreamIn << std::endl;
oss << "LargeMvThresh = " << std::dec << +m_avcPar->LargeMvThresh << std::endl;
oss << "LargeMvPctThreshold = " << std::dec << +m_avcPar->LargeMvPctThreshold << std::endl;
// BRC Frame Update
oss << "Transform8x8PDisable = " << std::dec << +m_avcPar->Transform8x8PDisable << std::endl;
// PAK Params
oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl;
oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl;
oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
oss << "AdaptiveRoundingEnabled = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl;
}
else
{
oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl;
}
// Dump per frame par file
const char *fileName = m_debugInterface->CreateFileName(
"EncodeFrame",
"EncodePar",
CodechalDbgExtType::par);
std::ofstream ofs(fileName, std::ios::out);
ofs << oss.str();
ofs.close();
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::DumpSeqParFile()
{
CODECHAL_DEBUG_FUNCTION_ENTER;
CODECHAL_DEBUG_CHK_NULL(m_debugInterface);
if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDumpEncodePar))
{
return MOS_STATUS_SUCCESS;
}
std::ostringstream oss;
oss.setf(std::ios::showbase | std::ios::uppercase);
// I Slice Parameters
// DDI Params
oss << "ProfileIDC = " << std::dec << +m_avcPar->ProfileIDC << std::endl;
oss << "LevelIDC = " << std::dec << +m_avcPar->LevelIDC << std::endl;
oss << "DisableVUIHeader = " << std::dec << +m_avcPar->DisableVUIHeader << std::endl;
oss << "ChromaFormatIDC = " << std::dec << +m_avcPar->ChromaFormatIDC << std::endl;
oss << "ChromaQpOffset = " << std::dec << +m_avcPar->ChromaQpOffset << std::endl;
oss << "SecondChromaQpOffset = " << std::dec << +m_avcPar->SecondChromaQpOffset << std::endl;
oss << "PictureCodingType = " << std::dec << +m_avcPar->PictureCodingType << std::endl;
oss << "NumP = " << std::dec << +m_avcPar->NumP << std::endl;
oss << "NumB = " << std::dec << +m_avcPar->NumB << std::endl;
oss << "NumSlices = " << std::dec << +m_avcPar->NumSlices << std::endl;
oss << "SliceHeight = " << std::dec << +m_avcPar->SliceHeight << std::endl;
oss << "NumSuperSlices = " << std::dec << +m_avcPar->NumSuperSlices << std::endl;
if (m_avcPar->NumSuperSlices)
{
oss << "SuperSliceHeight = ";
uint32_t sliceIdx = 0;
for (; sliceIdx < m_avcPar->NumSuperSlices - 1; sliceIdx++)
{
oss << +m_avcPar->SuperSliceHeight[sliceIdx] << ",";
}
oss << +m_avcPar->SuperSliceHeight[sliceIdx] << std::endl;
}
oss << "ISliceQP = " << std::dec << +m_avcPar->ISliceQP << std::endl;
oss << "FrameRateM = " << std::dec << +m_avcPar->FrameRateM << std::endl;
oss << "FrameRateD = " << std::dec << +m_avcPar->FrameRateD << std::endl;
oss << "BRCMethod = " << std::dec << +m_avcPar->BRCMethod << std::endl;
oss << "BRCType = " << std::dec << +m_avcPar->BRCType << std::endl;
oss << "DeblockingIDC = " << std::dec << +m_avcPar->DeblockingIDC << std::endl;
oss << "DeblockingFilterAlpha = " << std::dec << +m_avcPar->DeblockingFilterAlpha << std::endl;
oss << "DeblockingFilterBeta = " << std::dec << +m_avcPar->DeblockingFilterBeta << std::endl;
oss << "EntropyCodingMode = " << std::dec << +m_avcPar->EntropyCodingMode << std::endl;
oss << "DirectInference = " << std::dec << +m_avcPar->DirectInference << std::endl;
oss << "Transform8x8Mode = " << std::dec << +m_avcPar->Transform8x8Mode << std::endl;
oss << "CRFQualityFactor = " << std::dec << +m_avcPar->CRFQualityFactor << std::endl;
oss << "ConstrainedIntraPred = " << std::dec << +m_avcPar->ConstrainedIntraPred << std::endl;
if (m_avcPar->NumP == 0) // There's no P frame
{
oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
}
oss << "SliceMode = " << std::dec << +m_avcPar->SliceMode << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "MaxNumSlicesCheckEnable = 1" << std::endl;
}
// DS Params
oss << "MBFlatnessThreshold = " << std::dec << +m_encodeParState->m_commonPar->mbFlatnessThreshold << std::endl;
// BRC init Params
oss << "MBBRCEnable = " << std::dec << +m_avcPar->MBBRCEnable << std::endl;
oss << "MBRC = " << std::dec << +m_avcPar->MBRC << std::endl;
oss << "BitRate = " << std::dec << +m_avcPar->BitRate << std::endl;
oss << "InitVbvFullnessInBit = " << std::dec << +m_avcPar->InitVbvFullnessInBit << std::endl;
oss << "MaxBitRate = " << std::dec << +m_avcPar->MaxBitRate << std::endl;
oss << "VbvSzInBit = " << std::dec << +m_avcPar->VbvSzInBit << std::endl;
oss << "UserMaxFrame = " << std::dec << +m_avcPar->UserMaxFrame << std::endl;
oss << "SlidingWindowRCEnable = " << std::dec << +m_avcPar->SlidingWindowEnable << std::endl;
oss << "SlidingWindowSize = " << std::dec << +m_avcPar->SlidingWindowSize << std::endl;
oss << "SlidingWindowMaxRateRatio = " << std::dec << +m_avcPar->SlidingWindowMaxRateRatio << std::endl;
oss << "LowDelayGoldenFrameBoost = " << std::dec << +m_avcPar->LowDelayGoldenFrameBoost << std::endl;
oss << "TopQPDeltaThrforAdaptive2Pass = " << std::dec << +m_avcPar->TopQPDeltaThrforAdaptive2Pass << std::endl;
oss << "BotQPDeltaThrforAdaptive2Pass = " << std::dec << +m_avcPar->BotQPDeltaThrforAdaptive2Pass << std::endl;
oss << "TopFrmSzPctThrforAdaptive2Pass = " << std::dec << +m_avcPar->TopFrmSzPctThrforAdaptive2Pass << std::endl;
oss << "BotFrmSzPctThrforAdaptive2Pass = " << std::dec << +m_avcPar->BotFrmSzPctThrforAdaptive2Pass << std::endl;
oss << "MBHeaderCompensation = " << std::dec << +m_avcPar->MBHeaderCompensation << std::endl;
oss << "QPSelectMethodforFirstPass = " << std::dec << +m_avcPar->QPSelectMethodforFirstPass << std::endl;
oss << "MBQpCtrl = " << std::dec << +m_avcPar->MBQpCtrl << std::endl;
oss << "QPMax = " << std::dec << +m_avcPar->QPMax << std::endl;
oss << "QPMin = " << std::dec << +m_avcPar->QPMin << std::endl;
oss << "HrdConformanceCheckDisable = " << std::dec << +m_avcPar->HrdConformanceCheckDisable << std::endl;
oss << "ICQReEncode = " << std::dec << +m_avcPar->ICQReEncode << std::endl;
oss << "AdaptiveCostAdjustEnable = " << std::dec << +m_avcPar->AdaptiveCostAdjustEnable << std::endl;
oss << "AdaptiveHMEExtension = " << std::dec << +m_avcPar->AdaptiveHMEExtension << std::endl;
oss << "StreamInStaticRegion = " << std::dec << +m_avcPar->StreamInStaticRegion << std::endl;
oss << "ScenarioInfo = " << std::dec << +m_avcPar->ScenarioInfo << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "SliceSizeWA = " << std::dec << +m_avcPar->SliceSizeWA << std::endl;
}
// BRC frame update Params
oss << "EnableMultipass = " << std::dec << +m_avcPar->EnableMultipass << std::endl;
oss << "MaxNumPakPasses = " << std::dec << +m_avcPar->MaxNumPakPasses << std::endl;
oss << "SceneChgDetectEn = " << std::dec << +m_avcPar->SceneChgDetectEn << std::endl;
oss << "SceneChgPrevIntraPctThresh = " << std::dec << +m_avcPar->SceneChgPrevIntraPctThresh << std::endl;
oss << "SceneChgCurIntraPctThresh = " << std::dec << +m_avcPar->SceneChgCurIntraPctThresh << std::endl;
oss << "SceneChgWidth0 = " << std::dec << +m_avcPar->SceneChgWidth0 << std::endl;
oss << "SceneChgWidth1 = " << std::dec << +m_avcPar->SceneChgWidth1 << std::endl;
if (m_avcPar->SliceMode == 2)
{
oss << "SliceSizeThr = " << std::dec << +m_avcPar->SliceSizeThr << std::endl;
oss << "SliceMaxSize = " << std::dec << +m_avcPar->SliceMaxSize << std::endl;
}
// Enc Params
oss << "BlockBasedSkip = " << std::dec << +m_avcPar->BlockBasedSkip << std::endl;
oss << "VDEncPerfMode = " << std::dec << +m_avcPar->VDEncPerfMode << std::endl;
oss << "SubPelMode = " << std::dec << +m_avcPar->SubPelMode << std::endl;
oss << "LeftNbrPelMode = " << std::dec << +m_avcPar->LeftNbrPelMode << std::endl;
oss << "ImePredOverlapThr = " << std::dec << +m_avcPar->ImePredOverlapThr << std::endl;
oss << "MBSizeEstScalingRatioINTRA = " << std::dec << +m_avcPar->MBSizeEstScalingRatioINTRA << std::endl;
oss << "IntraMBHdrScaleFactor = " << std::dec << +m_avcPar->IntraMBHdrScaleFactor << std::endl;
oss << "MBSizeEstScalingRatioINTER = " << std::dec << +m_avcPar->MBSizeEstScalingRatioINTER << std::endl;
oss << "InterMBHdrScaleFactor = " << std::dec << +m_avcPar->InterMBHdrScaleFactor << std::endl;
oss << "HMERefWindowSize = " << std::dec << +m_avcPar->HMERefWindowSize << std::endl;
oss << "IMELeftPredDep = " << std::dec << +m_avcPar->IMELeftPredDep << std::endl;
oss << "NumFMECandCheck = " << std::dec << +m_avcPar->NumFMECandCheck << std::endl;
oss << "RdoChromaEnable = " << std::dec << +m_avcPar->RdoChromaEnable << std::endl;
oss << "Intra4x4ModeMask = " << std::dec << +m_avcPar->Intra4x4ModeMask << std::endl;
oss << "Intra8x8ModeMask = " << std::dec << +m_avcPar->Intra8x8ModeMask << std::endl;
oss << "RdoIntraChromaSearch = " << std::dec << +m_avcPar->RdoIntraChromaSearch << std::endl;
oss << "Intra16x16ModeMask = " << std::dec << +m_avcPar->Intra16x16ModeMask << std::endl;
oss << "InitMBBudgetTr4x4 = " << std::dec << +m_avcPar->InitMBBudgetTr4x4 << std::endl;
oss << "ROIEnable = " << std::dec << +m_avcPar->ROIEnable << std::endl;
oss << "ForceIPCMMinQP = " << std::dec << +m_avcPar->ForceIPCMMinQP << std::endl;
oss << "IntraTr4x4Percent = " << std::dec << +m_avcPar->IntraTr4x4Percent << std::endl;
oss << "IntraPredictionIFrame = " << std::dec << +m_avcPar->IntraPredictionIFrame << std::endl;
oss << "IntraPrediction = " << std::dec << +m_avcPar->IntraPrediction << std::endl;
// PAK Params
oss << "TrellisQuantizationEnable = " << std::dec << +m_avcPar->TrellisQuantizationEnable << std::endl;
oss << "RoundingIntraEnabled = " << std::dec << +m_avcPar->RoundingIntraEnabled << std::endl;
oss << "RoundingIntra = " << std::dec << +m_avcPar->RoundingIntra << std::endl;
oss << "EnableAdaptiveTrellisQuantization = " << std::dec << +m_avcPar->EnableAdaptiveTrellisQuantization << std::endl;
oss << "TrellisQuantizationRounding = " << std::dec << +m_avcPar->TrellisQuantizationRounding << std::endl;
oss << "TrellisQuantizationChromaDisable = " << std::dec << +m_avcPar->TrellisQuantizationChromaDisable << std::endl;
oss << "ExtendedRhoDomainEn = " << std::dec << +m_avcPar->ExtendedRhoDomainEn << std::endl;
oss << "EnableSEI = " << std::dec << +m_avcPar->EnableSEI << std::endl;
if (m_avcPar->NumP == 0) // There's no P frame
{
oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
}
oss << "VDEncMode = 1" << std::endl;
oss << "EnableExternalCost = 0" << std::endl;
oss << "EnableNewCost = 1" << std::endl;
oss << "BestDistQPDelta0 = 0" << std::endl;
oss << "BestDistQPDelta1 = 0" << std::endl;
oss << "BestDistQPDelta2 = 0" << std::endl;
oss << "BestDistQPDelta3 = 0" << std::endl;
oss << "BestIntra4x4QPDelta = 0" << std::endl;
oss << "BestIntra8x8QPDelta = 0" << std::endl;
oss << "BestIntra16x16QPDelta = 0" << std::endl;
if (m_avcPar->NumP > 0)
{
// P Slice Parameters
// DDI Params
oss << "PSliceQP = " << std::dec << +m_avcPar->PSliceQP << std::endl;
oss << "CabacInitIDC = " << std::dec << +m_avcPar->CabacInitIDC << std::endl;
oss << "MaxRefIdxL0 = " << std::dec << +m_avcPar->MaxRefIdxL0 << std::endl;
oss << "MaxRefIdxL1 = " << std::dec << +m_avcPar->MaxRefIdxL1 << std::endl;
if (m_avcPar->NumB == 0) // There's no B frame
{
oss << "EnableWeightPredictionDetection = " << std::dec << +m_avcPar->EnableWeightPredictionDetection << std::endl;
}
oss << "WeightedPred = " << std::dec << +m_avcPar->WeightedPred << std::endl;
oss << "WeightedBiPred = " << std::dec << +m_avcPar->WeightedBiPred << std::endl;
if (m_avcPar->WeightedPred)
{
oss << "EnableWeightPredictionDetection = 1" << std::endl;
oss << "FadeDetectionMethod = 1" << std::endl;
}
oss << "UseOrigAsRef = " << std::dec << +m_avcPar->UseOrigAsRef << std::endl;
oss << "BiSubMbPartMask = " << std::dec << +m_avcPar->BiSubMbPartMask << std::endl;
oss << "StaticFrameZMVPercent = " << std::dec << +m_avcPar->StaticFrameZMVPercent << std::endl;
oss << "HME0XOffset = " << std::dec << +m_avcPar->hme0XOffset << std::endl;
oss << "HME0YOffset = " << std::dec << +m_avcPar->hme0YOffset << std::endl;
oss << "HME1XOffset = " << std::dec << +m_avcPar->hme1XOffset << std::endl;
oss << "HME1YOffset = " << std::dec << +m_avcPar->hme1YOffset << std::endl;
// HME Params
oss << "SuperHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superHME : m_avcPar->SuperHME) << std::endl;
oss << "UltraHME = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->ultraHME : m_avcPar->UltraHME) << std::endl;
oss << "SuperCombineDist = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->superCombineDist : m_avcPar->SuperCombineDist) << std::endl;
oss << "StreamInEnable = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInEnable : m_avcPar->StreamInEnable) << std::endl;
oss << "StreamInL0FromNewRef = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInL0FromNewRef : m_avcPar->StreamInL0FromNewRef) << std::endl;
oss << "StreamInL1FromNewRef = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->streamInL1FromNewRef : m_avcPar->StreamInL1FromNewRef) << std::endl;
oss << "MEMethod = " << std::dec << +(m_useCommonKernel ? m_encodeParState->m_commonPar->meMethod : m_avcPar->MEMethod) << std::endl;
// Enc Params
oss << "FTQBasedSkip = " << std::dec << +m_avcPar->FTQBasedSkip << std::endl;
oss << "BiMixDisable = " << std::dec << +m_avcPar->BiMixDisable << std::endl;
oss << "SurvivedSkipCost = " << std::dec << +m_avcPar->SurvivedSkipCost << std::endl;
oss << "UniMixDisable = " << std::dec << +m_avcPar->UniMixDisable << std::endl;
oss << "EnableIntraCostScalingForStaticFrame = " << std::dec << +m_avcPar->EnableIntraCostScalingForStaticFrame << std::endl;
if (m_avcPar->EnableIntraCostScalingForStaticFrame)
{
oss << "IntraCostUpdateMethod = 3" << std::endl;
}
oss << "StaticFrameIntraCostScalingRatioP = " << std::dec << +m_avcPar->StaticFrameIntraCostScalingRatioP << std::endl;
oss << "VdencExtPakObjDisable = " << std::dec << +m_avcPar->VdencExtPakObjDisable << std::endl;
oss << "PPMVDisable = " << std::dec << +m_avcPar->PPMVDisable << std::endl;
oss << "AdaptiveMvStreamIn = " << std::dec << +m_avcPar->AdaptiveMvStreamIn << std::endl;
oss << "LargeMvThresh = " << std::dec << +m_avcPar->LargeMvThresh << std::endl;
oss << "LargeMvPctThreshold = " << std::dec << +m_avcPar->LargeMvPctThreshold << std::endl;
oss << "DisPSubPartMask = " << std::dec << +m_avcPar->DisPSubPartMask << std::endl;
oss << "DisPSubMbMask = " << std::dec << +m_avcPar->DisPSubMbMask << std::endl;
oss << "PFrameMaxNumImePred = " << std::dec << +m_avcPar->PFrameMaxNumImePred << std::endl;
oss << "PFrameImePredLargeSW = " << std::dec << +m_avcPar->PFrameImePredLargeSW << std::endl;
oss << "PFrameZeroCbfEn = " << std::dec << +m_avcPar->PFrameZeroCbfEn << std::endl;
oss << "DirectMode = " << std::dec << +m_avcPar->DirectMode << std::endl;
oss << "MultiPassHmeEnable = " << std::dec << +m_avcPar->MultiPassHmeEnable << std::endl;
// BRC Frame Update
oss << "Transform8x8PDisable = " << std::dec << +m_avcPar->Transform8x8PDisable << std::endl;
// PAK Params
oss << "RoundingInterEnabled = " << std::dec << +m_avcPar->RoundingInterEnabled << std::endl;
oss << "RoundingInter = " << std::dec << +m_avcPar->RoundingInter << std::endl;
oss << "FrmHdrEncodingFrequency = " << std::dec << +m_avcPar->FrmHdrEncodingFrequency << std::endl;
oss << "AdaptiveRoundingEnabled = " << std::dec << +m_avcPar->EnableAdaptiveRounding << std::endl;
}
if (m_avcPar->NumB > 0)
{
oss << "BSliceQP = " << std::dec << +m_avcPar->BSliceQP << std::endl;
oss << "DisBSubPartMask = " << std::dec << +m_avcPar->DisBSubPartMask << std::endl;
oss << "DisBSubMbMask = " << std::dec << +m_avcPar->DisBSubMbMask << std::endl;
oss << "BFrameMaxNumImePred = " << std::dec << +m_avcPar->BFrameMaxNumImePred << std::endl;
oss << "BFrameImePredLargeSW = " << std::dec << +m_avcPar->BFrameImePredLargeSW << std::endl;
oss << "BFrameZeroCbfEn = " << std::dec << +m_avcPar->BFrameZeroCbfEn << std::endl;
}
const char *fileName = m_debugInterface->CreateFileName(
"EncodeSequence",
"EncodePar",
CodechalDbgExtType::par);
std::ofstream ofs(fileName, std::ios::app);
ofs << oss.str();
ofs.close();
return MOS_STATUS_SUCCESS;
}
MOS_STATUS CodechalVdencAvcState::ModifyEncodedFrameSizeWithFakeHeaderSize( PMOS_COMMAND_BUFFER /*cmdBuffer*/)
{
CODECHAL_ENCODE_FUNCTION_ENTER;
return MOS_STATUS_SUCCESS;
}
#endif