1 /*
2 * Copyright (c) 2017-2019, 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_encode_tracked_buffer.cpp
24 //! \brief    Class to manage tracked buffer used in encoder
25 //!
26 
27 #include "codechal_encode_tracked_buffer.h"
28 #include "codechal_encoder_base.h"
29 
AllocateForCurrFrame()30 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateForCurrFrame()
31 {
32     CODEC_REF_LIST* currRefList = m_encoder->m_currRefList;
33 
34     // in case of resolution change, defer-deallocate remaining 3 buffers from last session
35     if (m_trackedBufCountResize)
36     {
37         DeferredDeallocateOnResChange();
38         m_trackedBufCountResize--;
39     }
40 
41     // update the last 3 buffer index, find a new slot for current frame
42     m_trackedBufAnteIdx = m_trackedBufPenuIdx;
43     m_trackedBufPenuIdx = m_trackedBufCurrIdx;
44     m_trackedBufCurrIdx = LookUpBufIndex(currRefList->RefList, currRefList->ucNumRef, currRefList->bUsedAsRef);
45 
46     CODECHAL_ENCODE_CHK_COND_RETURN(m_trackedBufCurrIdx >= CODEC_NUM_TRACKED_BUFFERS, "No tracked buffer is available!");
47 
48     // wait to re-use once # of non-ref slots being used reaches 3
49     m_waitTrackedBuffer = (m_trackedBufCurrIdx >= CODEC_NUM_REF_BUFFERS && m_trackedBufCountNonRef >= CODEC_NUM_NON_REF_BUFFERS);
50 
51     CODECHAL_ENCODE_NORMALMESSAGE("currFrame = %d, currRef = %d, ucNumRef = %d, usedAsRef = %d, tracked buf index = %d",
52         m_encoder->m_currOriginalPic.FrameIdx, m_encoder->m_currReconstructedPic.FrameIdx,
53         currRefList->ucNumRef, currRefList->bUsedAsRef, m_trackedBufCurrIdx);
54 
55     if (m_allocateMbCode)
56     {
57         LookUpBufIndexMbCode();
58         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateMbCodeResources(m_mbCodeCurrIdx));
59 
60         // for non-AVC codec, MbCode and MvData surface are combined, this function won't be called
61         if (m_encoder->m_mvDataSize)
62         {
63             CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateMvDataResources(m_trackedBufCurrIdx));
64         }
65     }
66 
67     // allocate MV temporal buffer
68     AllocateMvTemporalBuffer(m_trackedBufCurrIdx);
69 
70     // allocate VDEnc downscaled recon surface
71     if (m_encoder->m_vdencEnabled)
72     {
73         CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateDsReconSurfacesVdenc());
74         //re-allocate VDEnc downscaled recon surface in case there is resolution change
75         if (CODECHAL_VP9 == m_standard)
76         {
77             CODECHAL_ENCODE_CHK_STATUS_RETURN(ResizeDsReconSurfacesVdenc());
78         }
79     }
80     return MOS_STATUS_SUCCESS;
81 }
82 
83 /*
84 * When resolution changes, tracked buffers used by earlier submitted frames may not have finished execution,
85 * destruction of these in-the-fly buffers need to be deferred after execution completes
86 * We make a resonable assumption that the number of unfinished frames should not exceed 3, and free all other
87 * existing buffers except the last 3 used
88 * Inside LookUpBufIndex(), the counter is checked and decremented, each time freeing
89 * one of the remaining 3 buffers in previous encode session/sequence (with old resolution)
90 * The net result is that 3 frames into the new encode session/sequence, all tracked buffers have been re-allocated
91 * according to the new resolution
92 */
Resize()93 void CodechalEncodeTrackedBuffer::Resize()
94 {
95     CODECHAL_ENCODE_FUNCTION_ENTER;
96 
97     // free existing allocations except last 3 slots
98     m_trackedBufCountResize = CODEC_NUM_NON_REF_BUFFERS;
99     for (uint8_t i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
100     {
101         if (m_trackedBufAnteIdx != i && m_trackedBufPenuIdx != i && m_trackedBufCurrIdx != i)
102         {
103             if (m_mbCodeIsTracked)
104             {
105                 ReleaseMbCode(i);
106             }
107             ReleaseMvData(i);
108             ReleaseDsRecon(i);
109             if (m_encoder->m_cscDsState)
110                 ReleaseSurfaceDS(i);
111             if (m_encoder->m_vdencEnabled)
112                 m_allocator->ReleaseResource(m_standard, mvTemporalBuffer, i);
113 
114             // this slot can now be re-used
115             m_tracker[i].ucSurfIndex7bits = PICTURE_MAX_7BITS;
116         }
117         else
118         {
119             m_tracker[i].ucSurfIndex7bits = PICTURE_RESIZE;
120         }
121     }
122     if (m_encoder->m_cscDsState)
123         ResizeCsc();
124 
125     return;
126 }
127 
ResizeCsc()128 void CodechalEncodeTrackedBuffer::ResizeCsc()
129 {
130     // free CSC surfaces except last 3 slots
131     for (uint8_t i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
132     {
133         if (m_cscBufAnteIdx != i && m_cscBufPenuIdx != i && m_cscBufCurrIdx != i)
134         {
135             ReleaseSurfaceCsc(i);
136         }
137     }
138 }
139 
AllocateForCurrFramePreenc(uint8_t bufIndex)140 void CodechalEncodeTrackedBuffer::AllocateForCurrFramePreenc(uint8_t bufIndex)
141 {
142     // update the last 3 buffer index
143     m_trackedBufAnteIdx = m_trackedBufPenuIdx;
144     m_trackedBufPenuIdx = m_trackedBufCurrIdx;
145     // use the buffer index passed in by Preenc
146     m_trackedBufCurrIdx = bufIndex;
147 }
148 
ResetUsedForCurrFrame()149 void CodechalEncodeTrackedBuffer::ResetUsedForCurrFrame()
150 {
151     for (auto i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
152     {
153         m_tracker[i].bUsedforCurFrame = false;
154     }
155 }
156 
PreencLookUpBufIndex(uint8_t frameIdx,bool * inCache)157 uint8_t CodechalEncodeTrackedBuffer::PreencLookUpBufIndex(
158     uint8_t         frameIdx,
159     bool            *inCache)
160 {
161     CODECHAL_ENCODE_FUNCTION_ENTER;
162 
163     *inCache = false;
164     uint8_t j = frameIdx % CODEC_NUM_TRACKED_BUFFERS;
165     uint8_t emptyEntry = CODEC_NUM_TRACKED_BUFFERS;
166 
167     for (auto i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
168     {
169         if (m_tracker[j].ucSurfIndex7bits == frameIdx)
170         {
171             //this frame is already in cache
172             *inCache = true;
173             m_tracker[j].bUsedforCurFrame = true;
174 
175             return emptyEntry = j;
176         }
177         j = (j + 1) % CODEC_NUM_TRACKED_BUFFERS;
178     }
179 
180     j = frameIdx % CODEC_NUM_TRACKED_BUFFERS;
181     for (auto i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
182     {
183         if (!m_tracker[j].bUsedforCurFrame)
184         {
185             //find the first empty entry
186             emptyEntry = j;
187             break;
188         }
189         j = (j + 1) % CODEC_NUM_TRACKED_BUFFERS;
190     }
191 
192     if (emptyEntry < CODEC_NUM_TRACKED_BUFFERS)
193     {
194         m_tracker[emptyEntry].ucSurfIndex7bits = frameIdx;
195         m_tracker[emptyEntry].bUsedforCurFrame = true;
196     }
197 
198     return emptyEntry;
199 }
200 
LookUpBufIndex(PCODEC_PICTURE refList,uint8_t numRefFrame,bool usedAsRef)201 uint8_t CodechalEncodeTrackedBuffer::LookUpBufIndex(
202     PCODEC_PICTURE refList,
203     uint8_t        numRefFrame,
204     bool           usedAsRef)
205 {
206     CODECHAL_ENCODE_FUNCTION_ENTER;
207 
208     uint8_t index = PICTURE_MAX_7BITS;
209     if (usedAsRef && numRefFrame <= CODEC_MAX_NUM_REF_FRAME && !m_encoder->m_gopIsIdrFrameOnly)
210     {
211         uint8_t refPicIdx[CODEC_MAX_NUM_REF_FRAME];
212         bool notFound = true;
213 
214         for (auto i = 0; i < numRefFrame; i++)
215         {
216             refPicIdx[i] = refList[i].FrameIdx;
217         }
218 
219         // find the first empty slot to re-use
220         for (uint8_t i = 0; i < CODEC_NUM_REF_BUFFERS; i++)
221         {
222             tracker* trackedBuffer = &m_tracker[i];
223             uint8_t refFrameIdx = trackedBuffer->ucSurfIndex7bits;
224 
225             if (refFrameIdx != PICTURE_MAX_7BITS && refFrameIdx != PICTURE_RESIZE)
226             {
227                 // check whether this ref frame is still active
228                 uint8_t j = 0;
229                 for (j = 0; j < numRefFrame; j++)
230                 {
231                     if (refFrameIdx == refPicIdx[j])
232                         break;
233                 }
234 
235                 if (j == numRefFrame)
236                 {
237                     // this ref frame is no longer active, can be re-used
238                     trackedBuffer->ucSurfIndex7bits = PICTURE_MAX_7BITS;
239                 }
240             }
241 
242             if (notFound && PICTURE_MAX_7BITS == trackedBuffer->ucSurfIndex7bits)
243             {
244                 index = i;
245                 notFound = false;
246                 continue;
247             }
248         }
249     }
250     else
251     {
252         if (!m_encoder->m_waitForPak)
253         {
254             m_trackedBufCountNonRef += m_trackedBufCountNonRef < CODEC_NUM_NON_REF_BUFFERS;
255             CODECHAL_ENCODE_NORMALMESSAGE("Tracked buffer count = %d", m_trackedBufCountNonRef);
256         }
257         else
258         {
259             m_trackedBufCountNonRef = 0;
260         }
261 
262         m_trackedBufNonRefIdx = (m_trackedBufNonRefIdx + 1) % CODEC_NUM_NON_REF_BUFFERS;
263         index = CODEC_NUM_REF_BUFFERS + m_trackedBufNonRefIdx;
264     }
265 
266     if (index < CODEC_NUM_TRACKED_BUFFERS)
267     {
268         m_tracker[index].ucSurfIndex7bits = m_encoder->m_currReconstructedPic.FrameIdx;
269     }
270 
271     return index;
272 }
273 
LookUpBufIndexCsc()274 uint8_t CodechalEncodeTrackedBuffer::LookUpBufIndexCsc()
275 {
276     CODECHAL_ENCODE_FUNCTION_ENTER;
277 
278     if (m_encoder->m_useRawForRef)
279     {
280         return m_trackedBufCurrIdx;
281     }
282     else
283     {
284         // if Raw won't be used as Ref, can use the size-3 ring buffer
285         if (!m_encoder->m_waitForPak)
286         {
287             m_cscBufCountNonRef += m_cscBufCountNonRef <= CODEC_NUM_NON_REF_BUFFERS;
288             CODECHAL_ENCODE_NORMALMESSAGE("CSC buffer count = %d", m_cscBufCountNonRef);
289         }
290         else
291         {
292             m_cscBufCountNonRef = 0;
293         }
294 
295         m_cscBufNonRefIdx %= CODEC_NUM_NON_REF_BUFFERS;
296         return m_cscBufNonRefIdx += CODEC_NUM_REF_BUFFERS;
297     }
298 }
299 
DeferredDeallocateOnResChange()300 void CodechalEncodeTrackedBuffer::DeferredDeallocateOnResChange()
301 {
302     if (m_trackedBufAnteIdx != m_trackedBufPenuIdx && m_trackedBufAnteIdx != m_trackedBufCurrIdx)
303     {
304         if (m_mbCodeIsTracked)
305         {
306             ReleaseMbCode(m_trackedBufAnteIdx);
307         }
308         ReleaseMvData(m_trackedBufAnteIdx);
309         ReleaseDsRecon(m_trackedBufAnteIdx);
310         if (m_encoder->m_cscDsState)
311         {
312             ReleaseSurfaceDS(m_trackedBufAnteIdx);
313         }
314         if (m_encoder->m_vdencEnabled)
315             m_allocator->ReleaseResource(m_standard, mvTemporalBuffer, m_trackedBufAnteIdx);
316 
317         m_tracker[m_trackedBufAnteIdx].ucSurfIndex7bits = PICTURE_MAX_7BITS;
318         CODECHAL_ENCODE_NORMALMESSAGE("Tracked buffer = %d re-allocated", m_trackedBufAnteIdx);
319     }
320 
321     if (m_encoder->m_cscDsState && m_cscBufAnteIdx != m_cscBufPenuIdx && m_cscBufAnteIdx != m_cscBufCurrIdx)
322     {
323         ReleaseSurfaceCsc(m_cscBufAnteIdx);
324         CODECHAL_ENCODE_NORMALMESSAGE("CSC buffer = %d re-allocated", m_cscBufAnteIdx);
325     }
326 }
327 
AllocateMbCodeResources(uint8_t bufIndex)328 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateMbCodeResources(uint8_t bufIndex)
329 {
330     CODECHAL_ENCODE_FUNCTION_ENTER;
331 
332     CODECHAL_ENCODE_CHK_COND_RETURN(
333         bufIndex >= CODEC_NUM_TRACKED_BUFFERS,
334         "No MbCode buffer is available!");
335 
336     MEDIA_WA_TABLE *waTable = m_osInterface->pfnGetWaTable(m_osInterface);
337     uint32_t        memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4) && m_standard == CODECHAL_AVC) ? MOS_MEMPOOL_DEVICEMEMORY : 0;
338 
339     // early exit if already allocated
340     if ((m_trackedBufCurrMbCode = (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mbCodeBuffer, bufIndex)))
341     {
342         return MOS_STATUS_SUCCESS;
343     }
344 
345     // Must reserve at least 8 cachelines after MI_BATCH_BUFFER_END_CMD since HW prefetch max 8 cachelines from BB everytime
346     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrMbCode = (MOS_RESOURCE *)m_allocator->AllocateResource(
347         m_standard, m_encoder->m_mbCodeSize + 8 * CODECHAL_CACHELINE_SIZE, 1, mbCodeBuffer, "mbCodeBuffer", bufIndex, true, Format_Buffer, MOS_TILE_LINEAR, memType));
348 
349     return MOS_STATUS_SUCCESS;
350 }
351 
AllocateMvDataResources(uint8_t bufIndex)352 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateMvDataResources(uint8_t bufIndex)
353 {
354     CODECHAL_ENCODE_FUNCTION_ENTER;
355 
356     MEDIA_WA_TABLE *waTable = m_osInterface->pfnGetWaTable(m_osInterface);
357     uint32_t        memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4) && m_standard == CODECHAL_AVC) ? MOS_MEMPOOL_DEVICEMEMORY : 0;
358 
359     // early exit if already allocated
360     if ((m_trackedBufCurrMvData = (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mvDataBuffer, bufIndex)))
361     {
362         return MOS_STATUS_SUCCESS;
363     }
364 
365     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrMvData = (MOS_RESOURCE*)m_allocator->AllocateResource(
366         m_standard, m_encoder->m_mvDataSize, 1, mvDataBuffer, "mvDataBuffer", bufIndex, true, Format_Buffer, MOS_TILE_LINEAR, memType));
367 
368     return MOS_STATUS_SUCCESS;
369 }
370 
AllocateSurfaceCsc()371 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateSurfaceCsc()
372 {
373     // update the last 3 buffer index, find a new slot for current frame
374     m_cscBufAnteIdx = m_cscBufPenuIdx;
375     m_cscBufPenuIdx = m_cscBufCurrIdx;
376     m_cscBufCurrIdx = LookUpBufIndexCsc();
377 
378     CODECHAL_ENCODE_CHK_COND_RETURN(m_cscBufCurrIdx >= CODEC_NUM_TRACKED_BUFFERS, "No CSC buffer is available!");
379 
380     // wait to re-use once # of non-ref slots being used reaches 3
381     m_waitCscSurface = (m_cscBufCurrIdx >= CODEC_NUM_REF_BUFFERS && m_cscBufCountNonRef > CODEC_NUM_NON_REF_BUFFERS);
382 
383     if ((m_trackedBufCurrCsc = (MOS_SURFACE*)m_allocator->GetResource(m_standard, cscSurface, m_cscBufCurrIdx)))
384     {
385         return MOS_STATUS_SUCCESS;
386     }
387 
388     uint32_t width = 0, height = 0;
389     MOS_FORMAT format = Format_Invalid;
390     m_encoder->m_cscDsState->GetCscAllocation(width, height, format);
391 
392     // allocating Csc surface
393     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrCsc = (MOS_SURFACE*)m_allocator->AllocateResource(
394         m_standard, width, height, cscSurface, "cscSurface", m_cscBufCurrIdx, false, format, MOS_TILE_Y));
395 
396     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrCsc));
397 
398     return MOS_STATUS_SUCCESS;
399 }
400 
AllocateSurfaceCopy(MOS_FORMAT format,uint32_t cp_tag)401 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateSurfaceCopy(MOS_FORMAT format, uint32_t cp_tag)
402 {
403     // update the last 3 buffer index, find a new slot for current frame
404     m_cscBufAnteIdx = m_cscBufPenuIdx;
405     m_cscBufPenuIdx = m_cscBufCurrIdx;
406     m_cscBufCurrIdx = LookUpBufIndexCsc();
407 
408     CODECHAL_ENCODE_CHK_COND_RETURN(m_cscBufCurrIdx >= CODEC_NUM_TRACKED_BUFFERS, "No Copy buffer is available!");
409 
410     if ((m_trackedBufCurrCsc = (MOS_SURFACE *)m_allocator->GetResource(m_standard, cscSurface, m_cscBufCurrIdx)))
411     {
412         return MOS_STATUS_SUCCESS;
413     }
414 
415     // allocating csc surface for copy
416     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrCsc = (MOS_SURFACE *)m_allocator->AllocateResource(
417                                         m_standard, m_encoder->m_frameWidth, m_encoder->m_frameHeight,
418                                         cscSurface, "cscSurface", m_cscBufCurrIdx, false, format, MOS_TILE_Y));
419 
420     m_trackedBufCurrCsc->OsResource.pGmmResInfo->GetSetCpSurfTag(true, cp_tag);
421 
422     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrCsc));
423 
424     return MOS_STATUS_SUCCESS;
425 }
426 
ResizeSurfaceDS()427 MOS_STATUS CodechalEncodeTrackedBuffer::ResizeSurfaceDS() {
428 
429     CODECHAL_ENCODE_FUNCTION_ENTER;
430 
431     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
432 
433     //Get the 4x 16x and 32x DS surfaces
434     m_trackedBufCurrDs4x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xSurface, m_trackedBufCurrIdx);
435 
436     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs4x);
437 
438     if (m_encoder->m_16xMeSupported)
439     {
440         m_trackedBufCurrDs16x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds16xSurface, m_trackedBufCurrIdx);
441         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs16x);
442     }
443 
444     if (m_encoder->m_32xMeSupported)
445     {
446         m_trackedBufCurrDs32x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds32xSurface, m_trackedBufCurrIdx);
447         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs32x);
448     }
449 
450     uint32_t downscaledSurfaceWidth4x, downscaledSurfaceHeight4x;
451     uint32_t downscaledSurfaceWidth16x, downscaledSurfaceHeight16x;
452     uint32_t downscaledSurfaceWidth32x, downscaledSurfaceHeight32x;
453     //Get the dimensions of the 4x 16x and 32x surfaces
454     if (m_encoder->m_useCommonKernel)
455     {
456         downscaledSurfaceWidth4x = CODECHAL_GET_4xDS_SIZE_32ALIGNED(m_encoder->m_frameWidth);
457         downscaledSurfaceHeight4x = CODECHAL_GET_4xDS_SIZE_32ALIGNED(m_encoder->m_frameHeight);
458 
459         downscaledSurfaceWidth16x = CODECHAL_GET_4xDS_SIZE_32ALIGNED(downscaledSurfaceWidth4x);
460         downscaledSurfaceHeight16x = CODECHAL_GET_4xDS_SIZE_32ALIGNED(downscaledSurfaceHeight4x);
461 
462         downscaledSurfaceWidth32x = CODECHAL_GET_2xDS_SIZE_32ALIGNED(downscaledSurfaceWidth16x);
463         downscaledSurfaceHeight32x = CODECHAL_GET_2xDS_SIZE_32ALIGNED(downscaledSurfaceHeight16x);
464     }
465     else
466     {
467         // MB-alignment not required since dataport handles out-of-bound pixel replication, but IME requires this.
468         downscaledSurfaceWidth4x = m_encoder->m_downscaledWidth4x;
469         // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
470         // Width will be allocated tile Y aligned, so also tile align height.
471         downscaledSurfaceHeight4x = ((m_encoder->m_downscaledHeight4x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
472         downscaledSurfaceHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
473 
474         downscaledSurfaceWidth16x = m_encoder->m_downscaledWidth16x;
475         downscaledSurfaceHeight16x = ((m_encoder->m_downscaledHeight16x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
476         downscaledSurfaceHeight16x = MOS_ALIGN_CEIL(downscaledSurfaceHeight16x, MOS_YTILE_H_ALIGNMENT) << 1;
477 
478         downscaledSurfaceWidth32x = m_encoder->m_downscaledWidth32x;
479         downscaledSurfaceHeight32x = ((m_encoder->m_downscaledHeight32x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
480         downscaledSurfaceHeight32x = MOS_ALIGN_CEIL(downscaledSurfaceHeight32x, MOS_YTILE_H_ALIGNMENT) << 1;
481     }
482 
483     bool dsCurr4xAvailable = true;
484     bool dsCurr16xAvailable = true;
485     bool dsCurr32xAvailable = true;
486 
487     if ((m_trackedBufCurrDs4x->dwWidth < downscaledSurfaceWidth4x) || (m_trackedBufCurrDs4x->dwHeight < downscaledSurfaceHeight4x))
488     {
489         m_allocator->ReleaseResource(m_standard, ds4xSurface, m_trackedBufCurrIdx);
490         dsCurr4xAvailable = false;
491     }
492 
493     if (m_encoder->m_16xMeSupported)
494     {
495         if ((m_trackedBufCurrDs16x->dwWidth < downscaledSurfaceWidth16x) || (m_trackedBufCurrDs16x->dwHeight < downscaledSurfaceHeight16x))
496         {
497             m_allocator->ReleaseResource(m_standard, ds16xSurface, m_trackedBufCurrIdx);
498             dsCurr16xAvailable = false;
499         }
500     }
501 
502     if (m_encoder->m_32xMeSupported)
503     {
504         if ((m_trackedBufCurrDs32x->dwWidth < downscaledSurfaceWidth32x) || (m_trackedBufCurrDs32x->dwHeight < downscaledSurfaceHeight32x))
505         {
506             m_allocator->ReleaseResource(m_standard, ds32xSurface, m_trackedBufCurrIdx);
507             dsCurr32xAvailable = false;
508         }
509     }
510 
511     if (dsCurr4xAvailable && dsCurr16xAvailable && dsCurr32xAvailable)
512     {
513         //No need to resize
514         return MOS_STATUS_SUCCESS;
515     }
516 
517     if (!dsCurr4xAvailable)
518     {
519         // allocating 4x DS surface
520         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs4x = (MOS_SURFACE*)m_allocator->AllocateResource(
521             m_standard, downscaledSurfaceWidth4x, downscaledSurfaceHeight4x, ds4xSurface, "ds4xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
522 
523         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs4x));
524     }
525 
526     if (m_encoder->m_16xMeSupported && !dsCurr16xAvailable)
527     {
528         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs16x = (MOS_SURFACE*)m_allocator->AllocateResource(
529             m_standard, downscaledSurfaceWidth16x, downscaledSurfaceHeight16x, ds16xSurface, "ds16xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
530 
531         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs16x));
532     }
533 
534     // allocate 32x DS surface
535     if (m_encoder->m_32xMeSupported && !dsCurr32xAvailable)
536     {
537         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs32x = (MOS_SURFACE*)m_allocator->AllocateResource(
538             m_standard, downscaledSurfaceWidth32x, downscaledSurfaceHeight32x, ds32xSurface, "ds32xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
539 
540         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs32x));
541     }
542 
543     return eStatus;
544 }
545 
AllocateSurfaceDS()546 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateSurfaceDS()
547 {
548     CODECHAL_ENCODE_FUNCTION_ENTER;
549 
550     MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface);
551     uint32_t memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : 0;
552 
553     // early exit if already allocated
554     if ((m_trackedBufCurrDs4x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xSurface, m_trackedBufCurrIdx)))
555     {
556         if (m_encoder->m_16xMeSupported)
557         {
558             m_trackedBufCurrDs16x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds16xSurface, m_trackedBufCurrIdx);
559         }
560 
561         if (m_encoder->m_32xMeSupported)
562         {
563             m_trackedBufCurrDs32x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds32xSurface, m_trackedBufCurrIdx);
564         }
565         return MOS_STATUS_SUCCESS;
566     }
567 
568     uint32_t downscaledSurfaceWidth4x, downscaledSurfaceHeight4x;
569     uint32_t downscaledSurfaceWidth16x, downscaledSurfaceHeight16x;
570     uint32_t downscaledSurfaceWidth32x, downscaledSurfaceHeight32x;
571     if (m_encoder->m_useCommonKernel)
572     {
573         downscaledSurfaceWidth4x = m_encoder->m_downscaledWidth4x;
574         downscaledSurfaceHeight4x = MOS_ALIGN_CEIL(m_encoder->m_downscaledHeight4x, MOS_YTILE_H_ALIGNMENT);
575         downscaledSurfaceWidth16x = m_encoder->m_downscaledWidth16x;
576         downscaledSurfaceHeight16x = MOS_ALIGN_CEIL(m_encoder->m_downscaledHeight16x, MOS_YTILE_H_ALIGNMENT);
577         downscaledSurfaceWidth32x = m_encoder->m_downscaledWidth32x;
578         downscaledSurfaceHeight32x = MOS_ALIGN_CEIL(m_encoder->m_downscaledHeight32x, MOS_YTILE_H_ALIGNMENT);
579     }
580     else
581     {
582         // MB-alignment not required since dataport handles out-of-bound pixel replication, but IME requires this.
583         downscaledSurfaceWidth4x = m_encoder->m_downscaledWidth4x;
584         // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
585         // Width will be allocated tile Y aligned, so also tile align height.
586         downscaledSurfaceHeight4x = ((m_encoder->m_downscaledHeight4x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
587         downscaledSurfaceHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
588 
589         downscaledSurfaceWidth16x = m_encoder->m_downscaledWidth16x;
590         downscaledSurfaceHeight16x = ((m_encoder->m_downscaledHeight16x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
591         downscaledSurfaceHeight16x = MOS_ALIGN_CEIL(downscaledSurfaceHeight16x, MOS_YTILE_H_ALIGNMENT) << 1;
592 
593         downscaledSurfaceWidth32x = m_encoder->m_downscaledWidth32x;
594         downscaledSurfaceHeight32x = ((m_encoder->m_downscaledHeight32x / CODECHAL_MACROBLOCK_HEIGHT + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
595         downscaledSurfaceHeight32x = MOS_ALIGN_CEIL(downscaledSurfaceHeight32x, MOS_YTILE_H_ALIGNMENT) << 1;
596     }
597 
598     // allocating 4x DS surface
599     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs4x = (MOS_SURFACE*)m_allocator->AllocateResource(
600                                         m_standard, downscaledSurfaceWidth4x, downscaledSurfaceHeight4x, ds4xSurface, "ds4xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y, memType));
601 
602     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs4x));
603 
604     // allocate 16x DS surface
605     if (m_encoder->m_16xMeSupported)
606     {
607         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs16x = (MOS_SURFACE*)m_allocator->AllocateResource(
608                                             m_standard, downscaledSurfaceWidth16x, downscaledSurfaceHeight16x, ds16xSurface, "ds16xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y, memType));
609 
610         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs16x));
611     }
612 
613     // allocate 32x DS surface
614     if (m_encoder->m_32xMeSupported)
615     {
616         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs32x = (MOS_SURFACE*)m_allocator->AllocateResource(
617                                             m_standard, downscaledSurfaceWidth32x, downscaledSurfaceHeight32x, ds32xSurface, "ds32xSurface", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y, memType));
618 
619         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs32x));
620     }
621 
622     if (!m_encoder->m_fieldScalingOutputInterleaved)
623     {
624         // Separated scaled surfaces
625         // Height should be 4K aligned for DI surface state, assume always Y tiled
626         m_encoder->m_scaledBottomFieldOffset = MOS_ALIGN_CEIL(
627             (m_trackedBufCurrDs4x->dwPitch * (m_trackedBufCurrDs4x->dwHeight / 2)), CODECHAL_PAGE_SIZE);
628 
629         if (m_encoder->m_16xMeSupported)
630         {
631             // Height should be 4K aligned for DI surface state, assume always Y tiled
632             m_encoder->m_scaled16xBottomFieldOffset = MOS_ALIGN_CEIL(
633                 (m_trackedBufCurrDs16x->dwPitch * (m_trackedBufCurrDs16x->dwHeight / 2)), CODECHAL_PAGE_SIZE);
634         }
635 
636         if (m_encoder->m_32xMeSupported)
637         {
638             // Height should be 4K aligned for DI surface state, assume always Y tiled
639             m_encoder->m_scaled32xBottomFieldOffset = MOS_ALIGN_CEIL(
640                 (m_trackedBufCurrDs32x->dwPitch * (m_trackedBufCurrDs32x->dwHeight / 2)), CODECHAL_PAGE_SIZE);
641         }
642 
643     }
644     else
645     {
646         // Interleaved scaled surfaces
647         m_encoder->m_scaledBottomFieldOffset =
648         m_encoder->m_scaled16xBottomFieldOffset =
649         m_encoder->m_scaled32xBottomFieldOffset = 0;
650     }
651 
652     return MOS_STATUS_SUCCESS;
653 }
654 
AllocateSurface2xDS()655 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateSurface2xDS()
656 {
657     CODECHAL_ENCODE_FUNCTION_ENTER;
658 
659     MEDIA_WA_TABLE* waTable = m_osInterface->pfnGetWaTable(m_osInterface);
660     uint32_t memType = (MEDIA_IS_WA(waTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : 0;
661 
662     // early exit if already allocated
663     if ((m_trackedBufCurrDs2x = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds2xSurface, m_trackedBufCurrIdx)))
664     {
665         return MOS_STATUS_SUCCESS;
666     }
667 
668     uint32_t surfaceWidth, surfaceHeight;
669     if (m_encoder->m_useCommonKernel)
670     {
671         surfaceWidth = CODECHAL_GET_2xDS_SIZE_32ALIGNED(m_encoder->m_frameWidth);
672         surfaceHeight = CODECHAL_GET_2xDS_SIZE_32ALIGNED(m_encoder->m_frameHeight);
673     }
674     else
675     {
676         surfaceWidth = MOS_ALIGN_CEIL(m_encoder->m_frameWidth, 64) >> 1;
677         surfaceHeight = MOS_ALIGN_CEIL(m_encoder->m_frameHeight, 64) >> 1;
678     }
679 
680     MOS_FORMAT format = Format_NV12;
681     if ((uint8_t)HCP_CHROMA_FORMAT_YUV422 == m_encoder->m_outputChromaFormat)
682     {
683         format = Format_YUY2;
684         surfaceWidth >>= 1;
685         surfaceHeight <<= 1;
686     }
687 
688     // allocate 2x DS surface
689     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrDs2x = (MOS_SURFACE*)m_allocator->AllocateResource(
690                                         m_standard, surfaceWidth, surfaceHeight, ds2xSurface, "ds2xSurface", m_trackedBufCurrIdx, false, format, MOS_TILE_Y, memType));
691 
692     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurrDs2x));
693 
694     if ((uint8_t)HCP_CHROMA_FORMAT_YUV422 == m_encoder->m_outputChromaFormat)
695     {
696         m_trackedBufCurrDs2x->Format = Format_YUY2V;
697         m_trackedBufCurrDs2x->dwWidth = surfaceWidth << 1;
698         m_trackedBufCurrDs2x->dwHeight = surfaceHeight >> 1;
699     }
700 
701     return MOS_STATUS_SUCCESS;
702 }
703 
ResizeDsReconSurfacesVdenc()704 MOS_STATUS CodechalEncodeTrackedBuffer::ResizeDsReconSurfacesVdenc()
705 {
706     MOS_STATUS estatus = MOS_STATUS_SUCCESS;
707 
708     //Get 4x buffer
709     m_trackedBufCurr4xDsRecon = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xRecon, m_trackedBufCurrIdx);
710 
711     if (m_trackedBufCurr4xDsRecon == nullptr)  {
712         //SURFACE IS NOT ALLOCATED
713         return estatus;
714     }
715 
716     //Get 8x buffer
717     m_trackedBufCurr8xDsRecon = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds8xRecon, m_trackedBufCurrIdx);
718 
719     if (m_trackedBufCurr8xDsRecon == nullptr) {
720         //SURFACE IS NOT ALLOCATED
721         return estatus;
722     }
723     uint32_t allocated4xWidth = m_trackedBufCurr4xDsRecon->dwWidth;
724     uint32_t allocated4xHeight = m_trackedBufCurr4xDsRecon->dwHeight;
725 
726     uint32_t allocated8xWidth = m_trackedBufCurr8xDsRecon->dwWidth;
727     uint32_t allocated8xHeight = m_trackedBufCurr8xDsRecon->dwHeight;
728 
729     uint32_t requiredDownscaledSurfaceWidth4x = m_encoder->m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
730     // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
731     // Width will be allocated tile Y aligned, so also tile align height.
732     uint32_t requiredDownscaledSurfaceHeight4x = ((m_encoder->m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
733     requiredDownscaledSurfaceHeight4x = MOS_ALIGN_CEIL(requiredDownscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
734 
735     uint32_t requiredDownscaledSurfaceWidth8x = requiredDownscaledSurfaceWidth4x >> 1;
736     uint32_t requiredDownscaledSurfaceHeight8x = requiredDownscaledSurfaceHeight4x >> 1;
737 
738     if (requiredDownscaledSurfaceHeight4x != allocated4xHeight || requiredDownscaledSurfaceWidth4x != allocated4xWidth)
739     {
740         //re-allocate 4xDsRecon based on current resolution
741         m_allocator->ReleaseResource(m_standard, ds4xRecon, m_trackedBufCurrIdx);
742         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurr4xDsRecon = (MOS_SURFACE*)m_allocator->AllocateResource(
743             m_standard, requiredDownscaledSurfaceWidth4x, requiredDownscaledSurfaceHeight4x, ds4xRecon, "ds4xRecon", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
744         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurr4xDsRecon));
745     }
746 
747     if (requiredDownscaledSurfaceHeight8x != allocated8xHeight || requiredDownscaledSurfaceWidth8x != allocated8xWidth)
748     {
749         //re-allocate 8xDsRecon based on current resolution
750         m_allocator->ReleaseResource(m_standard, ds8xRecon, m_trackedBufCurrIdx);
751         CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurr8xDsRecon = (MOS_SURFACE*)m_allocator->AllocateResource(
752             m_standard, requiredDownscaledSurfaceWidth8x, requiredDownscaledSurfaceHeight8x, ds8xRecon, "ds8xRecon", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
753         CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurr8xDsRecon));
754     }
755     return estatus;
756 }
757 
AllocateDsReconSurfacesVdenc()758 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateDsReconSurfacesVdenc()
759 {
760     CODECHAL_ENCODE_FUNCTION_ENTER;
761 
762     // early exit if already allocated
763     if ((m_trackedBufCurr4xDsRecon = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xRecon, m_trackedBufCurrIdx)))
764     {
765         m_trackedBufCurr8xDsRecon = (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds8xRecon, m_trackedBufCurrIdx);
766         return MOS_STATUS_SUCCESS;
767     }
768 
769     // MB-alignment not required since dataport handles out-of-bound pixel replication, but HW IME requires this.
770     uint32_t downscaledSurfaceWidth4x = m_encoder->m_downscaledWidthInMb4x * CODECHAL_MACROBLOCK_WIDTH;
771     // Account for field case, offset needs to be 4K aligned if tiled for DI surface state.
772     // Width will be allocated tile Y aligned, so also tile align height.
773     uint32_t downscaledSurfaceHeight4x = ((m_encoder->m_downscaledHeightInMb4x + 1) >> 1) * CODECHAL_MACROBLOCK_HEIGHT;
774     downscaledSurfaceHeight4x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x, MOS_YTILE_H_ALIGNMENT) << 1;
775 
776     // Allocating VDEnc 4x DsRecon surface
777     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurr4xDsRecon = (MOS_SURFACE*)m_allocator->AllocateResource(
778         m_standard, downscaledSurfaceWidth4x, downscaledSurfaceHeight4x, ds4xRecon, "ds4xRecon", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
779 
780     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurr4xDsRecon));
781 
782     // Allocating VDEnc 8x DsRecon surfaces
783     uint32_t downscaledSurfaceWidth8x  = downscaledSurfaceWidth4x >> 1;
784     uint32_t downscaledSurfaceHeight8x = MOS_ALIGN_CEIL(downscaledSurfaceHeight4x >> 1, MOS_YTILE_H_ALIGNMENT) << 1;
785     CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurr8xDsRecon = (MOS_SURFACE*)m_allocator->AllocateResource(
786         m_standard, downscaledSurfaceWidth8x, downscaledSurfaceHeight8x, ds8xRecon, "ds8xRecon", m_trackedBufCurrIdx, false, Format_NV12, MOS_TILE_Y));
787 
788     CODECHAL_ENCODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, m_trackedBufCurr8xDsRecon));
789 
790     return MOS_STATUS_SUCCESS;
791 }
792 
AllocateMvTemporalBuffer(uint8_t bufIndex)793 MOS_STATUS CodechalEncodeTrackedBuffer::AllocateMvTemporalBuffer(uint8_t bufIndex)
794 {
795     CODECHAL_ENCODE_FUNCTION_ENTER;
796 
797     if (m_encoder->m_vdencEnabled && m_encoder->m_vdencMvTemporalBufferSize)
798     {
799         // Allocate/fetch buffer if current frame can be used for reference or it's a special buffer for pre-generated I frame MV streamout surface
800         if((m_encoder->m_currRefList && m_encoder->m_currRefList->bUsedAsRef) || bufIndex == CODEC_NUM_REF_BUFFERS)
801         {
802             if ((m_trackedBufCurrMvTemporal = (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mvTemporalBuffer, bufIndex)))
803             {
804                 return MOS_STATUS_SUCCESS;
805             }
806 
807             CODECHAL_ENCODE_CHK_NULL_RETURN(m_trackedBufCurrMvTemporal = (MOS_RESOURCE*)m_allocator->AllocateResource(
808                 m_standard, m_encoder->m_vdencMvTemporalBufferSize, 1, mvTemporalBuffer, "mvTemporalBuffer", bufIndex, false));
809         }
810     }
811 
812     return MOS_STATUS_SUCCESS;
813 }
814 
ReleaseMbCode(uint8_t bufIndex)815 void CodechalEncodeTrackedBuffer::ReleaseMbCode(uint8_t bufIndex)
816 {
817     CODECHAL_ENCODE_FUNCTION_ENTER;
818 
819     m_allocator->ReleaseResource(m_standard, mbCodeBuffer, bufIndex);
820 }
821 
ReleaseMvData(uint8_t bufIndex)822 void CodechalEncodeTrackedBuffer::ReleaseMvData(uint8_t bufIndex)
823 {
824     CODECHAL_ENCODE_FUNCTION_ENTER;
825 
826     m_allocator->ReleaseResource(m_standard, mvDataBuffer, bufIndex);
827 }
828 
ReleaseSurfaceCsc(uint8_t bufIndex)829 void CodechalEncodeTrackedBuffer::ReleaseSurfaceCsc(uint8_t bufIndex)
830 {
831     CODECHAL_ENCODE_FUNCTION_ENTER;
832 
833     m_allocator->ReleaseResource(m_standard, cscSurface, bufIndex);
834 }
835 
ReleaseSurfaceDS(uint8_t bufIndex)836 void CodechalEncodeTrackedBuffer::ReleaseSurfaceDS(uint8_t bufIndex)
837 {
838     CODECHAL_ENCODE_FUNCTION_ENTER;
839 
840     m_allocator->ReleaseResource(m_standard, ds4xSurface, bufIndex);
841     m_allocator->ReleaseResource(m_standard, ds2xSurface, bufIndex);
842     m_allocator->ReleaseResource(m_standard, ds16xSurface, bufIndex);
843     m_allocator->ReleaseResource(m_standard, ds32xSurface, bufIndex);
844 }
845 
ReleaseDsRecon(uint8_t bufIndex)846 void CodechalEncodeTrackedBuffer::ReleaseDsRecon(uint8_t bufIndex)
847 {
848     CODECHAL_ENCODE_FUNCTION_ENTER;
849 
850     m_allocator->ReleaseResource(m_standard, ds4xRecon, bufIndex);
851     m_allocator->ReleaseResource(m_standard, ds8xRecon, bufIndex);
852 }
853 
CodechalEncodeTrackedBuffer(CodechalEncoderState * encoder)854 CodechalEncodeTrackedBuffer::CodechalEncodeTrackedBuffer(CodechalEncoderState* encoder)
855 {
856     // Initilize interface pointers
857     m_encoder = encoder;
858     m_allocator = encoder->m_allocator;
859     m_standard = encoder->m_standard;
860     m_osInterface = encoder->GetOsInterface();
861     m_mbCodeIsTracked = true;
862 
863     for (auto i = 0; i < CODEC_NUM_TRACKED_BUFFERS; i++)
864     {
865         // Init all tracked buffer slots to usable
866         m_tracker[i].bUsedforCurFrame = false;
867         m_tracker[i].ucSurfIndex7bits = PICTURE_MAX_7BITS;
868     }
869 }
870 
~CodechalEncodeTrackedBuffer()871 CodechalEncodeTrackedBuffer::~CodechalEncodeTrackedBuffer()
872 {
873     CODECHAL_ENCODE_FUNCTION_ENTER;
874 }
875