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