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