1 /*
2 * Copyright (c) 2017-2019, 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     codechal_decode_sfc_vp9_g12.cpp
24 //! \brief    Implements the decode interface extension for CSC and scaling via SFC for VP9 decoder for G12+ platform.
25 //! \details  Downsampling in this case is supported by the SFC fixed function HW unit.
26 //!
27 
28 #include "codechal_decode_sfc_vp9_g12.h"
29 
CodechalVp9SfcStateG12()30 CodechalVp9SfcStateG12::CodechalVp9SfcStateG12()
31 {
32     CODECHAL_HW_FUNCTION_ENTER;
33 
34     MOS_ZeroMemory(&m_vp9PicParams, sizeof(m_vp9PicParams));
35     MOS_ZeroMemory(&m_scalabilityState, sizeof(m_scalabilityState));
36 }
37 
~CodechalVp9SfcStateG12()38 CodechalVp9SfcStateG12::~CodechalVp9SfcStateG12()
39 {
40     CODECHAL_HW_FUNCTION_ENTER;
41 
42     // Free AVS Line Buffer
43     if (m_resAvsLineBuffers)
44     {
45         for (int i = 0; i < m_numBuffersAllocated; i++)
46         {
47             m_osInterface->pfnFreeResource(m_osInterface, m_resAvsLineBuffers + i);
48         }
49         MOS_FreeMemory(m_resAvsLineBuffers);
50         m_resAvsLineBuffers = nullptr;
51     }
52     // Free SFD Line Buffer
53     if (m_resSfdLineBuffers)
54     {
55         for (int i = 0; i < m_numBuffersAllocated; i++)
56         {
57             m_osInterface->pfnFreeResource(m_osInterface, m_resSfdLineBuffers + i);
58         }
59         MOS_FreeMemory(m_resSfdLineBuffers);
60         m_resSfdLineBuffers = nullptr;
61     }
62     // Free AVS Line Tile Buffer
63     m_osInterface->pfnFreeResource(m_osInterface, &m_resAvsLineTileBuffer);
64     // Free SFD Line Tile Buffer
65     m_osInterface->pfnFreeResource(m_osInterface, &m_resSfdLineTileBuffer);
66 }
67 
AllocateResources()68 MOS_STATUS CodechalVp9SfcStateG12::AllocateResources()
69 {
70     if (m_numBuffersAllocated < m_numPipe)
71     {
72         // Allocate AVS line buffer for input row store
73         if (m_resAvsLineBuffers)
74         {
75             for (int i = 0; i < m_numBuffersAllocated; i++)
76             {
77                 m_osInterface->pfnFreeResource(m_osInterface, m_resAvsLineBuffers + i);
78             }
79             MOS_FreeMemory(m_resAvsLineBuffers);
80             m_resAvsLineBuffers = nullptr;
81         }
82         if (m_resAvsLineBuffers == nullptr)
83         {
84             m_resAvsLineBuffers = (MOS_RESOURCE *)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * m_numPipe);
85             CODECHAL_HW_CHK_NULL_RETURN(m_resAvsLineBuffers);
86 
87             MOS_ALLOC_GFXRES_PARAMS allocParams;
88             MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
89             allocParams.Type = MOS_GFXRES_BUFFER;
90             allocParams.TileType = MOS_TILE_LINEAR;
91             allocParams.Format = Format_Buffer;
92             allocParams.dwBytes = MOS_ROUNDUP_DIVIDE(m_inputFrameWidth, 8) * 6 * MHW_SFC_CACHELINE_SIZE;
93             allocParams.pBufName = "SfcAvsLineBuffer";
94 
95             for (int i = 0; i < m_numPipe; i++)
96             {
97                 CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
98                     m_osInterface,
99                     &allocParams,
100                     m_resAvsLineBuffers + i));
101             }
102         }
103 
104         // Allocate SFD line buffer for output row store, needed for 420
105         if (m_resSfdLineBuffers)
106         {
107             for (int i = 0; i < m_numBuffersAllocated; i++)
108             {
109                 m_osInterface->pfnFreeResource(m_osInterface, m_resSfdLineBuffers + i);
110             }
111             MOS_FreeMemory(m_resSfdLineBuffers);
112             m_resSfdLineBuffers = nullptr;
113         }
114         if (m_resSfdLineBuffers == nullptr)
115         {
116             m_resSfdLineBuffers = (MOS_RESOURCE *)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * m_numPipe);
117             CODECHAL_HW_CHK_NULL_RETURN(m_resSfdLineBuffers);
118 
119             MOS_ALLOC_GFXRES_PARAMS allocParams;
120             MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
121             allocParams.Type = MOS_GFXRES_BUFFER;
122             allocParams.TileType = MOS_TILE_LINEAR;
123             allocParams.Format = Format_Buffer;
124             allocParams.dwBytes = MOS_ROUNDUP_DIVIDE(m_outputSurfaceRegion.Width, 10) * MHW_SFC_CACHELINE_SIZE;
125             allocParams.pBufName = "SfcSfdLineBuffer";
126 
127             for (int i = 0; i < m_numPipe; i++)
128             {
129                 CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
130                     m_osInterface,
131                     &allocParams,
132                     m_resSfdLineBuffers + i));
133             }
134         }
135         m_numBuffersAllocated = m_numPipe;
136     }
137 
138     // Allocate IEF line buffer - no IEF for HCP SFC
139 
140     // Allocate AVS line tile buffer for input column store
141     if (Mos_ResourceIsNull(&m_resAvsLineTileBuffer))
142     {
143         MOS_ALLOC_GFXRES_PARAMS allocParams;
144         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
145         allocParams.Type = MOS_GFXRES_BUFFER;
146         allocParams.TileType = MOS_TILE_LINEAR;
147         allocParams.Format = Format_Buffer;
148         allocParams.dwBytes = MOS_ROUNDUP_DIVIDE(m_inputFrameHeight, 8) * 6 * MHW_SFC_CACHELINE_SIZE * 2; //double for safe
149         allocParams.pBufName = "SfcAvsLineTileBuffer";
150 
151         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
152             m_osInterface,
153             &allocParams,
154             &m_resAvsLineTileBuffer));
155     }
156     // Allocate SFD line tile buffer for output column store
157     if (Mos_ResourceIsNull(&m_resSfdLineTileBuffer))
158     {
159         MOS_ALLOC_GFXRES_PARAMS allocParams;
160         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
161         allocParams.Type = MOS_GFXRES_BUFFER;
162         allocParams.TileType = MOS_TILE_LINEAR;
163         allocParams.Format = Format_Buffer;
164         allocParams.dwBytes = MOS_ROUNDUP_DIVIDE(m_outputSurfaceRegion.Width, 10) * MHW_SFC_CACHELINE_SIZE * 2; //double for safe
165         allocParams.pBufName = "SfcSfdLineTileBuffer";
166 
167         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
168             m_osInterface,
169             &allocParams,
170             &m_resSfdLineTileBuffer));
171     }
172 
173     //Initialize AVS parameters, try to do once
174     if (m_scaling && !m_avsParams.piYCoefsX)
175     {
176         m_avsParams.Format = Format_None;
177         m_avsParams.fScaleX = 0.0F;
178         m_avsParams.fScaleY = 0.0F;
179         m_avsParams.piYCoefsX = nullptr;
180 
181         uint32_t ycoeffTableSize = POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9;
182         uint32_t uvcoeffTableSize = POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9;
183 
184         int32_t size = (ycoeffTableSize + uvcoeffTableSize) * 2;
185 
186         uint8_t *ptr = (uint8_t*)MOS_AllocAndZeroMemory(size);
187         CODECHAL_DECODE_CHK_NULL_RETURN(ptr);
188 
189         m_avsParams.piYCoefsX = (int32_t *)ptr;
190 
191         ptr += ycoeffTableSize;
192         m_avsParams.piUVCoefsX = (int32_t *)ptr;
193 
194         ptr += uvcoeffTableSize;
195         m_avsParams.piYCoefsY = (int32_t *)ptr;
196 
197         ptr += ycoeffTableSize;
198         m_avsParams.piUVCoefsY = (int32_t *)ptr;
199     }
200 
201     return MOS_STATUS_SUCCESS;
202 }
203 
CheckAndInitialize(PCODECHAL_DECODE_PROCESSING_PARAMS decProcessingParams,PCODEC_VP9_PIC_PARAMS vp9PicParams,PCODECHAL_DECODE_SCALABILITY_STATE scalabilityState)204 MOS_STATUS CodechalVp9SfcStateG12::CheckAndInitialize(
205     PCODECHAL_DECODE_PROCESSING_PARAMS  decProcessingParams,
206     PCODEC_VP9_PIC_PARAMS               vp9PicParams,
207     PCODECHAL_DECODE_SCALABILITY_STATE  scalabilityState)
208 {
209     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
210 
211     CODECHAL_HW_FUNCTION_ENTER;
212 
213     if (decProcessingParams)
214     {
215         if (IsSfcOutputSupported(decProcessingParams, MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP))
216         {
217             m_sfcPipeOut        = true;
218             m_vp9PicParams      = vp9PicParams;
219             m_scalabilityState  = static_cast<PCODECHAL_DECODE_SCALABILITY_STATE_G12>(scalabilityState);
220             m_numPipe           = m_scalabilityState ? m_scalabilityState->ucScalablePipeNum : 1;
221 
222             m_histogramSurface = decProcessingParams->pHistogramSurface;
223 
224             // Set the input region as the HCP output frame region
225             m_inputFrameWidth                                = MOS_ALIGN_CEIL(m_vp9PicParams->FrameWidthMinus1 + 1, CODEC_VP9_MIN_BLOCK_WIDTH);
226             m_inputFrameHeight                               = MOS_ALIGN_CEIL(m_vp9PicParams->FrameHeightMinus1 + 1, CODEC_VP9_MIN_BLOCK_HEIGHT);
227             decProcessingParams->rcInputSurfaceRegion.X = 0;
228             decProcessingParams->rcInputSurfaceRegion.Y = 0;
229             decProcessingParams->rcInputSurfaceRegion.Width  = m_inputFrameWidth;
230             decProcessingParams->rcInputSurfaceRegion.Height = m_inputFrameHeight;
231 
232             CODECHAL_HW_CHK_STATUS_RETURN(Initialize(decProcessingParams, MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP));
233 
234             if(m_decoder)
235             {
236                 m_decoder->SetVdSfcSupportedFlag(true);
237             }
238         }
239         else
240         {
241             if(m_decoder)
242             {
243                 m_decoder->SetVdSfcSupportedFlag(false);
244             }
245         }
246     }
247 
248     return eStatus;
249 }
250 
IsSfcFormatSupported(MOS_FORMAT inputFormat,MOS_FORMAT outputFormat)251 bool CodechalVp9SfcStateG12::IsSfcFormatSupported(
252     MOS_FORMAT   inputFormat,
253     MOS_FORMAT   outputFormat)
254 {
255     if ((inputFormat != Format_NV12) &&
256         (inputFormat != Format_400P) &&
257         (inputFormat != Format_IMC3) &&
258         (inputFormat != Format_422H) &&
259         (inputFormat != Format_444P) &&
260         (inputFormat != Format_P010) &&
261         (inputFormat != Format_YUY2) &&
262         (inputFormat != Format_AYUV) &&
263         (inputFormat != Format_Y210) &&
264         (inputFormat != Format_Y410) &&
265         (inputFormat != Format_P016) &&
266         (inputFormat != Format_Y216) &&
267         (inputFormat != Format_Y416))
268     {
269         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Input Format '0x%08x' for SFC.", inputFormat);
270         return false;
271     }
272 
273     if ((outputFormat != Format_A8R8G8B8) &&
274         (outputFormat != Format_NV12) &&
275         (outputFormat != Format_P010) &&
276         (outputFormat != Format_YUY2) &&
277         (outputFormat != Format_AYUV) &&
278         (outputFormat != Format_P016) &&
279         (outputFormat != Format_Y210) &&
280         (outputFormat != Format_Y216) &&
281         (outputFormat != Format_Y410) &&
282         (outputFormat != Format_Y416))
283     {
284         CODECHAL_DECODE_ASSERTMESSAGE("Unsupported Output Format '0x%08x' for SFC.", outputFormat);
285         return false;
286     }
287     return true;
288 }
289 
UpdateInputInfo(PMHW_SFC_STATE_PARAMS sfcStateParams)290 MOS_STATUS CodechalVp9SfcStateG12::UpdateInputInfo(
291     PMHW_SFC_STATE_PARAMS   sfcStateParams)
292 {
293     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
294 
295     CODECHAL_HW_FUNCTION_ENTER;
296 
297     CODECHAL_HW_CHK_NULL_RETURN(sfcStateParams);
298     CODECHAL_HW_CHK_NULL_RETURN(m_vp9PicParams);
299 
300     uint32_t  chromaIdc = (m_vp9PicParams->subsampling_x == 0 && m_vp9PicParams->subsampling_y == 0) ? HCP_CHROMA_FORMAT_YUV444 : HCP_CHROMA_FORMAT_YUV420;
301 
302     PMHW_SFC_STATE_PARAMS_G12 sfcStateParamsG12 = static_cast<PMHW_SFC_STATE_PARAMS_G12>(sfcStateParams);
303 
304     sfcStateParamsG12->sfcPipeMode                = MhwSfcInterfaceG12::SFC_PIPE_MODE_HCP;
305     sfcStateParamsG12->dwAVSFilterMode            = MEDIASTATE_SFC_AVS_FILTER_8x8;
306     sfcStateParamsG12->dwVDVEInputOrderingMode    = MhwSfcInterfaceG12::LCU_64_64_VP9;
307     sfcStateParamsG12->dwInputChromaSubSampling   = (HCP_CHROMA_FORMAT_YUV444 == chromaIdc) ? 4 : 1;
308     sfcStateParamsG12->dwInputFrameWidth          = m_inputFrameWidth;
309     sfcStateParamsG12->dwInputFrameHeight         = m_inputFrameHeight;
310     if (m_sfcOutputSurface->Format == Format_NV12 ||
311         m_sfcOutputSurface->Format == Format_P010 ||
312         m_sfcOutputSurface->Format == Format_P016)
313     {
314         sfcStateParams->dwChromaDownSamplingHorizontalCoef = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
315         sfcStateParams->dwChromaDownSamplingVerticalCoef = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
316     }
317     else if (m_sfcOutputSurface->Format == Format_YUY2 ||
318         m_sfcOutputSurface->Format == Format_Y210 ||
319         m_sfcOutputSurface->Format == Format_Y216)
320     {
321         sfcStateParams->dwChromaDownSamplingHorizontalCoef = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 : MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
322         sfcStateParams->dwChromaDownSamplingVerticalCoef = 0;
323     }
324     else
325     {
326         sfcStateParamsG12->dwChromaDownSamplingHorizontalCoef = 0;
327         sfcStateParamsG12->dwChromaDownSamplingVerticalCoef = 0;
328     }
329 
330     sfcStateParamsG12->inputBitDepth              = 0;
331     if (m_inputSurface)
332     {
333         if (m_inputSurface->Format == Format_P010 ||
334             m_inputSurface->Format == Format_Y210 ||
335             m_inputSurface->Format == Format_Y410)
336         {
337             sfcStateParamsG12->inputBitDepth = 1;
338         }
339         else if (m_inputSurface->Format == Format_P016 ||
340                  m_inputSurface->Format == Format_Y216 ||
341                  m_inputSurface->Format == Format_Y416)
342         {
343             sfcStateParamsG12->inputBitDepth = 2;
344         }
345     }
346 
347     // Scalability parameters
348     if (CodecHalDecodeScalabilityIsScalableMode(m_scalabilityState))
349     {
350         CODECHAL_DECODE_SFC_SCALABILITY_PARAMS  sfcScalaParams;
351 
352         MOS_ZeroMemory(&sfcScalaParams, sizeof(sfcScalaParams));
353         CODECHAL_HW_CHK_STATUS_RETURN(CodecHalDecodeScalability_SetSfcState(
354             m_scalabilityState,
355             m_vp9PicParams,
356             &m_inputSurfaceRegion,
357             &m_outputSurfaceRegion,
358             &sfcScalaParams));
359         sfcStateParamsG12->engineMode   = sfcScalaParams.engineMode;
360         sfcStateParamsG12->tileType     = sfcScalaParams.tileType;
361         sfcStateParamsG12->srcStartX    = sfcScalaParams.srcStartX;
362         sfcStateParamsG12->srcEndX      = sfcScalaParams.srcEndX;
363         sfcStateParamsG12->dstStartX    = sfcScalaParams.dstStartX;
364         sfcStateParamsG12->dstEndX      = sfcScalaParams.dstEndX;;
365 
366         if (m_scalabilityState->bIsRtMode)
367         {
368             m_curPipe = m_scalabilityState->u8RtCurPipe;
369         }
370         else if (CodecHalDecodeScalabilityIsBEPhaseG12(m_scalabilityState))
371         {
372             m_curPipe = m_scalabilityState->HcpDecPhase - CODECHAL_HCP_DECODE_PHASE_BE0;
373         }
374         else
375         {
376             m_curPipe = 0;
377         }
378     }
379 
380     sfcStateParamsG12->histogramSurface = m_histogramSurface;
381 
382     return eStatus;
383 }
384 
AddSfcCommands(PMOS_COMMAND_BUFFER cmdBuffer)385 MOS_STATUS CodechalVp9SfcStateG12::AddSfcCommands(
386     PMOS_COMMAND_BUFFER             cmdBuffer)
387 {
388     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
389 
390     CODECHAL_HW_FUNCTION_ENTER;
391 
392     CODECHAL_HW_CHK_NULL_RETURN(cmdBuffer);
393 
394     if (m_sfcPipeOut == false)
395     {
396         return eStatus;
397     }
398 
399     MHW_SFC_LOCK_PARAMS sfcLockParams;
400     MOS_ZeroMemory(&sfcLockParams, sizeof(sfcLockParams));
401 
402     sfcLockParams.sfcPipeMode = m_sfcPipeMode;
403     sfcLockParams.bOutputToMemory = ((MhwSfcInterface::SFC_PIPE_MODE_VEBOX != m_sfcPipeMode) && !m_jpegInUse);
404 
405     MHW_SFC_STATE_PARAMS_G12 sfcStateParams;
406     MOS_ZeroMemory(&sfcStateParams, sizeof(sfcStateParams));
407     MHW_SFC_OUT_SURFACE_PARAMS sfcOutSurfaceParams;
408     MOS_ZeroMemory(&sfcOutSurfaceParams, sizeof(sfcOutSurfaceParams));
409     CODECHAL_HW_CHK_STATUS_RETURN(SetSfcStateParams(&sfcStateParams, &sfcOutSurfaceParams));
410 
411     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcLock(cmdBuffer, &sfcLockParams));
412     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcState(cmdBuffer, &sfcStateParams, &sfcOutSurfaceParams));
413 
414     if (m_scaling)
415     {
416         CODECHAL_HW_CHK_STATUS_RETURN(SetSfcAvsStateParams());
417         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsState(cmdBuffer, &m_avsState));
418         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsLumaTable(cmdBuffer, &m_lumaTable));
419         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcAvsChromaTable(cmdBuffer, &m_chromaTable));
420     }
421 
422     if (m_csc)
423     {
424         MHW_SFC_IEF_STATE_PARAMS sfcIefStateParams;
425         MOS_ZeroMemory(&sfcIefStateParams, sizeof(sfcIefStateParams));
426         CODECHAL_HW_CHK_STATUS_RETURN(SetSfcIefStateParams(&sfcIefStateParams));
427         CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcIefState(cmdBuffer, &sfcIefStateParams));
428     }
429 
430     CODECHAL_HW_CHK_STATUS_RETURN(m_sfcInterface->AddSfcFrameStart(cmdBuffer, m_sfcPipeMode));
431 
432     return eStatus;
433 }
434 
SetSfcStateParams(PMHW_SFC_STATE_PARAMS sfcStateParams,PMHW_SFC_OUT_SURFACE_PARAMS outSurfaceParams)435 MOS_STATUS CodechalVp9SfcStateG12::SetSfcStateParams(
436     PMHW_SFC_STATE_PARAMS               sfcStateParams,
437     PMHW_SFC_OUT_SURFACE_PARAMS         outSurfaceParams)
438 {
439     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
440 
441     CODECHAL_HW_FUNCTION_ENTER;
442 
443     CODECHAL_HW_CHK_STATUS_RETURN(CodechalSfcState::SetSfcStateParams(sfcStateParams, outSurfaceParams));
444 
445     PMHW_SFC_STATE_PARAMS_G12 sfcStateParamsG12 = static_cast<PMHW_SFC_STATE_PARAMS_G12>(sfcStateParams);
446     sfcStateParamsG12->pOsResAVSLineBuffer = m_resAvsLineBuffers + m_curPipe;
447     sfcStateParamsG12->resSfdLineBuffer = m_resSfdLineBuffers + m_curPipe;
448     sfcStateParamsG12->resAvsLineTileBuffer = &m_resAvsLineTileBuffer;
449     sfcStateParamsG12->resSfdLineTileBuffer = &m_resSfdLineTileBuffer;
450 
451     // Force output frame size same as output region size
452     sfcStateParamsG12->dwOutputFrameWidth = sfcStateParamsG12->dwScaledRegionWidth;
453     sfcStateParamsG12->dwOutputFrameHeight = sfcStateParamsG12->dwScaledRegionHeight;
454 
455     if (CodecHalMmcState::IsMmcEnabled())
456     {
457         MOS_MEMCOMP_STATE mmcMode   = MOS_MEMCOMP_DISABLED;
458         CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &m_sfcOutputSurface->OsResource, &mmcMode));
459         sfcStateParams->bMMCEnable  = (mmcMode != MOS_MEMCOMP_DISABLED) ? true : false;
460         sfcStateParams->MMCMode     = (mmcMode == MOS_MEMCOMP_RC) ? MOS_MMC_RC : MOS_MMC_MC;
461         CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetMemoryCompressionFormat(
462             m_osInterface, &m_sfcOutputSurface->OsResource, &outSurfaceParams->dwCompressionFormat));
463     }
464 
465     return eStatus;
466 }
467 
SetSfcAvsStateParams()468 MOS_STATUS CodechalVp9SfcStateG12::SetSfcAvsStateParams()
469 {
470     CODECHAL_HW_FUNCTION_ENTER;
471 
472     CODECHAL_HW_CHK_STATUS_RETURN(CodechalSfcState::SetSfcAvsStateParams());
473 
474     PMHW_SFC_AVS_STATE mhwSfcAvsState = &m_avsState;
475 
476     if (m_vp9PicParams->subsampling_x == 0 && m_vp9PicParams->subsampling_y == 0) // 444
477     {
478         mhwSfcAvsState->dwInputHorizontalSiting = 0;
479         mhwSfcAvsState->dwInputVerticalSitting = 0;
480     }
481     else // 420
482     {
483         mhwSfcAvsState->dwInputHorizontalSiting = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
484         mhwSfcAvsState->dwInputVerticalSitting = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 : ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 : SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
485     }
486 
487     return MOS_STATUS_SUCCESS;
488 }
489