1 /*
2 * Copyright (c) 2019-2022, 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     decode_hevc_tile_coding.cpp
24 //! \brief    Defines the common interface for decode hevc tile coding
25 //!
26 
27 #include "decode_hevc_tile_coding.h"
28 #include "decode_hevc_basic_feature.h"
29 #include "codec_def_common.h"
30 #include "decode_pipeline.h"
31 
32 namespace decode
33 {
~HevcTileCoding()34 HevcTileCoding::~HevcTileCoding()
35 {
36     for (auto sliceTileInfo : m_sliceTileInfoList)
37     {
38         MOS_DeleteArray(sliceTileInfo->tileArrayBuf);
39         MOS_Delete(sliceTileInfo);
40     }
41     m_sliceTileInfoList.clear();
42 
43     if (m_pCtbAddrRsToTs)
44     {
45         MOS_FreeMemory(m_pCtbAddrRsToTs);
46     }
47 }
48 
Init(HevcBasicFeature * basicFeature,CodechalSetting * codecSettings)49 MOS_STATUS HevcTileCoding::Init(HevcBasicFeature *basicFeature, CodechalSetting *codecSettings)
50 {
51     DECODE_FUNC_CALL();
52     DECODE_CHK_NULL(basicFeature);
53     DECODE_CHK_NULL(codecSettings);
54 
55     m_basicFeature = basicFeature;
56 
57     return MOS_STATUS_SUCCESS;
58 }
59 
UpdatePicture(const CODEC_HEVC_PIC_PARAMS & picParams)60 MOS_STATUS HevcTileCoding::UpdatePicture(const CODEC_HEVC_PIC_PARAMS & picParams)
61 {
62     DECODE_FUNC_CALL();
63     if (picParams.tiles_enabled_flag == 1)
64     {
65         DECODE_CHK_STATUS(GetAllTileInfo(picParams, m_basicFeature->m_widthInCtb,
66                                          m_basicFeature->m_heightInCtb));
67     }
68 
69     return MOS_STATUS_SUCCESS;
70 }
71 
UpdateSlice(const CODEC_HEVC_PIC_PARAMS & picParams,const PCODEC_HEVC_SLICE_PARAMS sliceParams)72 MOS_STATUS HevcTileCoding::UpdateSlice(const CODEC_HEVC_PIC_PARAMS & picParams,
73                                        const PCODEC_HEVC_SLICE_PARAMS sliceParams)
74 {
75     DECODE_FUNC_CALL();
76 
77     if (m_basicFeature->m_shortFormatInUse)
78     {
79         return MOS_STATUS_SUCCESS;
80     }
81 
82     for (uint32_t slcIdx = 0; slcIdx < m_basicFeature->m_numSlices; slcIdx++)
83     {
84         SliceTileInfo* sliceTileInfo = AllocateSliceTileInfo(slcIdx);
85         DECODE_CHK_NULL(sliceTileInfo);
86 
87         if (m_basicFeature->IsIndependentSlice(slcIdx))
88         {
89             sliceTileInfo->origCtbX = sliceParams[slcIdx].slice_segment_address % m_basicFeature->m_widthInCtb;
90             sliceTileInfo->origCtbY = sliceParams[slcIdx].slice_segment_address / m_basicFeature->m_widthInCtb;
91 
92         }
93         else
94         {
95             // Dependent slice share same orig ctbx and ctby with previous slice in real tile and separate tile mode.
96             for (int32_t index = slcIdx - 1; index >= 0; --index) //search backword
97             {
98                 if(!sliceParams[index].LongSliceFlags.fields.dependent_slice_segment_flag) //independent slice
99                 {
100                     sliceTileInfo->origCtbX = sliceParams[index].slice_segment_address % m_basicFeature->m_widthInCtb;
101                     sliceTileInfo->origCtbY = sliceParams[index].slice_segment_address / m_basicFeature->m_widthInCtb;
102 
103                     break;
104                 }
105             }
106         }
107     }
108 
109     if (picParams.tiles_enabled_flag == 1)
110     {
111         for (uint32_t slcIdx = 0; slcIdx < m_basicFeature->m_numSlices; slcIdx++)
112         {
113             SliceTileInfo* sliceTileInfo = m_sliceTileInfoList[slcIdx];
114             DECODE_CHK_NULL(sliceTileInfo);
115             sliceTileInfo->sliceTileX = ComputeSliceTileX(picParams, sliceParams[slcIdx]);
116             sliceTileInfo->sliceTileY = ComputeSliceTileY(picParams, sliceParams[slcIdx]);
117         }
118     }
119 
120     return MOS_STATUS_SUCCESS;
121 }
122 
UpdateSliceTileInfo()123 MOS_STATUS HevcTileCoding::UpdateSliceTileInfo()
124 {
125     DECODE_FUNC_CALL();
126 
127     if (m_basicFeature->m_shortFormatInUse)
128     {
129         return MOS_STATUS_SUCCESS;
130     }
131 
132     const CODEC_HEVC_PIC_PARAMS&   picParams   = *(m_basicFeature->m_hevcPicParams);
133     const PCODEC_HEVC_SLICE_PARAMS sliceParams = m_basicFeature->m_hevcSliceParams;
134 
135     DECODE_CHK_COND(m_basicFeature->m_numSlices > m_sliceTileInfoList.size(),
136                     "Number of slices is exceeds the size of tile info list!");
137 
138     /* To generate RsToTs convert table per frame */
139     if (picParams.tiles_enabled_flag == 1)
140     {
141         uint32_t picSizeInCtbsY = m_basicFeature->m_widthInCtb * m_basicFeature->m_heightInCtb;
142         if (nullptr == m_pCtbAddrRsToTs || m_CurRsToTsTableSize < picSizeInCtbsY)
143         {
144             if (m_pCtbAddrRsToTs)
145             {
146                 MOS_FreeMemory(m_pCtbAddrRsToTs);
147             }
148             m_pCtbAddrRsToTs = (uint32_t *)MOS_AllocAndZeroMemory(picSizeInCtbsY * sizeof(uint32_t));
149             DECODE_CHK_NULL(m_pCtbAddrRsToTs);
150             m_CurRsToTsTableSize = picSizeInCtbsY;
151         }
152         RsToTsAddrConvert(picParams, picSizeInCtbsY);
153     }
154 
155     for (uint32_t slcIdx = 0; slcIdx < m_basicFeature->m_numSlices; slcIdx++)
156     {
157         SliceTileInfo* sliceTileInfo = m_sliceTileInfoList[slcIdx];
158         DECODE_CHK_NULL(sliceTileInfo);
159 
160         if (slcIdx == 0)
161         {
162             sliceTileInfo->firstSliceOfTile = true;
163         }
164         else
165         {
166             auto tileInfo = GetSliceTileInfo(slcIdx-1);
167             DECODE_CHK_NULL(tileInfo);
168             sliceTileInfo->firstSliceOfTile = tileInfo->numTiles > 0;
169         }
170 
171         bool lastSlice = m_basicFeature->IsLastSlice(slcIdx);
172         sliceTileInfo->numTiles = ComputeTileNumForSlice(picParams, slcIdx,
173                                     sliceTileInfo->sliceTileX, sliceTileInfo->sliceTileY, lastSlice);
174         if(sliceTileInfo->numTiles > (picParams.num_tile_columns_minus1+1)*(picParams.num_tile_rows_minus1+1))
175         {
176             DECODE_ASSERTMESSAGE("Number of slice tile is exceeds the number of total tile!\n");
177             return MOS_STATUS_INVALID_PARAMETER;
178         }
179         // Case 1: multiple tiles in single slice, this is the last slice in tile.
180         // Case 2: multiple slices in single tile, these slices share same tile position which means numTilesInSlice is 0.
181         sliceTileInfo->lastSliceOfTile = (sliceTileInfo->numTiles > 0);
182 
183         if (picParams.tiles_enabled_flag == 1 && sliceTileInfo->numTiles > 1)
184         {
185             if (sliceTileInfo->numTiles > sliceTileInfo->tileArraySize)
186             {
187                 MOS_DeleteArray(sliceTileInfo->tileArrayBuf);
188                 sliceTileInfo->tileArrayBuf = MOS_NewArray(SubTileInfo, sliceTileInfo->numTiles);
189                 DECODE_CHK_NULL(sliceTileInfo->tileArrayBuf);
190                 sliceTileInfo->tileArraySize = sliceTileInfo->numTiles;
191             }
192             DECODE_CHK_STATUS(UpdateSubTileInfo(picParams, sliceParams[slcIdx], *sliceTileInfo));
193         }
194 
195         uint16_t tileStartCtbX = GetTileCtbX(sliceTileInfo->sliceTileX);
196         uint16_t tileStartCtbY = GetTileCtbY(sliceTileInfo->sliceTileY);
197         uint16_t subStreamCount = (sliceTileInfo->numTiles > 0) ? sliceTileInfo->numTiles : 1;
198         for (uint16_t tileId = 0; tileId < subStreamCount; tileId++)
199         {
200             if (sliceTileInfo->firstSliceOfTile)
201             {
202                 /* Check the startCtbX and startCtbY for firstsliceoftile and firsttileofslice */
203                 if (tileId == 0)
204                 {
205                     uint32_t slicestartCtbX = sliceParams[slcIdx].slice_segment_address % m_basicFeature->m_widthInCtb;
206                     uint32_t slicestartCtbY = sliceParams[slcIdx].slice_segment_address / m_basicFeature->m_widthInCtb;
207                     if (slicestartCtbY != tileStartCtbY || slicestartCtbX != tileStartCtbX)
208                     {
209                         DECODE_ASSERTMESSAGE("slicestartCtbX(%d) does not equal to tilestartCtbX(%d) or slicestartCtbY(%d) does not equal to tilestartCtbY(%d)\n",
210                                              slicestartCtbX, tileStartCtbX, slicestartCtbY, tileStartCtbY);
211                         return MOS_STATUS_INVALID_PARAMETER;
212                     }
213                 }
214             }
215         }
216 
217         /* Check slice segment address in tile scan should be increasing */
218         if (picParams.tiles_enabled_flag == 1)
219         {
220             if ((m_pCtbAddrRsToTs != nullptr) && (slcIdx > 0))
221             {
222                 if (m_pCtbAddrRsToTs[sliceParams[slcIdx].slice_segment_address] <= m_pCtbAddrRsToTs[sliceParams[slcIdx - 1].slice_segment_address]) // Tile scan address is not increasing
223                 {
224                     DECODE_ASSERTMESSAGE("Address in tile scan is not increasing, %dth slice tile scan address = %d, %dth slice tile scan address = %d\n",
225                                          slcIdx - 1,
226                                          m_pCtbAddrRsToTs[sliceParams[slcIdx - 1].slice_segment_address],
227                                          slcIdx,
228                                          m_pCtbAddrRsToTs[sliceParams[slcIdx].slice_segment_address]);
229                     return MOS_STATUS_INVALID_PARAMETER;
230                 }
231             }
232         }
233     }
234 
235     return MOS_STATUS_SUCCESS;
236 }
237 
UpdateSubTileInfo(const CODEC_HEVC_PIC_PARAMS & picParams,const CODEC_HEVC_SLICE_PARAMS & sliceParams,SliceTileInfo & sliceTileInfo)238 MOS_STATUS HevcTileCoding::UpdateSubTileInfo(const CODEC_HEVC_PIC_PARAMS & picParams,
239                                              const CODEC_HEVC_SLICE_PARAMS & sliceParams,
240                                              SliceTileInfo &sliceTileInfo)
241 {
242     if (sliceTileInfo.numTiles > 1)
243     {
244         if (!picParams.entropy_coding_sync_enabled_flag)
245         {
246             DECODE_CHK_COND(sliceTileInfo.numTiles != (sliceParams.num_entry_point_offsets + 1),
247                             "tiles number does not equal to current num_entry_point_offsets.");
248         }
249     }
250 
251     uint32_t* entryPointOffsets = nullptr;
252     if (m_basicFeature->m_hevcSubsetParams != nullptr)
253     {
254         auto hevcSubsetParams = m_basicFeature->m_hevcSubsetParams;
255         entryPointOffsets = &hevcSubsetParams->entry_point_offset_minus1[sliceParams.EntryOffsetToSubsetArray];
256     }
257 
258     uint16_t  tileX = sliceTileInfo.sliceTileX;
259     uint16_t  tileY = sliceTileInfo.sliceTileY;
260     uint32_t  bsdOffset = 0;
261 
262     for (uint16_t i = 0; i < sliceTileInfo.numTiles; i++)
263     {
264         sliceTileInfo.tileArrayBuf[i].tileX = tileX;
265         sliceTileInfo.tileArrayBuf[i].tileY = tileY;
266         sliceTileInfo.tileArrayBuf[i].ctbX = GetTileCtbX(tileX);
267         sliceTileInfo.tileArrayBuf[i].ctbY = GetTileCtbY(tileY);
268         sliceTileInfo.tileArrayBuf[i].bsdOffset = bsdOffset;
269 
270         if (i == 0)
271         {
272             sliceTileInfo.tileArrayBuf[i].bsdLength = sliceParams.ByteOffsetToSliceData +
273                                                       sliceParams.NumEmuPrevnBytesInSliceHdr;
274             sliceTileInfo.tileArrayBuf[i].bsdLength += (entryPointOffsets != nullptr) ? entryPointOffsets[i] + 1 : 1;
275         }
276         else if (i == sliceTileInfo.numTiles - 1)
277         {
278             sliceTileInfo.tileArrayBuf[i].bsdLength = sliceParams.slice_data_size -
279                                                       sliceTileInfo.tileArrayBuf[i].bsdOffset;
280         }
281         else
282         {
283             sliceTileInfo.tileArrayBuf[i].bsdLength = (entryPointOffsets != nullptr) ? entryPointOffsets[i] + 1 : 1;
284         }
285 
286         // Check BSD data length
287         DECODE_CHK_COND(sliceTileInfo.tileArrayBuf[i].bsdLength > sliceParams.slice_data_size, "Slice tile bsd length exceeds slice data size!");
288 
289         bsdOffset += sliceTileInfo.tileArrayBuf[i].bsdLength;
290 
291         if (++tileX > picParams.num_tile_columns_minus1)
292         {
293             tileX = 0;
294             ++tileY;
295         }
296     }
297 
298     return MOS_STATUS_SUCCESS;
299 }
300 
RsToTsAddrConvert(const CODEC_HEVC_PIC_PARAMS & picParams,uint32_t picSizeInCtbsY)301 MOS_STATUS HevcTileCoding::RsToTsAddrConvert(const CODEC_HEVC_PIC_PARAMS &picParams, uint32_t picSizeInCtbsY)
302 {
303     uint32_t tbX = 0;
304     uint32_t tbY = 0;
305     uint32_t ctbAddrRs = 0;
306     uint32_t colBd[HEVC_NUM_MAX_TILE_COLUMN + 1] = {0};
307     uint32_t rowBd[HEVC_NUM_MAX_TILE_ROW + 1]    = {0};
308     uint32_t colWidth[HEVC_NUM_MAX_TILE_COLUMN + 1] = {0};
309     uint32_t rowHeight[HEVC_NUM_MAX_TILE_ROW + 1]   = {0};
310     uint8_t  i = 0, j = 0;
311 
312     if (picParams.tiles_enabled_flag && picParams.uniform_spacing_flag)
313     {
314         for (i = 0; i <= picParams.num_tile_columns_minus1; i++)
315         {
316             colWidth[i] = ((i + 1) * m_basicFeature->m_widthInCtb) / (picParams.num_tile_columns_minus1 + 1) -
317                 (i * m_basicFeature->m_widthInCtb) / (picParams.num_tile_columns_minus1 + 1);
318         }
319 
320         for (j = 0; j <= picParams.num_tile_rows_minus1; j++)
321         {
322             rowHeight[j] = ((j + 1) * m_basicFeature->m_heightInCtb) / (picParams.num_tile_rows_minus1 + 1) -
323                 (j * m_basicFeature->m_heightInCtb) / (picParams.num_tile_rows_minus1 + 1);
324         }
325     }
326     else
327     {
328         colWidth[picParams.num_tile_columns_minus1] = m_basicFeature->m_widthInCtb;
329         for (i = 0; i < picParams.num_tile_columns_minus1; i++)
330         {
331             colWidth[i] = picParams.column_width_minus1[i] + 1;
332             colWidth[picParams.num_tile_columns_minus1] -= colWidth[i];
333         }
334 
335         rowHeight[picParams.num_tile_rows_minus1] = m_basicFeature->m_heightInCtb;
336         for (j = 0; j < picParams.num_tile_rows_minus1; j++)
337         {
338             rowHeight[j] = picParams.row_height_minus1[j] + 1;
339             rowHeight[picParams.num_tile_rows_minus1] -= rowHeight[j];
340         }
341     }
342 
343     /* The list colBd[i] for i ranging from 0 to num_tile_columns_minus1 + 1, inclusive,
344      * specifying the location of the i-th tile column boundary in units of CTBs */
345     for (colBd[0] = 0, i = 0; i <= picParams.num_tile_columns_minus1; i ++)
346     {
347         colBd[i + 1] = colBd[i] + colWidth[i];
348     }
349 
350     /* The list rowBd[j] for j ranging from 0 to num_tile_rows_minus1 + 1, inclusive,
351      * specifying the location of the j-th tile row boundary in units of CTBs */
352     for (rowBd[0] = 0, j = 0; j <= picParams.num_tile_rows_minus1; j ++)
353     {
354         rowBd[j + 1] = rowBd[j] + rowHeight[j];
355     }
356 
357     /* The list CtbAddrRsToTs[ctbAddrRs] for ctbAddrRs ranging from 0 to PicSizeInCtbsY - 1, inclusive,
358      * specifying the conversion from a CTB address in CTB raster scan of a picture to a CTB address in tile scan */
359     uint16_t tileX = 0, tileY = 0;
360     for (ctbAddrRs = 0; ctbAddrRs < picSizeInCtbsY; ctbAddrRs++)
361     {
362         tbX = ctbAddrRs % m_basicFeature->m_widthInCtb;
363         tbY = ctbAddrRs / m_basicFeature->m_widthInCtb;
364 
365         for (j = 0; j <= picParams.num_tile_rows_minus1; j++)
366         {
367             if (tbY >= rowBd[j])
368             {
369                 tileY = j;
370             }
371         }
372 
373         for (i = 0; i <= picParams.num_tile_columns_minus1; i++)
374         {
375             if (tbX >= colBd[i])
376             {
377                 tileX = i;
378             }
379         }
380 
381         m_pCtbAddrRsToTs[ctbAddrRs] = 0;
382         for (i = 0; i < tileX; i++)
383         {
384             m_pCtbAddrRsToTs[ctbAddrRs] += rowHeight[tileY] * colWidth[i];
385         }
386         for (j = 0; j < tileY; j++)
387         {
388             m_pCtbAddrRsToTs[ctbAddrRs] += m_basicFeature->m_widthInCtb * rowHeight[j];
389         }
390 
391         m_pCtbAddrRsToTs[ctbAddrRs] += (tbY - rowBd[tileY]) * colWidth[tileX] + tbX - colBd[tileX];
392     }
393 
394     return MOS_STATUS_SUCCESS;
395 }
396 
GetSliceTileX(uint32_t sliceIndex)397 uint16_t HevcTileCoding::GetSliceTileX(uint32_t sliceIndex)
398 {
399     if (sliceIndex >= m_sliceTileInfoList.size())
400     {
401         return 0;
402     }
403     return m_sliceTileInfoList[sliceIndex]->sliceTileX;
404 }
405 
GetSliceTileY(uint32_t sliceIndex)406 uint16_t HevcTileCoding::GetSliceTileY(uint32_t sliceIndex)
407 {
408     if (sliceIndex >= m_sliceTileInfoList.size())
409     {
410         return 0;
411     }
412     return m_sliceTileInfoList[sliceIndex]->sliceTileY;
413 }
414 
AllocateSliceTileInfo(uint32_t sliceIndex)415 HevcTileCoding::SliceTileInfo* HevcTileCoding::AllocateSliceTileInfo(uint32_t sliceIndex)
416 {
417     SliceTileInfo* sliceTileInfo;
418     if (sliceIndex < m_sliceTileInfoList.size())
419     {
420         sliceTileInfo = m_sliceTileInfoList[sliceIndex];
421         DECODE_ASSERT(sliceTileInfo != nullptr);
422 
423         sliceTileInfo->sliceTileX       = 0;
424         sliceTileInfo->sliceTileY       = 0;
425         sliceTileInfo->firstSliceOfTile = false;
426         sliceTileInfo->lastSliceOfTile  = false;
427         sliceTileInfo->origCtbX         = 0;
428         sliceTileInfo->origCtbY         = 0;
429         sliceTileInfo->numTiles         = 0;
430     }
431     else
432     {
433         sliceTileInfo = MOS_New(SliceTileInfo);
434         if (sliceTileInfo != nullptr)
435         {
436             MOS_ZeroMemory(sliceTileInfo, sizeof(SliceTileInfo));
437             m_sliceTileInfoList.push_back(sliceTileInfo);
438         }
439     }
440     return sliceTileInfo;
441 }
442 
GetAllTileInfo(const CODEC_HEVC_PIC_PARAMS & picParams,uint32_t widthInCtb,uint32_t heightInCtb)443 MOS_STATUS HevcTileCoding::GetAllTileInfo(const CODEC_HEVC_PIC_PARAMS & picParams,
444                                           uint32_t widthInCtb, uint32_t heightInCtb)
445 {
446     DECODE_FUNC_CALL();
447 
448     if (picParams.uniform_spacing_flag == 1)
449     {
450         for (auto i = 0; i <= picParams.num_tile_columns_minus1; i++)
451         {
452             m_tileColWidth[i] = ((i + 1) * widthInCtb) / (picParams.num_tile_columns_minus1 + 1) -
453                                 (i * widthInCtb) / (picParams.num_tile_columns_minus1 + 1);
454         }
455 
456         for (auto i = 0; i <= picParams.num_tile_rows_minus1; i++)
457         {
458             m_tileRowHeight[i] = ((i + 1) * heightInCtb) / (picParams.num_tile_rows_minus1 + 1) -
459                                  (i * heightInCtb) / (picParams.num_tile_rows_minus1 + 1);
460         }
461     }
462     else
463     {
464         m_tileColWidth[picParams.num_tile_columns_minus1] = widthInCtb & 0xffff;
465         for (auto i = 0; i < picParams.num_tile_columns_minus1; i++)
466         {
467             m_tileColWidth[i] = picParams.column_width_minus1[i] + 1;
468             m_tileColWidth[picParams.num_tile_columns_minus1] -= m_tileColWidth[i];
469         }
470 
471         m_tileRowHeight[picParams.num_tile_rows_minus1] = heightInCtb & 0xffff;
472         for (auto i = 0; i < picParams.num_tile_rows_minus1; i++)
473         {
474             m_tileRowHeight[i] = picParams.row_height_minus1[i] + 1;
475             m_tileRowHeight[picParams.num_tile_rows_minus1] -= m_tileRowHeight[i];
476         }
477     }
478 
479     return MOS_STATUS_SUCCESS;
480 }
481 
GetTileColWidth()482 const uint16_t *HevcTileCoding::GetTileColWidth()
483 {
484     return m_tileColWidth;
485 }
486 
GetTileRowHeight()487 const uint16_t *HevcTileCoding::GetTileRowHeight()
488 {
489     return m_tileRowHeight;
490 }
491 
GetSliceTileInfo(uint32_t sliceIndex)492 const HevcTileCoding::SliceTileInfo *HevcTileCoding::GetSliceTileInfo(uint32_t sliceIndex)
493 {
494     if (sliceIndex >= m_sliceTileInfoList.size())
495     {
496         return nullptr;
497     }
498     return m_sliceTileInfoList[sliceIndex];
499 }
500 
ComputeSliceTileX(const CODEC_HEVC_PIC_PARAMS & picParams,const CODEC_HEVC_SLICE_PARAMS & slc)501 uint16_t HevcTileCoding::ComputeSliceTileX(const CODEC_HEVC_PIC_PARAMS & picParams,
502                                            const CODEC_HEVC_SLICE_PARAMS & slc)
503 {
504     DECODE_FUNC_CALL();
505 
506     uint16_t ctbX, ctbStart = 0;
507 
508     ctbX = slc.slice_segment_address % m_basicFeature->m_widthInCtb;
509     for (uint16_t i = 0; i <= picParams.num_tile_columns_minus1; i++)
510     {
511         if (ctbX >= ctbStart && ctbX < ctbStart + m_tileColWidth[i])
512         {
513             return i;
514         }
515         ctbStart += m_tileColWidth[i];
516     }
517     return 0;
518 }
519 
ComputeSliceTileY(const CODEC_HEVC_PIC_PARAMS & picParams,const CODEC_HEVC_SLICE_PARAMS & slc)520 uint16_t HevcTileCoding::ComputeSliceTileY(const CODEC_HEVC_PIC_PARAMS & picParams,
521                                            const CODEC_HEVC_SLICE_PARAMS & slc)
522 {
523     DECODE_FUNC_CALL();
524 
525     uint32_t ctbY, ctbStart = 0;
526 
527     ctbY = slc.slice_segment_address / m_basicFeature->m_widthInCtb;
528     for (uint16_t i = 0; i <= picParams.num_tile_rows_minus1; i++)
529     {
530         if (ctbY >= ctbStart && ctbY < ctbStart + m_tileRowHeight[i])
531         {
532             return i;
533         }
534         ctbStart += m_tileRowHeight[i];
535     }
536     return 0;
537 }
538 
ComputeTileNumForSlice(const CODEC_HEVC_PIC_PARAMS & picParams,uint32_t sliceIdx,uint16_t sliceTileX,uint16_t sliceTileY,bool lastSlice)539 uint16_t HevcTileCoding::ComputeTileNumForSlice(const CODEC_HEVC_PIC_PARAMS & picParams,
540                                                 uint32_t sliceIdx,
541                                                 uint16_t sliceTileX,
542                                                 uint16_t sliceTileY,
543                                                 bool lastSlice)
544 {
545     uint16_t numTiles;
546     if (lastSlice)
547     {
548         numTiles = (picParams.num_tile_columns_minus1 + 1) *
549                    (picParams.num_tile_rows_minus1 + 1 - sliceTileY) - sliceTileX;
550     }
551     else
552     {
553         uint32_t nextTileX = GetSliceTileX(sliceIdx + 1);
554         uint32_t nextTileY = GetSliceTileY(sliceIdx + 1);
555         numTiles = (picParams.num_tile_columns_minus1 + 1) * (nextTileY - sliceTileY) +
556                    nextTileX - sliceTileX;
557     }
558     return numTiles;
559 }
560 
GetTileCtbX(uint16_t col)561 uint16_t HevcTileCoding::GetTileCtbX(uint16_t col)
562 {
563     DECODE_FUNC_CALL();
564 
565     uint16_t ctbX = 0;
566     for (uint16_t i = 0; i < col; i++)
567     {
568         ctbX += m_tileColWidth[i];
569     }
570     return ctbX;
571 }
572 
GetTileCtbY(uint16_t row)573 uint16_t HevcTileCoding::GetTileCtbY(uint16_t row)
574 {
575     DECODE_FUNC_CALL();
576 
577     uint16_t ctbY = 0;
578     for (uint16_t i = 0; i < row; i++)
579     {
580         ctbY += m_tileRowHeight[i];
581     }
582     return ctbY;
583 }
584 
585 }
586