1 /*
2 * Copyright (c) 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_mpeg2_slice_packet_xe_m_base.cpp
24 //! \brief    Defines the interface of mpeg2 decode slice packet for Xe_M_Base
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_mpeg2_slice_packet_xe_m_base.h"
28 
29 namespace decode {
30 
Init()31     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::Init()
32     {
33         DECODE_FUNC_CALL();
34 
35         DECODE_CHK_NULL(m_featureManager);
36         DECODE_CHK_NULL(m_hwInterface);
37         DECODE_CHK_NULL(m_osInterface);
38         DECODE_CHK_NULL(m_miInterface);
39         DECODE_CHK_NULL(m_mpeg2Pipeline);
40         DECODE_CHK_NULL(m_mfxInterface);
41 
42         m_mpeg2BasicFeature = dynamic_cast<Mpeg2BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
43         DECODE_CHK_NULL(m_mpeg2BasicFeature);
44 
45         m_allocator = m_pipeline->GetDecodeAllocator();
46         DECODE_CHK_NULL(m_allocator);
47 
48         m_decodecp = m_pipeline->GetDecodeCp();
49 
50         DECODE_CHK_STATUS(CalculateSliceStateCommandSize());
51 
52         return MOS_STATUS_SUCCESS;
53     }
54 
Prepare()55     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::Prepare()
56     {
57         DECODE_FUNC_CALL();
58 
59         DECODE_CHK_NULL(m_mpeg2BasicFeature->m_mpeg2PicParams);
60         DECODE_CHK_NULL(m_mpeg2BasicFeature->m_mpeg2SliceParams);
61 
62         m_mpeg2PicParams = m_mpeg2BasicFeature->m_mpeg2PicParams;
63 
64         return MOS_STATUS_SUCCESS;
65     }
66 
SetMpeg2SliceStateParams(MHW_VDBOX_MPEG2_SLICE_STATE & mpeg2SliceState,uint16_t slcIdx)67     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::SetMpeg2SliceStateParams(
68         MHW_VDBOX_MPEG2_SLICE_STATE& mpeg2SliceState, uint16_t slcIdx)
69     {
70         DECODE_FUNC_CALL();
71 
72         MOS_ZeroMemory(&mpeg2SliceState, sizeof(mpeg2SliceState));
73         CodecDecodeMpeg2SliceParams* slc = &m_mpeg2BasicFeature->m_sliceRecord[slcIdx].recordSliceParam;
74 
75         mpeg2SliceState.presDataBuffer = &m_mpeg2BasicFeature->m_resDataBuffer.OsResource;
76         mpeg2SliceState.wPicWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
77         mpeg2SliceState.wPicHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
78         mpeg2SliceState.pMpeg2SliceParams = slc;
79         mpeg2SliceState.dwLength = m_mpeg2BasicFeature->m_sliceRecord[slcIdx].length;
80         mpeg2SliceState.dwOffset = m_mpeg2BasicFeature->m_sliceRecord[slcIdx].offset;
81         mpeg2SliceState.dwSliceStartMbOffset = m_mpeg2BasicFeature->m_sliceRecord[slcIdx].sliceStartMbOffset;
82         mpeg2SliceState.bLastSlice = m_mpeg2BasicFeature->m_sliceRecord[slcIdx].isLastSlice;
83 
84         return MOS_STATUS_SUCCESS;
85     }
86 
AddBsdObj(MHW_BATCH_BUFFER & batchBuffer,uint16_t slcIdx)87     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::AddBsdObj(MHW_BATCH_BUFFER& batchBuffer, uint16_t slcIdx)
88     {
89         DECODE_FUNC_CALL();
90 
91         MHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState;
92         DECODE_CHK_STATUS(SetMpeg2SliceStateParams(mpeg2SliceState, slcIdx));
93         DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2BsdObject(
94             nullptr,
95             &batchBuffer,
96             &mpeg2SliceState));
97 
98         return MOS_STATUS_SUCCESS;
99     }
100 
InsertDummySlice(MHW_BATCH_BUFFER & batchBuffer,uint16_t startMB,uint16_t endMB)101     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::InsertDummySlice(
102         MHW_BATCH_BUFFER& batchBuffer,
103         uint16_t startMB,
104         uint16_t endMB)
105     {
106         DECODE_FUNC_CALL();
107 
108         MHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState;
109         CodecDecodeMpeg2SliceParams slc;
110         MOS_ZeroMemory(&mpeg2SliceState, sizeof(mpeg2SliceState));
111         MOS_ZeroMemory(&slc, sizeof(CodecDecodeMpeg2SliceParams));
112 
113         uint16_t intraVLDFormat = m_mpeg2PicParams->W0.m_intraVlcFormat;
114         uint16_t quantizerScaleType = m_mpeg2PicParams->W0.m_quantizerScaleType;
115         uint16_t dummySliceIndex = quantizerScaleType * 2 + intraVLDFormat;
116 
117         mpeg2SliceState.presDataBuffer = nullptr;
118         mpeg2SliceState.wPicWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
119         mpeg2SliceState.wPicHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
120         mpeg2SliceState.dwLength = m_mpeg2BasicFeature->Mpeg2DummySliceLengths[dummySliceIndex];
121         mpeg2SliceState.dwOffset = m_mpeg2BasicFeature->Mpeg2DummySliceOffsets[dummySliceIndex] +
122             m_mpeg2BasicFeature->m_dummySliceDataOffset;
123         // force disable cp for dummy slices
124         bool isCpEnabled = false;
125         if (m_decodecp)
126         {
127             isCpEnabled = m_decodecp->IsCpEnabled();
128             if (isCpEnabled)
129             {
130                 m_decodecp->SetCpEnabled(false);
131             }
132         }
133 
134         bool isLastSlice = false;
135         uint16_t expectedEndMB = m_mpeg2BasicFeature->m_picWidthInMb * m_mpeg2BasicFeature->m_picHeightInMb;
136 
137         while (startMB < endMB)
138         {
139             slc.m_macroblockOffset = 6;
140             slc.m_sliceHorizontalPosition = startMB % m_mpeg2BasicFeature->m_picWidthInMb;
141             slc.m_sliceVerticalPosition = startMB / m_mpeg2BasicFeature->m_picWidthInMb;
142             slc.m_quantiserScaleCode = 10;
143             slc.m_numMbsForSlice = 1;
144 
145             isLastSlice = ((startMB + 1) == expectedEndMB);
146 
147             mpeg2SliceState.pMpeg2SliceParams = &slc;
148             mpeg2SliceState.dwSliceStartMbOffset = startMB;
149             mpeg2SliceState.bLastSlice = isLastSlice;
150 
151             DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2BsdObject(
152                 nullptr,
153                 &batchBuffer,
154                 &mpeg2SliceState));
155 
156             startMB++;
157         }
158 
159         // restore Cp state
160         if (m_decodecp && isCpEnabled)
161         {
162             m_decodecp->SetCpEnabled(true);
163         }
164 
165         return MOS_STATUS_SUCCESS;
166     }
167 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)168     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::CalculateCommandSize(uint32_t& commandBufferSize,
169         uint32_t& requestedPatchListSize)
170     {
171         DECODE_FUNC_CALL();
172 
173         commandBufferSize = m_sliceStatesSize;
174         requestedPatchListSize = m_slicePatchListSize;
175 
176         return MOS_STATUS_SUCCESS;
177     }
178 
CalculateSliceStateCommandSize()179     MOS_STATUS Mpeg2DecodeSlcPktXe_M_Base::CalculateSliceStateCommandSize()
180     {
181         DECODE_FUNC_CALL();
182 
183         // Slice Level Commands
184         DECODE_CHK_STATUS(m_hwInterface->GetMfxPrimitiveCommandsDataSize(
185             m_mpeg2BasicFeature->m_mode,
186             &m_sliceStatesSize,
187             &m_slicePatchListSize,
188             0));
189 
190         return MOS_STATUS_SUCCESS;
191     }
192 
193 }  // namespace decode
194