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_encode_csc_ds_g9.cpp
24 //! \brief    This file implements the Csc+Ds feature for all codecs on Gen9 platform
25 //!
26 
27 #include "codechal_encoder_base.h"
28 #include "codechal_encode_csc_ds_g9.h"
29 #include "codeckrnheader.h"
30 #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
31 #include "igcodeckrn_g9.h"
32 #endif
33 #if USE_CODECHAL_DEBUG_TOOL
34 #include "codechal_debug_encode_par_g9.h"
35 #endif
36 
SetCurbeCsc()37 MOS_STATUS CodechalEncodeCscDsG9::SetCurbeCsc()
38 {
39     CODECHAL_ENCODE_FUNCTION_ENTER;
40 
41     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
42 
43     CscKernelCurbeData curbe;
44 
45     curbe.DW0_InputPictureWidth = m_curbeParams.dwInputPictureWidth;
46     curbe.DW0_InputPictureHeight = m_curbeParams.dwInputPictureHeight;
47 
48     if (m_curbeParams.bCscOrCopyOnly)
49     {
50         curbe.DW1_CscDsCopyOpCode = 0;    // Copy only
51     }
52     else
53     {
54         // Enable DS kernel (0  disable, 1  enable)
55         curbe.DW1_CscDsCopyOpCode = 1;    // 0x01 to 0x7F: DS + Copy
56     }
57 
58     if (cscColorNv12TileY == m_colorRawSurface ||
59         cscColorNv12Linear == m_colorRawSurface)
60     {
61         curbe.DW1_InputColorFormat = 0;
62     }
63     else if (cscColorYUY2 == m_colorRawSurface)
64     {
65         curbe.DW1_InputColorFormat = 1;
66     }
67     else if ((cscColorARGB == m_colorRawSurface) || (cscColorABGR == m_colorRawSurface))
68     {
69         curbe.DW1_InputColorFormat = 2;
70     }
71 
72     if (m_curbeParams.bFlatnessCheckEnabled ||
73         m_curbeParams.bMBVarianceOutputEnabled ||
74         m_curbeParams.bMBPixelAverageOutputEnabled)
75     {
76         curbe.DW2_FlatnessThreshold = 128;
77         curbe.DW3_EnableMBStatSurface = true;
78     }
79     else
80     {
81         curbe.DW3_EnableMBStatSurface = false;
82     }
83 
84     // RGB->YUV CSC coefficients
85     if (m_curbeParams.inputColorSpace == ECOLORSPACE_P709)
86     {
87         curbe.DW4_CscCoefficientC0 = 0xFFCD;
88         curbe.DW5_CscCoefficientC3 = 0x0080;
89         curbe.DW6_CscCoefficientC4 = 0x004F;
90         curbe.DW7_CscCoefficientC7 = 0x0010;
91         curbe.DW8_CscCoefficientC8 = 0xFFD5;
92         curbe.DW9_CscCoefficientC11 = 0x0080;
93         if (cscColorARGB == m_colorRawSurface)
94         {
95             curbe.DW4_CscCoefficientC1 = 0xFFFB;
96             curbe.DW5_CscCoefficientC2 = 0x0038;
97             curbe.DW6_CscCoefficientC5 = 0x0008;
98             curbe.DW7_CscCoefficientC6 = 0x0017;
99             curbe.DW8_CscCoefficientC9 = 0x0038;
100             curbe.DW9_CscCoefficientC10 = 0xFFF3;
101         }
102         else // cscColorABGR == m_colorRawSurface
103         {
104             curbe.DW4_CscCoefficientC1 = 0x0038;
105             curbe.DW5_CscCoefficientC2 = 0xFFFB;
106             curbe.DW6_CscCoefficientC5 = 0x0017;
107             curbe.DW7_CscCoefficientC6 = 0x0008;
108             curbe.DW8_CscCoefficientC9 = 0xFFF3;
109             curbe.DW9_CscCoefficientC10 = 0x0038;
110         }
111     }
112     else if (m_curbeParams.inputColorSpace == ECOLORSPACE_P601)
113     {
114         curbe.DW4_CscCoefficientC0 = 0xFFD1;
115         curbe.DW5_CscCoefficientC3 = 0x0080;
116         curbe.DW6_CscCoefficientC4 = 0x0041;
117         curbe.DW7_CscCoefficientC7 = 0x0010;
118         curbe.DW8_CscCoefficientC8 = 0xFFDB;
119         curbe.DW9_CscCoefficientC11 = 0x0080;
120         if (cscColorARGB == m_colorRawSurface)
121         {
122             curbe.DW4_CscCoefficientC1 = 0xFFF7;
123             curbe.DW5_CscCoefficientC2 = 0x0038;
124             curbe.DW6_CscCoefficientC5 = 0x000D;
125             curbe.DW7_CscCoefficientC6 = 0x0021;
126             curbe.DW8_CscCoefficientC9 = 0x0038;
127             curbe.DW9_CscCoefficientC10 = 0xFFED;
128         }
129         else // cscColorABGR == m_colorRawSurface
130         {
131             curbe.DW4_CscCoefficientC1 = 0x0038;
132             curbe.DW5_CscCoefficientC2 = 0xFFF7;
133             curbe.DW6_CscCoefficientC5 = 0x0021;
134             curbe.DW7_CscCoefficientC6 = 0x000D;
135             curbe.DW8_CscCoefficientC9 = 0xFFED;
136             curbe.DW9_CscCoefficientC10 = 0x0038;
137         }
138     }
139     else
140     {
141         CODECHAL_ENCODE_ASSERTMESSAGE("Unsupported ARGB input color space = %d!", m_curbeParams.inputColorSpace);
142         return MOS_STATUS_INVALID_PARAMETER;
143     }
144 
145     curbe.DW16_SrcNV12SurfYIndex = cscSrcYPlane;
146     curbe.DW17_DstYSurfIndex = cscDstDsYPlane;
147     curbe.DW18_MbStatDstSurfIndex = cscDstFlatOrMbStats;
148     curbe.DW19_CopyDstNV12SurfIndex = cscDstCopyYPlane;
149     curbe.DW20_SrcNV12SurfUVIndex = cscSrcUVPlane;
150 
151     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_cscKernelState->m_dshRegion.AddData(
152         &curbe,
153         m_cscKernelState->dwCurbeOffset,
154         sizeof(curbe)));
155 
156     return eStatus;
157 }
158 
InitKernelStateDS()159 MOS_STATUS CodechalEncodeCscDsG9::InitKernelStateDS()
160 {
161     CODECHAL_ENCODE_FUNCTION_ENTER;
162 
163     if (CODECHAL_AVC == m_standard)
164     {
165         m_dsBTCount[0] = ds4xNumSurfaces;
166         m_dsCurbeLength[0] =
167         m_dsInlineDataLength = sizeof(Ds4xKernelCurbeData);
168         m_dsBTISrcY = ds4xSrcYPlane;
169         m_dsBTIDstY = ds4xDstYPlane;
170         m_dsBTISrcYTopField = ds4xSrcYPlaneTopField;
171         m_dsBTIDstYTopField = ds4xDstYPlaneTopField;
172         m_dsBTISrcYBtmField = ds4xSrcYPlaneBtmField;
173         m_dsBTIDstYBtmField = ds4xDstYPlaneBtmField;
174         m_dsBTIDstMbVProc = ds4xDstMbVProc;
175         m_dsBTIDstMbVProcTopField = ds4xDstMbVProcTopField;
176         m_dsBTIDstMbVProcBtmField = ds4xDstMbVProcBtmField;
177     }
178 
179     return CodechalEncodeCscDs::InitKernelStateDS();
180 }
181 
SetCurbeDS4x()182 MOS_STATUS CodechalEncodeCscDsG9::SetCurbeDS4x()
183 {
184     CODECHAL_ENCODE_FUNCTION_ENTER;
185 
186     if (CODECHAL_AVC != m_standard)
187     {
188         return CodechalEncodeCscDs::SetCurbeDS4x();
189     }
190 
191     Ds4xKernelCurbeData curbe;
192 
193     curbe.DW0_InputPictureWidth = m_curbeParams.dwInputPictureWidth;
194     curbe.DW0_InputPictureHeight = m_curbeParams.dwInputPictureHeight;
195 
196     curbe.DW1_InputYBTIFrame = ds4xSrcYPlane;
197     curbe.DW2_OutputYBTIFrame = ds4xDstYPlane;
198 
199     if (m_curbeParams.bFieldPicture)
200     {
201         curbe.DW3_InputYBTIBottomField = ds4xSrcYPlaneBtmField;
202         curbe.DW4_OutputYBTIBottomField = ds4xDstYPlaneBtmField;
203     }
204 
205     if ((curbe.DW6_EnableMBFlatnessCheck = m_curbeParams.bFlatnessCheckEnabled))
206     {
207         curbe.DW5_FlatnessThreshold = 128;
208     }
209 
210     // For gen10 DS kernel, If Flatness Check enabled, need enable MBVariance as well. Otherwise will not output MbIsFlat.
211     curbe.DW6_EnableMBVarianceOutput = m_curbeParams.bFlatnessCheckEnabled || m_curbeParams.bMBVarianceOutputEnabled;
212     curbe.DW6_EnableMBPixelAverageOutput = m_curbeParams.bMBPixelAverageOutputEnabled;
213     curbe.DW6_EnableBlock8x8StatisticsOutput = m_curbeParams.bBlock8x8StatisticsEnabled;
214 
215     if (curbe.DW6_EnableMBVarianceOutput || curbe.DW6_EnableMBPixelAverageOutput)
216     {
217         curbe.DW8_MBVProcStatsBTIFrame = ds4xDstMbVProc;
218 
219         if (m_curbeParams.bFieldPicture)
220         {
221             curbe.DW9_MBVProcStatsBTIBottomField = ds4xDstMbVProcBtmField;
222         }
223     }
224 
225     CODECHAL_ENCODE_CHK_STATUS_RETURN(m_dsKernelState->m_dshRegion.AddData(
226         &curbe,
227         m_dsKernelState->dwCurbeOffset,
228         sizeof(curbe)));
229 
230     CODECHAL_DEBUG_TOOL(
231         if (m_encoder->m_encodeParState)
232         {
233             CODECHAL_ENCODE_CHK_STATUS_RETURN(m_encoder->m_encodeParState->PopulateDsParam(&curbe));
234         }
235     )
236 
237     return MOS_STATUS_SUCCESS;
238 }
239 
CodechalEncodeCscDsG9(CodechalEncoderState * encoder)240 CodechalEncodeCscDsG9::CodechalEncodeCscDsG9(CodechalEncoderState* encoder)
241     : CodechalEncodeCscDs(encoder)
242 {
243     m_cscKernelUID = IDR_CODEC_Downscale_Copy;
244     m_cscCurbeLength = sizeof(CscKernelCurbeData);
245 #if defined(ENABLE_KERNELS) && !defined(_FULL_OPEN_SOURCE)
246     m_kernelBase = (uint8_t*)IGCODECKRN_G9;
247 #endif
248 }