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