1 /*
2 * Copyright (c) 2020-2021, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file encode_avc_vdenc_weighted_prediction.cpp
24 //! \brief Implemetation for avc weighted prediction feature
25 //!
26
27 #include "encode_avc_vdenc_weighted_prediction.h"
28 #include "encode_avc_vdenc_feature_manager.h"
29
30 namespace encode
31 {
32
AvcVdencWeightedPred(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)33 AvcVdencWeightedPred::AvcVdencWeightedPred(
34 MediaFeatureManager *featureManager,
35 EncodeAllocator *allocator,
36 CodechalHwInterfaceNext *hwInterface,
37 void *constSettings) :
38 MediaFeature(constSettings)
39 {
40 auto encFeatureManager = dynamic_cast<EncodeAvcVdencFeatureManager*>(featureManager);
41 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
42
43 m_basicFeature = dynamic_cast<AvcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
44 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
45 }
46
MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE,AvcVdencWeightedPred)47 MHW_SETPAR_DECL_SRC(VDENC_WEIGHTSOFFSETS_STATE, AvcVdencWeightedPred)
48 {
49 auto picParams = m_basicFeature->m_picParam;
50 auto sliceParams = &m_basicFeature->m_sliceParams[m_basicFeature->m_curNumSlices];
51
52 params.weightsLuma[0][0] = 1;
53 params.weightsLuma[0][1] = 1;
54 params.weightsLuma[0][2] = 1;
55 params.weightsLuma[1][0] = 1;
56
57 if ((Slice_Type[sliceParams->slice_type] == SLICE_P) &&
58 (picParams->weighted_pred_flag == EXPLICIT_WEIGHTED_INTER_PRED_MODE) ||
59 (Slice_Type[sliceParams->slice_type] == SLICE_B) &&
60 (picParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE))
61 {
62 if (picParams->weighted_pred_flag)
63 {
64 params.weightsLuma[0][0] = (int8_t)sliceParams->Weights[0][0][0][0];
65 params.offsetsLuma[0][0] = sliceParams->Weights[0][0][0][1];
66 params.weightsLuma[0][1] = (int8_t)sliceParams->Weights[0][1][0][0];
67 params.offsetsLuma[0][1] = sliceParams->Weights[0][1][0][1];
68 params.weightsLuma[0][2] = (int8_t)sliceParams->Weights[0][2][0][0];
69 params.offsetsLuma[0][2] = sliceParams->Weights[0][2][0][1];
70 }
71
72 if (picParams->weighted_bipred_idc == EXPLICIT_WEIGHTED_INTER_PRED_MODE)
73 {
74 params.weightsLuma[1][0] = (int8_t)sliceParams->Weights[1][0][0][0];
75 params.offsetsLuma[1][0] = sliceParams->Weights[1][0][0][1];
76 }
77 }
78
79 return MOS_STATUS_SUCCESS;
80 }
81
MHW_SETPAR_DECL_SRC(VDENC_AVC_IMG_STATE,AvcVdencWeightedPred)82 MHW_SETPAR_DECL_SRC(VDENC_AVC_IMG_STATE, AvcVdencWeightedPred)
83 {
84 auto picParams = m_basicFeature->m_picParam;
85
86 if (picParams->CodingType == B_TYPE)
87 {
88 if (picParams->weighted_bipred_idc == 2)
89 {
90 params.bidirectionalWeight = (uint8_t)m_basicFeature->m_ref->GetBiWeight();
91 }
92 else
93 {
94 params.bidirectionalWeight = 0x20;
95 }
96 }
97
98 return MOS_STATUS_SUCCESS;
99 }
100
MHW_SETPAR_DECL_SRC(MFX_AVC_WEIGHTOFFSET_STATE,AvcVdencWeightedPred)101 MHW_SETPAR_DECL_SRC(MFX_AVC_WEIGHTOFFSET_STATE, AvcVdencWeightedPred)
102 {
103 auto sliceParams = &m_basicFeature->m_sliceParams[m_basicFeature->m_curNumSlices];
104
105 int32_t uiNumRefForList[2] = {sliceParams->num_ref_idx_l0_active_minus1 + 1, sliceParams->num_ref_idx_l1_active_minus1 + 1};
106
107 for (auto i = 0; i < uiNumRefForList[params.uiList]; i++)
108 {
109 if (sliceParams->luma_weight_flag[params.uiList] & (1 << i))
110 {
111 params.weightoffset[3 * i] = sliceParams->Weights[params.uiList][i][0][0] & 0xFFFF; // Y weight
112 params.weightoffset[3 * i] |= (sliceParams->Weights[params.uiList][i][0][1] & 0xFFFF) << 16; // Y offset
113 }
114 else
115 {
116 params.weightoffset[3 * i] = 1 << (sliceParams->luma_log2_weight_denom); // Y weight
117 }
118
119 if (sliceParams->chroma_weight_flag[params.uiList] & (1 << i))
120 {
121 params.weightoffset[3 * i + 1] = sliceParams->Weights[params.uiList][i][1][0] & 0xFFFF; // Cb weight
122 params.weightoffset[3 * i + 1] |= (sliceParams->Weights[params.uiList][i][1][1] & 0xFFFF) << 16; // Cb offset
123 params.weightoffset[3 * i + 2] = sliceParams->Weights[params.uiList][i][2][0] & 0xFFFF; // Cr weight
124 params.weightoffset[3 * i + 2] |= (sliceParams->Weights[params.uiList][i][2][1] & 0xFFFF) << 16; // Cr offset
125 }
126 else
127 {
128 params.weightoffset[3 * i + 1] = 1 << (sliceParams->chroma_log2_weight_denom); // Cb weight
129 params.weightoffset[3 * i + 2] = 1 << (sliceParams->chroma_log2_weight_denom); // Cr weight
130 }
131 }
132
133 return MOS_STATUS_SUCCESS;
134 }
135
136 } // namespace encode
137