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