1 /*
2 * Copyright (c) 2022, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_avc_vdenc_preenc.cpp
24 //! \brief    Defines the common interface for encode avc preenc parameter
25 //!
26 
27 #include "encode_avc_basic_feature.h"
28 #include "encode_avc_vdenc_preenc.h"
29 #include "encode_allocator.h"
30 
31 namespace encode
32 {
AvcVdencPreEnc(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,TrackedBuffer * trackedBuf,RecycleResource * recycleBuf,void * constSettings)33 AvcVdencPreEnc::AvcVdencPreEnc(
34     MediaFeatureManager *featureManager,
35     EncodeAllocator     *allocator,
36     CodechalHwInterfaceNext *hwInterface,
37     TrackedBuffer       *trackedBuf,
38     RecycleResource     *recycleBuf,
39     void                *constSettings) : PreEncBasicFeature(featureManager, allocator, hwInterface, trackedBuf, recycleBuf, constSettings)
40 {
41     ENCODE_FUNC_CALL();
42     auto encFeatureManager = (featureManager);
43     ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
44     m_allocator    = allocator;
45     m_basicFeature = dynamic_cast<AvcBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
46     ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
47 }
48 
~AvcVdencPreEnc()49 AvcVdencPreEnc::~AvcVdencPreEnc()
50 {
51 }
52 
53 // This function may be used by fullenc feature.
54 // Please don't use class member variables in the function.
CalculatePreEncInfo(uint32_t width,uint32_t height,PreEncInfo & preEncInfo)55 MOS_STATUS AvcVdencPreEnc::CalculatePreEncInfo(uint32_t width, uint32_t height, PreEncInfo &preEncInfo)
56 {
57     ENCODE_FUNC_CALL();
58 
59     preEncInfo.EncodePreEncInfo2 = 2;
60     if (width >= 1920 && height >= 1080)
61         preEncInfo.EncodePreEncInfo2 = 2;  //8x8
62     else
63         preEncInfo.EncodePreEncInfo2 = 1;  //8x8
64 
65     preEncInfo.EncodePreEncInfo3 = 0;
66     if (width >= 3840 && height >= 2160)
67         preEncInfo.EncodePreEncInfo3 = 2;  //4x
68     else if (width >= 1920 && height >= 1080)
69         preEncInfo.EncodePreEncInfo3 = 1;  //2x
70 
71     preEncInfo.EncodePreEncInfo0 = 0;
72     if (width >= 3840 && height >= 2160)
73         preEncInfo.EncodePreEncInfo0 = 2;  //4x
74     else if (width >= 1920 && height >= 1080)
75         preEncInfo.EncodePreEncInfo0 = 1;  //2x
76     else
77         preEncInfo.EncodePreEncInfo0 = 0;  //1x
78 
79     //calculate the mv replication factor
80     uint8_t vdencMvRepFactor = MAX(0, (5 - preEncInfo.EncodePreEncInfo2) + (preEncInfo.EncodePreEncInfo0 == 3 ? -1 : preEncInfo.EncodePreEncInfo0) - 4);
81 
82     uint32_t offset          = (1 << preEncInfo.EncodePreEncInfo3) - 1;
83     uint32_t preEncSrcWidth  = (width + offset) >> preEncInfo.EncodePreEncInfo3;
84     uint32_t preEncSrcHeight = (height + offset) >> preEncInfo.EncodePreEncInfo3;
85 
86     preEncSrcWidth  = ((preEncSrcWidth + 7) >> 3) << 3;
87     preEncSrcHeight = ((preEncSrcHeight + 7) >> 3) << 3;
88 
89     preEncInfo.preEncSrcWidth  = preEncSrcWidth;
90     preEncInfo.preEncSrcHeight = preEncSrcHeight;
91 
92     //pitch be 64 aligned and height be 32 aligned
93     uint16_t vdencPreencInfoStride = (uint16_t)((((preEncSrcWidth + 63) >> 6) << 6) >> (5 - preEncInfo.EncodePreEncInfo2));
94     uint16_t vdencPreencInfoHeight = (uint16_t)((((preEncSrcHeight + 63) >> 6) << 6) >> (5 - preEncInfo.EncodePreEncInfo2));
95 
96     vdencPreencInfoStride = ((vdencPreencInfoStride + 7) >> 3) << 3;
97 
98     vdencPreencInfoStride <<= vdencMvRepFactor;
99     vdencPreencInfoHeight <<= vdencMvRepFactor;
100 
101     preEncInfo.EncodePreEncInfo1 = vdencPreencInfoStride * vdencPreencInfoHeight;
102 
103     return MOS_STATUS_SUCCESS;
104 }
105 
PreparePreEncConfig(void * params)106 MOS_STATUS AvcVdencPreEnc::PreparePreEncConfig(void *params)
107 {
108     ENCODE_FUNC_CALL();
109     ENCODE_CHK_NULL_RETURN(params);
110 
111     EncoderParams *encodeParams = (EncoderParams *)params;
112 
113     m_avcSeqParams = static_cast<PCODEC_AVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
114     ENCODE_CHK_NULL_RETURN(m_avcSeqParams);
115     m_avcPicParams = static_cast<PCODEC_AVC_ENCODE_PIC_PARAMS>(encodeParams->pPicParams);
116     ENCODE_CHK_NULL_RETURN(m_avcPicParams);
117     m_avcSliceParams = static_cast<PCODEC_AVC_ENCODE_SLICE_PARAMS>(encodeParams->pSliceParams);
118     ENCODE_CHK_NULL_RETURN(m_avcSliceParams);
119     m_nalUnitParams = encodeParams->ppNALUnitParams;
120     ENCODE_CHK_NULL_RETURN(m_nalUnitParams);
121     m_NumNalUnits = encodeParams->uiNumNalUnits;
122 
123     m_preEncConfig.LowDelayMode         = m_avcSeqParams->LowDelayMode;
124     m_preEncConfig.BitDepthLumaMinus8   = m_avcSeqParams->bit_depth_luma_minus8;
125     m_preEncConfig.BitDepthChromaMinus8 = m_avcSeqParams->bit_depth_chroma_minus8;
126     m_preEncConfig.CodingType           = m_avcPicParams->CodingType;
127     if (m_preEncConfig.CodingType == P_TYPE)
128     {
129         m_preEncConfig.CodingType = B_TYPE;
130         m_preEncConfig.isPToB     = true;
131     }
132     else
133     {
134         m_preEncConfig.isPToB = false;
135     }
136     m_preEncConfig.CurrReconstructedPic = m_avcPicParams->CurrReconstructedPic;
137     for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
138     {
139         m_preEncConfig.RefFrameList[i]    = m_avcPicParams->RefFrameList[i];
140         m_preEncConfig.RefFramePOCList[i] = m_avcPicParams->FieldOrderCntList[i][0] / 2;
141     }
142     for (auto i = 0; i < 2; i++)
143     {
144         for (auto ii = 0; ii < CODEC_MAX_NUM_REF_FRAME_HEVC; ii++)
145         {
146             m_preEncConfig.RefPicList[i][ii] = m_avcSliceParams->RefPicList[i][ii];
147         }
148     }
149     m_preEncConfig.CurrPicOrderCnt  = m_avcPicParams->CurrFieldOrderCnt[0] / 2;
150     m_preEncConfig.HierarchicalFlag = m_avcSeqParams->HierarchicalFlag;
151     m_preEncConfig.GopRefDist       = (uint8_t)m_avcSeqParams->GopRefDist;
152 
153     uint8_t  depth = 0;
154     uint32_t poc   = 0;
155     if (m_preEncConfig.GopRefDist == 0)
156     {
157         return MOS_STATUS_INVALID_PARAMETER;
158     }
159     poc = m_preEncConfig.CurrPicOrderCnt % m_preEncConfig.GopRefDist;
160 
161 
162     if (poc == 0)
163     {
164         depth = 0;
165     }
166     else
167     {
168         uint32_t step = m_preEncConfig.GopRefDist;
169 
170         depth = 0;
171 
172         for (uint32_t ii = step >> 1; ii >= 1; ii >>= 1)
173         {
174             for (uint32_t jj = ii; jj < (uint32_t)m_preEncConfig.GopRefDist; jj += step)
175             {
176                 if (jj == poc)
177                 {
178                     ii = 0;
179                     break;
180                 }
181             }
182 
183             step >>= 1;
184             depth++;
185         }
186     }
187     m_preEncConfig.HierarchLevelPlus1 = depth + 1;
188 
189     ENCODE_CHK_COND_RETURN(m_avcSliceParams->slice_type >= 10, "slice_type cannot bigger than 10.");
190     m_preEncConfig.SliceType       = (uint8_t)HevcSliceType[m_avcSliceParams->slice_type];
191     m_preEncConfig.CurrOriginalPic = m_avcPicParams->CurrOriginalPic;
192     m_preEncConfig.UsedAsRef       = m_avcPicParams->RefPicFlag;
193     m_preEncConfig.InputColorSpace = m_avcSeqParams->InputColorSpace;
194 
195     PCODEC_PIC_ID pAvcPicIdx = m_basicFeature->m_ref->GetPicIndex();
196 
197     for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
198     {
199         m_preEncConfig.PicIdx[i] = pAvcPicIdx[i];
200     }
201 
202     m_preEncConfig.RefList = m_basicFeature->m_ref->GetRefList();
203 
204     return MOS_STATUS_SUCCESS;
205 }
206 
207 }  // namespace encode
208