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