1 /*
2 * Copyright (c) 2020-2023, 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_vp9_hpu.cpp
24 //! \brief Defines the common interface for vp9 encode hpu (header probability update) features
25 //!
26
27 #include "encode_vp9_hpu.h"
28 #include "encode_vp9_pak.h"
29 #include "encode_vp9_vdenc_feature_manager.h"
30 #include "encode_vp9_vdenc_const_settings.h"
31 #include "media_vp9_packet_defs.h"
32
33 namespace encode
34 {
35 const uint32_t Vp9EncodeHpu::m_probDmem[320] = {
36 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
37 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
38 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
39 0x00000004, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
40 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x0000FF00, 0x00000000, 0x00000000, 0x00000000,
41 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001,
42 0x00540049, 0x00000060, 0x00000072, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
43 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
44 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
45 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
46 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
47 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
48 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
49 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
50 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
51 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
52 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
53 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
54 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
55 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
56 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
57 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
58 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
59 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
60 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
61 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
62 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
63 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
64 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
65 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
66 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
67 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
68 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
69 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
70 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
71 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
72 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
73 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
74 0x00000000, 0x00000000, 0x00000000, 0x02B80078, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
75 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
76 };
77
Vp9EncodeHpu(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)78 Vp9EncodeHpu::Vp9EncodeHpu(
79 MediaFeatureManager *featureManager,
80 EncodeAllocator * allocator,
81 CodechalHwInterfaceNext *hwInterface,
82 void * constSettings)
83 : MediaFeature(constSettings),
84 m_allocator(allocator)
85 {
86 ENCODE_FUNC_CALL();
87 ENCODE_CHK_NULL_NO_STATUS_RETURN(featureManager);
88
89 m_featureManager = featureManager;
90 auto encFeatureManager = dynamic_cast<EncodeVp9VdencFeatureManager *>(featureManager);
91 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager);
92
93 m_basicFeature = dynamic_cast<Vp9BasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature));
94 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
95 }
96
Init(void * settings)97 MOS_STATUS Vp9EncodeHpu::Init(void *settings)
98 {
99 ENCODE_FUNC_CALL();
100
101 m_enabled = true;
102
103 ENCODE_CHK_STATUS_RETURN(AllocateResources());
104
105 return MOS_STATUS_SUCCESS;
106 }
107
Update(void * params)108 MOS_STATUS Vp9EncodeHpu::Update(void *params)
109 {
110 ENCODE_FUNC_CALL();
111 ENCODE_CHK_NULL_RETURN(params);
112
113 EncoderParams *encodeParams = (EncoderParams *)params;
114
115 auto vp9SeqParams = static_cast<PCODEC_VP9_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
116 ENCODE_CHK_NULL_RETURN(vp9SeqParams);
117 auto vp9PicParams = static_cast<PCODEC_VP9_ENCODE_PIC_PARAMS>(encodeParams->pPicParams);
118 ENCODE_CHK_NULL_RETURN(vp9PicParams);
119
120 if (m_basicFeature->m_newSeq)
121 {
122 ENCODE_CHK_STATUS_RETURN(SetConstSettings());
123 }
124
125 // Initialize huc prob dmem buffers in the first pass.
126 for (auto i = 0; i < 3; ++i)
127 {
128 auto dmem = (HucProbDmem *)m_allocator->LockResourceForWrite(
129 &m_resHucProbDmemBuffer[m_basicFeature->m_currRecycledBufIdx][i]);
130 ENCODE_CHK_NULL_RETURN(dmem);
131
132 MOS_SecureMemcpy(dmem, sizeof(HucProbDmem), m_probDmem, sizeof(HucProbDmem));
133
134 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(
135 &m_resHucProbDmemBuffer[m_basicFeature->m_currRecycledBufIdx][i]));
136 }
137
138 return MOS_STATUS_SUCCESS;
139 }
140
SetRegions(mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR & params) const141 MOS_STATUS Vp9EncodeHpu::SetRegions(mhw::vdbox::huc::HUC_VIRTUAL_ADDR_STATE_PAR ¶ms) const
142 {
143 ENCODE_FUNC_CALL();
144
145 auto frameCtxtIdx = m_basicFeature->m_vp9PicParams->PicFlags.fields.frame_context_idx;
146
147 // Input regions: 0,1
148
149 params.regionParams[0].presRegion = const_cast<MOS_RESOURCE *>(&m_resProbBuffer[frameCtxtIdx]);
150 params.regionParams[0].isWritable = true; // Region 0 is both read and write for HuC.
151 // Has input probabilities before running HuC and updated
152 // probabilities after running HuC, which will then be input to next pass
153 params.regionParams[1].presRegion = const_cast<MOS_RESOURCE *>(&m_resProbabilityCounterBuffer);
154 params.regionParams[1].dwOffset = 0;
155
156 // Output regions: 2,3
157 // Final probability output from HuC after each pass
158 params.regionParams[2].presRegion = const_cast<MOS_RESOURCE *>(&m_resHucProbOutputBuffer);
159 params.regionParams[2].isWritable = true;
160 params.regionParams[3].presRegion = const_cast<MOS_RESOURCE *>(&m_resProbabilityDeltaBuffer);
161 params.regionParams[3].isWritable = true;
162
163 return MOS_STATUS_SUCCESS;
164 }
165
GetProbabilityBuffer(uint32_t idx,PMOS_RESOURCE & buffer)166 MOS_STATUS Vp9EncodeHpu::GetProbabilityBuffer(uint32_t idx, PMOS_RESOURCE &buffer)
167 {
168 ENCODE_FUNC_CALL();
169
170 if (idx >= CODEC_VP9_NUM_CONTEXTS)
171 {
172 ENCODE_ASSERTMESSAGE("Index exceeds the max number, when try to get resProbBuffer");
173 return MOS_STATUS_INVALID_PARAMETER;
174 }
175
176 buffer = &m_resProbBuffer[idx];
177
178 return MOS_STATUS_SUCCESS;
179 }
180
GetHucProbDmemBuffer(uint32_t idx,PMOS_RESOURCE & buffer)181 MOS_STATUS Vp9EncodeHpu::GetHucProbDmemBuffer(uint32_t idx, PMOS_RESOURCE &buffer)
182 {
183 ENCODE_FUNC_CALL();
184
185 if (idx >= 3)
186 {
187 ENCODE_ASSERTMESSAGE("Index exceeds the max number, when try to get resHucProbDmemBuffer");
188 return MOS_STATUS_INVALID_PARAMETER;
189 }
190
191 buffer = &m_resHucProbDmemBuffer[m_basicFeature->m_currRecycledBufIdx][idx];
192
193 return MOS_STATUS_SUCCESS;
194 }
195
AllocateResources()196 MOS_STATUS Vp9EncodeHpu::AllocateResources()
197 {
198 ENCODE_FUNC_CALL();
199 ENCODE_CHK_NULL_RETURN(m_basicFeature);
200
201 MOS_RESOURCE *allocatedBuffer = nullptr;
202
203 // Initiate allocation parameters and lock flags
204 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
205 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
206 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
207 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
208 allocParamsForBufferLinear.Format = Format_Buffer;
209
210 // Probability delta buffer
211 allocParamsForBufferLinear.dwBytes = 29 * CODECHAL_CACHELINE_SIZE;
212 allocParamsForBufferLinear.pBufName = "ProbabilityDeltaBuffer";
213 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
214 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
215 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
216 m_resProbabilityDeltaBuffer = *allocatedBuffer;
217
218 // Probability counter buffer
219 allocParamsForBufferLinear.dwBytes = m_probabilityCounterBufferSize * m_basicFeature->m_maxTileNumber;
220 allocParamsForBufferLinear.pBufName = "ProbabilityCounterBuffer";
221 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
222 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
223 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
224 m_resProbabilityCounterBuffer = *allocatedBuffer;
225
226 // Huc Prob DMEM buffer
227 allocParamsForBufferLinear.dwBytes = MOS_ALIGN_CEIL(MOS_MAX(sizeof(HucProbDmem), sizeof(HucProbDmem)), CODECHAL_CACHELINE_SIZE);
228 allocParamsForBufferLinear.pBufName = "HucProbDmemBuffer";
229 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
230 for (auto i = 0; i < CODECHAL_ENCODE_RECYCLED_BUFFER_NUM; ++i)
231 {
232 for (auto j = 0; j < 3; ++j)
233 {
234 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
235 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
236 m_resHucProbDmemBuffer[i][j] = *allocatedBuffer;
237 }
238 }
239
240 // Huc probability output buffer
241 allocParamsForBufferLinear.dwBytes = 32 * CODECHAL_CACHELINE_SIZE;
242 allocParamsForBufferLinear.pBufName = "HucProbabilityOutputBuffer";
243 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ;
244 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
245 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
246 m_resHucProbOutputBuffer = *allocatedBuffer;
247
248 // Probability buffers
249 allocParamsForBufferLinear.dwBytes = 32 * CODECHAL_CACHELINE_SIZE;
250 allocParamsForBufferLinear.pBufName = "ProbabilityBuffer";
251 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE;
252 for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; ++i)
253 {
254 allocatedBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, true);
255 ENCODE_CHK_NULL_RETURN(allocatedBuffer);
256 m_resProbBuffer[i] = *allocatedBuffer;
257 }
258
259 return MOS_STATUS_SUCCESS;
260 }
261
SetIsLastPass(bool isLastPass)262 MOS_STATUS Vp9EncodeHpu::SetIsLastPass(bool isLastPass)
263 {
264 m_isLastPass = isLastPass;
265
266 return MOS_STATUS_SUCCESS;
267 }
268
MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,Vp9EncodeHpu)269 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, Vp9EncodeHpu)
270 {
271 ENCODE_FUNC_CALL();
272
273 auto basicFeature = dynamic_cast<Vp9BasicFeature *>(m_basicFeature);
274 ENCODE_CHK_NULL_RETURN(basicFeature);
275
276 params.presProbabilityDeltaBuffer = const_cast<PMOS_RESOURCE>(&m_resProbabilityDeltaBuffer);
277 params.dwProbabilityDeltaSize = 29 * CODECHAL_CACHELINE_SIZE;
278
279 if (!basicFeature->m_scalableMode)
280 {
281 params.presProbabilityCounterBuffer = const_cast<PMOS_RESOURCE>(&m_resProbabilityCounterBuffer);
282 params.dwProbabilityCounterOffset = 0;
283 params.dwProbabilityCounterSize = 193 * CODECHAL_CACHELINE_SIZE;
284 }
285
286 return MOS_STATUS_SUCCESS;
287 }
288
MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,Vp9EncodeHpu)289 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, Vp9EncodeHpu)
290 {
291 ENCODE_FUNC_CALL();
292
293 // Huc first pass doesn't write probabilities to output prob region but only updates to the input region.
294 // HuC run before repak writes to the ouput region.
295 if (m_basicFeature->m_hucEnabled && m_isLastPass)
296 {
297 params.presVp9ProbBuffer = const_cast<PMOS_RESOURCE>(&m_resHucProbOutputBuffer);
298 }
299 else
300 {
301 auto frameCtxIdx = m_basicFeature->m_vp9PicParams->PicFlags.fields.frame_context_idx;
302 ENCODE_ASSERT(frameCtxIdx < CODEC_VP9_NUM_CONTEXTS);
303 params.presVp9ProbBuffer = const_cast<PMOS_RESOURCE>(&m_resProbBuffer[frameCtxIdx]);
304 }
305
306 return MOS_STATUS_SUCCESS;
307 }
308
SetDefaultTxProbs(uint8_t * ctxBuffer,uint32_t & byteCnt) const309 MOS_STATUS Vp9EncodeHpu::SetDefaultTxProbs(uint8_t *ctxBuffer, uint32_t &byteCnt) const
310 {
311 ENCODE_FUNC_CALL();
312
313 int32_t i, j;
314 // TX probs
315 for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; ++i)
316 {
317 for (j = 0; j < CODEC_VP9_TX_SIZES - 3; ++j)
318 {
319 ctxBuffer[byteCnt++] = DefaultTxProbs.p8x8[i][j];
320 }
321 }
322 for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; ++i)
323 {
324 for (j = 0; j < CODEC_VP9_TX_SIZES - 2; ++j)
325 {
326 ctxBuffer[byteCnt++] = DefaultTxProbs.p16x16[i][j];
327 }
328 }
329 for (i = 0; i < CODEC_VP9_TX_SIZE_CONTEXTS; ++i)
330 {
331 for (j = 0; j < CODEC_VP9_TX_SIZES - 1; ++j)
332 {
333 ctxBuffer[byteCnt++] = DefaultTxProbs.p32x32[i][j];
334 }
335 }
336
337 return MOS_STATUS_SUCCESS;
338 }
339
SetDefaultCoeffProbs(uint8_t * ctxBuffer,uint32_t & byteCnt) const340 MOS_STATUS Vp9EncodeHpu::SetDefaultCoeffProbs(uint8_t *ctxBuffer, uint32_t &byteCnt) const
341 {
342 ENCODE_FUNC_CALL();
343
344 uint8_t blocktype = 0;
345 uint8_t reftype = 0;
346 uint8_t coeffbands = 0;
347 uint8_t unConstrainedNodes = 0;
348 uint8_t prevCoefCtx = 0;
349 // Coeff probs
350 for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; ++blocktype)
351 {
352 for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; ++reftype)
353 {
354 for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; ++coeffbands)
355 {
356 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
357 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; ++prevCoefCtx)
358 {
359 for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; ++unConstrainedNodes)
360 {
361 ctxBuffer[byteCnt++] = DefaultCoefProbs4x4[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
362 }
363 }
364 }
365 }
366 }
367
368 for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; ++blocktype)
369 {
370 for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; ++reftype)
371 {
372 for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; ++coeffbands)
373 {
374 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
375 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; ++prevCoefCtx)
376 {
377 for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; ++unConstrainedNodes)
378 {
379 ctxBuffer[byteCnt++] = DefaultCoefPprobs8x8[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
380 }
381 }
382 }
383 }
384 }
385
386 for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; ++blocktype)
387 {
388 for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; ++reftype)
389 {
390 for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; ++coeffbands)
391 {
392 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
393 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; ++prevCoefCtx)
394 {
395 for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; ++unConstrainedNodes)
396 {
397 ctxBuffer[byteCnt++] = DefaultCoefProbs16x16[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
398 }
399 }
400 }
401 }
402 }
403
404 for (blocktype = 0; blocktype < CODEC_VP9_BLOCK_TYPES; ++blocktype)
405 {
406 for (reftype = 0; reftype < CODEC_VP9_REF_TYPES; ++reftype)
407 {
408 for (coeffbands = 0; coeffbands < CODEC_VP9_COEF_BANDS; ++coeffbands)
409 {
410 uint8_t numPrevCoeffCtxts = (coeffbands == 0) ? 3 : CODEC_VP9_PREV_COEF_CONTEXTS;
411 for (prevCoefCtx = 0; prevCoefCtx < numPrevCoeffCtxts; ++prevCoefCtx)
412 {
413 for (unConstrainedNodes = 0; unConstrainedNodes < CODEC_VP9_UNCONSTRAINED_NODES; ++unConstrainedNodes)
414 {
415 ctxBuffer[byteCnt++] = DefaultCoefProbs32x32[blocktype][reftype][coeffbands][prevCoefCtx][unConstrainedNodes];
416 }
417 }
418 }
419 }
420 }
421
422 return MOS_STATUS_SUCCESS;
423 }
424
SetDefaultMbskipProbs(uint8_t * ctxBuffer,uint32_t & byteCnt) const425 MOS_STATUS Vp9EncodeHpu::SetDefaultMbskipProbs(uint8_t *ctxBuffer, uint32_t &byteCnt) const
426 {
427 ENCODE_FUNC_CALL();
428
429 // mb skip probs
430 for (auto i = 0; i < CODEC_VP9_MBSKIP_CONTEXTS; ++i)
431 {
432 ctxBuffer[byteCnt++] = DefaultMbskipProbs[i];
433 }
434
435 return MOS_STATUS_SUCCESS;
436 }
437
SetDefaultInterModeProbs(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const438 MOS_STATUS Vp9EncodeHpu::SetDefaultInterModeProbs(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
439 {
440 ENCODE_FUNC_CALL();
441
442 int32_t i, j;
443
444 // Inter mode probs
445 for (i = 0; i < CODEC_VP9_INTER_MODE_CONTEXTS; ++i)
446 {
447 for (j = 0; j < CODEC_VP9_INTER_MODES - 1; ++j)
448 {
449 if (!setToKey)
450 {
451 ctxBuffer[byteCnt++] = DefaultInterModeProbs[i][j];
452 }
453 else
454 {
455 // Zeros for key frame
456 byteCnt++;
457 }
458 }
459 }
460
461 return MOS_STATUS_SUCCESS;
462 }
463
SetDefaultSwitchableInterpProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const464 MOS_STATUS Vp9EncodeHpu::SetDefaultSwitchableInterpProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
465 {
466 ENCODE_FUNC_CALL();
467
468 int32_t i, j;
469
470 // Switchable interprediction probs
471 for (i = 0; i < CODEC_VP9_SWITCHABLE_FILTERS + 1; ++i)
472 {
473 for (j = 0; j < CODEC_VP9_SWITCHABLE_FILTERS - 1; ++j)
474 {
475 if (!setToKey)
476 {
477 ctxBuffer[byteCnt++] = DefaultSwitchableInterpProb[i][j];
478 }
479 else
480 {
481 // Zeros for key frame
482 byteCnt++;
483 }
484 }
485 }
486
487 return MOS_STATUS_SUCCESS;
488 }
489
SetDefaultIntraInterProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const490 MOS_STATUS Vp9EncodeHpu::SetDefaultIntraInterProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
491 {
492 ENCODE_FUNC_CALL();
493
494 // Intra inter probs
495 for (auto i = 0; i < CODEC_VP9_INTRA_INTER_CONTEXTS; ++i)
496 {
497 if (!setToKey)
498 {
499 ctxBuffer[byteCnt++] = DefaultIntraInterProb[i];
500 }
501 else
502 {
503 // Zeros for key frame
504 byteCnt++;
505 }
506 }
507
508 return MOS_STATUS_SUCCESS;
509 }
510
SetDefaultCompInterProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const511 MOS_STATUS Vp9EncodeHpu::SetDefaultCompInterProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
512 {
513 ENCODE_FUNC_CALL();
514
515 // Comp inter probs
516 for (auto i = 0; i < CODEC_VP9_COMP_INTER_CONTEXTS; ++i)
517 {
518 if (!setToKey)
519 {
520 ctxBuffer[byteCnt++] = DefaultCompInterProb[i];
521 }
522 else
523 {
524 // Zeros for key frame
525 byteCnt++;
526 }
527 }
528
529 return MOS_STATUS_SUCCESS;
530 }
531
SetDefaultSingleRefProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const532 MOS_STATUS Vp9EncodeHpu::SetDefaultSingleRefProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
533 {
534 ENCODE_FUNC_CALL();
535
536 int32_t i, j;
537
538 // Single ref probs
539 for (i = 0; i < CODEC_VP9_REF_CONTEXTS; ++i)
540 {
541 for (j = 0; j < 2; ++j)
542 {
543 if (!setToKey)
544 {
545 ctxBuffer[byteCnt++] = DefaultSingleRefProb[i][j];
546 }
547 else
548 {
549 // Zeros for key frame
550 byteCnt++;
551 }
552 }
553 }
554
555 return MOS_STATUS_SUCCESS;
556 }
557
SetDefaultCompRefProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const558 MOS_STATUS Vp9EncodeHpu::SetDefaultCompRefProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
559 {
560 ENCODE_FUNC_CALL();
561
562 // Comp ref probs
563 for (auto i = 0; i < CODEC_VP9_REF_CONTEXTS; ++i)
564 {
565 if (!setToKey)
566 {
567 ctxBuffer[byteCnt++] = DefaultCompRefProb[i];
568 }
569 else
570 {
571 // Zeros for key frame
572 byteCnt++;
573 }
574 }
575
576 return MOS_STATUS_SUCCESS;
577 }
578
SetDefaultYModeProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const579 MOS_STATUS Vp9EncodeHpu::SetDefaultYModeProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
580 {
581 ENCODE_FUNC_CALL();
582
583 int32_t i, j;
584
585 // y mode probs
586 for (i = 0; i < CODEC_VP9_BLOCK_SIZE_GROUPS; ++i)
587 {
588 for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; ++j)
589 {
590 if (!setToKey)
591 {
592 ctxBuffer[byteCnt++] = DefaultIFYProb[i][j];
593 }
594 else
595 {
596 // Zeros for key frame, since HW will not use this buffer, but default right buffer
597 byteCnt++;
598 }
599 }
600 }
601
602 return MOS_STATUS_SUCCESS;
603 }
604
SetDefaultPartitionProb(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const605 MOS_STATUS Vp9EncodeHpu::SetDefaultPartitionProb(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
606 {
607 ENCODE_FUNC_CALL();
608
609 int32_t i, j;
610
611 // Partition probs, key & intra-only frames use key type, other inter frames use inter type
612 for (i = 0; i < CODECHAL_VP9_PARTITION_CONTEXTS; ++i)
613 {
614 for (j = 0; j < CODEC_VP9_PARTITION_TYPES - 1; ++j)
615 {
616 if (setToKey)
617 {
618 ctxBuffer[byteCnt++] = DefaultKFPartitionProb[i][j];
619 }
620 else
621 {
622 ctxBuffer[byteCnt++] = DefaultPartitionProb[i][j];
623 }
624 }
625 }
626
627 return MOS_STATUS_SUCCESS;
628 }
629
SetDefaultNmvContext(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const630 MOS_STATUS Vp9EncodeHpu::SetDefaultNmvContext(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
631 {
632 ENCODE_FUNC_CALL();
633
634 int32_t i, j;
635
636 for (i = 0; i < (CODEC_VP9_MV_JOINTS - 1); ++i)
637 {
638 if (!setToKey)
639 {
640 ctxBuffer[byteCnt++] = DefaultNmvContext.joints[i];
641 }
642 else
643 {
644 byteCnt++;
645 }
646 }
647
648 for (i = 0; i < 2; ++i)
649 {
650 if (!setToKey)
651 {
652 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].sign;
653 for (j = 0; j < (CODEC_VP9_MV_CLASSES - 1); ++j)
654 {
655 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].classes[j];
656 }
657 for (j = 0; j < (CODECHAL_VP9_CLASS0_SIZE - 1); ++j)
658 {
659 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0[j];
660 }
661 for (j = 0; j < CODECHAL_VP9_MV_OFFSET_BITS; ++j)
662 {
663 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].bits[j];
664 }
665 }
666 else
667 {
668 byteCnt += 1;
669 byteCnt += (CODEC_VP9_MV_CLASSES - 1);
670 byteCnt += (CODECHAL_VP9_CLASS0_SIZE - 1);
671 byteCnt += (CODECHAL_VP9_MV_OFFSET_BITS);
672 }
673 }
674 for (i = 0; i < 2; ++i)
675 {
676 if (!setToKey)
677 {
678 for (j = 0; j < CODECHAL_VP9_CLASS0_SIZE; ++j)
679 {
680 for (int32_t k = 0; k < (CODEC_VP9_MV_FP_SIZE - 1); ++k)
681 {
682 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_fp[j][k];
683 }
684 }
685 for (j = 0; j < (CODEC_VP9_MV_FP_SIZE - 1); ++j)
686 {
687 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].fp[j];
688 }
689 }
690 else
691 {
692 byteCnt += (CODECHAL_VP9_CLASS0_SIZE * (CODEC_VP9_MV_FP_SIZE - 1));
693 byteCnt += (CODEC_VP9_MV_FP_SIZE - 1);
694 }
695 }
696 for (i = 0; i < 2; ++i)
697 {
698 if (!setToKey)
699 {
700 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].class0_hp;
701 ctxBuffer[byteCnt++] = DefaultNmvContext.comps[i].hp;
702 }
703 else
704 {
705 byteCnt += 2;
706 }
707 }
708
709 return MOS_STATUS_SUCCESS;
710 }
711
SetDefaultUVModeProbs(uint8_t * ctxBuffer,uint32_t & byteCnt,bool setToKey) const712 MOS_STATUS Vp9EncodeHpu::SetDefaultUVModeProbs(uint8_t *ctxBuffer, uint32_t &byteCnt, bool setToKey) const
713 {
714 ENCODE_FUNC_CALL();
715
716 int32_t i, j;
717
718 // uv mode probs
719 for (i = 0; i < CODEC_VP9_INTRA_MODES; ++i)
720 {
721 for (j = 0; j < CODEC_VP9_INTRA_MODES - 1; ++j)
722 {
723 if (setToKey)
724 {
725 ctxBuffer[byteCnt++] = DefaultKFUVModeProb[i][j];
726 }
727 else
728 {
729 ctxBuffer[byteCnt++] = DefaultIFUVProbs[i][j];
730 }
731 }
732 }
733
734 return MOS_STATUS_SUCCESS;
735 }
736
CtxBufDiffInit(uint8_t * ctxBuffer,bool setToKey) const737 MOS_STATUS Vp9EncodeHpu::CtxBufDiffInit(uint8_t *ctxBuffer, bool setToKey) const
738 {
739 ENCODE_FUNC_CALL();
740
741 uint32_t byteCnt = CODEC_VP9_INTER_PROB_OFFSET;
742
743 ENCODE_CHK_STATUS_RETURN(SetDefaultInterModeProbs(ctxBuffer, byteCnt, setToKey));
744
745 ENCODE_CHK_STATUS_RETURN(SetDefaultSwitchableInterpProb(ctxBuffer, byteCnt, setToKey));
746
747 ENCODE_CHK_STATUS_RETURN(SetDefaultIntraInterProb(ctxBuffer, byteCnt, setToKey));
748
749 ENCODE_CHK_STATUS_RETURN(SetDefaultCompInterProb(ctxBuffer, byteCnt, setToKey));
750
751 ENCODE_CHK_STATUS_RETURN(SetDefaultSingleRefProb(ctxBuffer, byteCnt, setToKey));
752
753 ENCODE_CHK_STATUS_RETURN(SetDefaultCompRefProb(ctxBuffer, byteCnt, setToKey));
754
755 ENCODE_CHK_STATUS_RETURN(SetDefaultYModeProb(ctxBuffer, byteCnt, setToKey));
756
757 ENCODE_CHK_STATUS_RETURN(SetDefaultPartitionProb(ctxBuffer, byteCnt, setToKey));
758
759 ENCODE_CHK_STATUS_RETURN(SetDefaultNmvContext(ctxBuffer, byteCnt, setToKey));
760
761 // 47 bytes of zeros
762 byteCnt += 47;
763
764 ENCODE_CHK_STATUS_RETURN(SetDefaultUVModeProbs(ctxBuffer, byteCnt, setToKey));
765
766 return MOS_STATUS_SUCCESS;
767 }
768
ContextBufferInit(uint8_t * ctxBuffer,bool setToKey) const769 MOS_STATUS Vp9EncodeHpu::ContextBufferInit(uint8_t *ctxBuffer, bool setToKey) const
770 {
771 ENCODE_FUNC_CALL();
772
773 MOS_ZeroMemory(ctxBuffer, CODEC_VP9_SEG_PROB_OFFSET);
774
775 uint32_t byteCnt = 0;
776
777 ENCODE_CHK_STATUS_RETURN(SetDefaultTxProbs(ctxBuffer, byteCnt));
778
779 // 52 bytes of zeros
780 byteCnt += 52;
781
782 ENCODE_CHK_STATUS_RETURN(SetDefaultCoeffProbs(ctxBuffer, byteCnt));
783
784 // 16 bytes of zeros
785 byteCnt += 16;
786
787 ENCODE_CHK_STATUS_RETURN(SetDefaultMbskipProbs(ctxBuffer, byteCnt));
788
789 // Populate prob values which are different between Key and Non-Key frame
790 CtxBufDiffInit(ctxBuffer, setToKey);
791
792 // Skip Seg tree/pred probs, updating not done in this function
793 byteCnt = CODEC_VP9_SEG_PROB_OFFSET;
794 byteCnt += 7;
795 byteCnt += 3;
796
797 // 28 bytes of zeros
798 for (auto i = 0; i < 28; i++)
799 {
800 ctxBuffer[byteCnt++] = 0;
801 }
802
803 if (byteCnt > CODEC_VP9_PROB_MAX_NUM_ELEM)
804 {
805 CODECHAL_PUBLIC_ASSERTMESSAGE("Error: FrameContext array out-of-bounds, byteCnt = %d!\n", byteCnt);
806 return MOS_STATUS_NO_SPACE;
807 }
808 else
809 {
810 return MOS_STATUS_SUCCESS;
811 }
812 }
813
PutDataForCompressedHdr(CompressedHeader * compressedHdr,uint32_t bit,uint32_t prob,uint32_t binIdx)814 void Vp9EncodeHpu::PutDataForCompressedHdr(
815 CompressedHeader *compressedHdr,
816 uint32_t bit,
817 uint32_t prob,
818 uint32_t binIdx)
819 {
820 compressedHdr[binIdx].fields.valid = 1;
821 compressedHdr[binIdx].fields.bin_probdiff = 1;
822 compressedHdr[binIdx].fields.bin = bit;
823 compressedHdr[binIdx].fields.prob = (prob == 128) ? 0 : 1;
824 }
825
RefreshFrameInternalBuffers()826 MOS_STATUS Vp9EncodeHpu::RefreshFrameInternalBuffers()
827 {
828 ENCODE_FUNC_CALL();
829 ENCODE_CHK_NULL_RETURN(m_basicFeature);
830 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_vp9PicParams);
831
832 auto hpuFeature = dynamic_cast<Vp9EncodeHpu *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9HpuFeature));
833 ENCODE_CHK_NULL_RETURN(hpuFeature);
834 auto pakFeature = dynamic_cast<Vp9EncodePak *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9PakFeature));
835 ENCODE_CHK_NULL_RETURN(pakFeature);
836
837 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
838
839 auto &picFields = m_basicFeature->m_vp9PicParams->PicFlags.fields;
840 ENCODE_ASSERT(picFields.refresh_frame_context == 0);
841
842 MOS_LOCK_PARAMS lockFlagsWriteOnly;
843 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
844 lockFlagsWriteOnly.WriteOnly = 1;
845
846 bool keyFrame = !picFields.frame_type;
847 bool isScaling = (m_basicFeature->m_oriFrameWidth == m_basicFeature->m_prevFrameInfo.FrameWidth) &&
848 (m_basicFeature->m_oriFrameHeight == m_basicFeature->m_prevFrameInfo.FrameHeight)
849 ? false
850 : true;
851 bool resetSegIdBuf = keyFrame || isScaling ||
852 picFields.error_resilient_mode ||
853 picFields.intra_only;
854
855 if (resetSegIdBuf)
856 {
857 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(m_basicFeature->m_resSegmentIdBuffer);
858 ENCODE_CHK_NULL_RETURN(data);
859
860 MOS_ZeroMemory(data, m_basicFeature->m_picSizeInSb * CODECHAL_CACHELINE_SIZE);
861
862 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(m_basicFeature->m_resSegmentIdBuffer));
863 }
864
865 //refresh inter probs in needed frame context buffers
866 bool clearAll = (keyFrame || picFields.error_resilient_mode ||
867 (picFields.reset_frame_context == 3 && picFields.intra_only));
868
869 bool clearSpecified = (picFields.reset_frame_context == 2 &&
870 picFields.intra_only);
871
872 for (auto i = 0; i < CODEC_VP9_NUM_CONTEXTS; i++)
873 {
874 PMOS_RESOURCE resProbBuffer = nullptr;
875 ENCODE_CHK_STATUS_RETURN(hpuFeature->GetProbabilityBuffer(i, resProbBuffer));
876 ENCODE_CHK_NULL_RETURN(resProbBuffer);
877
878 if (clearAll || (clearSpecified && i == picFields.frame_context_idx))
879 {
880 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(resProbBuffer);
881 ENCODE_CHK_NULL_RETURN(data);
882
883 eStatus = ContextBufferInit(data, keyFrame || picFields.intra_only);
884
885 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(resProbBuffer));
886 ENCODE_CHK_STATUS_RETURN(eStatus);
887
888 m_clearAllToKey[i] = keyFrame || picFields.intra_only;
889 if (i == 0) //reset this flag when Ctx buffer 0 is cleared.
890 {
891 m_isPreCtx0InterProbSaved = false;
892 }
893 }
894 else if (m_clearAllToKey[i]) // this buffer is inside inter frame, but its interProb has not been init to default inter type data.
895 {
896 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(resProbBuffer);
897 ENCODE_CHK_NULL_RETURN(data);
898
899 if (picFields.intra_only && i == 0) // this buffer is used as intra_only context, do not need to set interprob to be inter type.
900 {
901 eStatus = CtxBufDiffInit(data, true);
902 }
903 else // set interprob to be inter type.
904 {
905 eStatus = CtxBufDiffInit(data, false);
906 m_clearAllToKey[i] = false;
907 }
908
909 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(resProbBuffer));
910 ENCODE_CHK_STATUS_RETURN(eStatus);
911 }
912 else if (i == 0) // this buffer do not need to clear in current frame, also it has not been cleared to key type in previous frame.
913 { // in this case, only context buffer 0 will be temporally overwritten.
914 if (picFields.intra_only)
915 {
916 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(resProbBuffer);
917 ENCODE_CHK_NULL_RETURN(data);
918
919 if (!m_isPreCtx0InterProbSaved) // only when non intra-only -> intra-only need save InterProb, otherwise leave saved InterProb unchanged.
920 {
921 //save current interprob
922 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(m_preCtx0InterProbSaved, CODECHAL_VP9_INTER_PROB_SIZE, data + CODEC_VP9_INTER_PROB_OFFSET, CODECHAL_VP9_INTER_PROB_SIZE));
923 m_isPreCtx0InterProbSaved = true;
924 }
925 eStatus = CtxBufDiffInit(data, true);
926 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(resProbBuffer));
927 ENCODE_CHK_STATUS_RETURN(eStatus);
928 }
929 else if (m_isPreCtx0InterProbSaved)
930 {
931 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(resProbBuffer);
932 ENCODE_CHK_NULL_RETURN(data);
933
934 //reload former interprob
935 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(data + CODEC_VP9_INTER_PROB_OFFSET, CODECHAL_VP9_INTER_PROB_SIZE, m_preCtx0InterProbSaved, CODECHAL_VP9_INTER_PROB_SIZE));
936
937 ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(resProbBuffer));
938 m_isPreCtx0InterProbSaved = false;
939 }
940 }
941 }
942
943 // compressed header
944 uint32_t index = 0;
945 auto txMode = m_basicFeature->m_txMode;
946 CompressedHeader *compressedHdr = (CompressedHeader *)MOS_AllocAndZeroMemory(sizeof(CompressedHeader) * (PAK_COMPRESSED_HDR_SYNTAX_ELEMS + 1));
947 ENCODE_CHK_NULL_RETURN(compressedHdr);
948
949 if (!picFields.LosslessFlag)
950 {
951 if (txMode == CODEC_VP9_TX_SELECTABLE)
952 {
953 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX);
954 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1);
955 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_SELECT_IDX);
956 }
957 else if (txMode == CODEC_VP9_TX_32X32)
958 {
959 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX);
960 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_TX_MODE_IDX + 1);
961 PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_TX_MODE_SELECT_IDX);
962 }
963 else
964 {
965 PutDataForCompressedHdr(compressedHdr, (txMode & 0x02) >> 1, 128, PAK_TX_MODE_IDX);
966 PutDataForCompressedHdr(compressedHdr, (txMode & 0x01), 128, PAK_TX_MODE_IDX + 1);
967 }
968
969 if (txMode == CODEC_VP9_TX_SELECTABLE)
970 {
971 index = PAK_TX_8x8_PROB_IDX;
972 for (auto i = 0; i < 2; i++)
973 {
974 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
975 index += 2;
976 }
977
978 index = PAK_TX_16x16_PROB_IDX;
979 for (auto i = 0; i < 2; i++)
980 {
981 for (auto j = 0; j < 2; j++)
982 {
983 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
984 index += 2;
985 }
986 }
987
988 index = PAK_TX_32x32_PROB_IDX;
989 for (auto i = 0; i < 2; i++)
990 {
991 for (auto j = 0; j < 3; j++)
992 {
993 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
994 index += 2;
995 }
996 }
997 }
998 }
999
1000 for (auto coeffSize = 0; coeffSize < 4; coeffSize++)
1001 {
1002 if (coeffSize > txMode)
1003 {
1004 continue;
1005 }
1006
1007 switch (coeffSize)
1008 {
1009 case 0:
1010 index = PAK_TX_4x4_COEFF_PROB_IDX;
1011 break;
1012 case 1:
1013 index = PAK_TX_8x8_COEFF_PROB_IDX;
1014 break;
1015 case 2:
1016 index = PAK_TX_16x16_COEFF_PROB_IDX;
1017 break;
1018 case 3:
1019 index = PAK_TX_32x32_COEFF_PROB_IDX;
1020 break;
1021 }
1022
1023 PutDataForCompressedHdr(compressedHdr, 0, 128, index);
1024 }
1025
1026 PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX);
1027 PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 2);
1028 PutDataForCompressedHdr(compressedHdr, 0, 252, PAK_SKIP_CONTEXT_IDX + 4);
1029
1030 if (picFields.frame_type != 0 && !picFields.intra_only)
1031 {
1032 index = PAK_INTER_MODE_CTX_IDX;
1033 for (auto i = 0; i < 7; i++)
1034 {
1035 for (auto j = 0; j < 3; j++)
1036 {
1037 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1038 index += 2;
1039 }
1040 }
1041
1042 if (picFields.mcomp_filter_type == CODEC_VP9_SWITCHABLE_FILTERS)
1043 {
1044 index = PAK_SWITCHABLE_FILTER_CTX_IDX;
1045 for (auto i = 0; i < 4; i++)
1046 {
1047 for (auto j = 0; j < 2; j++)
1048 {
1049 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1050 index += 2;
1051 }
1052 }
1053 }
1054
1055 index = PAK_INTRA_INTER_CTX_IDX;
1056 for (auto i = 0; i < 4; i++)
1057 {
1058 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1059 index += 2;
1060 }
1061
1062 auto &picRefFields = m_basicFeature->m_vp9PicParams->RefFlags.fields;
1063 bool allowComp = !(
1064 (picRefFields.LastRefSignBias && picRefFields.GoldenRefSignBias && picRefFields.AltRefSignBias) ||
1065 (!picRefFields.LastRefSignBias && !picRefFields.GoldenRefSignBias && !picRefFields.AltRefSignBias));
1066
1067 if (allowComp)
1068 {
1069 if (picFields.comp_prediction_mode == PRED_MODE_HYBRID)
1070 {
1071 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX);
1072 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX + 1);
1073 index = PAK_HYBRID_PRED_CTX_IDX;
1074 for (auto i = 0; i < 5; i++)
1075 {
1076 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1077 index += 2;
1078 }
1079 }
1080 else if (picFields.comp_prediction_mode == PRED_MODE_COMPOUND)
1081 {
1082 PutDataForCompressedHdr(compressedHdr, 1, 128, PAK_COMPOUND_PRED_MODE_IDX);
1083 PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX + 1);
1084 }
1085 else
1086 {
1087 PutDataForCompressedHdr(compressedHdr, 0, 128, PAK_COMPOUND_PRED_MODE_IDX);
1088 }
1089 }
1090
1091 if (picFields.comp_prediction_mode != PRED_MODE_COMPOUND)
1092 {
1093 index = PAK_SINGLE_REF_PRED_CTX_IDX;
1094 for (auto i = 0; i < 5; i++)
1095 {
1096 for (auto j = 0; j < 2; j++)
1097 {
1098 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1099 index += 2;
1100 }
1101 }
1102 }
1103
1104 if (picFields.comp_prediction_mode != PRED_MODE_SINGLE)
1105 {
1106 index = PAK_CMPUND_PRED_CTX_IDX;
1107 for (auto i = 0; i < 5; i++)
1108 {
1109 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1110 index += 2;
1111 }
1112 }
1113
1114 index = PAK_INTRA_MODE_PROB_CTX_IDX;
1115 for (auto i = 0; i < 4; i++)
1116 {
1117 for (auto j = 0; j < 9; j++)
1118 {
1119 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1120 index += 2;
1121 }
1122 }
1123
1124 index = PAK_PARTITION_PROB_IDX;
1125 for (auto i = 0; i < 16; i++)
1126 {
1127 for (auto j = 0; j < 3; j++)
1128 {
1129 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1130 index += 2;
1131 }
1132 }
1133
1134 index = PAK_MVJOINTS_PROB_IDX;
1135 for (auto i = 0; i < 3; i++)
1136 {
1137 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1138 index += 8;
1139 }
1140
1141 for (auto d = 0; d < 2; d++)
1142 {
1143 index = (d == 0) ? PAK_MVCOMP0_IDX : PAK_MVCOMP1_IDX;
1144 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1145 index += 8;
1146 for (auto i = 0; i < 10; i++)
1147 {
1148 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1149 index += 8;
1150 }
1151 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1152 index += 8;
1153 for (auto i = 0; i < 10; i++)
1154 {
1155 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1156 index += 8;
1157 }
1158 }
1159
1160 for (auto d = 0; d < 2; d++)
1161 {
1162 index = (d == 0) ? PAK_MVFRAC_COMP0_IDX : PAK_MVFRAC_COMP1_IDX;
1163 for (auto i = 0; i < 3; i++)
1164 {
1165 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1166 index += 8;
1167 }
1168 for (auto i = 0; i < 3; i++)
1169 {
1170 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1171 index += 8;
1172 }
1173 for (auto i = 0; i < 3; i++)
1174 {
1175 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1176 index += 8;
1177 }
1178 }
1179
1180 if (picFields.allow_high_precision_mv)
1181 {
1182 for (auto d = 0; d < 2; d++)
1183 {
1184 index = (d == 0) ? PAK_MVHP_COMP0_IDX : PAK_MVHP_COMP1_IDX;
1185 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1186 index += 8;
1187 PutDataForCompressedHdr(compressedHdr, 0, 252, index);
1188 }
1189 }
1190 }
1191
1192 PMOS_RESOURCE comprHeaderBuffer = pakFeature->GetCompressedHeaderBuffer();
1193 ENCODE_CHK_NULL_RETURN(comprHeaderBuffer);
1194
1195 uint8_t *data = (uint8_t *)m_allocator->LockResourceForWrite(comprHeaderBuffer);
1196 if (data == nullptr)
1197 {
1198 MOS_FreeMemory(compressedHdr);
1199 ENCODE_CHK_NULL_RETURN(nullptr);
1200 }
1201
1202 for (uint32_t i = 0; i < PAK_COMPRESSED_HDR_SYNTAX_ELEMS; i += 2)
1203 {
1204 data[i >> 1] = (compressedHdr[i + 1].value << 0x04) | (compressedHdr[i].value);
1205 }
1206
1207 eStatus = m_allocator->UnLock(comprHeaderBuffer);
1208 if (eStatus != MOS_STATUS_SUCCESS)
1209 {
1210 MOS_FreeMemory(compressedHdr);
1211 ENCODE_CHK_STATUS_RETURN(eStatus);
1212 }
1213
1214 MOS_FreeMemory(compressedHdr);
1215 return eStatus;
1216 }
1217
1218 } // namespace encode
1219