1 /*
2 * Copyright (c) 2017, 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     codechal_decode_histogram_vebox.cpp
24 //! \brief    implements the decode histogram through vebox.
25 //! \details  decode histogram through vebox.
26 //!
27 #include "codechal_decode_histogram_vebox.h"
28 #include "mos_utilities.h"
29 
CodechalDecodeHistogramVebox(CodechalHwInterface * hwInterface,MOS_INTERFACE * osInterface)30 CodechalDecodeHistogramVebox::CodechalDecodeHistogramVebox(
31     CodechalHwInterface *hwInterface,
32     MOS_INTERFACE *osInterface):
33     CodechalDecodeHistogram(hwInterface, osInterface),
34     m_veboxInterface(hwInterface->GetVeboxInterface())
35 {
36     MOS_ZeroMemory(&m_resSyncObject, sizeof(m_resSyncObject));
37     MOS_ZeroMemory(&m_resStatisticsOutput, sizeof(m_resStatisticsOutput));
38     MOS_ZeroMemory(&m_outputSurface, sizeof(m_outputSurface));
39     // allocate heap
40     m_veboxInterface->CreateHeap();
41 
42     // create Vebox context
43     MOS_GPUCTX_CREATOPTIONS  createOpts;
44     m_osInterface->pfnCreateGpuContext(
45         m_osInterface,
46         MOS_GPU_CONTEXT_VEBOX,
47         MOS_GPU_NODE_VE,
48         &createOpts);
49 
50     // register Vebox GPU context with the Batch Buffer completion event
51     m_osInterface->pfnRegisterBBCompleteNotifyEvent(
52         m_osInterface,
53         MOS_GPU_CONTEXT_VEBOX);
54 }
55 
~CodechalDecodeHistogramVebox()56 CodechalDecodeHistogramVebox::~CodechalDecodeHistogramVebox()
57 {
58     if (!Mos_ResourceIsNull(&m_resSyncObject))
59     {
60         m_osInterface->pfnDestroySyncResource(m_osInterface, &m_resSyncObject);
61     }
62     if (!Mos_ResourceIsNull(&m_resStatisticsOutput))
63     {
64         m_osInterface->pfnFreeResource(m_osInterface, &m_resStatisticsOutput);
65     }
66     if (!Mos_ResourceIsNull(&m_outputSurface.OsResource))
67     {
68         m_osInterface->pfnFreeResource(m_osInterface, &m_outputSurface.OsResource);
69     }
70 }
71 
AllocateResources()72 MOS_STATUS CodechalDecodeHistogramVebox::AllocateResources()
73 {
74     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
75 
76     CODECHAL_HW_FUNCTION_ENTER;
77 
78     // allocate sync object
79     if (Mos_ResourceIsNull(&m_resSyncObject))
80     {
81         CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
82             m_osInterface, &m_resSyncObject));
83     }
84 
85     uint32_t size = 0;
86     // allocate internal histogram resource
87     if (Mos_ResourceIsNull(&m_resHistogram) ||
88         m_preWidth != m_inputSurface->dwWidth ||
89         m_preHeight != m_inputSurface->dwHeight)
90     {
91         // Need to reallocate
92         if (m_preWidth != m_inputSurface->dwWidth ||
93             m_preHeight != m_inputSurface->dwHeight)
94         {
95             m_osInterface->pfnFreeResource(m_osInterface, &m_resHistogram);
96         }
97 
98         m_hwInterface->GetHcpInterface()->GetOsResLaceOrAceOrRgbHistogramBufferSize(
99             m_inputSurface->dwWidth,
100             m_inputSurface->dwHeight,
101             &size);
102 
103         MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
104         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
105         allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
106         allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
107         allocParamsForBufferLinear.Format = Format_Buffer;
108         allocParamsForBufferLinear.dwBytes = size;
109         allocParamsForBufferLinear.pBufName = "ResLaceOrAceOrRgbHistogram";
110 
111         eStatus = m_osInterface->pfnAllocateResource(
112             m_osInterface,
113             &allocParamsForBufferLinear,
114             &m_resHistogram);
115 
116         if (eStatus != MOS_STATUS_SUCCESS)
117         {
118             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate histogram buffer.");
119             return eStatus;
120         }
121     }
122 
123     // allocate statistics output resource to avoid Page Fault issue since HW will access it
124     if (Mos_ResourceIsNull(&m_resStatisticsOutput) ||
125         m_preWidth != m_inputSurface->dwWidth ||
126         m_preHeight != m_inputSurface->dwHeight)
127     {
128         // Need to reallocate
129         if (m_preWidth != m_inputSurface->dwWidth ||
130             m_preHeight != m_inputSurface->dwHeight)
131         {
132             m_osInterface->pfnFreeResource(m_osInterface, &m_resStatisticsOutput);
133         }
134 
135         m_hwInterface->GetHcpInterface()->GetOsResStatisticsOutputBufferSize(
136             m_inputSurface->dwWidth,
137             m_inputSurface->dwHeight,
138             &size);
139 
140         MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
141         MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
142         allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
143         allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
144         allocParamsForBufferLinear.Format = Format_Buffer;
145         allocParamsForBufferLinear.dwBytes = size;
146         allocParamsForBufferLinear.pBufName = "m_resStatisticsOutput";
147 
148         eStatus = m_osInterface->pfnAllocateResource(
149             m_osInterface,
150             &allocParamsForBufferLinear,
151             &m_resStatisticsOutput);
152 
153         if (eStatus != MOS_STATUS_SUCCESS)
154         {
155             CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate statistics output buffer.");
156             return eStatus;
157         }
158     }
159 
160     // allocate vebox output surface
161     if (Mos_ResourceIsNull(&m_outputSurface.OsResource) ||
162         m_preWidth != m_inputSurface->dwWidth ||
163         m_preHeight != m_inputSurface->dwHeight)
164     {
165         // Need to reallocate
166         if (m_preWidth != m_inputSurface->dwWidth ||
167             m_preHeight != m_inputSurface->dwHeight)
168         {
169             m_osInterface->pfnFreeResource(m_osInterface, &m_outputSurface.OsResource);
170         }
171 
172         CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(m_decoder->AllocateSurface(
173                                                       &m_outputSurface,
174                                                       m_inputSurface->dwWidth,
175                                                       m_inputSurface->dwHeight,
176                                                       "VeboxOutputBuffer"),
177             "Failed to allocate vebox output surface buffer.");
178     }
179 
180     m_preWidth  = m_inputSurface->dwWidth;
181     m_preHeight = m_inputSurface->dwHeight;
182 
183     return eStatus;
184 }
185 
SetVeboxStateParams(PMHW_VEBOX_STATE_CMD_PARAMS veboxCmdParams)186 MOS_STATUS CodechalDecodeHistogramVebox::SetVeboxStateParams(
187     PMHW_VEBOX_STATE_CMD_PARAMS veboxCmdParams)
188 {
189     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
190 
191     CODECHAL_HW_FUNCTION_ENTER;
192 
193     veboxCmdParams->bNoUseVeboxHeap                         = 0;
194 
195     veboxCmdParams->VeboxMode.ColorGamutExpansionEnable     = 0;
196     veboxCmdParams->VeboxMode.ColorGamutCompressionEnable   = 0;
197     // On SKL, GlobalIECP must be enabled when the output pipe is Vebox or SFC
198     veboxCmdParams->VeboxMode.GlobalIECPEnable              = 1;
199     veboxCmdParams->VeboxMode.DNEnable                      = 0;
200     veboxCmdParams->VeboxMode.DIEnable                      = 0;
201     veboxCmdParams->VeboxMode.DNDIFirstFrame                = 0;
202     veboxCmdParams->VeboxMode.DIOutputFrames                = 0;
203     veboxCmdParams->VeboxMode.PipeSynchronizeDisable        = 0;
204     veboxCmdParams->VeboxMode.DemosaicEnable                = 0;
205     veboxCmdParams->VeboxMode.VignetteEnable                = 0;
206     veboxCmdParams->VeboxMode.AlphaPlaneEnable              = 0;
207     veboxCmdParams->VeboxMode.HotPixelFilteringEnable       = 0;
208     // 0-both slices enabled   1-Slice 0 enabled   2-Slice 1 enabled
209     // On SKL GT3 and GT4, there are 2 Veboxes. But only Vebox0 can be used,Vebox1 cannot be used
210     veboxCmdParams->VeboxMode.SingleSliceVeboxEnable        = 1;
211     veboxCmdParams->VeboxMode.LACECorrectionEnable          = 0;
212     veboxCmdParams->VeboxMode.DisableEncoderStatistics      = 1;
213     veboxCmdParams->VeboxMode.DisableTemporalDenoiseFilter  = 1;
214     veboxCmdParams->VeboxMode.SinglePipeIECPEnable          = 0;
215     veboxCmdParams->VeboxMode.SFCParallelWriteEnable        = 0;
216     veboxCmdParams->VeboxMode.ScalarMode                    = 0;
217     veboxCmdParams->VeboxMode.ForwardGammaCorrectionEnable  = 0;
218 
219     return eStatus;
220 }
221 
SetVeboxSurfaceStateParams(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS veboxSurfParams)222 MOS_STATUS CodechalDecodeHistogramVebox::SetVeboxSurfaceStateParams(
223     PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS veboxSurfParams)
224 {
225     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
226 
227     CODECHAL_HW_FUNCTION_ENTER;
228 
229     // Initialize SurfInput
230     veboxSurfParams->SurfInput.bActive          = true;
231     veboxSurfParams->SurfInput.Format           = m_inputSurface->Format;
232     veboxSurfParams->SurfInput.dwWidth          = m_inputSurface->dwWidth;
233     veboxSurfParams->SurfInput.dwHeight         = m_inputSurface->UPlaneOffset.iYOffset;  // For Planar formats, pParams->SurfInput.dwHeight will be assigned to VEBOX U.Y offset, which is only used for PLANAR surface formats.
234     veboxSurfParams->SurfInput.dwUYoffset       = m_inputSurface->UPlaneOffset.iYOffset;
235     veboxSurfParams->SurfInput.dwPitch          = m_inputSurface->dwPitch;
236     veboxSurfParams->SurfInput.TileType         = m_inputSurface->TileType;
237     veboxSurfParams->SurfInput.TileModeGMM      = m_inputSurface->TileModeGMM;
238     veboxSurfParams->SurfInput.bGMMTileEnabled  = m_inputSurface->bGMMTileEnabled;
239     veboxSurfParams->SurfInput.pOsResource      = &m_inputSurface->OsResource;
240     veboxSurfParams->SurfInput.rcMaxSrc.left    = 0;
241     veboxSurfParams->SurfInput.rcMaxSrc.top     = 0;
242     veboxSurfParams->SurfInput.rcMaxSrc.right =
243         MOS_ALIGN_CEIL(m_inputSurface->dwWidth, MHW_SFC_VE_WIDTH_ALIGN);
244     veboxSurfParams->SurfInput.rcMaxSrc.bottom =
245         MOS_ALIGN_CEIL(m_inputSurface->dwHeight, MHW_SFC_VE_HEIGHT_ALIGN);
246 
247     // Initialize SurfSTMM
248     veboxSurfParams->SurfSTMM.dwPitch = m_inputSurface->dwPitch;
249 
250     veboxSurfParams->bDIEnable                  = false;
251     veboxSurfParams->bOutputValid               = false;
252 
253     return eStatus;
254 }
255 
SetVeboxDiIecpParams(PMHW_VEBOX_DI_IECP_CMD_PARAMS veboxDiIecpParams)256 MOS_STATUS CodechalDecodeHistogramVebox::SetVeboxDiIecpParams(
257     PMHW_VEBOX_DI_IECP_CMD_PARAMS veboxDiIecpParams)
258 {
259     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
260 
261     CODECHAL_HW_FUNCTION_ENTER;
262 
263     veboxDiIecpParams->dwStartingX              = 0;
264     veboxDiIecpParams->dwEndingX                = m_inputSurface->dwWidth - 1;
265     veboxDiIecpParams->dwCurrInputSurfOffset    = m_inputSurface->dwOffset;
266     veboxDiIecpParams->pOsResCurrInput          = &m_inputSurface->OsResource;
267     veboxDiIecpParams->pOsResCurrOutput         = &m_outputSurface.OsResource;
268     veboxDiIecpParams->CurrInputSurfCtrl.Value  = 0;
269     veboxDiIecpParams->CurrOutputSurfCtrl.Value = 0;
270 
271     CodecHalGetResourceInfo(m_osInterface, m_inputSurface);
272     CodecHalGetResourceInfo(m_osInterface, &m_outputSurface);
273 
274     veboxDiIecpParams->CurInputSurfMMCState =
275         (MOS_MEMCOMP_STATE)(m_inputSurface->CompressionMode);
276     veboxDiIecpParams->pOsResLaceOrAceOrRgbHistogram    = &m_resHistogram;
277     veboxDiIecpParams->pOsResStatisticsOutput           = &m_resStatisticsOutput;
278 
279     return eStatus;
280 }
281 
SetVeboxIecpParams(PMHW_VEBOX_IECP_PARAMS veboxIecpParams)282 MOS_STATUS CodechalDecodeHistogramVebox::SetVeboxIecpParams(
283     PMHW_VEBOX_IECP_PARAMS veboxIecpParams)
284 {
285     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
286 
287     CODECHAL_HW_FUNCTION_ENTER;
288 
289     veboxIecpParams->ColorPipeParams.bActive    = true;
290     veboxIecpParams->ColorPipeParams.bEnableACE = true;
291     veboxIecpParams->AceParams.bActive          = true;
292     veboxIecpParams->srcFormat                  = m_inputSurface->Format;
293     veboxIecpParams->bCSCEnable                 = false;
294 
295     return eStatus;
296 }
297 
RenderHistogram(CodechalDecode * codechalDecoder,MOS_SURFACE * inputSurface)298 MOS_STATUS CodechalDecodeHistogramVebox::RenderHistogram(
299     CodechalDecode *codechalDecoder,
300     MOS_SURFACE *inputSurface)
301 {
302     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
303 
304     CODECHAL_HW_FUNCTION_ENTER;
305 
306     if (Mos_ResourceIsNull(&m_inputHistogramSurfaces[m_histogramComponent].OsResource))
307     {
308         CODECHAL_DECODE_VERBOSEMESSAGE("Input histogram surface is null");
309         return MOS_STATUS_INVALID_PARAMETER;
310     }
311 
312     m_decoder       = codechalDecoder;
313     m_inputSurface  = inputSurface;
314 
315     AllocateResources();
316 
317     MOS_SYNC_PARAMS syncParams  = g_cInitSyncParams;
318     syncParams.GpuContext       = m_decoder->GetVideoContext();
319     syncParams.presSyncResource = &m_resSyncObject;
320 
321     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
322         m_osInterface,
323         &syncParams));
324 
325     syncParams                  = g_cInitSyncParams;
326     syncParams.GpuContext       = MOS_GPU_CONTEXT_VEBOX;
327     syncParams.presSyncResource = &m_resSyncObject;
328 
329     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
330         m_osInterface,
331         &syncParams));
332 
333     // Switch GPU context to VEBOX
334     m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
335     // Reset allocation list and house keeping
336     m_osInterface->pfnResetOsStates(m_osInterface);
337 
338     // Send command buffer header at the beginning
339     MOS_COMMAND_BUFFER cmdBuffer;
340     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
341     CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
342         m_osInterface,
343         &cmdBuffer,
344         0));
345     CODECHAL_HW_CHK_STATUS_RETURN(m_decoder->SendPrologWithFrameTracking(
346         &cmdBuffer,
347         true));
348 
349     // Setup cmd prameters
350     MHW_VEBOX_STATE_CMD_PARAMS veboxStateCmdParams;
351     MOS_ZeroMemory(&veboxStateCmdParams, sizeof(veboxStateCmdParams));
352     CODECHAL_HW_CHK_STATUS_RETURN(SetVeboxStateParams(&veboxStateCmdParams));
353 
354     MHW_VEBOX_SURFACE_STATE_CMD_PARAMS veboxSurfaceStateCmdParams;
355     MOS_ZeroMemory(&veboxSurfaceStateCmdParams, sizeof(veboxSurfaceStateCmdParams));
356     CODECHAL_HW_CHK_STATUS_RETURN(SetVeboxSurfaceStateParams(&veboxSurfaceStateCmdParams));
357 
358     MHW_VEBOX_DI_IECP_CMD_PARAMS veboxDiIecpCmdParams;
359     MOS_ZeroMemory(&veboxDiIecpCmdParams, sizeof(veboxDiIecpCmdParams));
360     CODECHAL_HW_CHK_STATUS_RETURN(SetVeboxDiIecpParams(&veboxDiIecpCmdParams));
361 
362     MHW_VEBOX_IECP_PARAMS veboxIecpParams;
363     MOS_ZeroMemory(&veboxIecpParams, sizeof(veboxIecpParams));
364     CODECHAL_HW_CHK_STATUS_RETURN(SetVeboxIecpParams(&veboxIecpParams));
365 
366     // send Vebox cmd
367     CODECHAL_HW_CHK_STATUS_RETURN(m_veboxInterface->AddVeboxIecpState(
368         &veboxIecpParams));
369 
370     CODECHAL_HW_CHK_STATUS_RETURN(m_veboxInterface->AddVeboxState(
371         &cmdBuffer,
372         &veboxStateCmdParams, 0));
373 
374     CODECHAL_HW_CHK_STATUS_RETURN(m_veboxInterface->AddVeboxSurfaces(
375         &cmdBuffer,
376         &veboxSurfaceStateCmdParams));
377 
378     CODECHAL_HW_CHK_STATUS_RETURN(m_veboxInterface->AddVeboxDiIecp(
379         &cmdBuffer,
380         &veboxDiIecpCmdParams));
381 
382     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(
383         &cmdBuffer,
384         nullptr));
385 
386     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
387     CODECHAL_HW_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
388         m_osInterface,
389         &cmdBuffer,
390         m_decoder->GetVideoContextUsesNullHw()));
391 
392     m_osInterface->pfnFreeResource(
393         m_osInterface,
394         &veboxStateCmdParams.DummyIecpResource);
395 
396     // copy histogram to input buffer
397     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
398         m_osInterface, m_decoder->GetVideoWAContext()));
399     m_osInterface->pfnResetOsStates(m_osInterface);
400 
401     m_osInterface->pfnSetPerfTag(
402         m_osInterface,
403         (uint16_t)(((m_decoder->GetMode() << 4) & 0xF0) | COPY_TYPE));
404     m_osInterface->pfnResetPerfBufferID(m_osInterface);
405 
406     MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
407     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
408         m_osInterface,
409         &cmdBuffer,
410         0));
411 
412     CODECHAL_DECODE_CHK_STATUS_RETURN(m_decoder->SendPrologWithFrameTracking(
413         &cmdBuffer,
414         false));
415 
416     CODECHAL_DECODE_CHK_STATUS_RETURN(m_decoder->HucCopy(
417         &cmdBuffer,
418         &m_resHistogram,
419         &m_inputHistogramSurfaces[m_histogramComponent].OsResource,
420         HISTOGRAM_BINCOUNT * 4,
421         m_veboxHistogramOffset,
422         m_inputHistogramSurfaces[m_histogramComponent].dwOffset));
423 
424     MHW_MI_FLUSH_DW_PARAMS flushDwParams;
425     MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
426     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiFlushDwCmd(
427         &cmdBuffer,
428         &flushDwParams));
429 
430     CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(
431         &cmdBuffer,
432         nullptr));
433 
434     m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
435 
436     // sync resource
437     syncParams = g_cInitSyncParams;
438     syncParams.GpuContext = MOS_GPU_CONTEXT_VEBOX;
439     syncParams.presSyncResource = &m_resSyncObject;
440     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(
441         m_osInterface,
442         &syncParams));
443 
444     syncParams = g_cInitSyncParams;
445     syncParams.GpuContext = m_decoder->GetVideoWAContext();
446     syncParams.presSyncResource = &m_resSyncObject;
447     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(
448         m_osInterface,
449         &syncParams));
450 
451     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
452         m_osInterface,
453         &cmdBuffer,
454         m_decoder->GetVideoContextUsesNullHw()));
455 
456     CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
457         m_osInterface,
458         m_decoder->GetVideoContext()));
459 
460     MOS_USER_FEATURE_VALUE_WRITE_DATA userFeatureWriteData;
461     MOS_ZeroMemory(&userFeatureWriteData, sizeof(userFeatureWriteData));
462     userFeatureWriteData.Value.i32Data = 1;
463     userFeatureWriteData.ValueID       = __MEDIA_USER_FEATURE_VALUE_DECODE_HISTOGRAM_FROM_VEBOX_ID;
464     MOS_UserFeature_WriteValues_ID(nullptr, &userFeatureWriteData, 1);
465 
466     return eStatus;
467 }
468