1 /*
2 * Copyright (c) 2017, 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         destSurface->Format == Format_A8R8G8B8 &&  // Currently only support this SFC usage in JPEG
42         (picParams->m_interleavedData ||           // SFC only support interleaved single scan (YUV400 is excluded for "interleaved" limitation)
43             picParams->m_chromaType == jpegYUV400) &&
44         picParams->m_totalScans == 1)
45     {
46         // Create the suedo SFC input surface (fill only the parameters will be used)
47         m_sfcInSurface.dwWidth               = destSurface->dwWidth;
48         m_sfcInSurface.dwHeight              = destSurface->dwHeight;
49         m_sfcInSurface.dwPitch               = MOS_ALIGN_CEIL(destSurface->dwWidth, CODECHAL_SURFACE_PITCH_ALIGNMENT);
50         m_sfcInSurface.UPlaneOffset.iYOffset = destSurface->dwHeight;
51         m_sfcInSurface.TileType              = destSurface->TileType;
52 
53         m_sfcPipeOut = true;
54 
55         switch (picParams->m_chromaType)
56         {
57         case jpegYUV400:
58             m_sfcInSurface.Format = Format_400P;
59             break;
60         case jpegYUV420:
61             m_sfcInSurface.Format = Format_IMC3;
62             m_sfcInSurface.VPlaneOffset.iYOffset =
63                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + (destSurface->dwHeight >> 1);
64             break;
65         case jpegYUV422H2Y:
66         case jpegYUV422H4Y:
67             m_sfcInSurface.Format = Format_422H;
68             m_sfcInSurface.VPlaneOffset.iYOffset =
69                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + (destSurface->dwHeight >> 1);
70             break;
71         case jpegYUV444:
72         case jpegRGB:
73         case jpegBGR:
74             m_sfcInSurface.Format = Format_444P;
75             m_sfcInSurface.VPlaneOffset.iYOffset =
76                 MOS_ALIGN_CEIL(destSurface->dwHeight, MHW_VDBOX_MFX_UV_PLANE_ALIGNMENT_LEGACY) + destSurface->dwHeight;
77             break;
78         default:
79             m_sfcPipeOut = false;
80         }
81 
82         if (m_sfcPipeOut)
83         {
84             CODECHAL_DECODE_PROCESSING_PARAMS   procParams;
85             MOS_ZeroMemory(&procParams, sizeof(CODECHAL_DECODE_PROCESSING_PARAMS));
86             procParams.pInputSurface                = &m_sfcInSurface;
87             procParams.pOutputSurface = destSurface;
88             procParams.rcInputSurfaceRegion.Width   = m_sfcInSurface.dwWidth;
89             procParams.rcInputSurfaceRegion.Height  = m_sfcInSurface.dwHeight;
90             procParams.rcOutputSurfaceRegion.Width = destSurface->dwWidth;
91             procParams.rcOutputSurfaceRegion.Height = destSurface->dwHeight;
92 
93             if (IsSfcOutputSupported(&procParams, MhwSfcInterface::SFC_PIPE_MODE_VDBOX))
94             {
95                 m_jpegInUse      = true;
96                 m_jpegChromaType = picParams->m_chromaType;
97 
98                 CODECHAL_HW_CHK_STATUS_RETURN(Initialize(
99                     &procParams,
100                     MhwSfcInterface::SFC_PIPE_MODE_VDBOX));
101 
102                 // Use SFC for Direct YUV->ARGB on SKL
103                 m_sfcPipeOut = true;
104             }
105             else
106             {
107                 m_sfcPipeOut = false;
108             }
109         }
110     }
111 
112     if (m_decoder)
113     {
114         m_decoder->SetVdSfcSupportedFlag(m_sfcPipeOut);
115     }
116 
117     return eStatus;
118 }
119 
UpdateInputInfo(PMHW_SFC_STATE_PARAMS sfcStateParams)120 MOS_STATUS CodechalJpegSfcState::UpdateInputInfo(
121     PMHW_SFC_STATE_PARAMS   sfcStateParams)
122 {
123     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
124 
125     CODECHAL_HW_FUNCTION_ENTER;
126 
127     sfcStateParams->sfcPipeMode                = MEDIASTATE_SFC_PIPE_VD_TO_SFC;
128     sfcStateParams->dwAVSFilterMode            = MEDIASTATE_SFC_AVS_FILTER_5x5;
129 
130     uint16_t widthAlignUnit                             = CODECHAL_SFC_ALIGNMENT_16;
131     uint16_t heightAlignUnit                            = CODECHAL_SFC_ALIGNMENT_16;
132 
133     switch (m_jpegChromaType)
134     {
135     case jpegYUV400:
136         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
137         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_400;
138         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
139         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
140         break;
141     case jpegYUV420:
142         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
143         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_420;
144         break;
145     case jpegYUV422H2Y:
146         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
147         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
148         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
149         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
150         break;
151     case jpegYUV422H4Y:
152         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_16x16_JPEG;
153         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_422H;
154         break;
155     case jpegYUV444:
156     case jpegRGB:
157     case jpegBGR:
158         sfcStateParams->dwVDVEInputOrderingMode    = MEDIASTATE_SFC_INPUT_ORDERING_VD_8x8_JPEG;
159         sfcStateParams->dwInputChromaSubSampling   = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
160         widthAlignUnit                     = CODECHAL_SFC_ALIGNMENT_8;
161         heightAlignUnit                    = CODECHAL_SFC_ALIGNMENT_8;
162         break;
163     default:
164         CODECHAL_HW_ASSERTMESSAGE("Unsupported input format of SFC.");
165         return MOS_STATUS_UNKNOWN;
166     }
167 
168     sfcStateParams->dwInputFrameWidth  = MOS_ALIGN_CEIL(m_inputSurface->dwWidth, widthAlignUnit);
169     sfcStateParams->dwInputFrameHeight = MOS_ALIGN_CEIL(m_inputSurface->dwHeight, heightAlignUnit);
170 
171     return eStatus;
172 }
173