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