1 /*
2 * Copyright (c) 2019-2021, 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     decode_hevc_slice_packet_m12.cpp
24 //! \brief    Defines the interface for hevc decode slice packet for M12
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_hevc_slice_packet_m12.h"
28 #include "mhw_vdbox_hcp_g12_X.h"
29 
30 namespace decode
31 {
32 
~HevcDecodeSlcPktM12()33 HevcDecodeSlcPktM12::~HevcDecodeSlcPktM12()
34 {
35 }
36 
Execute(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)37 MOS_STATUS HevcDecodeSlcPktM12::Execute(MOS_COMMAND_BUFFER& cmdBuffer, uint32_t sliceIdx, uint32_t subTileIdx)
38 {
39     DECODE_CHK_STATUS(AddHcpPaletteInitializerState(cmdBuffer, sliceIdx));
40     DECODE_CHK_STATUS(AddHcpSliceState(cmdBuffer, sliceIdx, subTileIdx));
41     DECODE_CHK_STATUS(AddRefIdxState(cmdBuffer, sliceIdx));
42     DECODE_CHK_STATUS(AddWeightOffset(cmdBuffer, sliceIdx));
43     DECODE_CHK_STATUS(AddHcpCpState(cmdBuffer, sliceIdx, subTileIdx));
44     DECODE_CHK_STATUS(AddBsdObj(cmdBuffer, sliceIdx, subTileIdx));
45     return MOS_STATUS_SUCCESS;
46 }
47 
AddHcpPaletteInitializerState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx)48 MOS_STATUS HevcDecodeSlcPktM12::AddHcpPaletteInitializerState(
49     MOS_COMMAND_BUFFER &cmdBuffer,
50     uint32_t            sliceIdx)
51 {
52     const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
53     DECODE_CHK_NULL(sliceTileInfo);
54 
55     bool sccPaletteMode = m_hevcBasicFeature->m_isSCCPLTMode;
56     bool firstSliceOfTile = sliceTileInfo->firstSliceOfTile;
57     bool independentSlice = m_hevcBasicFeature->IsIndependentSlice(sliceIdx);
58 
59     if (sccPaletteMode && (firstSliceOfTile || independentSlice))
60     {
61         MhwVdboxHcpInterfaceG12* hcpInterfaceG12 = dynamic_cast<MhwVdboxHcpInterfaceG12*>(m_hcpInterface);
62         DECODE_CHK_NULL(hcpInterfaceG12);
63         DECODE_CHK_STATUS(hcpInterfaceG12->AddHcpPaletteInitializerStateCmd(&cmdBuffer, m_hevcSccPicParams));
64     }
65 
66     return MOS_STATUS_SUCCESS;
67 }
68 
SetHcpSliceStateParams(MHW_VDBOX_HEVC_SLICE_STATE & sliceStateParamsBase,uint32_t sliceIdx,uint32_t subTileIdx)69 MOS_STATUS HevcDecodeSlcPktM12::SetHcpSliceStateParams(
70     MHW_VDBOX_HEVC_SLICE_STATE &sliceStateParamsBase,
71     uint32_t                    sliceIdx,
72     uint32_t                    subTileIdx)
73 {
74     DECODE_FUNC_CALL();
75 
76     MHW_VDBOX_HEVC_SLICE_STATE_G12 &sliceStateParams =
77         static_cast<MHW_VDBOX_HEVC_SLICE_STATE_G12&>(sliceStateParamsBase);
78 
79     const HevcTileCoding::SliceTileInfo *sliceTileInfo = m_hevcBasicFeature->m_tileCoding.GetSliceTileInfo(sliceIdx);
80     DECODE_CHK_NULL(sliceTileInfo);
81     DECODE_CHK_STATUS(ValidateSubTileIdx(*sliceTileInfo, subTileIdx));
82 
83     DECODE_CHK_STATUS(HevcDecodeSlcPktXe_M_Base::SetHcpSliceStateParams(sliceStateParamsBase, sliceIdx, subTileIdx));
84 
85     sliceStateParams.pHevcExtPicParam    = m_hevcRextPicParams;
86     sliceStateParams.pHevcSccPicParam    = m_hevcSccPicParams;
87     sliceStateParams.pHevcExtSliceParams = m_hevcRextSliceParams + sliceIdx;
88 
89     sliceStateParams.u16OrigCtbX         = sliceTileInfo->origCtbX;
90     sliceStateParams.u16OrigCtbY         = sliceTileInfo->origCtbY;
91 
92     sliceStateParams.bTileInSlice        = sliceTileInfo->numTiles > 1;
93     if (sliceStateParams.bTileInSlice)
94     {
95         CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcBasicFeature->m_hevcSliceParams + sliceIdx;
96 
97         sliceStateParams.u16SliceHeaderLength = (subTileIdx == 0) ? sliceParams->ByteOffsetToSliceData : 0;
98         sliceStateParams.u16TileCtbX          = sliceTileInfo->tileArrayBuf[subTileIdx].ctbX;
99         sliceStateParams.u16TileCtbY          = sliceTileInfo->tileArrayBuf[subTileIdx].ctbY;
100         sliceStateParams.dwOffset             = sliceTileInfo->tileArrayBuf[subTileIdx].bsdOffset;
101         sliceStateParams.dwLength             = sliceTileInfo->tileArrayBuf[subTileIdx].bsdLength;
102         sliceStateParams.bLastSlice           = m_hevcBasicFeature->IsLastSlice(sliceIdx) &&
103                                                 (subTileIdx == sliceTileInfo->numTiles - 1);
104         sliceStateParams.bIsNotFirstTile      = (subTileIdx != 0);
105         sliceStateParams.bLastSliceInTile     = true;
106 
107         uint16_t tileY = (sliceTileInfo->sliceTileX + subTileIdx) / (m_hevcPicParams->num_tile_columns_minus1 + 1) +
108                          sliceTileInfo->sliceTileY;
109         sliceStateParams.bLastSliceInTileColumn = (tileY == m_hevcPicParams->num_tile_rows_minus1);
110 
111         if (sliceStateParams.bLastSlice)
112         {
113             sliceStateParams.u16NextTileCtbX = 0;
114             sliceStateParams.u16NextTileCtbY = 0;
115         }
116         else if (subTileIdx == sliceTileInfo->numTiles - 1)
117         {
118             sliceStateParams.u16NextTileCtbX = (sliceParams + 1)->slice_segment_address %
119                                                m_hevcBasicFeature->m_widthInCtb;
120             sliceStateParams.u16NextTileCtbY = (sliceParams + 1)->slice_segment_address /
121                                                m_hevcBasicFeature->m_widthInCtb;
122         }
123         else
124         {
125             sliceStateParams.u16NextTileCtbX = sliceTileInfo->tileArrayBuf[subTileIdx + 1].ctbX;
126             sliceStateParams.u16NextTileCtbY = sliceTileInfo->tileArrayBuf[subTileIdx + 1].ctbY;
127         }
128     }
129 
130     return MOS_STATUS_SUCCESS;
131 }
132 
AddHcpSliceState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx,uint32_t subTileIdx)133 MOS_STATUS HevcDecodeSlcPktM12::AddHcpSliceState(
134     MOS_COMMAND_BUFFER &cmdBuffer,
135     uint32_t           sliceIdx,
136     uint32_t           subTileIdx)
137 {
138     DECODE_FUNC_CALL();
139 
140     MHW_VDBOX_HEVC_SLICE_STATE_G12 sliceStateParams;
141     DECODE_CHK_STATUS(SetHcpSliceStateParams(sliceStateParams, sliceIdx, subTileIdx));
142     DECODE_CHK_STATUS(m_hcpInterface->AddHcpSliceStateCmd(&cmdBuffer, &sliceStateParams));
143 
144     return MOS_STATUS_SUCCESS;
145 }
146 
AddRefIdxState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t sliceIdx)147 MOS_STATUS HevcDecodeSlcPktM12::AddRefIdxState(
148     MOS_COMMAND_BUFFER &cmdBuffer,
149     uint32_t            sliceIdx)
150 {
151     CODEC_HEVC_SLICE_PARAMS *sliceParams = m_hevcBasicFeature->m_hevcSliceParams + sliceIdx;
152 
153     // Below cases don't need refIdxState command.
154     // 1. I slice in simulation.
155     // 2. I slice without dummy reference workaround.
156     if (m_hcpInterface->IsHevcISlice(sliceParams->LongSliceFlags.fields.slice_type) &&
157         (!m_hevcBasicFeature->m_useDummyReference || m_osInterface->bSimIsActive))
158     {
159         return MOS_STATUS_SUCCESS;
160     }
161 
162     MHW_VDBOX_HEVC_REF_IDX_PARAMS_G12 refIdxParams;
163 
164     DECODE_CHK_STATUS(SetRefIdxParams(refIdxParams, sliceIdx));
165     DECODE_CHK_STATUS(m_hcpInterface->AddHcpRefIdxStateCmd(&cmdBuffer, nullptr, &refIdxParams));
166 
167     if (m_hcpInterface->IsHevcBSlice(sliceParams->LongSliceFlags.fields.slice_type))
168     {
169         refIdxParams.ucList = 1;
170         refIdxParams.ucNumRefForList = sliceParams->num_ref_idx_l1_active_minus1 + 1;
171         DECODE_CHK_STATUS(m_hcpInterface->AddHcpRefIdxStateCmd(&cmdBuffer, nullptr, &refIdxParams));
172     }
173 
174     return MOS_STATUS_SUCCESS;
175 }
176 
177 }
178