1 /*
2 * Copyright (c) 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_encode_sfc_base.h
24 //! \brief    Defines the encode interface for CSC via SFC.
25 //! \details  Downsampling in this case is supported by the SFC fixed function HW unit.
26 //!
27 
28 #ifndef __CODECHAL_ENCODE_SFC_BASE_H__
29 #define __CODECHAL_ENCODE_SFC_BASE_H__
30 
31 #include "codechal.h"
32 #include "codechal_hw.h"
33 
34 #define CODECHAL_SFC_ALIGNMENT_16        16
35 #define CODECHAL_SFC_ALIGNMENT_8         8
36 
37 #define CODECHAL_SFC_VEBOX_STATISTICS_SIZE                        (32 * 4)
38 #define CODECHAL_SFC_VEBOX_LACE_HISTOGRAM_256_BIN_PER_BLOCK       (256 * 2)
39 #define CODECHAL_SFC_VEBOX_ACE_HISTOGRAM_SIZE_PER_FRAME_PER_SLICE (256 * 4)
40 #define CODECHAL_SFC_NUM_FRAME_PREVIOUS_CURRENT                    2
41 
42 #define CODECHAL_SFC_VEBOX_RGB_HISTOGRAM_SIZE_PER_SLICE           (256 * 4)
43 #define CODECHAL_SFC_NUM_RGB_CHANNEL                               3
44 #define CODECHAL_SFC_AVS_LINEBUFFER_SIZE_PER_VERTICAL_PIXEL       (5 * MHW_SFC_CACHELINE_SIZE)
45 
46 typedef struct _CODECHAL_ENCODE_RECTANGLE
47 {
48     uint32_t              X;
49     uint32_t              Y;
50     uint32_t              Width;
51     uint32_t              Height;
52 } CODECHAL_ENCODE_RECTANGLE, *PCODECHAL_ENCODE_RECTANGLE;
53 
54 //!
55 //! \struct    CODECHAL_ENCODE_SFC_PARAMS
56 //! \brief     Parameters needed for the processing of the encode render target
57 //!
58 struct CODECHAL_ENCODE_SFC_PARAMS
59 {
CODECHAL_ENCODE_SFC_PARAMSCODECHAL_ENCODE_SFC_PARAMS60     CODECHAL_ENCODE_SFC_PARAMS()
61     {
62         MOS_ZeroMemory(this, sizeof(*this));
63     }
64 
65     // Input
66     PMOS_SURFACE                 pInputSurface;
67     CODECHAL_ENCODE_RECTANGLE    rcInputSurfaceRegion;
68     uint32_t                     uiChromaSitingType;
69 
70     // Output
71     PMOS_SURFACE                 pOutputSurface;
72     CODECHAL_ENCODE_RECTANGLE    rcOutputSurfaceRegion;
73 };
74 
75 class CodecHalEncodeSfcBase
76 {
77 public:
78     //!
79     //! \brief    Constructor
80     //!
CodecHalEncodeSfcBase()81     CodecHalEncodeSfcBase() {};
82 
83     //!
84     //! \brief    Destructor
85     //!
86     virtual ~CodecHalEncodeSfcBase();
87 
SetInputColorSpace(MHW_CSPACE colorSpace)88     void SetInputColorSpace(MHW_CSPACE colorSpace)
89     {
90         m_inputSurfaceColorSpace = colorSpace;
91     }
SetOutputColorSpace(MHW_CSPACE colorSpace)92     void SetOutputColorSpace(MHW_CSPACE colorSpace)
93     {
94         m_outputSurfaceColorSpace = colorSpace;
95     }
96     //!
97     //! \brief    Initialize
98     //!
99     //! \param    [in] hwInterface
100     //!           Codechal hardware interface
101     //! \param    [in] osInterface
102     //!           Pointer to MOS interface
103     //!
104     //! \return   MOS_STATUS
105     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
106     //!
107     MOS_STATUS Initialize(
108         CodechalHwInterface                *hwInterface,
109         PMOS_INTERFACE                      osInterface);
110 
111     //!
112     //! \brief    Allocate resources
113     //!
114     //! \return   MOS_STATUS
115     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
116     //!
117     MOS_STATUS AllocateResources();
118 
119     //!
120     //! \brief    Free resources
121     //!
122     //! \return   MOS_STATUS
123     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
124     //!
125     MOS_STATUS FreeResources();
126 
127     //!
128     //! \brief    Set parameters
129     //! \details    call every frame.  get the input/output surface and  color space...
130     //!
131     //! \param    [in] params
132     //!           Pointer to codechal encode sfc parameters
133     //!
134     //! \return   MOS_STATUS
135     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
136     //!
137     MOS_STATUS SetParams(
138         CODECHAL_ENCODE_SFC_PARAMS*         params);
139 
140     //!
141     //! \brief    Render start
142     //!
143     //! \param    [in] encoder
144     //!           Pointer to codechal encoder state
145     //!
146     //! \return   MOS_STATUS
147     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
148     //!
149     MOS_STATUS RenderStart(
150         CodechalEncoderState*           encoder);
151 
152     //!
153     //! \brief    Add sfc commands
154     //!
155     //! \param    [in] sfcInterface
156     //!           Pointer to MHW sfc interface
157     //! \param    [in] cmdBuffer
158     //!           Pointer to MOS command buffer
159     //!
160     //! \return   MOS_STATUS
161     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
162     //!
163     virtual MOS_STATUS AddSfcCommands(
164         PMHW_SFC_INTERFACE              sfcInterface,
165         PMOS_COMMAND_BUFFER             cmdBuffer);
166 
167     //!
168     //! \brief    Set sfc state parameters
169     //!
170     //! \param    [in] sfcInterface
171     //!           Pointer to MHW sfc interface
172     //! \param    [in] params
173     //!           Pointer to MHW sfc state parameters
174     //! \param    [in] outSurfaceParams
175     //!           Pointer to MHW sfc out surface parameters
176     //!
177     //! \return   MOS_STATUS
178     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
179     //!
180     MOS_STATUS SetSfcStateParams(
181         PMHW_SFC_INTERFACE             sfcInterface,
182         PMHW_SFC_STATE_PARAMS          params,
183         PMHW_SFC_OUT_SURFACE_PARAMS    outSurfaceParams);
184 
185     //!
186     //! \brief    Set sfc avs state parameters
187     //!
188     //! \param    [in] sfcInterface
189     //!           Pointer to MHW sfc interface
190     //!
191     //! \return   MOS_STATUS
192     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
193     //!
194     MOS_STATUS SetSfcAvsStateParams(
195         PMHW_SFC_INTERFACE             sfcInterface);
196 
197     //!
198     //! \brief    Set sfc ief state parameters
199     //!
200     //! \param    [in] params
201     //!           Pointer to MHW sfc ief state parameters
202     //!
203     //! \return   MOS_STATUS
204     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
205     //!
206     MOS_STATUS SetSfcIefStateParams(
207         PMHW_SFC_IEF_STATE_PARAMS         params);
208 
209     //!
210     //! \brief    Set vebox state parameters
211     //!
212     //! \param    [in] params
213     //!           Pointer to vebox state command params
214     //!
215     //! \return   MOS_STATUS
216     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
217     //!
218     MOS_STATUS SetVeboxStateParams(
219         PMHW_VEBOX_STATE_CMD_PARAMS         params);
220 
221     //!
222     //! \brief    Set vebox surface state params
223     //!
224     //! \param    [in] params
225     //!           Pointer to MHW vebox surface state command parameters
226     //!
227     //! \return   MOS_STATUS
228     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
229     //!
230     MOS_STATUS SetVeboxSurfaceStateParams(
231         PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS         params);
232 
233     //!
234     //! \brief    Set vebox di iecp parameters
235     //!
236     //! \param    [in] params
237     //!           Pointer to MHW vebox di iecp command parameters
238     //!
239     //! \return   MOS_STATUS
240     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
241     //!
242     virtual MOS_STATUS SetVeboxDiIecpParams(
243         PMHW_VEBOX_DI_IECP_CMD_PARAMS         params);
244 
245     //!
246     //! \brief    Vebox set iecp parameters
247     //! \details  input -> RGB (from app)
248     //!           output -> NV12 (raw surface?)
249     //!
250     //! \param    [in] mhwVeboxIecpParams
251     //!           Pointer t MHW vebox iecp paramters
252     //!
253     //! \return   MOS_STATUS
254     //!           Return MOS_STATUS_SUCCESS if call success, else fail reason
255     //!
256     MOS_STATUS VeboxSetIecpParams(
257         PMHW_VEBOX_IECP_PARAMS         mhwVeboxIecpParams);
258 
259 #if (_DEBUG || _RELEASE_INTERNAL)
260     MOS_STATUS DumpBuffers(CodechalDebugInterface* debugInterface);
261 #endif
262 private:
263     //!
264     //! \brief    Check if is Cspac
265     //!
266     //! \param    [in] srcCspace
267     //!           MHW cspace
268     //! \param    [in] dstCspace
269     //!           MHW cspace
270     //!
271     //! \return   bool
272     //!           true if call success, else false
273     //!
274     bool IsCspace(MHW_CSPACE srcCspace, MHW_CSPACE dstCspace);
275 
276     //!
277     //! \brief    Get RGB range and offset
278     //!
279     //! \param    [in] srcCspace
280     //!           MHW cspace
281     //! \param    [in] rgbOffset
282     //!           RGB offset
283     //! \param    [in] rgbExcursion
284     //!           RGB excursion
285     //!
286     //! \return   bool
287     //!           true if call success, else false
288     //!
289     bool GetRgbRangeAndOffset(
290         MHW_CSPACE          srcCspace,
291         float               *rgbOffset,
292         float               *rgbExcursion);
293 
294     //!
295     //! \brief    Get YUV range and offset
296     //!
297     //! \param    [in] srcCspace
298     //!           MHW cspace
299     //! \param    [in] lumaOffset
300     //!           Luma offset
301     //! \param    [in] lumaExcursion
302     //!           Luma excursion
303     //! \param    [in] chromaZero
304     //!           Chroma zero
305     //! \param    [in] chromaExcursion
306     //!           Chroma excursion
307     //!
308     //! \return   bool
309     //!           true if call success, else false
310     //!
311     bool GetYuvRangeAndOffset(
312         MHW_CSPACE          srcCspace,
313         float               *lumaOffset,
314         float               *lumaExcursion,
315         float               *chromaZero,
316         float               *chromaExcursion);
317 
318     //!
319     //! \brief    Calculate YUV To RGB matrix
320     //! \details  Given the YUV->RGB transfer matrix, get the final matrix after
321     //!             applying offsets and excursions.
322     //!
323     //! [R']     [R_o]                                 [R_e/Y_e    0       0   ]  [Y'  - Y_o]
324     //! [G']  =  [R_o] + [YUVtoRGBCoeff (3x3 matrix)]. [   0    R_e/C_e    0   ]. [Cb' - C_z]
325     //! [B']     [R_o]                                 [   0       0    R_e/C_e]. [Cr' - C_z]
326     //!
327     //! [R']  = [C0  C1   C2] [Y' ]   [C3]      {Out pMatrix}
328     //! [G']  = [C4  C5   C6].[Cb'] + [C7]
329     //! [B']  = [C8  C9  C10] [Cr'] + [C11]
330     //!
331     //! \param    [in] srcCspace
332     //!           YUV Color space
333     //! \param    [in] dstCspace
334     //!           RGB Color space
335     //! \param    [in] transferMatrix
336     //!           Transfer matrix (3x3)
337     //! \param    [out] outMatrix
338     //!           Conversion matrix (3x4)
339     //! \return   true if success else false
340     //!
341     bool CalcYuvToRgbMatrix(
342         MHW_CSPACE      srcCspace,
343         MHW_CSPACE      dstCspace,
344         float           *transferMatrix,
345         float           *outMatrix);
346 
347     //!
348     //! \brief    Calculate RGB To YUV matrix
349     //!
350     //! \param    [in] srcCspace
351     //!           RGB Color space
352     //! \param    [in] dstCspace
353     //!           YUV Color space
354     //! \param    [in] transferMatrix
355     //!           Transfer matrix (3x3)
356     //! \param    [out] outMatrix
357     //!           Conversion matrix (3x4)
358     //! \return   bool
359     //!           true if call success, else false
360     bool CalcRgbToYuvMatrix(
361         MHW_CSPACE      srcCspace,
362         MHW_CSPACE      dstCspace,
363         float           *transferMatrix,
364         float           *outMatrix);
365 
366     //!
367     //! \brief    Get csc matrix
368     //!
369     //! \param    [in] srcCspace
370     //!           Source Color space
371     //! \param    [in] dstCspace
372     //!           Destination Color space
373     //! \param    [out] cscMatrix
374     //!           CSC matrix to use
375     //!
376     void GetCSCMatrix(
377         MHW_CSPACE          srcCspace,
378         MHW_CSPACE          dstCspace,
379         float               *cscMatrix);
380 
381     //!
382     //! \brief    Get csc matrix
383     //!
384     //! \param    [in] srcCspace
385     //!           Source Cspace
386     //! \param    [in] dstCspace
387     //!           Destination Cspace
388     //! \param    [out] cscCoeff
389     //!           Coefficients matrix
390     //! \param    [out] cscInOffset
391     //!           Input Offset matrix
392     //! \param    [out] cscOutOffset
393     //!           Output Offset matrix
394     //!
395     void GetCscMatrix(
396         MHW_CSPACE             srcCspace,
397         MHW_CSPACE             dstCspace,
398         float                  *cscCoeff,
399         float                  *cscInOffset,
400         float                  *cscOutOffset);
401 
402 protected:
403     virtual int32_t GetAvsLineBufferSize() const;
404 
405     virtual int32_t GetSfcVeboxStatisticsSize() const = 0;
406     virtual int32_t GetStatisticsOutputBufferSize() const;
407 
408     // ACE/LACE/RGB Histogram buffer
409     virtual int32_t GetVeboxRgbHistogramSize() const;
410     virtual int32_t GetVeboxRgbAceHistogramSizeReserved() const = 0;
411     virtual int32_t GetVeboxMaxSlicesNum() const = 0;
412     virtual int32_t GetResLaceOrAceOrRgbHistogramBufferSize() const;
413 
414     CodechalHwInterface            *m_hwInterface = nullptr;  //!< Pointer to CodechalHwInterface
415     PMOS_INTERFACE                  m_osInterface = nullptr;  //!< Pointer to MOS_INTERFACE
416 
417     PMOS_SURFACE    m_inputSurface = nullptr;
418     MHW_CSPACE      m_inputSurfaceColorSpace = MHW_CSpace_Any;
419     PMOS_SURFACE    m_veboxOutputSurface = nullptr;
420     PMOS_SURFACE    m_sfcOutputSurface = nullptr;
421     MHW_CSPACE      m_outputSurfaceColorSpace = MHW_CSpace_Any;
422 
423     MOS_RESOURCE    m_resAvsLineBuffer = { 0, };
424     MOS_RESOURCE    m_resLaceOrAceOrRgbHistogram = { 0, };
425     MOS_RESOURCE    m_resStatisticsOutput = { 0, };
426 
427     bool            m_scaling = false;
428     bool            m_colorFill = false;
429     bool            m_IEF = false;
430     bool            m_CSC = false;
431 
432     float           m_scaleX = 0.0f;
433     float           m_scaleY = 0.0f;
434 
435     uint16_t        m_iefFactor = 0;
436     uint32_t        m_rotationMode = 0;
437     uint32_t        m_chromaSiting = 0;
438     uint32_t        m_inputFrameWidth = 0;
439     uint32_t        m_inputFrameHeight = 0;
440 
441     CODECHAL_ENCODE_RECTANGLE       m_inputSurfaceRegion = { 0, };
442     CODECHAL_ENCODE_RECTANGLE       m_outputSurfaceRegion = { 0, };
443 
444     // CSC in VEBOX params
445     bool                            m_veboxCsc = false;
446     MHW_CSPACE                      m_cscOutputCspace = MHW_CSpace_Any;    //!< Cspace of Output Frame
447     MHW_CSPACE                      m_cscInputCspace = MHW_CSpace_Any;     //!< Cspace of Input frame
448     float                           m_cscCoeff[9] = { 0.0f, };
449     float                           m_cscInOffset[3] = { 0.0f, };
450     float                           m_cscOutOffset[3] = { 0.0f, };
451 
452     MHW_AVS_PARAMS                  m_avsParams = { Format_Any, };
453     MHW_SFC_AVS_LUMA_TABLE          m_lumaTable = { 0, };
454     MHW_SFC_AVS_CHROMA_TABLE        m_chromaTable = { 0, };
455     MHW_SFC_AVS_STATE               m_avsState = { 0, };
456 };
457 #endif  // __CODECHAL_ENCODE_SFC_BASE_H__
458