1 /*
2 * Copyright (c) 2020-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 //!
24 //! \file decode_downsampling_feature.cpp
25 //! \brief Defines the common interface for decode downsampling features
26 //! \details The decode downsampling feature interface is further sub-divided by codec standard,
27 //! this file is for the base interface which is shared by all codecs.
28 //!
29 #include "decode_downsampling_feature.h"
30 #include "decode_utils.h"
31 #include "codechal_debug.h"
32
33 #ifdef _DECODE_PROCESSING_SUPPORTED
34
35 namespace decode
36 {
DecodeDownSamplingFeature(MediaFeatureManager * featureManager,DecodeAllocator * allocator,PMOS_INTERFACE osInterface)37 DecodeDownSamplingFeature::DecodeDownSamplingFeature(
38 MediaFeatureManager *featureManager, DecodeAllocator *allocator, PMOS_INTERFACE osInterface) :
39 m_osInterface(osInterface), m_allocator(allocator)
40 {
41 m_featureManager = featureManager;
42 }
43
~DecodeDownSamplingFeature()44 DecodeDownSamplingFeature::~DecodeDownSamplingFeature()
45 {
46 if (m_allocator != nullptr)
47 {
48 for (auto i = 0; i < DecodeBasicFeature::m_maxFrameIndex; i++)
49 {
50 MOS_BUFFER *histogramBuffer = m_histogramBufferList[i];
51 if (histogramBuffer == nullptr ||
52 m_allocator->ResourceIsNull(&histogramBuffer->OsResource))
53 {
54 continue;
55 }
56 MOS_STATUS eStatus = m_allocator->Destroy(m_histogramBuffer);
57 if (eStatus != MOS_STATUS_SUCCESS)
58 {
59 DECODE_ASSERTMESSAGE("Failed to free histogram internal buffer!");
60 }
61 }
62 }
63 }
64
Init(void * setting)65 MOS_STATUS DecodeDownSamplingFeature::Init(void *setting)
66 {
67 DECODE_FUNC_CALL();
68 DECODE_CHK_NULL(m_featureManager);
69 DECODE_CHK_NULL(m_allocator);
70
71 DECODE_CHK_STATUS(m_internalTargets.Init(*m_allocator));
72
73 m_basicFeature = dynamic_cast<DecodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
74 DECODE_CHK_NULL(m_basicFeature);
75
76 MOS_ZeroMemory(&m_outputSurface, sizeof(m_outputSurface));
77
78 DECODE_CHK_NULL(m_osInterface);
79 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
80
81 #if (_DEBUG || _RELEASE_INTERNAL)
82 m_histogramDebug = ReadUserFeature(m_userSettingPtr, "Decode Histogram Debug", MediaUserSetting::Group::Sequence).Get<bool>();
83 #endif
84
85 return MOS_STATUS_SUCCESS;
86 }
87
Update(void * params)88 MOS_STATUS DecodeDownSamplingFeature::Update(void *params)
89 {
90 DECODE_FUNC_CALL();
91 DECODE_CHK_NULL(params);
92
93 CodechalDecodeParams *decodeParams = (CodechalDecodeParams *)params;
94
95 if (decodeParams->m_procParams == nullptr)
96 {
97 m_inputSurface = nullptr;
98 m_enabled = false;
99 return MOS_STATUS_SUCCESS;
100 }
101 else
102 {
103 m_enabled = true;
104 }
105
106 DecodeProcessingParams *procParams = (DecodeProcessingParams *)decodeParams->m_procParams;
107
108 m_chromaSitingType = procParams->m_chromaSitingType;
109 m_rotationState = procParams->m_rotationState;
110 m_blendState = procParams->m_blendState;
111 m_mirrorState = procParams->m_mirrorState;
112 m_scalingMode = procParams->m_scalingMode;
113 m_isReferenceOnlyPattern = procParams->m_isReferenceOnlyPattern;
114
115 if (m_isReferenceOnlyPattern)
116 {
117 m_enabled = false;
118 m_inputSurface = procParams->m_inputSurface;
119 return MOS_STATUS_SUCCESS;
120 }
121
122 DECODE_CHK_NULL(procParams->m_outputSurface);
123 m_outputSurface = *(procParams->m_outputSurface);
124 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&m_outputSurface));
125
126 m_outputSurfaceRegion.m_x = procParams->m_outputSurfaceRegion.m_x;
127 m_outputSurfaceRegion.m_y = procParams->m_outputSurfaceRegion.m_y;
128 m_outputSurfaceRegion.m_width = (procParams->m_outputSurfaceRegion.m_width == 0) ?
129 m_outputSurface.dwWidth : procParams->m_outputSurfaceRegion.m_width;
130 m_outputSurfaceRegion.m_height = (procParams->m_outputSurfaceRegion.m_height == 0) ?
131 m_outputSurface.dwHeight : procParams->m_outputSurfaceRegion.m_height;
132
133 if (procParams->m_inputSurface != nullptr)
134 {
135 m_inputSurface = procParams->m_inputSurface;
136 DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(m_inputSurface));
137
138 m_inputSurfaceRegion.m_x = procParams->m_inputSurfaceRegion.m_x;
139 m_inputSurfaceRegion.m_y = procParams->m_inputSurfaceRegion.m_y;
140 m_inputSurfaceRegion.m_width = (procParams->m_inputSurfaceRegion.m_width == 0) ?
141 m_inputSurface->dwWidth : procParams->m_inputSurfaceRegion.m_width;
142 m_inputSurfaceRegion.m_height = (procParams->m_inputSurfaceRegion.m_height == 0) ?
143 m_inputSurface->dwHeight : procParams->m_inputSurfaceRegion.m_height;
144 }
145 else
146 {
147 if (m_basicFeature->m_curRenderPic.FrameIdx >= decodeParams->m_refFrameCnt)
148 {
149 DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Index !");
150 return MOS_STATUS_INVALID_PARAMETER;
151 }
152
153 DECODE_CHK_STATUS(UpdateInternalTargets(*m_basicFeature));
154
155 m_inputSurface = m_internalTargets.GetCurSurf();
156 DECODE_CHK_NULL(m_inputSurface);
157
158 m_inputSurfaceRegion.m_x = 0;
159 m_inputSurfaceRegion.m_y = 0;
160 m_inputSurfaceRegion.m_width = (procParams->m_inputSurfaceRegion.m_width == 0 || procParams->m_inputSurfaceRegion.m_width > m_basicFeature->m_width) ?
161 m_basicFeature->m_width : procParams->m_inputSurfaceRegion.m_width;
162 m_inputSurfaceRegion.m_height = (procParams->m_inputSurfaceRegion.m_height == 0 || procParams->m_inputSurfaceRegion.m_height > m_basicFeature->m_height) ?
163 m_basicFeature->m_height : procParams->m_inputSurfaceRegion.m_height;
164 }
165
166 // Histogram
167 if (m_allocator->ResourceIsNull(&decodeParams->m_histogramSurface.OsResource) && !m_histogramDebug)
168 {
169 m_histogramDestSurf = nullptr;
170 m_histogramBuffer = nullptr;
171 }
172 else
173 {
174 m_histogramDestSurf = &decodeParams->m_histogramSurface;
175 m_histogramBuffer = AllocateHistogramBuffer(m_basicFeature->m_curRenderPic.FrameIdx);
176 DECODE_CHK_NULL(m_histogramBuffer);
177 }
178
179 // Update decode output in basic feature
180 DECODE_CHK_STATUS(UpdateDecodeTarget(*m_inputSurface));
181
182 #if (_DEBUG || _RELEASE_INTERNAL)
183 m_outputSurfaceList[m_basicFeature->m_curRenderPic.FrameIdx] = m_outputSurface;
184 #endif
185
186 return MOS_STATUS_SUCCESS;
187 }
188
UpdateInternalTargets(DecodeBasicFeature & basicFeature)189 MOS_STATUS DecodeDownSamplingFeature::UpdateInternalTargets(DecodeBasicFeature &basicFeature)
190 {
191 DECODE_FUNC_CALL();
192
193 uint32_t curFrameIdx = basicFeature.m_curRenderPic.FrameIdx;
194
195 std::vector<uint32_t> refFrameList;
196 DECODE_CHK_STATUS(GetRefFrameList(refFrameList));
197 DECODE_CHK_STATUS(m_internalTargets.UpdateRefList(curFrameIdx, refFrameList));
198
199 MOS_SURFACE surface;
200 MOS_ZeroMemory(&surface, sizeof(surface));
201 DECODE_CHK_STATUS(GetDecodeTargetSize(surface.dwWidth, surface.dwHeight));
202 DECODE_CHK_STATUS(GetDecodeTargetFormat(surface.Format));
203 DECODE_CHK_STATUS(m_internalTargets.ActiveCurSurf(
204 curFrameIdx, &surface, basicFeature.IsMmcEnabled(), resourceOutputPicture, notLockableVideoMem));
205
206 return MOS_STATUS_SUCCESS;
207 }
208
AllocateHistogramBuffer(uint8_t frameIndex)209 PMOS_BUFFER DecodeDownSamplingFeature::AllocateHistogramBuffer(uint8_t frameIndex)
210 {
211 DECODE_FUNC_CALL();
212
213 if (frameIndex >= DecodeBasicFeature::m_maxFrameIndex)
214 {
215 return nullptr;
216 }
217
218 if (m_histogramBufferList[frameIndex] == nullptr)
219 {
220 auto histogramBuffer = m_allocator->AllocateBuffer(HISTOGRAM_BINCOUNT * m_histogramBinWidth,
221 "Histogram internal buffer",
222 resourceInternalReadWriteCache,
223 lockableVideoMem,
224 true,
225 0,
226 false);
227
228 if (histogramBuffer == nullptr ||
229 m_allocator->ResourceIsNull(&histogramBuffer->OsResource))
230 {
231 DECODE_ASSERTMESSAGE("Failed to allocate hsitogram internal buffer!");
232 }
233
234 m_histogramBufferList[frameIndex] = histogramBuffer;
235 }
236
237 return m_histogramBufferList[frameIndex];
238 }
239
DumpSfcOutputs(CodechalDebugInterface * debugInterface)240 MOS_STATUS DecodeDownSamplingFeature::DumpSfcOutputs(CodechalDebugInterface* debugInterface)
241 {
242 DECODE_FUNC_CALL();
243 DECODE_CHK_NULL(debugInterface);
244 DECODE_CHK_NULL(m_basicFeature);
245
246 // Dump histogram
247 if ((m_histogramDestSurf != nullptr || m_histogramDebug) &&
248 m_histogramBuffer != nullptr &&
249 !m_allocator->ResourceIsNull(&m_histogramBuffer->OsResource))
250 {
251 CODECHAL_DEBUG_TOOL(
252 debugInterface->m_bufferDumpFrameNum = m_basicFeature->m_frameNum;
253 DECODE_CHK_STATUS(debugInterface->DumpBuffer(
254 &m_histogramBuffer->OsResource,
255 CodechalDbgAttr::attrSfcHistogram,
256 "_DEC",
257 HISTOGRAM_BINCOUNT * m_histogramBinWidth));)
258 }
259
260 // Dump SFC
261 if (!m_allocator->ResourceIsNull(&m_outputSurface.OsResource) &&
262 m_inputSurface != nullptr)
263 {
264 CODECHAL_DEBUG_TOOL(
265 debugInterface->m_bufferDumpFrameNum = m_basicFeature->m_frameNum;
266 DECODE_CHK_STATUS(debugInterface->DumpYUVSurface(
267 &m_outputSurface,
268 CodechalDbgAttr::attrSfcOutputSurface,
269 "_SFCSurf"));)
270 }
271
272 return MOS_STATUS_SUCCESS;
273 }
274 }
275
276 #endif
277