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_hevc_long_g12.h
24 //! \brief    Defines HEVC slice level command processing for HEVC long format.
25 //! \details  Defines HEVC slice level command processing for all HEVC/SCC configuration and
26 //!           generate tile/slice level commands into second level buffer as short format.
27 //!
28 
29 #ifndef __CODECHAL_DECODER_HEVC_LONG_G12_H__
30 #define __CODECHAL_DECODER_HEVC_LONG_G12_H__
31 
32 #include "codechal_decode_hevc_g12.h"
33 #include "mhw_vdbox_hcp_g12_X.h"
34 #include "codechal_secure_decode_interface.h"
35 #include "mhw_mi_g12_X.h"
36 
37 //!
38 //! \class HevcDecodeSliceLongG12
39 //! \brief This class defines all HEVC long slice processing functions and provided a interface to
40 //!        HEVC decoder to generate tile/slice level commands into 2nd level batch buffer.
41 //!
42 class HevcDecodeSliceLongG12
43 {
44     //!
45     //! \struct HEVC_SLICE_TILE_PARAMS
46     //! \brief  Describe tile informations in a slice
47     //!
48     typedef struct _HEVC_SLICE_TILE_PARAMS
49     {
50         PCODEC_HEVC_SLICE_PARAMS                    slc;                 //!< Pointer to slice parameters
51         uint16_t                                    numTiles;            //!< Number of tiles in this slice
52         uint16_t                                    tileX;               //!< First tile index in horizontal
53         uint16_t                                    tileY;               //!< First tile index in vertical
54         uint16_t                                    origCtbX;            //!< Original slice start Ctb X index
55         uint16_t                                    origCtbY;            //!< Original slice start Ctb Y index
56         struct PER_TILE_INFO
57         {
58             uint16_t                                    ctbX;            //!< Tile horizontal offset in ctb
59             uint16_t                                    ctbY;            //!< Tile vertical offset in ctb
60             uint32_t                                    bsdOffset;       //!< Tile bitstream offset in the slice segment
61             uint32_t                                    bsdLength;       //!< Tile bitstream length
62         } TileArray[1];
63     } HEVC_SLICE_TILE_PARAMS, *PHEVC_SLICE_TILE_PARAMS;
64 
65     //!
66     //! \struct HEVC_TILE_SLICE_PARAMS
67     //! \brief  Describe slice informations in a tile
68     //!
69     typedef struct _HEVC_TILE_SLICE_PARAMS
70     {
71         uint16_t                                    tileX;               //!< The tile index in horizontal
72         uint16_t                                    tileY;               //!< The tile index in vertical
73         bool                                        lastSliceOfTile;     //!< Last slice of current tile
74     } HEVC_TILE_SLICE_PARAMS, *PHEVC_TILE_SLICE_PARAMS;
75 
76 public:
77     //!
78     //! \brief  Constructor
79     //! \param    [in] decoder
80     //!           Pointer to the HEVC decoder
81     //! \param    [in] hcpInterface
82     //!           Pointer to MHW HCP interface
83     //! \param    [in] miInterface
84     //!           Pointer to MHW MI interface
85     //!
86     HevcDecodeSliceLongG12(
87         CodechalDecodeHevcG12   *decoder,
88         MhwVdboxHcpInterface    *hcpInterface,
89         MhwMiInterface          *miInterface);
90     //!
91     //! \brief  Destructor
92     //!
~HevcDecodeSliceLongG12()93     ~HevcDecodeSliceLongG12() {};
94 
95     //!
96     //! \brief    Interface for decoder to process long slice
97     //! \details  Provide a interface to  HEVC decoder to process long slices and
98     //!           generate 2nd level command in specific buffer.
99     //! \param    [in] cmdResBase
100     //!           Base address to 2nd level buffer resource
101     //! \param    [in] cmdBufSize
102     //!           Command buffer size for each 2nd batch buffer in the resource
103     //!
104     //! \return   MOS_STATUS
105     //!           MOS_STATUS_SUCCESS if success, else fail reason
106     //!
107     MOS_STATUS ProcessSliceLong(uint8_t *cmdResBase, uint32_t cmdBufSize);
108 
109 protected:
110     //!
111     //! \brief    Utility to get tile index for the 1st tile in the slice
112     //!
113     //! \return   uint16_t
114     //!           tile index in horizontal
115     //!
GetSliceTileX(PCODEC_HEVC_SLICE_PARAMS slc)116     uint16_t GetSliceTileX(PCODEC_HEVC_SLICE_PARAMS slc) const
117     {
118         uint16_t  ctbX, ctbStart = 0;
119 
120         ctbX = slc->slice_segment_address % m_widthInCtb;
121         for (uint16_t i = 0; i <= m_hevcPicParams->num_tile_columns_minus1; i++)
122         {
123             if (ctbX >= ctbStart && ctbX < ctbStart + m_tileColWidth[i])
124             {
125                 return i;
126             }
127             ctbStart += m_tileColWidth[i];
128         }
129         return 0;
130     }
131 
132     //!
133     //! \brief    Utility to get tile index for the 1st tile in the slice
134     //!
135     //! \return   uint16_t
136     //!           tile index in vertical
137     //!
GetSliceTileY(PCODEC_HEVC_SLICE_PARAMS slc)138     uint16_t GetSliceTileY(PCODEC_HEVC_SLICE_PARAMS slc) const
139     {
140         uint32_t    ctbY, ctbStart = 0;
141 
142         ctbY = slc->slice_segment_address / m_widthInCtb;
143         for (uint16_t i = 0; i <= m_hevcPicParams->num_tile_rows_minus1; i++)
144         {
145             if (ctbY >= ctbStart && ctbY < ctbStart + m_tileRowHeight[i])
146             {
147                 return i;
148             }
149             ctbStart += m_tileRowHeight[i];
150         }
151         return 0;
152     }
153 
154     //!
155     //! \brief    Utility to get LCU index for specified tile column
156     //!
157     //! \return   uint16_t
158     //!           LCU index in horizontal
159     //!
GetTileCtbX(uint16_t col)160     uint16_t  GetTileCtbX(uint16_t col) const
161     {
162         uint16_t ctbX = 0;
163         for (uint16_t i = 0; i < col; i++)
164         {
165             ctbX += m_tileColWidth[i];
166         }
167         return ctbX;
168     }
169 
170     //!
171     //! \brief    Utility to get LCU index for specified tile row
172     //!
173     //! \return   uint16_t
174     //!           LCU index in vertical
175     //!
GetTileCtbY(uint16_t row)176     uint16_t GetTileCtbY(uint16_t row) const
177     {
178         uint16_t ctbY = 0;
179         for (uint16_t i = 0; i < row; i++)
180         {
181             ctbY += m_tileRowHeight[i];
182         }
183         return ctbY;
184     }
185 
186     //!
187     //! \brief    Utility to fix referen list of HEVC slice
188     //!
FixSliceRefList(PCODEC_HEVC_SLICE_PARAMS slc)189     void FixSliceRefList(PCODEC_HEVC_SLICE_PARAMS slc)
190     {
191         uint32_t m = 0, n = 0, k = 0, j = 0;
192         for (m = 0; m < CODEC_MAX_NUM_REF_FRAME_HEVC; m++)
193         {
194             int32_t poc = m_hevcPicParams->PicOrderCntValList[m];
195             for (n = m + 1; n < CODEC_MAX_NUM_REF_FRAME_HEVC; n++)
196             {
197                 if (poc == m_hevcPicParams->PicOrderCntValList[n])
198                 {
199                     for (k = 0; k < 2; k++)
200                     {
201                         for (j = 0; j < CODEC_MAX_NUM_REF_FRAME_HEVC; j++)
202                         {
203                             if (slc->RefPicList[k][j].FrameIdx == m_hevcPicParams->RefFrameList[n].FrameIdx)
204                             {
205                                 slc->RefPicList[k][j].FrameIdx = m_hevcPicParams->RefFrameList[m].FrameIdx;
206                                 slc->RefPicList[k][j].PicEntry = m_hevcPicParams->RefFrameList[m].PicEntry;
207                                 slc->RefPicList[k][j].PicFlags = m_hevcPicParams->RefFrameList[m].PicFlags;
208                             }
209                         }
210                     }
211                 }
212             }
213         }
214     }
215 
216     //!
217     //! \brief    Helper function to initialize tile coding parameters
218     //!
219     //! \param    [in] col
220     //!           Tile index in horizontal
221     //! \param    [in] row
222     //!           Tile index in vertical
223     //! \param    [in] hcpTileCodingParam
224     //!           Pointer to tile coding parameters
225     //!
226     //! \return   MOS_STATUS
227     //!           MOS_STATUS_SUCCESS if success, else fail reason
228     //!
229     MOS_STATUS InitTileCodingParams(
230         uint32_t                              col,
231         uint32_t                              row,
232         MHW_VDBOX_HCP_TILE_CODING_PARAMS_G12 *hcpTileCodingParam);
233 
234     //!
235     //! \brief    Helper function to fill tile information of slice
236     //!
237     //! \param    [in] sliceTileParams
238     //!           Pointer to slice tile parameters
239     //!
240     //! \return   MOS_STATUS
241     //!           MOS_STATUS_SUCCESS if success, else fail reason
242     //!
243     MOS_STATUS InitSliceTileParams(PHEVC_SLICE_TILE_PARAMS sliceTileParams);
244 
245     //!
246     //! \brief    Helper function to fill MHW HEVC slice state parameters
247     //!
248     //! \param    [in] sliceState
249     //!           Pointer to MHW HEVC slice state
250     //! \param    [in] sliceParams
251     //!           Pointer to HEVC slice parameters
252     //! \param    [in] extSliceParams
253     //!           Pointer to HEVC extended slice parameters
254     //! \param    [in] tileSliceParams
255     //!           Pointer to tile slice infor
256     //! \param    [in] sliceTileParams
257     //!           Pointer to slice tile infor
258     //! \param    [in] tileIndex
259     //!           Tile index in the slice
260     //!
261     //! \return   MOS_STATUS
262     //!           MOS_STATUS_SUCCESS if success, else fail reason
263     //!
264     MOS_STATUS InitSliceStateParams(
265         PMHW_VDBOX_HEVC_SLICE_STATE_G12  sliceState,
266         PCODEC_HEVC_SLICE_PARAMS         sliceParams,
267         PCODEC_HEVC_EXT_SLICE_PARAMS     extSliceParams,
268         PHEVC_TILE_SLICE_PARAMS          tileSliceParams,
269         PHEVC_SLICE_TILE_PARAMS          sliceTileParams,
270         uint16_t                         tileIndex);
271 
272     //!
273     //! \brief    Helper function to program HcpRefIdx cmds
274     //!
275     //! \param    [in] cmdBuf
276     //!           Pointer to cmd buffer
277     //! \param    [in] sliceState
278     //!           Pointer to MHW HEVC slice state
279     //!
280     //! \return   MOS_STATUS
281     //!           MOS_STATUS_SUCCESS if success, else fail reason
282     //!
283     MOS_STATUS SendRefIdxState(
284         PMOS_COMMAND_BUFFER             cmdBuf,
285         PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState);
286 
287     //!
288     //! \brief    Helper function to program HcpWeightOffset cmds
289     //!
290     //! \param    [in] cmdBuf
291     //!           Pointer to cmd buffer
292     //! \param    [in] sliceState
293     //!           Pointer to MHW HEVC slice state
294     //!
295     //! \return   MOS_STATUS
296     //!           MOS_STATUS_SUCCESS if success, else fail reason
297     //!
298     MOS_STATUS SendWeightOffset(
299         PMOS_COMMAND_BUFFER             cmdBuf,
300         PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState);
301 
302     //!
303     //! \brief    Helper function to program secure decode cmds
304     //!
305     //! \param    [in] cmdBuf
306     //!           Pointer to cmd buffer
307     //! \param    [in] sliceState
308     //!           Pointer to MHW HEVC slice state
309     //!
310     //! \return   MOS_STATUS
311     //!           MOS_STATUS_SUCCESS if success, else fail reason
312     //!
313     MOS_STATUS SendSecureDecodeState(
314         PMOS_COMMAND_BUFFER             cmdBuf,
315         PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState);
316 
317     //!
318     //! \brief    Helper function to program HcpBsdObj cmds
319     //!
320     //! \param    [in] cmdBuf
321     //!           Pointer to cmd buffer
322     //! \param    [in] sliceState
323     //!           Pointer to MHW HEVC slice state
324     //!
325     //! \return   MOS_STATUS
326     //!           MOS_STATUS_SUCCESS if success, else fail reason
327     //!
328     MOS_STATUS SendBsdObj(
329         PMOS_COMMAND_BUFFER             cmdBuf,
330         PMHW_VDBOX_HEVC_SLICE_STATE_G12 sliceState);
331 
332 private:
333     PMOS_INTERFACE              m_osInterface   = nullptr;        //!< Pointer to OS interface
334     CodechalDecodeHevcG12       *m_decoder = nullptr;             //!< Pointer to the HEVC decoder
335     MhwVdboxHcpInterfaceG12     *m_hcpInterface = nullptr;        //!< Pointer to MHW HCP interface
336     MhwMiInterface              *m_miInterface = nullptr;         //!< Pointer to MHW MI interface
337     CodechalSecureDecodeInterface   *m_secureDecoder = nullptr;   //!< Secure decoder pointer
338     CodechalHwInterface         *m_hwInterface       = nullptr;   //!< Pointer to HW interface
339     MhwVdboxVdencInterface      *m_vdencInterface    = nullptr;   //!< Pointer to Vdenc Interface
340     uint32_t                     m_numSlices = 0;                 //!< Number of slices in the frame
341     PCODEC_HEVC_PIC_PARAMS       m_hevcPicParams = nullptr;       //!< Pointer to HEVC picture parameter
342     PCODEC_HEVC_SLICE_PARAMS     m_hevcSliceParams = nullptr;     //!< Pointer to HEVC slice parameter
343     PCODEC_HEVC_EXT_PIC_PARAMS   m_hevcExtPicParams = nullptr;    //!< Extended pic params for Rext
344     PCODEC_HEVC_EXT_SLICE_PARAMS m_hevcExtSliceParams = nullptr;  //!< Extended slice params for Rext
345     PCODEC_HEVC_SCC_PIC_PARAMS   m_hevcSccPicParams = nullptr;    //!< Pic params for SCC
346     PCODEC_HEVC_SUBSET_PARAMS    m_hevcSubsetParams = nullptr;    //!< Hevc subset params for tile entrypoint offset
347 
348     PCODECHAL_DECODE_SCALABILITY_STATE_G12  m_scalabilityState = nullptr;   //!< Scalability state pointer
349 
350     uint16_t       *m_tileColWidth = nullptr;           //!< Pointer to table of tile column width
351     uint16_t       *m_tileRowHeight = nullptr;          //!< Pointer to table of tile row height
352 
353     uint16_t        m_widthInCtb = 0;                   //!< Frame width in LCU
354 
355     bool            m_copyDataBufferInUse = false;      //!< Indicate if BSD is from copied
356     MOS_RESOURCE   *m_resCopyDataBuffer = nullptr;      //!< Poiner to the copied data buffer
357     MOS_RESOURCE   *m_resDataBuffer = nullptr;          //!< Pointer to the original BSD buffer
358 
359     int8_t             *m_refIdxMapping = nullptr;      //!< Pointer to RefIdx mapping table
360     PCODEC_REF_LIST    *m_hevcRefList = nullptr;        //!< Pointer to RefList
361 
362     bool            m_isRealTile = false;               //!< Flag to indicate if real tile decoding mode in use
363     bool            m_isSeparateTileDecoding = false;   //!< Flag to indicate if SCC seperate tile decoding in use
364     bool            m_isSccPaletteMode = false;         //!< Flag to indicate if SCC palette mode decoding in use
365     bool            m_tileDecoding = false;             //!< Flag to indicate if tile decoding mode in use
366 };
367 #endif  // __CODECHAL_DECODER_HEVC_LONG_G12_H__
368