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