1 /*
2 * Copyright (c) 2017-2020, 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_jpeg.cpp
24 //! \brief    Implements the decode interface extension for CSC and scaling via SFC for jpeg decoder.
25 //! \details  Downsampling in this case is supported by the SFC fixed function HW unit.
26 //!
27 
28 #include "codechal_decoder.h"
29 #include "codechal_decode_sfc_jpeg.h"
30 
CheckAndInitialize(PMOS_SURFACE destSurface,CodecDecodeJpegPicParams * picParams)31 MOS_STATUS CodechalJpegSfcState::CheckAndInitialize(
32         PMOS_SURFACE            destSurface,
33         CodecDecodeJpegPicParams*  picParams)
34 {
35     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
36 
37     CODECHAL_HW_FUNCTION_ENTER;
38 
39     // Check if SFC output is supported
40     if (MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrSFCPipe) &&
41         !MEDIA_IS_SKU(m_hwInterface->GetSkuTable(), FtrDisableVDBox2SFC) &&
42         destSurface->Format == Format_A8R8G8B8 &&  // Currently only support this SFC usage in JPEG
43         (picParams->m_interleavedData ||           // SFC only support interleaved single scan (YUV400 is excluded for "interleaved" limitation)
44             picParams->m_chromaType == jpegYUV400) &&
45         picParams->m_totalScans == 1)
46     {
47         // Create the suedo SFC input surface (fill only the parameters will be used)
48         m_sfcInSurface.dwWidth               = destSurface->dwWidth;
49         m_sfcInSurface.dwHeight              = destSurface->dwHeight;
50         m_sfcInSurface.dwPitch               = MOS_ALIGN_CEIL(destSurface->dwWidth, CODECHAL_SURFACE_PITCH_ALIGNMENT);
51         m_sfcInSurface.UPlaneOffset.iYOffset = destSurface->dwHeight;
52         m_sfcInSurface.TileType              = destSurface->TileType;
53 
54         m_sfcPipeOut = true;
55 
56         switch (picParams->m_chromaType)
57         {
58         case jpegYUV400:
59             m_sfcInSurface.Format = Format_400P;
60             break;
61         case jpegYUV420:
62             m_sfcInSurface.Format = Format_IMC3;
63             m_sfcInSurface.VPlaneOffset.iYOffset =
64                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + (destSurface->dwHeight >> 1);
65             break;
66         case jpegYUV422H2Y:
67         case jpegYUV422H4Y:
68             m_sfcInSurface.Format = Format_422H;
69             m_sfcInSurface.VPlaneOffset.iYOffset =
70                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + (destSurface->dwHeight >> 1);
71             break;
72         case jpegYUV444:
73         case jpegRGB:
74         case jpegBGR:
75             m_sfcInSurface.Format = Format_444P;
76             m_sfcInSurface.VPlaneOffset.iYOffset =
77                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + destSurface->dwHeight;
78             break;
79         default:
80             m_sfcPipeOut = false;
81         }
82 
83         if (m_sfcPipeOut)
84         {
85             DecodeProcessingParams procParams;
86             MOS_ZeroMemory(&procParams, sizeof(DecodeProcessingParams));
87             procParams.m_inputSurface                 = &m_sfcInSurface;
88             procParams.m_outputSurface                = destSurface;
89             procParams.m_inputSurfaceRegion.m_width   = m_sfcInSurface.dwWidth;
90             procParams.m_inputSurfaceRegion.m_height  = m_sfcInSurface.dwHeight;
91             procParams.m_outputSurfaceRegion.m_width  = destSurface->dwWidth;
92             procParams.m_outputSurfaceRegion.m_height = destSurface->dwHeight;
93 
94             if (IsSfcOutputSupported(&procParams, MhwSfcInterface::SFC_PIPE_MODE_VDBOX))
95             {
96                 m_jpegInUse      = true;
97                 m_jpegChromaType = picParams->m_chromaType;
98 
99                 CODECHAL_HW_CHK_STATUS_RETURN(Initialize(
100                     &procParams,
101                     MhwSfcInterface::SFC_PIPE_MODE_VDBOX));
102 
103                 // Use SFC for Direct YUV->ARGB on SKL
104                 m_sfcPipeOut = true;
105             }
106             else
107             {
108                 m_sfcPipeOut = false;
109             }
110         }
111     }
112 
113     if (m_decoder)
114     {
115         m_decoder->SetVdSfcSupportedFlag(m_sfcPipeOut);
116     }
117 
118     return eStatus;
119 }
120 
UpdateInputInfo(PMHW_SFC_STATE_PARAMS sfcStateParams)121 MOS_STATUS CodechalJpegSfcState::UpdateInputInfo(
122     PMHW_SFC_STATE_PARAMS   sfcStateParams)
123 {
124     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
125 
126     CODECHAL_HW_FUNCTION_ENTER;
127 
128     sfcStateParams->sfcPipeMode                = MEDIASTATE_SFC_PIPE_VD_TO_SFC;
129     sfcStateParams->dwAVSFilterMode            = MEDIASTATE_SFC_AVS_FILTER_5x5;
130 
131     uint16_t widthAlignUnit                             = CODECHAL_SFC_ALIGNMENT_16;
132     uint16_t heightAlignUnit                            = CODECHAL_SFC_ALIGNMENT_16;
133 
134     switch (m_jpegChromaType)
135     {
136     case jpegYUV400:
137         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
138         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400;
139         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
140         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
141         break;
142     case jpegYUV420:
143         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
144         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420;
145         break;
146     case jpegYUV422H2Y:
147         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
148         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
149         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
150         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
151         break;
152     case jpegYUV422H4Y:
153         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
154         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
155         break;
156     case jpegYUV444:
157     case jpegRGB:
158     case jpegBGR:
159         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
160         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
161         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
162         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
163         break;
164     default:
165         CODECHAL_HW_ASSERTMESSAGE("Unsupported input format of SFC.");
166         return MOS_STATUS_UNKNOWN;
167     }
168 
169     sfcStateParams->dwInputFrameWidth  = MOS_ALIGN_CEIL(m_inputSurface->dwWidth, widthAlignUnit);
170     sfcStateParams->dwInputFrameHeight = MOS_ALIGN_CEIL(m_inputSurface->dwHeight, heightAlignUnit);
171 
172     return eStatus;
173 }
174