1 /*
2 * Copyright (c) 2021-2024, 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     decode_av1_tile_packet.cpp
24 //! \brief    Defines the interface for av1 decode tile packet
25 //!
26 #include "decode_av1_tile_packet.h"
27 
28 namespace decode
29 {
Init()30     MOS_STATUS Av1DecodeTilePkt::Init()
31     {
32         DECODE_FUNC_CALL();
33 
34         DECODE_CHK_NULL(m_featureManager);
35         DECODE_CHK_NULL(m_hwInterface);
36         DECODE_CHK_NULL(m_osInterface);
37         DECODE_CHK_NULL(m_miItf);
38         DECODE_CHK_NULL(m_av1Pipeline);
39 
40         m_av1BasicFeature = dynamic_cast<Av1BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
41         DECODE_CHK_NULL(m_av1BasicFeature);
42 
43         m_allocator = m_pipeline ->GetDecodeAllocator();
44         DECODE_CHK_NULL(m_allocator);
45 
46         DECODE_CHK_STATUS(CalculateTileStateCommandSize());
47 
48         return MOS_STATUS_SUCCESS;
49     }
50 
Prepare()51     MOS_STATUS Av1DecodeTilePkt::Prepare()
52     {
53         DECODE_FUNC_CALL();
54 
55         DECODE_CHK_NULL(m_av1BasicFeature->m_av1PicParams);
56         DECODE_CHK_NULL(m_av1BasicFeature->m_av1TileParams);
57 
58         m_av1PicParams = m_av1BasicFeature->m_av1PicParams;
59         m_av1TileParams = m_av1BasicFeature->m_av1TileParams;
60 
61         return MOS_STATUS_SUCCESS;
62     }
63 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)64     MOS_STATUS Av1DecodeTilePkt::CalculateCommandSize(uint32_t &commandBufferSize,
65                                                       uint32_t &requestedPatchListSize)
66     {
67         DECODE_FUNC_CALL();
68 
69         commandBufferSize      = m_tileStatesSize;
70         requestedPatchListSize = m_tilePatchListSize;
71 
72         return MOS_STATUS_SUCCESS;
73     }
74 
CalculateTileStateCommandSize()75     MOS_STATUS Av1DecodeTilePkt::CalculateTileStateCommandSize()
76     {
77         DECODE_FUNC_CALL();
78 
79         // Tile Level Commands
80         DECODE_CHK_STATUS(m_hwInterface->GetAvpPrimitiveCommandSize(
81                             m_av1BasicFeature->m_mode,
82                             &m_tileStatesSize,
83                             &m_tilePatchListSize));
84 
85         return MOS_STATUS_SUCCESS;
86     }
87 
MHW_SETPAR_DECL_SRC(AVP_INLOOP_FILTER_STATE,Av1DecodeTilePkt)88     MHW_SETPAR_DECL_SRC(AVP_INLOOP_FILTER_STATE, Av1DecodeTilePkt)
89     {
90         params.loopFilterLevel[0]     = m_av1PicParams->m_filterLevel[0];
91         params.loopFilterLevel[1]     = m_av1PicParams->m_filterLevel[1];
92         params.loopFilterLevel[2]     = m_av1PicParams->m_filterLevelU;
93         params.loopFilterLevel[3]     = m_av1PicParams->m_filterLevelV;
94         params.loopFilterSharpness    = m_av1PicParams->m_loopFilterInfoFlags.m_fields.m_sharpnessLevel;
95         params.loopFilterDeltaEnabled = m_av1PicParams->m_loopFilterInfoFlags.m_fields.m_modeRefDeltaEnabled;
96         params.deltaLfRes             = m_av1PicParams->m_modeControlFlags.m_fields.m_log2DeltaLfRes;
97         params.deltaLfMulti           = m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfMulti;
98         params.loopFilterDeltaUpdate  = m_av1PicParams->m_modeControlFlags.m_fields.m_deltaLfPresentFlag;
99 
100         for (uint8_t i = 0 ; i < 8 ; i++)
101         {
102             //ref_deltas[0..7]
103             params.loopFilterRefDeltas[i] = m_av1PicParams->m_refDeltas[i];
104 
105             //cdef strength
106             params.cdefYStrength[i]       = m_av1PicParams->m_cdefYStrengths[i];
107             params.cdefUVStrength[i]      = m_av1PicParams->m_cdefUvStrengths[i];
108         }
109 
110         params.cdefBits                   = m_av1PicParams->m_cdefBits;
111         params.cdefDampingMinus3          = m_av1PicParams->m_cdefDampingMinus3;
112 
113         //mode_deltas[0..1]
114         params.loopFilterModeDeltas[0]    = m_av1PicParams->m_modeDeltas[0];
115         params.loopFilterModeDeltas[1]    = m_av1PicParams->m_modeDeltas[1];
116 
117         params.LoopRestorationType[0]     = m_av1PicParams->m_loopRestorationFlags.m_fields.m_yframeRestorationType;
118         params.LoopRestorationType[1]     = m_av1PicParams->m_loopRestorationFlags.m_fields.m_cbframeRestorationType;
119         params.LoopRestorationType[2]     = m_av1PicParams->m_loopRestorationFlags.m_fields.m_crframeRestorationType;
120 
121         params.superresUpscaledWidthMinus1 = m_av1PicParams->m_superResUpscaledWidthMinus1;
122         params.superresDenom               = m_av1PicParams->m_picInfoFlags.m_fields.m_useSuperres ?
123                                               m_av1PicParams->m_superresScaleDenominator : 8;
124 
125         //LRU size for Y
126         if (m_av1PicParams->m_loopRestorationFlags.m_fields.m_yframeRestorationType  == 0 &&
127             m_av1PicParams->m_loopRestorationFlags.m_fields.m_cbframeRestorationType == 0 &&
128             m_av1PicParams->m_loopRestorationFlags.m_fields.m_crframeRestorationType == 0)
129         {
130             params.LoopRestorationSizeLuma = 0;
131         }
132         else
133         {
134             params.LoopRestorationSizeLuma = m_av1PicParams->m_loopRestorationFlags.m_fields.m_lrUnitShift + 1;
135         }
136 
137         //LRU size for UV
138         if (m_av1PicParams->m_loopRestorationFlags.m_fields.m_yframeRestorationType == 0  &&
139             m_av1PicParams->m_loopRestorationFlags.m_fields.m_cbframeRestorationType == 0 &&
140             m_av1PicParams->m_loopRestorationFlags.m_fields.m_crframeRestorationType == 0)
141         {
142             params.UseSameLoopRestorationSizeForChroma = 0;
143         }
144         else
145         {
146             params.UseSameLoopRestorationSizeForChroma = (m_av1PicParams->m_loopRestorationFlags.m_fields.m_lrUvShift == 0) ? 1 : 0;
147         }
148 
149         if (m_av1PicParams->m_picInfoFlags.m_fields.m_useSuperres)
150         {
151             //setup super-res step/offset for luma/chroma, per av1_upscale_normative_rows()
152             if (m_av1BasicFeature->m_tileCoding.m_curTile == 0)
153             {
154                 m_av1BasicFeature->m_tileCoding.GetUpscaleConvolveStepX0(*m_av1PicParams, false); // Luma
155                 m_av1BasicFeature->m_tileCoding.GetUpscaleConvolveStepX0(*m_av1PicParams, true);  // Chroma
156             }
157 
158             uint16_t col = m_av1BasicFeature->m_tileCoding.m_tileDesc[m_av1BasicFeature->m_tileCoding.m_curTile].m_tileColumn;
159             params.lumaPlaneXStepQn     = m_av1BasicFeature->m_tileCoding.m_lumaXStepQn;
160             params.lumaPlaneX0Qn        = m_av1BasicFeature->m_tileCoding.m_lumaX0Qn[col];
161             params.chromaPlaneXStepQn   = m_av1BasicFeature->m_tileCoding.m_chromaXStepQn;
162             params.chromaPlaneX0Qn      = m_av1BasicFeature->m_tileCoding.m_chromaX0Qn[col];
163         }
164 
165         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile)
166         {
167             //set to 0 to disable
168             params.loopFilterLevel[2] = 0;
169             params.loopFilterLevel[3] = 0;
170 
171             //ref_deltas[0..7]
172             params.loopFilterRefDeltas[0] = 1;
173             params.loopFilterRefDeltas[1] = 0;
174             params.loopFilterRefDeltas[2] = 0;
175             params.loopFilterRefDeltas[3] = 0;
176             params.loopFilterRefDeltas[4] = 0;
177             params.loopFilterRefDeltas[5] = -1;
178             params.loopFilterRefDeltas[6] = -1;
179             params.loopFilterRefDeltas[7] = -1;
180         }
181 
182         return MOS_STATUS_SUCCESS;
183     }
184 
AddCmd_AVP_TILE_CODING(MOS_COMMAND_BUFFER & cmdBuffer,int16_t tileIdx)185     MOS_STATUS Av1DecodeTilePkt::AddCmd_AVP_TILE_CODING(MOS_COMMAND_BUFFER &cmdBuffer, int16_t tileIdx)
186     {
187         DECODE_FUNC_CALL()
188 
189         auto &par = m_avpItf->MHW_GETPAR_F(AVP_TILE_CODING)();
190         par = {};
191 
192         Av1DecodeTile::TileDesc *m_tileDesc=m_av1BasicFeature->m_tileCoding.m_tileDesc;
193         uint16_t curCol = m_tileDesc[tileIdx].m_tileColumn;
194         uint16_t curRow = m_tileDesc[tileIdx].m_tileRow;
195         uint16_t srcTileId = curCol + curRow * m_av1PicParams->m_tileCols;
196 
197         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile)
198         {
199             DECODE_ASSERT(tileIdx == m_tileDesc[tileIdx].m_tileIndex);
200         }
201 
202         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile)
203         {
204             par.tileId                 = srcTileId;
205             par.tgTileNum              = srcTileId;
206             par.tileGroupId            = 0;
207             par.tileColPositionInSb    = m_av1BasicFeature->m_tileCoding.m_tileColStartSb[curCol];
208             par.tileRowPositionInSb    = m_av1BasicFeature->m_tileCoding.m_tileRowStartSb[curRow];
209             par.tileWidthInSbMinus1    = m_av1PicParams->m_widthInSbsMinus1[curCol];
210             par.tileHeightInSbMinus1   = m_av1PicParams->m_heightInSbsMinus1[curRow];
211             par.tileRowIndependentFlag = true;
212             par.lastTileOfColumn       = (curRow == m_av1PicParams->m_tileRows - 1) ? true : false;
213             par.lastTileOfRow          = (curCol == m_av1PicParams->m_tileCols - 1) ? true : false;
214             par.firstTileOfTileGroup   = (srcTileId == 0) ? true : false;
215             par.lastTileOfTileGroup    = (curCol == m_av1PicParams->m_tileCols - 1) && (curRow == m_av1PicParams->m_tileRows - 1);
216             par.lastTileOfFrame        = (curCol == m_av1PicParams->m_tileCols - 1) && (curRow == m_av1PicParams->m_tileRows - 1);
217         }
218         else
219         {
220             par.tileId                 = tileIdx;
221             par.tgTileNum              = m_tileDesc[tileIdx].m_tileNum;
222             par.tileGroupId            = m_tileDesc[tileIdx].m_tileGroupId;
223             par.tileColPositionInSb    = m_av1BasicFeature->m_tileCoding.m_tileColStartSb[curCol];
224             par.tileRowPositionInSb    = m_av1BasicFeature->m_tileCoding.m_tileRowStartSb[curRow];
225             par.tileWidthInSbMinus1    = m_av1PicParams->m_widthInSbsMinus1[curCol];
226             par.tileHeightInSbMinus1   = m_av1PicParams->m_heightInSbsMinus1[curRow];
227             par.tileRowIndependentFlag = true;
228             par.lastTileOfColumn       = (curRow == m_av1PicParams->m_tileRows - 1) ? true : false;
229             par.lastTileOfRow          = (curCol == m_av1PicParams->m_tileCols - 1) ? true : false;
230             par.firstTileOfTileGroup   = (m_tileDesc[tileIdx].m_tileNum == 0) ? true : false;
231             par.lastTileOfTileGroup    = m_tileDesc[tileIdx].m_lastInGroup;
232             par.lastTileOfFrame        = (curCol == m_av1PicParams->m_tileCols - 1) && (curRow == m_av1PicParams->m_tileRows - 1);
233         }
234 
235         par.disableCdfUpdateFlag             = m_av1PicParams->m_picInfoFlags.m_fields.m_disableCdfUpdate;
236         par.disableFrameContextUpdateFlag    = m_av1PicParams->m_picInfoFlags.m_fields.m_disableFrameEndUpdateCdf
237                                                || (tileIdx != m_av1PicParams->m_contextUpdateTileId);
238         par.numOfActiveBePipes               = 1;
239 
240         if (m_av1PicParams->m_picInfoFlags.m_fields.m_largeScaleTile)
241         {
242             par.numOfTileColumnsInFrame = m_av1PicParams->m_outputFrameWidthInTilesMinus1 + 1;
243             par.numOfTileRowsInFrame    = m_av1PicParams->m_outputFrameHeightInTilesMinus1 + 1;
244             par.outputDecodedTileColPos = (m_tileDesc[tileIdx].m_tileIndex % (m_av1PicParams->m_outputFrameWidthInTilesMinus1 + 1)) *
245                                                            (m_av1PicParams->m_widthInSbsMinus1[0] + 1);  //AV1 Conformance: tile width is identical for all tiles
246             par.outputDecodedTileRowPos = (m_tileDesc[tileIdx].m_tileIndex / (m_av1PicParams->m_outputFrameWidthInTilesMinus1 + 1)); //tile height is exactly one SB
247         }
248         else
249         {
250             par.numOfTileColumnsInFrame = m_av1PicParams->m_tileCols;
251             par.numOfTileRowsInFrame = m_av1PicParams->m_tileRows;
252         }
253 
254         m_av1BasicFeature->m_frameCompletedFlag = par.lastTileOfFrame;
255 
256         DECODE_CHK_STATUS(m_avpItf->MHW_ADDCMD_F(AVP_TILE_CODING)(&cmdBuffer));
257 
258         return MOS_STATUS_SUCCESS;
259     }
260 
AddCmd_AVP_BSD_OBJECT(MOS_COMMAND_BUFFER & cmdBuffer,int16_t tileIdx)261     MOS_STATUS Av1DecodeTilePkt::AddCmd_AVP_BSD_OBJECT(MOS_COMMAND_BUFFER &cmdBuffer, int16_t tileIdx)
262     {
263         DECODE_FUNC_CALL()
264 
265         auto &par = m_avpItf->MHW_GETPAR_F(AVP_BSD_OBJECT)();
266         par = {};
267         Av1DecodeTile::TileDesc *m_tileDesc=m_av1BasicFeature->m_tileCoding.m_tileDesc;
268 
269         par.bsdDataLength = m_tileDesc[tileIdx].m_size;
270         par.bsdDataStartOffset =m_tileDesc[tileIdx].m_offset;
271 
272         DECODE_CHK_STATUS(m_avpItf->MHW_ADDCMD_F(AVP_BSD_OBJECT)(&cmdBuffer));
273 
274         return MOS_STATUS_SUCCESS;
275     }
276 
GetFrameUncompressSize()277     uint32_t Av1DecodeTilePkt::GetFrameUncompressSize()
278     {
279         uint32_t upScaleWidth = m_av1BasicFeature->m_av1PicParams->m_superResUpscaledWidthMinus1 + 1;
280         uint32_t frameHeight = m_av1BasicFeature->m_av1PicParams->m_frameHeightMinus1 + 1;
281         uint32_t picSizeProfileFactor = 0;
282         switch (m_av1BasicFeature->m_av1PicParams->m_profile)
283         {
284         case 0:
285             picSizeProfileFactor = 15;
286             break;
287         case 1:
288             picSizeProfileFactor = 30;
289             break;
290         default:
291             picSizeProfileFactor = 36;
292             break;
293         }
294         // Calculate uncompressed frame size according to spec,
295         // ( UpscaledWidth * FrameHeight * PicSizeProfileFactor ) >> 3
296         return ((upScaleWidth * frameHeight * picSizeProfileFactor) >> 3);
297     }
298 
MHW_SETPAR_DECL_SRC(AVP_FILM_GRAIN_STATE,Av1DecodeTilePkt)299     MHW_SETPAR_DECL_SRC(AVP_FILM_GRAIN_STATE, Av1DecodeTilePkt)
300     {
301         auto filmGrainParams = m_av1PicParams->m_filmGrainParams;
302 
303         params.grainRandomSeed       = filmGrainParams.m_randomSeed;
304         params.clipToRestrictedRange = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_clipToRestrictedRange;
305         params.numOfYPoints          = filmGrainParams.m_numYPoints;
306         params.numOfCbPoints         = filmGrainParams.m_numCbPoints;
307         params.numOfCrPoints         = filmGrainParams.m_numCrPoints;
308         params.matrixCoefficients    = (m_av1PicParams->m_matrixCoefficients == 0) ? 1 : 0;
309         params.grainScalingMinus8    = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_grainScalingMinus8;
310         params.arCoeffLag            = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_arCoeffLag;
311         params.arCoeffShiftMinus6    = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_arCoeffShiftMinus6;
312         params.grainScaleShift       = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_grainScaleShift;
313         params.chromaScalingFromLuma = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_chromaScalingFromLuma;
314         params.grainNoiseOverlap     = filmGrainParams.m_filmGrainInfoFlags.m_fields.m_overlapFlag;
315 
316         MOS_SecureMemcpy(params.pointYValue,
317             sizeof(filmGrainParams.m_pointYValue),
318             filmGrainParams.m_pointYValue,
319             sizeof(filmGrainParams.m_pointYValue)
320         );
321 
322         MOS_SecureMemcpy(params.pointYScaling,
323             sizeof(filmGrainParams.m_pointYScaling),
324             filmGrainParams.m_pointYScaling,
325             sizeof(filmGrainParams.m_pointYScaling)
326         );
327 
328         MOS_SecureMemcpy(params.pointCbValue,
329             sizeof(filmGrainParams.m_pointCbValue),
330             filmGrainParams.m_pointCbValue,
331             sizeof(filmGrainParams.m_pointCbValue)
332         );
333 
334         MOS_SecureMemcpy(params.pointCbScaling,
335             sizeof(filmGrainParams.m_pointCbScaling),
336             filmGrainParams.m_pointCbScaling,
337             sizeof(filmGrainParams.m_pointCbScaling)
338         );
339 
340         MOS_SecureMemcpy(params.pointCrValue,
341             sizeof(filmGrainParams.m_pointCrValue),
342             filmGrainParams.m_pointCrValue,
343             sizeof(filmGrainParams.m_pointCrValue)
344         );
345 
346         MOS_SecureMemcpy(params.pointCrScaling,
347             sizeof(filmGrainParams.m_pointCrScaling),
348             filmGrainParams.m_pointCrScaling,
349             sizeof(filmGrainParams.m_pointCrScaling)
350         );
351 
352         uint32_t i;
353         for (i = 0; i < sizeof(filmGrainParams.m_arCoeffsY) / sizeof(int8_t); i++)
354         {
355             params.arCoeffsY[i] = 128 + filmGrainParams.m_arCoeffsY[i];
356         }
357 
358         for (i = 0; i < sizeof(filmGrainParams.m_arCoeffsCb) / sizeof(int8_t); i++)
359         {
360             params.arCoeffsCb[i] = 128 + filmGrainParams.m_arCoeffsCb[i];
361         }
362 
363         for (i = 0; i < sizeof(filmGrainParams.m_arCoeffsCr) / sizeof(int8_t); i++)
364         {
365             params.arCoeffsCr[i] = 128 + filmGrainParams.m_arCoeffsCr[i];
366         }
367 
368         params.cbMult               = filmGrainParams.m_cbMult;
369         params.cbLumaMult           = filmGrainParams.m_cbLumaMult;
370         params.cbOffset             = filmGrainParams.m_cbOffset;
371         params.crMult               = filmGrainParams.m_crMult;
372         params.crLumaMult           = filmGrainParams.m_crLumaMult;
373         params.crOffset             = filmGrainParams.m_crOffset;
374 
375         return MOS_STATUS_SUCCESS;
376     }
377 
378 
379 }
380