1 /*****************************************************************************
2 * Copyright (C) 2014 x265 project
4 * Authors: Steve Borho <steve@borho.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
26 #include "framedata.h"
34 // file private namespace
36 /* for all bcast* and copy* functions, dst and src are aligned to MIN(size, 32) */
38 void bcast1(uint8_t* dst
, uint8_t val
) { dst
[0] = val
; }
40 void copy4(uint8_t* dst
, uint8_t* src
) { ((uint32_t*)dst
)[0] = ((uint32_t*)src
)[0]; }
41 void bcast4(uint8_t* dst
, uint8_t val
) { ((uint32_t*)dst
)[0] = 0x01010101 * val
; }
43 void copy16(uint8_t* dst
, uint8_t* src
) { ((uint64_t*)dst
)[0] = ((uint64_t*)src
)[0]; ((uint64_t*)dst
)[1] = ((uint64_t*)src
)[1]; }
44 void bcast16(uint8_t* dst
, uint8_t val
) { uint64_t bval
= 0x0101010101010101ULL
* val
; ((uint64_t*)dst
)[0] = bval
; ((uint64_t*)dst
)[1] = bval
; }
46 void copy64(uint8_t* dst
, uint8_t* src
) { ((uint64_t*)dst
)[0] = ((uint64_t*)src
)[0]; ((uint64_t*)dst
)[1] = ((uint64_t*)src
)[1];
47 ((uint64_t*)dst
)[2] = ((uint64_t*)src
)[2]; ((uint64_t*)dst
)[3] = ((uint64_t*)src
)[3];
48 ((uint64_t*)dst
)[4] = ((uint64_t*)src
)[4]; ((uint64_t*)dst
)[5] = ((uint64_t*)src
)[5];
49 ((uint64_t*)dst
)[6] = ((uint64_t*)src
)[6]; ((uint64_t*)dst
)[7] = ((uint64_t*)src
)[7]; }
50 void bcast64(uint8_t* dst
, uint8_t val
) { uint64_t bval
= 0x0101010101010101ULL
* val
;
51 ((uint64_t*)dst
)[0] = bval
; ((uint64_t*)dst
)[1] = bval
; ((uint64_t*)dst
)[2] = bval
; ((uint64_t*)dst
)[3] = bval
;
52 ((uint64_t*)dst
)[4] = bval
; ((uint64_t*)dst
)[5] = bval
; ((uint64_t*)dst
)[6] = bval
; ((uint64_t*)dst
)[7] = bval
; }
54 /* at 256 bytes, memset/memcpy will probably use SIMD more effectively than our uint64_t hack,
55 * but hand-written assembly would beat it. */
56 void copy256(uint8_t* dst
, uint8_t* src
) { memcpy(dst
, src
, 256); }
57 void bcast256(uint8_t* dst
, uint8_t val
) { memset(dst
, val
, 256); }
59 /* Check whether 2 addresses point to the same column */
60 inline bool isEqualCol(int addrA
, int addrB
, int numUnitsPerRow
)
62 // addrA % numUnitsPerRow == addrB % numUnitsPerRow
63 return ((addrA
^ addrB
) & (numUnitsPerRow
- 1)) == 0;
66 /* Check whether 2 addresses point to the same row */
67 inline bool isEqualRow(int addrA
, int addrB
, int numUnitsPerRow
)
69 // addrA / numUnitsPerRow == addrB / numUnitsPerRow
70 return ((addrA
^ addrB
) & ~(numUnitsPerRow
- 1)) == 0;
73 /* Check whether 2 addresses point to the same row or column */
74 inline bool isEqualRowOrCol(int addrA
, int addrB
, int numUnitsPerRow
)
76 return isEqualCol(addrA
, addrB
, numUnitsPerRow
) | isEqualRow(addrA
, addrB
, numUnitsPerRow
);
79 /* Check whether one address points to the first column */
80 inline bool isZeroCol(int addr
, int numUnitsPerRow
)
82 // addr % numUnitsPerRow == 0
83 return (addr
& (numUnitsPerRow
- 1)) == 0;
86 /* Check whether one address points to the first row */
87 inline bool isZeroRow(int addr
, int numUnitsPerRow
)
89 // addr / numUnitsPerRow == 0
90 return (addr
& ~(numUnitsPerRow
- 1)) == 0;
93 /* Check whether one address points to a column whose index is smaller than a given value */
94 inline bool lessThanCol(int addr
, int val
, int numUnitsPerRow
)
96 // addr % numUnitsPerRow < val
97 return (addr
& (numUnitsPerRow
- 1)) < val
;
100 /* Check whether one address points to a row whose index is smaller than a given value */
101 inline bool lessThanRow(int addr
, int val
, int numUnitsPerRow
)
103 // addr / numUnitsPerRow < val
104 return addr
< val
* numUnitsPerRow
;
107 inline MV
scaleMv(MV mv
, int scale
)
109 int mvx
= Clip3(-32768, 32767, (scale
* mv
.x
+ 127 + (scale
* mv
.x
< 0)) >> 8);
110 int mvy
= Clip3(-32768, 32767, (scale
* mv
.y
+ 127 + (scale
* mv
.y
< 0)) >> 8);
112 return MV((int16_t)mvx
, (int16_t)mvy
);
116 // First index is partitioning mode. Second index is partition index.
117 // Third index is 0 for partition sizes, 1 for partition offsets. The
118 // sizes and offsets are encoded as two packed 4-bit values (X,Y).
119 // X and Y represent 1/4 fractions of the block size.
120 const uint32_t partTable
[8][4][2] =
123 { { 0x44, 0x00 }, { 0x00, 0x00 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_2Nx2N.
124 { { 0x42, 0x00 }, { 0x42, 0x02 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_2NxN.
125 { { 0x24, 0x00 }, { 0x24, 0x20 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_Nx2N.
126 { { 0x22, 0x00 }, { 0x22, 0x20 }, { 0x22, 0x02 }, { 0x22, 0x22 } }, // SIZE_NxN.
127 { { 0x41, 0x00 }, { 0x43, 0x01 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_2NxnU.
128 { { 0x43, 0x00 }, { 0x41, 0x03 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_2NxnD.
129 { { 0x14, 0x00 }, { 0x34, 0x10 }, { 0x00, 0x00 }, { 0x00, 0x00 } }, // SIZE_nLx2N.
130 { { 0x34, 0x00 }, { 0x14, 0x30 }, { 0x00, 0x00 }, { 0x00, 0x00 } } // SIZE_nRx2N.
133 // Partition Address table.
134 // First index is partitioning mode. Second index is partition address.
135 const uint32_t partAddrTable
[8][4] =
137 { 0x00, 0x00, 0x00, 0x00 }, // SIZE_2Nx2N.
138 { 0x00, 0x08, 0x08, 0x08 }, // SIZE_2NxN.
139 { 0x00, 0x04, 0x04, 0x04 }, // SIZE_Nx2N.
140 { 0x00, 0x04, 0x08, 0x0C }, // SIZE_NxN.
141 { 0x00, 0x02, 0x02, 0x02 }, // SIZE_2NxnU.
142 { 0x00, 0x0A, 0x0A, 0x0A }, // SIZE_2NxnD.
143 { 0x00, 0x01, 0x01, 0x01 }, // SIZE_nLx2N.
144 { 0x00, 0x05, 0x05, 0x05 } // SIZE_nRx2N.
149 cubcast_t
CUData::s_partSet
[NUM_FULL_DEPTH
] = { NULL
, NULL
, NULL
, NULL
, NULL
};
150 uint32_t CUData::s_numPartInCUSize
;
154 memset(this, 0, sizeof(*this));
157 void CUData::initialize(const CUDataMemPool
& dataPool
, uint32_t depth
, int csp
, int instance
)
159 m_chromaFormat
= csp
;
160 m_hChromaShift
= CHROMA_H_SHIFT(csp
);
161 m_vChromaShift
= CHROMA_V_SHIFT(csp
);
162 m_numPartitions
= NUM_CU_PARTITIONS
>> (depth
* 2);
166 s_numPartInCUSize
= 1 << g_maxFullDepth
;
167 switch (g_maxLog2CUSize
)
170 s_partSet
[0] = bcast256
;
171 s_partSet
[1] = bcast64
;
172 s_partSet
[2] = bcast16
;
173 s_partSet
[3] = bcast4
;
174 s_partSet
[4] = bcast1
;
177 s_partSet
[0] = bcast64
;
178 s_partSet
[1] = bcast16
;
179 s_partSet
[2] = bcast4
;
180 s_partSet
[3] = bcast1
;
184 s_partSet
[0] = bcast16
;
185 s_partSet
[1] = bcast4
;
186 s_partSet
[2] = bcast1
;
191 X265_CHECK(0, "unexpected CTU size\n");
196 switch (m_numPartitions
)
198 case 256: // 64x64 CU
199 m_partCopy
= copy256
;
200 m_partSet
= bcast256
;
201 m_subPartCopy
= copy64
;
202 m_subPartSet
= bcast64
;
207 m_subPartCopy
= copy16
;
208 m_subPartSet
= bcast16
;
213 m_subPartCopy
= copy4
;
214 m_subPartSet
= bcast4
;
219 m_subPartCopy
= NULL
;
223 X265_CHECK(0, "unexpected CU partition count\n");
227 /* Each CU's data is layed out sequentially within the charMemBlock */
228 uint8_t *charBuf
= dataPool
.charMemBlock
+ (m_numPartitions
* BytesPerPartition
) * instance
;
230 m_qp
= (char*)charBuf
; charBuf
+= m_numPartitions
;
231 m_log2CUSize
= charBuf
; charBuf
+= m_numPartitions
;
232 m_partSize
= charBuf
; charBuf
+= m_numPartitions
;
233 m_predMode
= charBuf
; charBuf
+= m_numPartitions
;
234 m_lumaIntraDir
= charBuf
; charBuf
+= m_numPartitions
;
235 m_tqBypass
= charBuf
; charBuf
+= m_numPartitions
;
236 m_refIdx
[0] = (char*)charBuf
; charBuf
+= m_numPartitions
;
237 m_refIdx
[1] = (char*)charBuf
; charBuf
+= m_numPartitions
;
238 m_cuDepth
= charBuf
; charBuf
+= m_numPartitions
;
239 m_skipFlag
= charBuf
; charBuf
+= m_numPartitions
; /* the order up to here is important in initCTU() and initSubCU() */
240 m_mergeFlag
= charBuf
; charBuf
+= m_numPartitions
;
241 m_interDir
= charBuf
; charBuf
+= m_numPartitions
;
242 m_mvpIdx
[0] = charBuf
; charBuf
+= m_numPartitions
;
243 m_mvpIdx
[1] = charBuf
; charBuf
+= m_numPartitions
;
244 m_tuDepth
= charBuf
; charBuf
+= m_numPartitions
;
245 m_transformSkip
[0] = charBuf
; charBuf
+= m_numPartitions
;
246 m_transformSkip
[1] = charBuf
; charBuf
+= m_numPartitions
;
247 m_transformSkip
[2] = charBuf
; charBuf
+= m_numPartitions
;
248 m_cbf
[0] = charBuf
; charBuf
+= m_numPartitions
;
249 m_cbf
[1] = charBuf
; charBuf
+= m_numPartitions
;
250 m_cbf
[2] = charBuf
; charBuf
+= m_numPartitions
;
251 m_chromaIntraDir
= charBuf
; charBuf
+= m_numPartitions
;
253 X265_CHECK(charBuf
== dataPool
.charMemBlock
+ (m_numPartitions
* BytesPerPartition
) * (instance
+ 1), "CU data layout is broken\n");
255 m_mv
[0] = dataPool
.mvMemBlock
+ (instance
* 4) * m_numPartitions
;
256 m_mv
[1] = m_mv
[0] + m_numPartitions
;
257 m_mvd
[0] = m_mv
[1] + m_numPartitions
;
258 m_mvd
[1] = m_mvd
[0] + m_numPartitions
;
260 uint32_t cuSize
= g_maxCUSize
>> depth
;
261 uint32_t sizeL
= cuSize
* cuSize
;
262 uint32_t sizeC
= sizeL
>> (m_hChromaShift
+ m_vChromaShift
);
263 m_trCoeff
[0] = dataPool
.trCoeffMemBlock
+ instance
* (sizeL
+ sizeC
* 2);
264 m_trCoeff
[1] = m_trCoeff
[0] + sizeL
;
265 m_trCoeff
[2] = m_trCoeff
[0] + sizeL
+ sizeC
;
268 void CUData::initCTU(const Frame
& frame
, uint32_t cuAddr
, int qp
)
270 m_encData
= frame
.m_encData
;
271 m_slice
= m_encData
->m_slice
;
273 m_cuPelX
= (cuAddr
% m_slice
->m_sps
->numCuInWidth
) << g_maxLog2CUSize
;
274 m_cuPelY
= (cuAddr
/ m_slice
->m_sps
->numCuInWidth
) << g_maxLog2CUSize
;
276 m_numPartitions
= NUM_CU_PARTITIONS
;
278 /* sequential memsets */
279 m_partSet((uint8_t*)m_qp
, (uint8_t)qp
);
280 m_partSet(m_log2CUSize
, (uint8_t)g_maxLog2CUSize
);
281 m_partSet(m_partSize
, (uint8_t)SIZE_NONE
);
282 m_partSet(m_predMode
, (uint8_t)MODE_NONE
);
283 m_partSet(m_lumaIntraDir
, (uint8_t)DC_IDX
);
284 m_partSet(m_tqBypass
, (uint8_t)frame
.m_encData
->m_param
->bLossless
);
285 if (m_slice
->m_sliceType
!= I_SLICE
)
287 m_partSet((uint8_t*)m_refIdx
[0], (uint8_t)REF_NOT_VALID
);
288 m_partSet((uint8_t*)m_refIdx
[1], (uint8_t)REF_NOT_VALID
);
291 X265_CHECK(!(frame
.m_encData
->m_param
->bLossless
&& !m_slice
->m_pps
->bTransquantBypassEnabled
), "lossless enabled without TQbypass in PPS\n");
293 /* initialize the remaining CU data in one memset */
294 memset(m_cuDepth
, 0, (BytesPerPartition
- 8) * m_numPartitions
);
296 uint32_t widthInCU
= m_slice
->m_sps
->numCuInWidth
;
297 m_cuLeft
= (m_cuAddr
% widthInCU
) ? m_encData
->getPicCTU(m_cuAddr
- 1) : NULL
;
298 m_cuAbove
= (m_cuAddr
/ widthInCU
) ? m_encData
->getPicCTU(m_cuAddr
- widthInCU
) : NULL
;
299 m_cuAboveLeft
= (m_cuLeft
&& m_cuAbove
) ? m_encData
->getPicCTU(m_cuAddr
- widthInCU
- 1) : NULL
;
300 m_cuAboveRight
= (m_cuAbove
&& ((m_cuAddr
% widthInCU
) < (widthInCU
- 1))) ? m_encData
->getPicCTU(m_cuAddr
- widthInCU
+ 1) : NULL
;
303 // initialize Sub partition
304 void CUData::initSubCU(const CUData
& ctu
, const CUGeom
& cuGeom
)
306 m_absIdxInCTU
= cuGeom
.encodeIdx
;
307 m_encData
= ctu
.m_encData
;
308 m_slice
= ctu
.m_slice
;
309 m_cuAddr
= ctu
.m_cuAddr
;
310 m_cuPelX
= ctu
.m_cuPelX
+ g_zscanToPelX
[cuGeom
.encodeIdx
];
311 m_cuPelY
= ctu
.m_cuPelY
+ g_zscanToPelY
[cuGeom
.encodeIdx
];
312 m_cuLeft
= ctu
.m_cuLeft
;
313 m_cuAbove
= ctu
.m_cuAbove
;
314 m_cuAboveLeft
= ctu
.m_cuAboveLeft
;
315 m_cuAboveRight
= ctu
.m_cuAboveRight
;
316 X265_CHECK(m_numPartitions
== cuGeom
.numPartitions
, "initSubCU() size mismatch\n");
318 /* sequential memsets */
319 m_partSet((uint8_t*)m_qp
, (uint8_t)ctu
.m_qp
[0]);
320 m_partSet(m_log2CUSize
, (uint8_t)cuGeom
.log2CUSize
);
321 m_partSet(m_partSize
, (uint8_t)SIZE_NONE
);
322 m_partSet(m_predMode
, (uint8_t)MODE_NONE
);
323 m_partSet(m_lumaIntraDir
, (uint8_t)DC_IDX
);
324 m_partSet(m_tqBypass
, (uint8_t)m_encData
->m_param
->bLossless
);
325 m_partSet((uint8_t*)m_refIdx
[0], (uint8_t)REF_NOT_VALID
);
326 m_partSet((uint8_t*)m_refIdx
[1], (uint8_t)REF_NOT_VALID
);
327 m_partSet(m_cuDepth
, (uint8_t)cuGeom
.depth
);
329 /* initialize the remaining CU data in one memset */
330 memset(m_skipFlag
, 0, (BytesPerPartition
- 9) * m_numPartitions
);
333 /* Copy the results of a sub-part (split) CU to the parent CU */
334 void CUData::copyPartFrom(const CUData
& subCU
, const CUGeom
& childGeom
, uint32_t subPartIdx
)
336 X265_CHECK(subPartIdx
< 4, "part unit should be less than 4\n");
338 uint32_t offset
= childGeom
.numPartitions
* subPartIdx
;
340 m_subPartCopy((uint8_t*)m_qp
+ offset
, (uint8_t*)subCU
.m_qp
);
341 m_subPartCopy(m_log2CUSize
+ offset
, subCU
.m_log2CUSize
);
342 m_subPartCopy(m_partSize
+ offset
, subCU
.m_partSize
);
343 m_subPartCopy(m_predMode
+ offset
, subCU
.m_predMode
);
344 m_subPartCopy(m_lumaIntraDir
+ offset
, subCU
.m_lumaIntraDir
);
345 m_subPartCopy(m_tqBypass
+ offset
, subCU
.m_tqBypass
);
346 m_subPartCopy((uint8_t*)m_refIdx
[0] + offset
, (uint8_t*)subCU
.m_refIdx
[0]);
347 m_subPartCopy((uint8_t*)m_refIdx
[1] + offset
, (uint8_t*)subCU
.m_refIdx
[1]);
348 m_subPartCopy(m_cuDepth
+ offset
, subCU
.m_cuDepth
);
349 m_subPartCopy(m_skipFlag
+ offset
, subCU
.m_skipFlag
);
350 m_subPartCopy(m_mergeFlag
+ offset
, subCU
.m_mergeFlag
);
351 m_subPartCopy(m_interDir
+ offset
, subCU
.m_interDir
);
352 m_subPartCopy(m_mvpIdx
[0] + offset
, subCU
.m_mvpIdx
[0]);
353 m_subPartCopy(m_mvpIdx
[1] + offset
, subCU
.m_mvpIdx
[1]);
354 m_subPartCopy(m_tuDepth
+ offset
, subCU
.m_tuDepth
);
355 m_subPartCopy(m_transformSkip
[0] + offset
, subCU
.m_transformSkip
[0]);
356 m_subPartCopy(m_transformSkip
[1] + offset
, subCU
.m_transformSkip
[1]);
357 m_subPartCopy(m_transformSkip
[2] + offset
, subCU
.m_transformSkip
[2]);
358 m_subPartCopy(m_cbf
[0] + offset
, subCU
.m_cbf
[0]);
359 m_subPartCopy(m_cbf
[1] + offset
, subCU
.m_cbf
[1]);
360 m_subPartCopy(m_cbf
[2] + offset
, subCU
.m_cbf
[2]);
361 m_subPartCopy(m_chromaIntraDir
+ offset
, subCU
.m_chromaIntraDir
);
363 memcpy(m_mv
[0] + offset
, subCU
.m_mv
[0], childGeom
.numPartitions
* sizeof(MV
));
364 memcpy(m_mv
[1] + offset
, subCU
.m_mv
[1], childGeom
.numPartitions
* sizeof(MV
));
365 memcpy(m_mvd
[0] + offset
, subCU
.m_mvd
[0], childGeom
.numPartitions
* sizeof(MV
));
366 memcpy(m_mvd
[1] + offset
, subCU
.m_mvd
[1], childGeom
.numPartitions
* sizeof(MV
));
368 uint32_t tmp
= 1 << ((g_maxLog2CUSize
- childGeom
.depth
) * 2);
369 uint32_t tmp2
= subPartIdx
* tmp
;
370 memcpy(m_trCoeff
[0] + tmp2
, subCU
.m_trCoeff
[0], sizeof(coeff_t
) * tmp
);
372 uint32_t tmpC
= tmp
>> (m_hChromaShift
+ m_vChromaShift
);
373 uint32_t tmpC2
= tmp2
>> (m_hChromaShift
+ m_vChromaShift
);
374 memcpy(m_trCoeff
[1] + tmpC2
, subCU
.m_trCoeff
[1], sizeof(coeff_t
) * tmpC
);
375 memcpy(m_trCoeff
[2] + tmpC2
, subCU
.m_trCoeff
[2], sizeof(coeff_t
) * tmpC
);
378 /* If a sub-CU part is not present (off the edge of the picture) its depth and
379 * log2size should still be configured */
380 void CUData::setEmptyPart(const CUGeom
& childGeom
, uint32_t subPartIdx
)
382 uint32_t offset
= childGeom
.numPartitions
* subPartIdx
;
383 m_subPartSet(m_cuDepth
+ offset
, (uint8_t)childGeom
.depth
);
384 m_subPartSet(m_log2CUSize
+ offset
, (uint8_t)childGeom
.log2CUSize
);
387 /* Copy all CU data from one instance to the next, except set lossless flag
388 * This will only get used when --cu-lossless is enabled but --lossless is not. */
389 void CUData::initLosslessCU(const CUData
& cu
, const CUGeom
& cuGeom
)
391 /* Start by making an exact copy */
392 m_encData
= cu
.m_encData
;
393 m_slice
= cu
.m_slice
;
394 m_cuAddr
= cu
.m_cuAddr
;
395 m_cuPelX
= cu
.m_cuPelX
;
396 m_cuPelY
= cu
.m_cuPelY
;
397 m_cuLeft
= cu
.m_cuLeft
;
398 m_cuAbove
= cu
.m_cuAbove
;
399 m_cuAboveLeft
= cu
.m_cuAboveLeft
;
400 m_cuAboveRight
= cu
.m_cuAboveRight
;
401 m_absIdxInCTU
= cuGeom
.encodeIdx
;
402 m_numPartitions
= cuGeom
.numPartitions
;
403 memcpy(m_qp
, cu
.m_qp
, BytesPerPartition
* m_numPartitions
);
404 memcpy(m_mv
[0], cu
.m_mv
[0], m_numPartitions
* sizeof(MV
));
405 memcpy(m_mv
[1], cu
.m_mv
[1], m_numPartitions
* sizeof(MV
));
406 memcpy(m_mvd
[0], cu
.m_mvd
[0], m_numPartitions
* sizeof(MV
));
407 memcpy(m_mvd
[1], cu
.m_mvd
[1], m_numPartitions
* sizeof(MV
));
409 /* force TQBypass to true */
410 m_partSet(m_tqBypass
, true);
412 /* clear residual coding flags */
413 m_partSet(m_skipFlag
, 0);
414 m_partSet(m_tuDepth
, 0);
415 m_partSet(m_transformSkip
[0], 0);
416 m_partSet(m_transformSkip
[1], 0);
417 m_partSet(m_transformSkip
[2], 0);
418 m_partSet(m_cbf
[0], 0);
419 m_partSet(m_cbf
[1], 0);
420 m_partSet(m_cbf
[2], 0);
423 /* Copy completed predicted CU to CTU in picture */
424 void CUData::copyToPic(uint32_t depth
) const
426 CUData
& ctu
= *m_encData
->getPicCTU(m_cuAddr
);
428 m_partCopy((uint8_t*)ctu
.m_qp
+ m_absIdxInCTU
, (uint8_t*)m_qp
);
429 m_partCopy(ctu
.m_log2CUSize
+ m_absIdxInCTU
, m_log2CUSize
);
430 m_partCopy(ctu
.m_partSize
+ m_absIdxInCTU
, m_partSize
);
431 m_partCopy(ctu
.m_predMode
+ m_absIdxInCTU
, m_predMode
);
432 m_partCopy(ctu
.m_lumaIntraDir
+ m_absIdxInCTU
, m_lumaIntraDir
);
433 m_partCopy(ctu
.m_tqBypass
+ m_absIdxInCTU
, m_tqBypass
);
434 m_partCopy((uint8_t*)ctu
.m_refIdx
[0] + m_absIdxInCTU
, (uint8_t*)m_refIdx
[0]);
435 m_partCopy((uint8_t*)ctu
.m_refIdx
[1] + m_absIdxInCTU
, (uint8_t*)m_refIdx
[1]);
436 m_partCopy(ctu
.m_cuDepth
+ m_absIdxInCTU
, m_cuDepth
);
437 m_partCopy(ctu
.m_skipFlag
+ m_absIdxInCTU
, m_skipFlag
);
438 m_partCopy(ctu
.m_mergeFlag
+ m_absIdxInCTU
, m_mergeFlag
);
439 m_partCopy(ctu
.m_interDir
+ m_absIdxInCTU
, m_interDir
);
440 m_partCopy(ctu
.m_mvpIdx
[0] + m_absIdxInCTU
, m_mvpIdx
[0]);
441 m_partCopy(ctu
.m_mvpIdx
[1] + m_absIdxInCTU
, m_mvpIdx
[1]);
442 m_partCopy(ctu
.m_tuDepth
+ m_absIdxInCTU
, m_tuDepth
);
443 m_partCopy(ctu
.m_transformSkip
[0] + m_absIdxInCTU
, m_transformSkip
[0]);
444 m_partCopy(ctu
.m_transformSkip
[1] + m_absIdxInCTU
, m_transformSkip
[1]);
445 m_partCopy(ctu
.m_transformSkip
[2] + m_absIdxInCTU
, m_transformSkip
[2]);
446 m_partCopy(ctu
.m_cbf
[0] + m_absIdxInCTU
, m_cbf
[0]);
447 m_partCopy(ctu
.m_cbf
[1] + m_absIdxInCTU
, m_cbf
[1]);
448 m_partCopy(ctu
.m_cbf
[2] + m_absIdxInCTU
, m_cbf
[2]);
449 m_partCopy(ctu
.m_chromaIntraDir
+ m_absIdxInCTU
, m_chromaIntraDir
);
451 memcpy(ctu
.m_mv
[0] + m_absIdxInCTU
, m_mv
[0], m_numPartitions
* sizeof(MV
));
452 memcpy(ctu
.m_mv
[1] + m_absIdxInCTU
, m_mv
[1], m_numPartitions
* sizeof(MV
));
453 memcpy(ctu
.m_mvd
[0] + m_absIdxInCTU
, m_mvd
[0], m_numPartitions
* sizeof(MV
));
454 memcpy(ctu
.m_mvd
[1] + m_absIdxInCTU
, m_mvd
[1], m_numPartitions
* sizeof(MV
));
456 uint32_t tmpY
= 1 << ((g_maxLog2CUSize
- depth
) * 2);
457 uint32_t tmpY2
= m_absIdxInCTU
<< (LOG2_UNIT_SIZE
* 2);
458 memcpy(ctu
.m_trCoeff
[0] + tmpY2
, m_trCoeff
[0], sizeof(coeff_t
) * tmpY
);
460 uint32_t tmpC
= tmpY
>> (m_hChromaShift
+ m_vChromaShift
);
461 uint32_t tmpC2
= tmpY2
>> (m_hChromaShift
+ m_vChromaShift
);
462 memcpy(ctu
.m_trCoeff
[1] + tmpC2
, m_trCoeff
[1], sizeof(coeff_t
) * tmpC
);
463 memcpy(ctu
.m_trCoeff
[2] + tmpC2
, m_trCoeff
[2], sizeof(coeff_t
) * tmpC
);
466 /* The reverse of copyToPic, called only by encodeResidue */
467 void CUData::copyFromPic(const CUData
& ctu
, const CUGeom
& cuGeom
)
469 m_encData
= ctu
.m_encData
;
470 m_slice
= ctu
.m_slice
;
471 m_cuAddr
= ctu
.m_cuAddr
;
472 m_cuPelX
= ctu
.m_cuPelX
+ g_zscanToPelX
[cuGeom
.encodeIdx
];
473 m_cuPelY
= ctu
.m_cuPelY
+ g_zscanToPelY
[cuGeom
.encodeIdx
];
474 m_absIdxInCTU
= cuGeom
.encodeIdx
;
475 m_numPartitions
= cuGeom
.numPartitions
;
477 /* copy out all prediction info for this part */
478 m_partCopy((uint8_t*)m_qp
, (uint8_t*)ctu
.m_qp
+ m_absIdxInCTU
);
479 m_partCopy(m_log2CUSize
, ctu
.m_log2CUSize
+ m_absIdxInCTU
);
480 m_partCopy(m_partSize
, ctu
.m_partSize
+ m_absIdxInCTU
);
481 m_partCopy(m_predMode
, ctu
.m_predMode
+ m_absIdxInCTU
);
482 m_partCopy(m_lumaIntraDir
, ctu
.m_lumaIntraDir
+ m_absIdxInCTU
);
483 m_partCopy(m_tqBypass
, ctu
.m_tqBypass
+ m_absIdxInCTU
);
484 m_partCopy((uint8_t*)m_refIdx
[0], (uint8_t*)ctu
.m_refIdx
[0] + m_absIdxInCTU
);
485 m_partCopy((uint8_t*)m_refIdx
[1], (uint8_t*)ctu
.m_refIdx
[1] + m_absIdxInCTU
);
486 m_partCopy(m_cuDepth
, ctu
.m_cuDepth
+ m_absIdxInCTU
);
487 m_partCopy(m_mergeFlag
, ctu
.m_mergeFlag
+ m_absIdxInCTU
);
488 m_partCopy(m_interDir
, ctu
.m_interDir
+ m_absIdxInCTU
);
489 m_partCopy(m_mvpIdx
[0], ctu
.m_mvpIdx
[0] + m_absIdxInCTU
);
490 m_partCopy(m_mvpIdx
[1], ctu
.m_mvpIdx
[1] + m_absIdxInCTU
);
491 m_partCopy(m_chromaIntraDir
, ctu
.m_chromaIntraDir
+ m_absIdxInCTU
);
493 memcpy(m_mv
[0], ctu
.m_mv
[0] + m_absIdxInCTU
, m_numPartitions
* sizeof(MV
));
494 memcpy(m_mv
[1], ctu
.m_mv
[1] + m_absIdxInCTU
, m_numPartitions
* sizeof(MV
));
495 memcpy(m_mvd
[0], ctu
.m_mvd
[0] + m_absIdxInCTU
, m_numPartitions
* sizeof(MV
));
496 memcpy(m_mvd
[1], ctu
.m_mvd
[1] + m_absIdxInCTU
, m_numPartitions
* sizeof(MV
));
498 /* clear residual coding flags */
499 m_partSet(m_skipFlag
, 0);
500 m_partSet(m_tuDepth
, 0);
501 m_partSet(m_transformSkip
[0], 0);
502 m_partSet(m_transformSkip
[1], 0);
503 m_partSet(m_transformSkip
[2], 0);
504 m_partSet(m_cbf
[0], 0);
505 m_partSet(m_cbf
[1], 0);
506 m_partSet(m_cbf
[2], 0);
509 /* Only called by encodeResidue, these fields can be modified during inter/intra coding */
510 void CUData::updatePic(uint32_t depth
) const
512 CUData
& ctu
= *m_encData
->getPicCTU(m_cuAddr
);
514 m_partCopy((uint8_t*)ctu
.m_qp
+ m_absIdxInCTU
, (uint8_t*)m_qp
);
515 m_partCopy(ctu
.m_transformSkip
[0] + m_absIdxInCTU
, m_transformSkip
[0]);
516 m_partCopy(ctu
.m_transformSkip
[1] + m_absIdxInCTU
, m_transformSkip
[1]);
517 m_partCopy(ctu
.m_transformSkip
[2] + m_absIdxInCTU
, m_transformSkip
[2]);
518 m_partCopy(ctu
.m_skipFlag
+ m_absIdxInCTU
, m_skipFlag
);
519 m_partCopy(ctu
.m_tuDepth
+ m_absIdxInCTU
, m_tuDepth
);
520 m_partCopy(ctu
.m_cbf
[0] + m_absIdxInCTU
, m_cbf
[0]);
521 m_partCopy(ctu
.m_cbf
[1] + m_absIdxInCTU
, m_cbf
[1]);
522 m_partCopy(ctu
.m_cbf
[2] + m_absIdxInCTU
, m_cbf
[2]);
523 m_partCopy(ctu
.m_chromaIntraDir
+ m_absIdxInCTU
, m_chromaIntraDir
);
525 uint32_t tmpY
= 1 << ((g_maxLog2CUSize
- depth
) * 2);
526 uint32_t tmpY2
= m_absIdxInCTU
<< (LOG2_UNIT_SIZE
* 2);
527 memcpy(ctu
.m_trCoeff
[0] + tmpY2
, m_trCoeff
[0], sizeof(coeff_t
) * tmpY
);
528 tmpY
>>= m_hChromaShift
+ m_vChromaShift
;
529 tmpY2
>>= m_hChromaShift
+ m_vChromaShift
;
530 memcpy(ctu
.m_trCoeff
[1] + tmpY2
, m_trCoeff
[1], sizeof(coeff_t
) * tmpY
);
531 memcpy(ctu
.m_trCoeff
[2] + tmpY2
, m_trCoeff
[2], sizeof(coeff_t
) * tmpY
);
534 const CUData
* CUData::getPULeft(uint32_t& lPartUnitIdx
, uint32_t curPartUnitIdx
) const
536 uint32_t absPartIdx
= g_zscanToRaster
[curPartUnitIdx
];
538 if (!isZeroCol(absPartIdx
, s_numPartInCUSize
))
540 uint32_t absZorderCUIdx
= g_zscanToRaster
[m_absIdxInCTU
];
541 lPartUnitIdx
= g_rasterToZscan
[absPartIdx
- 1];
542 if (isEqualCol(absPartIdx
, absZorderCUIdx
, s_numPartInCUSize
))
543 return m_encData
->getPicCTU(m_cuAddr
);
546 lPartUnitIdx
-= m_absIdxInCTU
;
551 lPartUnitIdx
= g_rasterToZscan
[absPartIdx
+ s_numPartInCUSize
- 1];
555 const CUData
* CUData::getPUAbove(uint32_t& aPartUnitIdx
, uint32_t curPartUnitIdx
, bool planarAtCTUBoundary
) const
557 uint32_t absPartIdx
= g_zscanToRaster
[curPartUnitIdx
];
559 if (!isZeroRow(absPartIdx
, s_numPartInCUSize
))
561 uint32_t absZorderCUIdx
= g_zscanToRaster
[m_absIdxInCTU
];
562 aPartUnitIdx
= g_rasterToZscan
[absPartIdx
- s_numPartInCUSize
];
563 if (isEqualRow(absPartIdx
, absZorderCUIdx
, s_numPartInCUSize
))
564 return m_encData
->getPicCTU(m_cuAddr
);
567 aPartUnitIdx
-= m_absIdxInCTU
;
572 if (planarAtCTUBoundary
)
575 aPartUnitIdx
= g_rasterToZscan
[absPartIdx
+ NUM_CU_PARTITIONS
- s_numPartInCUSize
];
579 const CUData
* CUData::getPUAboveLeft(uint32_t& alPartUnitIdx
, uint32_t curPartUnitIdx
) const
581 uint32_t absPartIdx
= g_zscanToRaster
[curPartUnitIdx
];
583 if (!isZeroCol(absPartIdx
, s_numPartInCUSize
))
585 if (!isZeroRow(absPartIdx
, s_numPartInCUSize
))
587 uint32_t absZorderCUIdx
= g_zscanToRaster
[m_absIdxInCTU
];
588 alPartUnitIdx
= g_rasterToZscan
[absPartIdx
- s_numPartInCUSize
- 1];
589 if (isEqualRowOrCol(absPartIdx
, absZorderCUIdx
, s_numPartInCUSize
))
590 return m_encData
->getPicCTU(m_cuAddr
);
593 alPartUnitIdx
-= m_absIdxInCTU
;
597 alPartUnitIdx
= g_rasterToZscan
[absPartIdx
+ NUM_CU_PARTITIONS
- s_numPartInCUSize
- 1];
601 if (!isZeroRow(absPartIdx
, s_numPartInCUSize
))
603 alPartUnitIdx
= g_rasterToZscan
[absPartIdx
- 1];
607 alPartUnitIdx
= g_rasterToZscan
[NUM_CU_PARTITIONS
- 1];
608 return m_cuAboveLeft
;
611 const CUData
* CUData::getPUAboveRight(uint32_t& arPartUnitIdx
, uint32_t curPartUnitIdx
) const
613 if ((m_encData
->getPicCTU(m_cuAddr
)->m_cuPelX
+ g_zscanToPelX
[curPartUnitIdx
] + UNIT_SIZE
) >= m_slice
->m_sps
->picWidthInLumaSamples
)
616 uint32_t absPartIdxRT
= g_zscanToRaster
[curPartUnitIdx
];
618 if (lessThanCol(absPartIdxRT
, s_numPartInCUSize
- 1, s_numPartInCUSize
))
620 if (!isZeroRow(absPartIdxRT
, s_numPartInCUSize
))
622 if (curPartUnitIdx
> g_rasterToZscan
[absPartIdxRT
- s_numPartInCUSize
+ 1])
624 uint32_t absZorderCUIdx
= g_zscanToRaster
[m_absIdxInCTU
] + (1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1;
625 arPartUnitIdx
= g_rasterToZscan
[absPartIdxRT
- s_numPartInCUSize
+ 1];
626 if (isEqualRowOrCol(absPartIdxRT
, absZorderCUIdx
, s_numPartInCUSize
))
627 return m_encData
->getPicCTU(m_cuAddr
);
630 arPartUnitIdx
-= m_absIdxInCTU
;
636 arPartUnitIdx
= g_rasterToZscan
[absPartIdxRT
+ NUM_CU_PARTITIONS
- s_numPartInCUSize
+ 1];
640 if (!isZeroRow(absPartIdxRT
, s_numPartInCUSize
))
643 arPartUnitIdx
= g_rasterToZscan
[NUM_CU_PARTITIONS
- s_numPartInCUSize
];
644 return m_cuAboveRight
;
647 const CUData
* CUData::getPUBelowLeft(uint32_t& blPartUnitIdx
, uint32_t curPartUnitIdx
) const
649 if ((m_encData
->getPicCTU(m_cuAddr
)->m_cuPelY
+ g_zscanToPelY
[curPartUnitIdx
] + UNIT_SIZE
) >= m_slice
->m_sps
->picHeightInLumaSamples
)
652 uint32_t absPartIdxLB
= g_zscanToRaster
[curPartUnitIdx
];
654 if (lessThanRow(absPartIdxLB
, s_numPartInCUSize
- 1, s_numPartInCUSize
))
656 if (!isZeroCol(absPartIdxLB
, s_numPartInCUSize
))
658 if (curPartUnitIdx
> g_rasterToZscan
[absPartIdxLB
+ s_numPartInCUSize
- 1])
660 uint32_t absZorderCUIdxLB
= g_zscanToRaster
[m_absIdxInCTU
] + ((1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1) * s_numPartInCUSize
;
661 blPartUnitIdx
= g_rasterToZscan
[absPartIdxLB
+ s_numPartInCUSize
- 1];
662 if (isEqualRowOrCol(absPartIdxLB
, absZorderCUIdxLB
, s_numPartInCUSize
))
663 return m_encData
->getPicCTU(m_cuAddr
);
666 blPartUnitIdx
-= m_absIdxInCTU
;
672 blPartUnitIdx
= g_rasterToZscan
[absPartIdxLB
+ s_numPartInCUSize
* 2 - 1];
679 const CUData
* CUData::getPUBelowLeftAdi(uint32_t& blPartUnitIdx
, uint32_t curPartUnitIdx
, uint32_t partUnitOffset
) const
681 if ((m_encData
->getPicCTU(m_cuAddr
)->m_cuPelY
+ g_zscanToPelY
[curPartUnitIdx
] + (partUnitOffset
<< LOG2_UNIT_SIZE
)) >= m_slice
->m_sps
->picHeightInLumaSamples
)
684 uint32_t absPartIdxLB
= g_zscanToRaster
[curPartUnitIdx
];
686 if (lessThanRow(absPartIdxLB
, s_numPartInCUSize
- partUnitOffset
, s_numPartInCUSize
))
688 if (!isZeroCol(absPartIdxLB
, s_numPartInCUSize
))
690 if (curPartUnitIdx
> g_rasterToZscan
[absPartIdxLB
+ partUnitOffset
* s_numPartInCUSize
- 1])
692 uint32_t absZorderCUIdxLB
= g_zscanToRaster
[m_absIdxInCTU
] + ((1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1) * s_numPartInCUSize
;
693 blPartUnitIdx
= g_rasterToZscan
[absPartIdxLB
+ partUnitOffset
* s_numPartInCUSize
- 1];
694 if (isEqualRowOrCol(absPartIdxLB
, absZorderCUIdxLB
, s_numPartInCUSize
))
695 return m_encData
->getPicCTU(m_cuAddr
);
698 blPartUnitIdx
-= m_absIdxInCTU
;
704 blPartUnitIdx
= g_rasterToZscan
[absPartIdxLB
+ (1 + partUnitOffset
) * s_numPartInCUSize
- 1];
705 if (!m_cuLeft
|| !m_cuLeft
->m_slice
)
713 const CUData
* CUData::getPUAboveRightAdi(uint32_t& arPartUnitIdx
, uint32_t curPartUnitIdx
, uint32_t partUnitOffset
) const
715 if ((m_encData
->getPicCTU(m_cuAddr
)->m_cuPelX
+ g_zscanToPelX
[curPartUnitIdx
] + (partUnitOffset
<< LOG2_UNIT_SIZE
)) >= m_slice
->m_sps
->picWidthInLumaSamples
)
718 uint32_t absPartIdxRT
= g_zscanToRaster
[curPartUnitIdx
];
720 if (lessThanCol(absPartIdxRT
, s_numPartInCUSize
- partUnitOffset
, s_numPartInCUSize
))
722 if (!isZeroRow(absPartIdxRT
, s_numPartInCUSize
))
724 if (curPartUnitIdx
> g_rasterToZscan
[absPartIdxRT
- s_numPartInCUSize
+ partUnitOffset
])
726 uint32_t absZorderCUIdx
= g_zscanToRaster
[m_absIdxInCTU
] + (1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1;
727 arPartUnitIdx
= g_rasterToZscan
[absPartIdxRT
- s_numPartInCUSize
+ partUnitOffset
];
728 if (isEqualRowOrCol(absPartIdxRT
, absZorderCUIdx
, s_numPartInCUSize
))
729 return m_encData
->getPicCTU(m_cuAddr
);
732 arPartUnitIdx
-= m_absIdxInCTU
;
738 arPartUnitIdx
= g_rasterToZscan
[absPartIdxRT
+ NUM_CU_PARTITIONS
- s_numPartInCUSize
+ partUnitOffset
];
739 if (!m_cuAbove
|| !m_cuAbove
->m_slice
)
744 if (!isZeroRow(absPartIdxRT
, s_numPartInCUSize
))
747 arPartUnitIdx
= g_rasterToZscan
[NUM_CU_PARTITIONS
- s_numPartInCUSize
+ partUnitOffset
- 1];
748 if ((m_cuAboveRight
== NULL
|| m_cuAboveRight
->m_slice
== NULL
|| (m_cuAboveRight
->m_cuAddr
) > m_cuAddr
))
750 return m_cuAboveRight
;
753 /* Get left QpMinCu */
754 const CUData
* CUData::getQpMinCuLeft(uint32_t& lPartUnitIdx
, uint32_t curAbsIdxInCTU
) const
756 uint32_t absZorderQpMinCUIdx
= curAbsIdxInCTU
& (0xFF << (g_maxFullDepth
- m_slice
->m_pps
->maxCuDQPDepth
) * 2);
757 uint32_t absRorderQpMinCUIdx
= g_zscanToRaster
[absZorderQpMinCUIdx
];
759 // check for left CTU boundary
760 if (isZeroCol(absRorderQpMinCUIdx
, s_numPartInCUSize
))
763 // get index of left-CU relative to top-left corner of current quantization group
764 lPartUnitIdx
= g_rasterToZscan
[absRorderQpMinCUIdx
- 1];
766 // return pointer to current CTU
767 return m_encData
->getPicCTU(m_cuAddr
);
770 /* Get above QpMinCu */
771 const CUData
* CUData::getQpMinCuAbove(uint32_t& aPartUnitIdx
, uint32_t curAbsIdxInCTU
) const
773 uint32_t absZorderQpMinCUIdx
= curAbsIdxInCTU
& (0xFF << (g_maxFullDepth
- m_slice
->m_pps
->maxCuDQPDepth
) * 2);
774 uint32_t absRorderQpMinCUIdx
= g_zscanToRaster
[absZorderQpMinCUIdx
];
776 // check for top CTU boundary
777 if (isZeroRow(absRorderQpMinCUIdx
, s_numPartInCUSize
))
780 // get index of top-CU relative to top-left corner of current quantization group
781 aPartUnitIdx
= g_rasterToZscan
[absRorderQpMinCUIdx
- s_numPartInCUSize
];
783 // return pointer to current CTU
784 return m_encData
->getPicCTU(m_cuAddr
);
787 /* Get reference QP from left QpMinCu or latest coded QP */
788 char CUData::getRefQP(uint32_t curAbsIdxInCTU
) const
790 uint32_t lPartIdx
= 0, aPartIdx
= 0;
791 const CUData
* cULeft
= getQpMinCuLeft(lPartIdx
, m_absIdxInCTU
+ curAbsIdxInCTU
);
792 const CUData
* cUAbove
= getQpMinCuAbove(aPartIdx
, m_absIdxInCTU
+ curAbsIdxInCTU
);
794 return ((cULeft
? cULeft
->m_qp
[lPartIdx
] : getLastCodedQP(curAbsIdxInCTU
)) + (cUAbove
? cUAbove
->m_qp
[aPartIdx
] : getLastCodedQP(curAbsIdxInCTU
)) + 1) >> 1;
797 int CUData::getLastValidPartIdx(int absPartIdx
) const
799 int lastValidPartIdx
= absPartIdx
- 1;
801 while (lastValidPartIdx
>= 0 && m_predMode
[lastValidPartIdx
] == MODE_NONE
)
803 uint32_t depth
= m_cuDepth
[lastValidPartIdx
];
804 lastValidPartIdx
-= m_numPartitions
>> (depth
<< 1);
807 return lastValidPartIdx
;
810 char CUData::getLastCodedQP(uint32_t absPartIdx
) const
812 uint32_t quPartIdxMask
= 0xFF << (g_maxFullDepth
- m_slice
->m_pps
->maxCuDQPDepth
) * 2;
813 int lastValidPartIdx
= getLastValidPartIdx(absPartIdx
& quPartIdxMask
);
815 if (lastValidPartIdx
>= 0)
816 return m_qp
[lastValidPartIdx
];
820 return m_encData
->getPicCTU(m_cuAddr
)->getLastCodedQP(m_absIdxInCTU
);
821 else if (m_cuAddr
> 0 && !(m_slice
->m_pps
->bEntropyCodingSyncEnabled
&& !(m_cuAddr
% m_slice
->m_sps
->numCuInWidth
)))
822 return m_encData
->getPicCTU(m_cuAddr
- 1)->getLastCodedQP(NUM_CU_PARTITIONS
);
824 return (char)m_slice
->m_sliceQp
;
828 /* Get allowed chroma intra modes */
829 void CUData::getAllowedChromaDir(uint32_t absPartIdx
, uint32_t* modeList
) const
831 modeList
[0] = PLANAR_IDX
;
832 modeList
[1] = VER_IDX
;
833 modeList
[2] = HOR_IDX
;
834 modeList
[3] = DC_IDX
;
835 modeList
[4] = DM_CHROMA_IDX
;
837 uint32_t lumaMode
= m_lumaIntraDir
[absPartIdx
];
839 for (int i
= 0; i
< NUM_CHROMA_MODE
- 1; i
++)
841 if (lumaMode
== modeList
[i
])
843 modeList
[i
] = 34; // VER+8 mode
849 /* Get most probable intra modes */
850 int CUData::getIntraDirLumaPredictor(uint32_t absPartIdx
, uint32_t* intraDirPred
) const
852 const CUData
* tempCU
;
853 uint32_t tempPartIdx
;
854 uint32_t leftIntraDir
, aboveIntraDir
;
856 // Get intra direction of left PU
857 tempCU
= getPULeft(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
);
859 leftIntraDir
= (tempCU
&& tempCU
->isIntra(tempPartIdx
)) ? tempCU
->m_lumaIntraDir
[tempPartIdx
] : DC_IDX
;
861 // Get intra direction of above PU
862 tempCU
= getPUAbove(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
, true);
864 aboveIntraDir
= (tempCU
&& tempCU
->isIntra(tempPartIdx
)) ? tempCU
->m_lumaIntraDir
[tempPartIdx
] : DC_IDX
;
866 if (leftIntraDir
== aboveIntraDir
)
868 if (leftIntraDir
>= 2) // angular modes
870 intraDirPred
[0] = leftIntraDir
;
871 intraDirPred
[1] = ((leftIntraDir
- 2 + 31) & 31) + 2;
872 intraDirPred
[2] = ((leftIntraDir
- 2 + 1) & 31) + 2;
876 intraDirPred
[0] = PLANAR_IDX
;
877 intraDirPred
[1] = DC_IDX
;
878 intraDirPred
[2] = VER_IDX
;
884 intraDirPred
[0] = leftIntraDir
;
885 intraDirPred
[1] = aboveIntraDir
;
887 if (leftIntraDir
&& aboveIntraDir
) //both modes are non-planar
888 intraDirPred
[2] = PLANAR_IDX
;
890 intraDirPred
[2] = (leftIntraDir
+ aboveIntraDir
) < 2 ? VER_IDX
: DC_IDX
;
895 uint32_t CUData::getCtxSplitFlag(uint32_t absPartIdx
, uint32_t depth
) const
897 const CUData
* tempCU
;
898 uint32_t tempPartIdx
;
901 // Get left split flag
902 tempCU
= getPULeft(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
);
903 ctx
= (tempCU
) ? ((tempCU
->m_cuDepth
[tempPartIdx
] > depth
) ? 1 : 0) : 0;
905 // Get above split flag
906 tempCU
= getPUAbove(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
);
907 ctx
+= (tempCU
) ? ((tempCU
->m_cuDepth
[tempPartIdx
] > depth
) ? 1 : 0) : 0;
912 void CUData::getIntraTUQtDepthRange(uint32_t tuDepthRange
[2], uint32_t absPartIdx
) const
914 uint32_t log2CUSize
= m_log2CUSize
[absPartIdx
];
915 uint32_t splitFlag
= m_partSize
[absPartIdx
] == SIZE_NxN
;
917 tuDepthRange
[0] = m_slice
->m_sps
->quadtreeTULog2MinSize
;
918 tuDepthRange
[1] = m_slice
->m_sps
->quadtreeTULog2MaxSize
;
920 tuDepthRange
[0] = X265_MAX(tuDepthRange
[0], X265_MIN(log2CUSize
- (m_slice
->m_sps
->quadtreeTUMaxDepthIntra
- 1 + splitFlag
), tuDepthRange
[1]));
923 void CUData::getInterTUQtDepthRange(uint32_t tuDepthRange
[2], uint32_t absPartIdx
) const
925 uint32_t log2CUSize
= m_log2CUSize
[absPartIdx
];
926 uint32_t quadtreeTUMaxDepth
= m_slice
->m_sps
->quadtreeTUMaxDepthInter
;
927 uint32_t splitFlag
= quadtreeTUMaxDepth
== 1 && m_partSize
[absPartIdx
] != SIZE_2Nx2N
;
929 tuDepthRange
[0] = m_slice
->m_sps
->quadtreeTULog2MinSize
;
930 tuDepthRange
[1] = m_slice
->m_sps
->quadtreeTULog2MaxSize
;
932 tuDepthRange
[0] = X265_MAX(tuDepthRange
[0], X265_MIN(log2CUSize
- (quadtreeTUMaxDepth
- 1 + splitFlag
), tuDepthRange
[1]));
935 uint32_t CUData::getCtxSkipFlag(uint32_t absPartIdx
) const
937 const CUData
* tempCU
;
938 uint32_t tempPartIdx
;
941 // Get BCBP of left PU
942 tempCU
= getPULeft(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
);
943 ctx
= tempCU
? tempCU
->isSkipped(tempPartIdx
) : 0;
945 // Get BCBP of above PU
946 tempCU
= getPUAbove(tempPartIdx
, m_absIdxInCTU
+ absPartIdx
);
947 ctx
+= tempCU
? tempCU
->isSkipped(tempPartIdx
) : 0;
952 bool CUData::setQPSubCUs(char qp
, uint32_t absPartIdx
, uint32_t depth
)
954 uint32_t curPartNumb
= NUM_CU_PARTITIONS
>> (depth
<< 1);
955 uint32_t curPartNumQ
= curPartNumb
>> 2;
957 if (m_cuDepth
[absPartIdx
] > depth
)
959 for (uint32_t subPartIdx
= 0; subPartIdx
< 4; subPartIdx
++)
960 if (setQPSubCUs(qp
, absPartIdx
+ subPartIdx
* curPartNumQ
, depth
+ 1))
965 if (getQtRootCbf(absPartIdx
))
968 setQPSubParts(qp
, absPartIdx
, depth
);
974 void CUData::setPUInterDir(uint8_t dir
, uint32_t absPartIdx
, uint32_t puIdx
)
976 uint32_t curPartNumQ
= m_numPartitions
>> 2;
977 X265_CHECK(puIdx
< 2, "unexpected part unit index\n");
979 switch (m_partSize
[absPartIdx
])
982 memset(m_interDir
+ absPartIdx
, dir
, 4 * curPartNumQ
);
985 memset(m_interDir
+ absPartIdx
, dir
, 2 * curPartNumQ
);
988 memset(m_interDir
+ absPartIdx
, dir
, curPartNumQ
);
989 memset(m_interDir
+ absPartIdx
+ 2 * curPartNumQ
, dir
, curPartNumQ
);
992 memset(m_interDir
+ absPartIdx
, dir
, curPartNumQ
);
997 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 1));
998 memset(m_interDir
+ absPartIdx
+ curPartNumQ
, dir
, (curPartNumQ
>> 1));
1002 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 1));
1003 memset(m_interDir
+ absPartIdx
+ curPartNumQ
, dir
, ((curPartNumQ
>> 1) + (curPartNumQ
<< 1)));
1009 memset(m_interDir
+ absPartIdx
, dir
, ((curPartNumQ
<< 1) + (curPartNumQ
>> 1)));
1010 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1) + curPartNumQ
, dir
, (curPartNumQ
>> 1));
1014 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 1));
1015 memset(m_interDir
+ absPartIdx
+ curPartNumQ
, dir
, (curPartNumQ
>> 1));
1021 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 2));
1022 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1023 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1), dir
, (curPartNumQ
>> 2));
1024 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1028 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 2));
1029 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
>> 1), dir
, (curPartNumQ
+ (curPartNumQ
>> 2)));
1030 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1), dir
, (curPartNumQ
>> 2));
1031 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1), dir
, (curPartNumQ
+ (curPartNumQ
>> 2)));
1037 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
+ (curPartNumQ
>> 2)));
1038 memset(m_interDir
+ absPartIdx
+ curPartNumQ
+ (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1039 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1), dir
, (curPartNumQ
+ (curPartNumQ
>> 2)));
1040 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1) + curPartNumQ
+ (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1044 memset(m_interDir
+ absPartIdx
, dir
, (curPartNumQ
>> 2));
1045 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1046 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1), dir
, (curPartNumQ
>> 2));
1047 memset(m_interDir
+ absPartIdx
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1), dir
, (curPartNumQ
>> 2));
1051 X265_CHECK(0, "unexpected part type\n");
1056 template<typename T
>
1057 void CUData::setAllPU(T
* p
, const T
& val
, int absPartIdx
, int puIdx
)
1062 int numElements
= m_numPartitions
;
1064 switch (m_partSize
[absPartIdx
])
1067 for (i
= 0; i
< numElements
; i
++)
1073 for (i
= 0; i
< numElements
; i
++)
1079 for (i
= 0; i
< numElements
; i
++)
1082 p
[i
+ 2 * numElements
] = val
;
1088 int curPartNumQ
= numElements
>> 2;
1092 T
*pT2
= p
+ curPartNumQ
;
1093 for (i
= 0; i
< (curPartNumQ
>> 1); i
++)
1102 for (i
= 0; i
< (curPartNumQ
>> 1); i
++)
1105 pT
= p
+ curPartNumQ
;
1106 for (i
= 0; i
< ((curPartNumQ
>> 1) + (curPartNumQ
<< 1)); i
++)
1114 int curPartNumQ
= numElements
>> 2;
1118 for (i
= 0; i
< ((curPartNumQ
>> 1) + (curPartNumQ
<< 1)); i
++)
1121 pT
= p
+ (numElements
- curPartNumQ
);
1122 for (i
= 0; i
< (curPartNumQ
>> 1); i
++)
1128 T
*pT2
= p
+ curPartNumQ
;
1129 for (i
= 0; i
< (curPartNumQ
>> 1); i
++)
1140 int curPartNumQ
= numElements
>> 2;
1144 T
*pT2
= p
+ (curPartNumQ
<< 1);
1145 T
*pT3
= p
+ (curPartNumQ
>> 1);
1146 T
*pT4
= p
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1);
1148 for (i
= 0; i
< (curPartNumQ
>> 2); i
++)
1159 T
*pT2
= p
+ (curPartNumQ
<< 1);
1160 for (i
= 0; i
< (curPartNumQ
>> 2); i
++)
1166 pT
= p
+ (curPartNumQ
>> 1);
1167 pT2
= p
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1);
1168 for (i
= 0; i
< ((curPartNumQ
>> 2) + curPartNumQ
); i
++)
1179 int curPartNumQ
= numElements
>> 2;
1183 T
*pT2
= p
+ (curPartNumQ
<< 1);
1184 for (i
= 0; i
< ((curPartNumQ
>> 2) + curPartNumQ
); i
++)
1190 pT
= p
+ curPartNumQ
+ (curPartNumQ
>> 1);
1191 pT2
= p
+ numElements
- curPartNumQ
+ (curPartNumQ
>> 1);
1192 for (i
= 0; i
< (curPartNumQ
>> 2); i
++)
1201 T
*pT2
= p
+ (curPartNumQ
>> 1);
1202 T
*pT3
= p
+ (curPartNumQ
<< 1);
1203 T
*pT4
= p
+ (curPartNumQ
<< 1) + (curPartNumQ
>> 1);
1204 for (i
= 0; i
< (curPartNumQ
>> 2); i
++)
1217 X265_CHECK(0, "unknown partition type\n");
1222 void CUData::setPUMv(int list
, const MV
& mv
, int absPartIdx
, int puIdx
)
1224 setAllPU(m_mv
[list
], mv
, absPartIdx
, puIdx
);
1227 void CUData::setPURefIdx(int list
, char refIdx
, int absPartIdx
, int puIdx
)
1229 setAllPU(m_refIdx
[list
], refIdx
, absPartIdx
, puIdx
);
1232 void CUData::getPartIndexAndSize(uint32_t partIdx
, uint32_t& outPartAddr
, int& outWidth
, int& outHeight
) const
1234 int cuSize
= 1 << m_log2CUSize
[0];
1235 int partType
= m_partSize
[0];
1237 int tmp
= partTable
[partType
][partIdx
][0];
1238 outWidth
= ((tmp
>> 4) * cuSize
) >> 2;
1239 outHeight
= ((tmp
& 0xF) * cuSize
) >> 2;
1240 outPartAddr
= (partAddrTable
[partType
][partIdx
] * m_numPartitions
) >> 4;
1243 void CUData::getMvField(const CUData
* cu
, uint32_t absPartIdx
, int picList
, MVField
& outMvField
) const
1247 outMvField
.mv
= cu
->m_mv
[picList
][absPartIdx
];
1248 outMvField
.refIdx
= cu
->m_refIdx
[picList
][absPartIdx
];
1253 outMvField
.mv
.word
= 0;
1254 outMvField
.refIdx
= REF_NOT_VALID
;
1258 void CUData::deriveLeftRightTopIdx(uint32_t partIdx
, uint32_t& partIdxLT
, uint32_t& partIdxRT
) const
1260 partIdxLT
= m_absIdxInCTU
;
1261 partIdxRT
= g_rasterToZscan
[g_zscanToRaster
[partIdxLT
] + (1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1];
1263 switch (m_partSize
[0])
1265 case SIZE_2Nx2N
: break;
1267 partIdxLT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 1;
1268 partIdxRT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 1;
1271 partIdxLT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 2;
1272 partIdxRT
-= (partIdx
== 1) ? 0 : m_numPartitions
>> 2;
1275 partIdxLT
+= (m_numPartitions
>> 2) * partIdx
;
1276 partIdxRT
+= (m_numPartitions
>> 2) * (partIdx
- 1);
1279 partIdxLT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 3;
1280 partIdxRT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 3;
1283 partIdxLT
+= (partIdx
== 0) ? 0 : (m_numPartitions
>> 1) + (m_numPartitions
>> 3);
1284 partIdxRT
+= (partIdx
== 0) ? 0 : (m_numPartitions
>> 1) + (m_numPartitions
>> 3);
1287 partIdxLT
+= (partIdx
== 0) ? 0 : m_numPartitions
>> 4;
1288 partIdxRT
-= (partIdx
== 1) ? 0 : (m_numPartitions
>> 2) + (m_numPartitions
>> 4);
1291 partIdxLT
+= (partIdx
== 0) ? 0 : (m_numPartitions
>> 2) + (m_numPartitions
>> 4);
1292 partIdxRT
-= (partIdx
== 1) ? 0 : m_numPartitions
>> 4;
1295 X265_CHECK(0, "unexpected part index\n");
1300 uint32_t CUData::deriveLeftBottomIdx(uint32_t puIdx
) const
1302 uint32_t outPartIdxLB
;
1303 outPartIdxLB
= g_rasterToZscan
[g_zscanToRaster
[m_absIdxInCTU
] + ((1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
- 1)) - 1) * s_numPartInCUSize
];
1305 switch (m_partSize
[0])
1308 outPartIdxLB
+= m_numPartitions
>> 1;
1311 outPartIdxLB
+= puIdx
? m_numPartitions
>> 1 : 0;
1314 outPartIdxLB
+= puIdx
? (m_numPartitions
>> 2) * 3 : m_numPartitions
>> 1;
1317 outPartIdxLB
+= (m_numPartitions
>> 2) * puIdx
;
1320 outPartIdxLB
+= puIdx
? m_numPartitions
>> 1 : -((int)m_numPartitions
>> 3);
1323 outPartIdxLB
+= puIdx
? m_numPartitions
>> 1 : (m_numPartitions
>> 2) + (m_numPartitions
>> 3);
1326 outPartIdxLB
+= puIdx
? (m_numPartitions
>> 1) + (m_numPartitions
>> 4) : m_numPartitions
>> 1;
1329 outPartIdxLB
+= puIdx
? (m_numPartitions
>> 1) + (m_numPartitions
>> 2) + (m_numPartitions
>> 4) : m_numPartitions
>> 1;
1332 X265_CHECK(0, "unexpected part index\n");
1335 return outPartIdxLB
;
1338 /* Derives the partition index of neighboring bottom right block */
1339 uint32_t CUData::deriveRightBottomIdx(uint32_t puIdx
) const
1341 uint32_t outPartIdxRB
;
1342 outPartIdxRB
= g_rasterToZscan
[g_zscanToRaster
[m_absIdxInCTU
] +
1343 ((1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
- 1)) - 1) * s_numPartInCUSize
+
1344 (1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
)) - 1];
1346 switch (m_partSize
[0])
1349 outPartIdxRB
+= m_numPartitions
>> 1;
1352 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : 0;
1355 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : m_numPartitions
>> 2;
1358 outPartIdxRB
+= (m_numPartitions
>> 2) * (puIdx
- 1);
1361 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : -((int)m_numPartitions
>> 3);
1364 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : (m_numPartitions
>> 2) + (m_numPartitions
>> 3);
1367 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : (m_numPartitions
>> 3) + (m_numPartitions
>> 4);
1370 outPartIdxRB
+= puIdx
? m_numPartitions
>> 1 : (m_numPartitions
>> 2) + (m_numPartitions
>> 3) + (m_numPartitions
>> 4);
1373 X265_CHECK(0, "unexpected part index\n");
1376 return outPartIdxRB
;
1379 void CUData::deriveLeftRightTopIdxAdi(uint32_t& outPartIdxLT
, uint32_t& outPartIdxRT
, uint32_t partOffset
, uint32_t partDepth
) const
1381 uint32_t numPartInWidth
= 1 << (m_log2CUSize
[0] - LOG2_UNIT_SIZE
- partDepth
);
1383 outPartIdxLT
= m_absIdxInCTU
+ partOffset
;
1384 outPartIdxRT
= g_rasterToZscan
[g_zscanToRaster
[outPartIdxLT
] + numPartInWidth
- 1];
1387 bool CUData::hasEqualMotion(uint32_t absPartIdx
, const CUData
& candCU
, uint32_t candAbsPartIdx
) const
1389 if (m_interDir
[absPartIdx
] != candCU
.m_interDir
[candAbsPartIdx
])
1392 for (uint32_t refListIdx
= 0; refListIdx
< 2; refListIdx
++)
1394 if (m_interDir
[absPartIdx
] & (1 << refListIdx
))
1396 if (m_mv
[refListIdx
][absPartIdx
] != candCU
.m_mv
[refListIdx
][candAbsPartIdx
] ||
1397 m_refIdx
[refListIdx
][absPartIdx
] != candCU
.m_refIdx
[refListIdx
][candAbsPartIdx
])
1405 /* Construct list of merging candidates */
1406 uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx
, uint32_t puIdx
, MVField(*mvFieldNeighbours
)[2], uint8_t* interDirNeighbours
) const
1408 uint32_t absPartAddr
= m_absIdxInCTU
+ absPartIdx
;
1409 const bool isInterB
= m_slice
->isInterB();
1411 const uint32_t maxNumMergeCand
= m_slice
->m_maxNumMergeCand
;
1413 for (uint32_t i
= 0; i
< maxNumMergeCand
; ++i
)
1415 mvFieldNeighbours
[i
][0].refIdx
= REF_NOT_VALID
;
1416 mvFieldNeighbours
[i
][1].refIdx
= REF_NOT_VALID
;
1419 /* calculate the location of upper-left corner pixel and size of the current PU */
1420 int xP
, yP
, nPSW
, nPSH
;
1422 int cuSize
= 1 << m_log2CUSize
[0];
1423 int partMode
= m_partSize
[0];
1425 int tmp
= partTable
[partMode
][puIdx
][0];
1426 nPSW
= ((tmp
>> 4) * cuSize
) >> 2;
1427 nPSH
= ((tmp
& 0xF) * cuSize
) >> 2;
1429 tmp
= partTable
[partMode
][puIdx
][1];
1430 xP
= ((tmp
>> 4) * cuSize
) >> 2;
1431 yP
= ((tmp
& 0xF) * cuSize
) >> 2;
1435 uint32_t partIdxLT
, partIdxRT
, partIdxLB
= deriveLeftBottomIdx(puIdx
);
1436 PartSize curPS
= (PartSize
)m_partSize
[absPartIdx
];
1439 uint32_t leftPartIdx
= 0;
1440 const CUData
* cuLeft
= getPULeft(leftPartIdx
, partIdxLB
);
1441 bool isAvailableA1
= cuLeft
&&
1442 cuLeft
->isDiffMER(xP
- 1, yP
+ nPSH
- 1, xP
, yP
) &&
1443 !(puIdx
== 1 && (curPS
== SIZE_Nx2N
|| curPS
== SIZE_nLx2N
|| curPS
== SIZE_nRx2N
)) &&
1444 !cuLeft
->isIntra(leftPartIdx
);
1448 interDirNeighbours
[count
] = cuLeft
->m_interDir
[leftPartIdx
];
1450 cuLeft
->getMvField(cuLeft
, leftPartIdx
, 0, mvFieldNeighbours
[count
][0]);
1452 cuLeft
->getMvField(cuLeft
, leftPartIdx
, 1, mvFieldNeighbours
[count
][1]);
1456 if (count
== maxNumMergeCand
)
1457 return maxNumMergeCand
;
1460 deriveLeftRightTopIdx(puIdx
, partIdxLT
, partIdxRT
);
1463 uint32_t abovePartIdx
= 0;
1464 const CUData
* cuAbove
= getPUAbove(abovePartIdx
, partIdxRT
);
1465 bool isAvailableB1
= cuAbove
&&
1466 cuAbove
->isDiffMER(xP
+ nPSW
- 1, yP
- 1, xP
, yP
) &&
1467 !(puIdx
== 1 && (curPS
== SIZE_2NxN
|| curPS
== SIZE_2NxnU
|| curPS
== SIZE_2NxnD
)) &&
1468 !cuAbove
->isIntra(abovePartIdx
);
1469 if (isAvailableB1
&& (!isAvailableA1
|| !cuLeft
->hasEqualMotion(leftPartIdx
, *cuAbove
, abovePartIdx
)))
1472 interDirNeighbours
[count
] = cuAbove
->m_interDir
[abovePartIdx
];
1474 cuAbove
->getMvField(cuAbove
, abovePartIdx
, 0, mvFieldNeighbours
[count
][0]);
1476 cuAbove
->getMvField(cuAbove
, abovePartIdx
, 1, mvFieldNeighbours
[count
][1]);
1480 if (count
== maxNumMergeCand
)
1481 return maxNumMergeCand
;
1485 uint32_t aboveRightPartIdx
= 0;
1486 const CUData
* cuAboveRight
= getPUAboveRight(aboveRightPartIdx
, partIdxRT
);
1487 bool isAvailableB0
= cuAboveRight
&&
1488 cuAboveRight
->isDiffMER(xP
+ nPSW
, yP
- 1, xP
, yP
) &&
1489 !cuAboveRight
->isIntra(aboveRightPartIdx
);
1490 if (isAvailableB0
&& (!isAvailableB1
|| !cuAbove
->hasEqualMotion(abovePartIdx
, *cuAboveRight
, aboveRightPartIdx
)))
1493 interDirNeighbours
[count
] = cuAboveRight
->m_interDir
[aboveRightPartIdx
];
1495 cuAboveRight
->getMvField(cuAboveRight
, aboveRightPartIdx
, 0, mvFieldNeighbours
[count
][0]);
1497 cuAboveRight
->getMvField(cuAboveRight
, aboveRightPartIdx
, 1, mvFieldNeighbours
[count
][1]);
1501 if (count
== maxNumMergeCand
)
1502 return maxNumMergeCand
;
1506 uint32_t leftBottomPartIdx
= 0;
1507 const CUData
* cuLeftBottom
= this->getPUBelowLeft(leftBottomPartIdx
, partIdxLB
);
1508 bool isAvailableA0
= cuLeftBottom
&&
1509 cuLeftBottom
->isDiffMER(xP
- 1, yP
+ nPSH
, xP
, yP
) &&
1510 !cuLeftBottom
->isIntra(leftBottomPartIdx
);
1511 if (isAvailableA0
&& (!isAvailableA1
|| !cuLeft
->hasEqualMotion(leftPartIdx
, *cuLeftBottom
, leftBottomPartIdx
)))
1514 interDirNeighbours
[count
] = cuLeftBottom
->m_interDir
[leftBottomPartIdx
];
1516 cuLeftBottom
->getMvField(cuLeftBottom
, leftBottomPartIdx
, 0, mvFieldNeighbours
[count
][0]);
1518 cuLeftBottom
->getMvField(cuLeftBottom
, leftBottomPartIdx
, 1, mvFieldNeighbours
[count
][1]);
1522 if (count
== maxNumMergeCand
)
1523 return maxNumMergeCand
;
1529 uint32_t aboveLeftPartIdx
= 0;
1530 const CUData
* cuAboveLeft
= getPUAboveLeft(aboveLeftPartIdx
, absPartAddr
);
1531 bool isAvailableB2
= cuAboveLeft
&&
1532 cuAboveLeft
->isDiffMER(xP
- 1, yP
- 1, xP
, yP
) &&
1533 !cuAboveLeft
->isIntra(aboveLeftPartIdx
);
1534 if (isAvailableB2
&& (!isAvailableA1
|| !cuLeft
->hasEqualMotion(leftPartIdx
, *cuAboveLeft
, aboveLeftPartIdx
))
1535 && (!isAvailableB1
|| !cuAbove
->hasEqualMotion(abovePartIdx
, *cuAboveLeft
, aboveLeftPartIdx
)))
1538 interDirNeighbours
[count
] = cuAboveLeft
->m_interDir
[aboveLeftPartIdx
];
1540 cuAboveLeft
->getMvField(cuAboveLeft
, aboveLeftPartIdx
, 0, mvFieldNeighbours
[count
][0]);
1542 cuAboveLeft
->getMvField(cuAboveLeft
, aboveLeftPartIdx
, 1, mvFieldNeighbours
[count
][1]);
1546 if (count
== maxNumMergeCand
)
1547 return maxNumMergeCand
;
1550 if (m_slice
->m_sps
->bTemporalMVPEnabled
)
1552 uint32_t partIdxRB
= deriveRightBottomIdx(puIdx
);
1556 // image boundary check
1557 if (m_encData
->getPicCTU(m_cuAddr
)->m_cuPelX
+ g_zscanToPelX
[partIdxRB
] + UNIT_SIZE
< m_slice
->m_sps
->picWidthInLumaSamples
&&
1558 m_encData
->getPicCTU(m_cuAddr
)->m_cuPelY
+ g_zscanToPelY
[partIdxRB
] + UNIT_SIZE
< m_slice
->m_sps
->picHeightInLumaSamples
)
1560 uint32_t absPartIdxRB
= g_zscanToRaster
[partIdxRB
];
1561 uint32_t numPartInCUSize
= s_numPartInCUSize
;
1562 bool bNotLastCol
= lessThanCol(absPartIdxRB
, numPartInCUSize
- 1, numPartInCUSize
); // is not at the last column of CTU
1563 bool bNotLastRow
= lessThanRow(absPartIdxRB
, numPartInCUSize
- 1, numPartInCUSize
); // is not at the last row of CTU
1565 if (bNotLastCol
&& bNotLastRow
)
1567 absPartAddr
= g_rasterToZscan
[absPartIdxRB
+ numPartInCUSize
+ 1];
1570 else if (bNotLastCol
)
1571 absPartAddr
= g_rasterToZscan
[(absPartIdxRB
+ numPartInCUSize
+ 1) & (numPartInCUSize
- 1)];
1572 else if (bNotLastRow
)
1574 absPartAddr
= g_rasterToZscan
[absPartIdxRB
+ 1];
1575 ctuIdx
= m_cuAddr
+ 1;
1577 else // is the right bottom corner of CTU
1582 uint32_t partIdxCenter
= deriveCenterIdx(puIdx
);
1583 uint32_t curCTUIdx
= m_cuAddr
;
1585 bool bExistMV
= ctuIdx
>= 0 && getColMVP(colmv
, refIdx
, 0, ctuIdx
, absPartAddr
);
1587 bExistMV
= getColMVP(colmv
, refIdx
, 0, curCTUIdx
, partIdxCenter
);
1591 mvFieldNeighbours
[count
][0].mv
= colmv
;
1592 mvFieldNeighbours
[count
][0].refIdx
= refIdx
;
1597 bExistMV
= ctuIdx
>= 0 && getColMVP(colmv
, refIdx
, 1, ctuIdx
, absPartAddr
);
1599 bExistMV
= getColMVP(colmv
, refIdx
, 1, curCTUIdx
, partIdxCenter
);
1604 mvFieldNeighbours
[count
][1].mv
= colmv
;
1605 mvFieldNeighbours
[count
][1].refIdx
= refIdx
;
1611 interDirNeighbours
[count
] = (uint8_t)dir
;
1615 if (count
== maxNumMergeCand
)
1616 return maxNumMergeCand
;
1622 const uint32_t cutoff
= count
* (count
- 1);
1623 uint32_t priorityList0
= 0xEDC984; // { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }
1624 uint32_t priorityList1
= 0xB73621; // { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }
1626 for (uint32_t idx
= 0; idx
< cutoff
; idx
++)
1628 int i
= priorityList0
& 3;
1629 int j
= priorityList1
& 3;
1630 priorityList0
>>= 2;
1631 priorityList1
>>= 2;
1633 if ((interDirNeighbours
[i
] & 0x1) && (interDirNeighbours
[j
] & 0x2))
1635 // get Mv from cand[i] and cand[j]
1636 int refIdxL0
= mvFieldNeighbours
[i
][0].refIdx
;
1637 int refIdxL1
= mvFieldNeighbours
[j
][1].refIdx
;
1638 int refPOCL0
= m_slice
->m_refPOCList
[0][refIdxL0
];
1639 int refPOCL1
= m_slice
->m_refPOCList
[1][refIdxL1
];
1640 if (!(refPOCL0
== refPOCL1
&& mvFieldNeighbours
[i
][0].mv
== mvFieldNeighbours
[j
][1].mv
))
1642 mvFieldNeighbours
[count
][0].mv
= mvFieldNeighbours
[i
][0].mv
;
1643 mvFieldNeighbours
[count
][0].refIdx
= refIdxL0
;
1644 mvFieldNeighbours
[count
][1].mv
= mvFieldNeighbours
[j
][1].mv
;
1645 mvFieldNeighbours
[count
][1].refIdx
= refIdxL1
;
1646 interDirNeighbours
[count
] = 3;
1650 if (count
== maxNumMergeCand
)
1651 return maxNumMergeCand
;
1656 int numRefIdx
= (isInterB
) ? X265_MIN(m_slice
->m_numRefIdx
[0], m_slice
->m_numRefIdx
[1]) : m_slice
->m_numRefIdx
[0];
1659 while (count
< maxNumMergeCand
)
1661 interDirNeighbours
[count
] = 1;
1662 mvFieldNeighbours
[count
][0].mv
.word
= 0;
1663 mvFieldNeighbours
[count
][0].refIdx
= r
;
1667 interDirNeighbours
[count
] = 3;
1668 mvFieldNeighbours
[count
][1].mv
.word
= 0;
1669 mvFieldNeighbours
[count
][1].refIdx
= r
;
1674 if (refcnt
== numRefIdx
- 1)
1686 /* Check whether the current PU and a spatial neighboring PU are in a same ME region */
1687 bool CUData::isDiffMER(int xN
, int yN
, int xP
, int yP
) const
1689 uint32_t plevel
= 2;
1691 if ((xN
>> plevel
) != (xP
>> plevel
))
1693 if ((yN
>> plevel
) != (yP
>> plevel
))
1698 /* Constructs a list of candidates for AMVP, and a larger list of motion candidates */
1699 int CUData::fillMvpCand(uint32_t puIdx
, uint32_t absPartIdx
, int picList
, int refIdx
, MV
* amvpCand
, MV
* mvc
) const
1704 uint32_t partIdxLT
, partIdxRT
, partIdxLB
= deriveLeftBottomIdx(puIdx
);
1706 deriveLeftRightTopIdx(puIdx
, partIdxLT
, partIdxRT
);
1708 MV mv
[MD_ABOVE_LEFT
+ 1];
1709 MV mvOrder
[MD_ABOVE_LEFT
+ 1];
1710 bool valid
[MD_ABOVE_LEFT
+ 1];
1711 bool validOrder
[MD_ABOVE_LEFT
+ 1];
1713 valid
[MD_BELOW_LEFT
] = addMVPCand(mv
[MD_BELOW_LEFT
], picList
, refIdx
, partIdxLB
, MD_BELOW_LEFT
);
1714 valid
[MD_LEFT
] = addMVPCand(mv
[MD_LEFT
], picList
, refIdx
, partIdxLB
, MD_LEFT
);
1715 valid
[MD_ABOVE_RIGHT
] = addMVPCand(mv
[MD_ABOVE_RIGHT
], picList
, refIdx
, partIdxRT
, MD_ABOVE_RIGHT
);
1716 valid
[MD_ABOVE
] = addMVPCand(mv
[MD_ABOVE
], picList
, refIdx
, partIdxRT
, MD_ABOVE
);
1717 valid
[MD_ABOVE_LEFT
] = addMVPCand(mv
[MD_ABOVE_LEFT
], picList
, refIdx
, partIdxLT
, MD_ABOVE_LEFT
);
1719 validOrder
[MD_BELOW_LEFT
] = addMVPCandOrder(mvOrder
[MD_BELOW_LEFT
], picList
, refIdx
, partIdxLB
, MD_BELOW_LEFT
);
1720 validOrder
[MD_LEFT
] = addMVPCandOrder(mvOrder
[MD_LEFT
], picList
, refIdx
, partIdxLB
, MD_LEFT
);
1721 validOrder
[MD_ABOVE_RIGHT
] = addMVPCandOrder(mvOrder
[MD_ABOVE_RIGHT
], picList
, refIdx
, partIdxRT
, MD_ABOVE_RIGHT
);
1722 validOrder
[MD_ABOVE
] = addMVPCandOrder(mvOrder
[MD_ABOVE
], picList
, refIdx
, partIdxRT
, MD_ABOVE
);
1723 validOrder
[MD_ABOVE_LEFT
] = addMVPCandOrder(mvOrder
[MD_ABOVE_LEFT
], picList
, refIdx
, partIdxLT
, MD_ABOVE_LEFT
);
1725 // Left predictor search
1726 if (valid
[MD_BELOW_LEFT
])
1727 amvpCand
[num
++] = mv
[MD_BELOW_LEFT
];
1728 else if (valid
[MD_LEFT
])
1729 amvpCand
[num
++] = mv
[MD_LEFT
];
1730 else if (validOrder
[MD_BELOW_LEFT
])
1731 amvpCand
[num
++] = mvOrder
[MD_BELOW_LEFT
];
1732 else if (validOrder
[MD_LEFT
])
1733 amvpCand
[num
++] = mvOrder
[MD_LEFT
];
1735 bool bAddedSmvp
= num
> 0;
1737 // Above predictor search
1738 if (valid
[MD_ABOVE_RIGHT
])
1739 amvpCand
[num
++] = mv
[MD_ABOVE_RIGHT
];
1740 else if (valid
[MD_ABOVE
])
1741 amvpCand
[num
++] = mv
[MD_ABOVE
];
1742 else if (valid
[MD_ABOVE_LEFT
])
1743 amvpCand
[num
++] = mv
[MD_ABOVE_LEFT
];
1747 if (validOrder
[MD_ABOVE_RIGHT
])
1748 amvpCand
[num
++] = mvOrder
[MD_ABOVE_RIGHT
];
1749 else if (validOrder
[MD_ABOVE
])
1750 amvpCand
[num
++] = mvOrder
[MD_ABOVE
];
1751 else if (validOrder
[MD_ABOVE_LEFT
])
1752 amvpCand
[num
++] = mvOrder
[MD_ABOVE_LEFT
];
1756 for (int dir
= MD_LEFT
; dir
<= MD_ABOVE_LEFT
; dir
++)
1758 if (valid
[dir
] && mv
[dir
].notZero())
1759 mvc
[numMvc
++] = mv
[dir
];
1761 if (validOrder
[dir
] && mvOrder
[dir
].notZero())
1762 mvc
[numMvc
++] = mvOrder
[dir
];
1767 if (amvpCand
[0] == amvpCand
[1])
1770 /* AMVP_NUM_CANDS = 2 */
1774 if (m_slice
->m_sps
->bTemporalMVPEnabled
)
1776 uint32_t absPartAddr
= m_absIdxInCTU
+ absPartIdx
;
1777 uint32_t partIdxRB
= deriveRightBottomIdx(puIdx
);
1780 // co-located RightBottom temporal predictor (H)
1783 // image boundary check
1784 if (m_encData
->getPicCTU(m_cuAddr
)->m_cuPelX
+ g_zscanToPelX
[partIdxRB
] + UNIT_SIZE
< m_slice
->m_sps
->picWidthInLumaSamples
&&
1785 m_encData
->getPicCTU(m_cuAddr
)->m_cuPelY
+ g_zscanToPelY
[partIdxRB
] + UNIT_SIZE
< m_slice
->m_sps
->picHeightInLumaSamples
)
1787 uint32_t absPartIdxRB
= g_zscanToRaster
[partIdxRB
];
1788 uint32_t numPartInCUSize
= s_numPartInCUSize
;
1789 bool bNotLastCol
= lessThanCol(absPartIdxRB
, numPartInCUSize
- 1, numPartInCUSize
); // is not at the last column of CTU
1790 bool bNotLastRow
= lessThanRow(absPartIdxRB
, numPartInCUSize
- 1, numPartInCUSize
); // is not at the last row of CTU
1792 if (bNotLastCol
&& bNotLastRow
)
1794 absPartAddr
= g_rasterToZscan
[absPartIdxRB
+ numPartInCUSize
+ 1];
1797 else if (bNotLastCol
)
1798 absPartAddr
= g_rasterToZscan
[(absPartIdxRB
+ numPartInCUSize
+ 1) & (numPartInCUSize
- 1)];
1799 else if (bNotLastRow
)
1801 absPartAddr
= g_rasterToZscan
[absPartIdxRB
+ 1];
1802 ctuIdx
= m_cuAddr
+ 1;
1804 else // is the right bottom corner of CTU
1807 if (ctuIdx
>= 0 && getColMVP(colmv
, refIdx
, picList
, ctuIdx
, absPartAddr
))
1809 amvpCand
[num
++] = colmv
;
1810 mvc
[numMvc
++] = colmv
;
1814 uint32_t partIdxCenter
= deriveCenterIdx(puIdx
);
1815 uint32_t curCTUIdx
= m_cuAddr
;
1816 if (getColMVP(colmv
, refIdx
, picList
, curCTUIdx
, partIdxCenter
))
1818 amvpCand
[num
++] = colmv
;
1819 mvc
[numMvc
++] = colmv
;
1824 while (num
< AMVP_NUM_CANDS
)
1825 amvpCand
[num
++] = 0;
1830 void CUData::clipMv(MV
& outMV
) const
1834 int xmax
= (m_slice
->m_sps
->picWidthInLumaSamples
+ offset
- m_cuPelX
- 1) << mvshift
;
1835 int xmin
= (-(int)g_maxCUSize
- offset
- (int)m_cuPelX
+ 1) << mvshift
;
1837 int ymax
= (m_slice
->m_sps
->picHeightInLumaSamples
+ offset
- m_cuPelY
- 1) << mvshift
;
1838 int ymin
= (-(int)g_maxCUSize
- offset
- (int)m_cuPelY
+ 1) << mvshift
;
1840 outMV
.x
= (int16_t)X265_MIN(xmax
, X265_MAX(xmin
, (int)outMV
.x
));
1841 outMV
.y
= (int16_t)X265_MIN(ymax
, X265_MAX(ymin
, (int)outMV
.y
));
1844 bool CUData::addMVPCand(MV
& mvp
, int picList
, int refIdx
, uint32_t partUnitIdx
, MVP_DIR dir
) const
1846 const CUData
* tmpCU
= NULL
;
1852 tmpCU
= getPULeft(idx
, partUnitIdx
);
1855 tmpCU
= getPUAbove(idx
, partUnitIdx
);
1857 case MD_ABOVE_RIGHT
:
1858 tmpCU
= getPUAboveRight(idx
, partUnitIdx
);
1861 tmpCU
= getPUBelowLeft(idx
, partUnitIdx
);
1864 tmpCU
= getPUAboveLeft(idx
, partUnitIdx
);
1873 int refPOC
= m_slice
->m_refPOCList
[picList
][refIdx
];
1874 int partRefIdx
= tmpCU
->m_refIdx
[picList
][idx
];
1875 if (partRefIdx
>= 0 && refPOC
== tmpCU
->m_slice
->m_refPOCList
[picList
][partRefIdx
])
1877 mvp
= tmpCU
->m_mv
[picList
][idx
];
1881 int refPicList2nd
= 0;
1884 else if (picList
== 1)
1887 int curRefPOC
= m_slice
->m_refPOCList
[picList
][refIdx
];
1890 partRefIdx
= tmpCU
->m_refIdx
[refPicList2nd
][idx
];
1891 if (partRefIdx
>= 0)
1893 neibRefPOC
= tmpCU
->m_slice
->m_refPOCList
[refPicList2nd
][partRefIdx
];
1894 if (neibRefPOC
== curRefPOC
)
1896 // Same reference frame but different list
1897 mvp
= tmpCU
->m_mv
[refPicList2nd
][idx
];
1904 bool CUData::addMVPCandOrder(MV
& outMV
, int picList
, int refIdx
, uint32_t partUnitIdx
, MVP_DIR dir
) const
1906 const CUData
* tmpCU
= NULL
;
1912 tmpCU
= getPULeft(idx
, partUnitIdx
);
1915 tmpCU
= getPUAbove(idx
, partUnitIdx
);
1917 case MD_ABOVE_RIGHT
:
1918 tmpCU
= getPUAboveRight(idx
, partUnitIdx
);
1921 tmpCU
= getPUBelowLeft(idx
, partUnitIdx
);
1924 tmpCU
= getPUAboveLeft(idx
, partUnitIdx
);
1933 int refPicList2nd
= 0;
1936 else if (picList
== 1)
1939 int curPOC
= m_slice
->m_poc
;
1940 int curRefPOC
= m_slice
->m_refPOCList
[picList
][refIdx
];
1941 int neibPOC
= curPOC
;
1944 int partRefIdx
= tmpCU
->m_refIdx
[picList
][idx
];
1945 if (partRefIdx
>= 0)
1947 neibRefPOC
= tmpCU
->m_slice
->m_refPOCList
[picList
][partRefIdx
];
1948 MV mvp
= tmpCU
->m_mv
[picList
][idx
];
1950 scaleMvByPOCDist(outMV
, mvp
, curPOC
, curRefPOC
, neibPOC
, neibRefPOC
);
1954 partRefIdx
= tmpCU
->m_refIdx
[refPicList2nd
][idx
];
1955 if (partRefIdx
>= 0)
1957 neibRefPOC
= tmpCU
->m_slice
->m_refPOCList
[refPicList2nd
][partRefIdx
];
1958 MV mvp
= tmpCU
->m_mv
[refPicList2nd
][idx
];
1960 scaleMvByPOCDist(outMV
, mvp
, curPOC
, curRefPOC
, neibPOC
, neibRefPOC
);
1967 bool CUData::getColMVP(MV
& outMV
, int& outRefIdx
, int picList
, int cuAddr
, int partUnitIdx
) const
1969 uint32_t absPartAddr
= partUnitIdx
& TMVP_UNIT_MASK
;
1972 int colPOC
, colRefPOC
, curPOC
, curRefPOC
;
1976 Frame
*colPic
= m_slice
->m_refPicList
[m_slice
->isInterB() ? 1 - m_slice
->m_colFromL0Flag
: 0][m_slice
->m_colRefIdx
];
1977 CUData
*colCU
= colPic
->m_encData
->getPicCTU(cuAddr
);
1979 if (colCU
->m_partSize
[partUnitIdx
] == SIZE_NONE
)
1982 curPOC
= m_slice
->m_poc
;
1983 colPOC
= colCU
->m_slice
->m_poc
;
1985 if (colCU
->isIntra(absPartAddr
))
1988 colRefPicList
= m_slice
->m_bCheckLDC
? picList
: m_slice
->m_colFromL0Flag
;
1990 int colRefIdx
= colCU
->m_refIdx
[colRefPicList
][absPartAddr
];
1994 colRefPicList
= 1 - colRefPicList
;
1995 colRefIdx
= colCU
->m_refIdx
[colRefPicList
][absPartAddr
];
2002 colRefPOC
= colCU
->m_slice
->m_refPOCList
[colRefPicList
][colRefIdx
];
2003 colmv
= colCU
->m_mv
[colRefPicList
][absPartAddr
];
2004 curRefPOC
= m_slice
->m_refPOCList
[picList
][outRefIdx
];
2006 scaleMvByPOCDist(outMV
, colmv
, curPOC
, curRefPOC
, colPOC
, colRefPOC
);
2010 void CUData::scaleMvByPOCDist(MV
& outMV
, const MV
& inMV
, int curPOC
, int curRefPOC
, int colPOC
, int colRefPOC
) const
2012 int diffPocD
= colPOC
- colRefPOC
;
2013 int diffPocB
= curPOC
- curRefPOC
;
2015 if (diffPocD
== diffPocB
)
2019 int tdb
= Clip3(-128, 127, diffPocB
);
2020 int tdd
= Clip3(-128, 127, diffPocD
);
2021 int x
= (0x4000 + abs(tdd
/ 2)) / tdd
;
2022 int scale
= Clip3(-4096, 4095, (tdb
* x
+ 32) >> 6);
2023 outMV
= scaleMv(inMV
, scale
);
2027 uint32_t CUData::deriveCenterIdx(uint32_t puIdx
) const
2029 uint32_t absPartIdx
;
2030 int puWidth
, puHeight
;
2032 getPartIndexAndSize(puIdx
, absPartIdx
, puWidth
, puHeight
);
2034 return g_rasterToZscan
[g_zscanToRaster
[m_absIdxInCTU
+ absPartIdx
]
2035 + (puHeight
>> (LOG2_UNIT_SIZE
+ 1)) * s_numPartInCUSize
2036 + (puWidth
>> (LOG2_UNIT_SIZE
+ 1))];
2039 ScanType
CUData::getCoefScanIdx(uint32_t absPartIdx
, uint32_t log2TrSize
, bool bIsLuma
, bool bIsIntra
) const
2046 // check that MDCS can be used for this TU
2049 if (log2TrSize
> MDCS_LOG2_MAX_SIZE
)
2052 dirMode
= m_lumaIntraDir
[absPartIdx
];
2056 if (log2TrSize
> (uint32_t)(MDCS_LOG2_MAX_SIZE
- m_hChromaShift
))
2059 dirMode
= m_chromaIntraDir
[absPartIdx
];
2060 if (dirMode
== DM_CHROMA_IDX
)
2062 dirMode
= m_lumaIntraDir
[(m_chromaFormat
== X265_CSP_I444
) ? absPartIdx
: absPartIdx
& 0xFC];
2063 dirMode
= (m_chromaFormat
== X265_CSP_I422
) ? g_chroma422IntraAngleMappingTable
[dirMode
] : dirMode
;
2067 if (abs((int)dirMode
- VER_IDX
) <= MDCS_ANGLE_LIMIT
)
2069 else if (abs((int)dirMode
- HOR_IDX
) <= MDCS_ANGLE_LIMIT
)
2075 void CUData::getTUEntropyCodingParameters(TUEntropyCodingParameters
&result
, uint32_t absPartIdx
, uint32_t log2TrSize
, bool bIsLuma
) const
2077 // set the group layout
2078 result
.log2TrSizeCG
= log2TrSize
- 2;
2080 // set the scan orders
2081 result
.scanType
= getCoefScanIdx(absPartIdx
, log2TrSize
, bIsLuma
, isIntra(absPartIdx
));
2082 result
.scan
= g_scanOrder
[result
.scanType
][log2TrSize
- 2];
2083 result
.scanCG
= g_scanOrderCG
[result
.scanType
][result
.log2TrSizeCG
];
2085 if (log2TrSize
== 2)
2086 result
.firstSignificanceMapContext
= 0;
2087 else if (log2TrSize
== 3)
2089 result
.firstSignificanceMapContext
= 9;
2090 if (result
.scanType
!= SCAN_DIAG
&& bIsLuma
)
2091 result
.firstSignificanceMapContext
+= 6;
2094 result
.firstSignificanceMapContext
= bIsLuma
? 21 : 12;
2097 #define CU_SET_FLAG(bitfield, flag, value) (bitfield) = ((bitfield) & (~(flag))) | ((~((value) - 1)) & (flag))
2099 void CUData::calcCTUGeoms(uint32_t picWidth
, uint32_t picHeight
, uint32_t maxCUSize
, CUGeom cuDataArray
[CUGeom::MAX_GEOMS
]) const
2101 // Initialize the coding blocks inside the CTB
2102 for (uint32_t log2CUSize
= g_log2Size
[maxCUSize
], rangeCUIdx
= 0; log2CUSize
>= MIN_LOG2_CU_SIZE
; log2CUSize
--)
2104 uint32_t blockSize
= 1 << log2CUSize
;
2105 uint32_t sbWidth
= 1 << (g_log2Size
[maxCUSize
] - log2CUSize
);
2106 int32_t lastLevelFlag
= log2CUSize
== MIN_LOG2_CU_SIZE
;
2107 for (uint32_t sbY
= 0; sbY
< sbWidth
; sbY
++)
2109 for (uint32_t sbX
= 0; sbX
< sbWidth
; sbX
++)
2111 uint32_t depthIdx
= g_depthScanIdx
[sbY
][sbX
];
2112 uint32_t cuIdx
= rangeCUIdx
+ depthIdx
;
2113 uint32_t childIdx
= rangeCUIdx
+ sbWidth
* sbWidth
+ (depthIdx
<< 2);
2114 uint32_t px
= m_cuPelX
+ sbX
* blockSize
;
2115 uint32_t py
= m_cuPelY
+ sbY
* blockSize
;
2116 int32_t presentFlag
= px
< picWidth
&& py
< picHeight
;
2117 int32_t splitMandatoryFlag
= presentFlag
&& !lastLevelFlag
&& (px
+ blockSize
> picWidth
|| py
+ blockSize
> picHeight
);
2119 /* Offset of the luma CU in the X, Y direction in terms of pixels from the CTU origin */
2120 uint32_t xOffset
= (sbX
* blockSize
) >> 3;
2121 uint32_t yOffset
= (sbY
* blockSize
) >> 3;
2122 X265_CHECK(cuIdx
< CUGeom::MAX_GEOMS
, "CU geom index bug\n");
2124 CUGeom
*cu
= cuDataArray
+ cuIdx
;
2125 cu
->log2CUSize
= log2CUSize
;
2126 cu
->childOffset
= childIdx
- cuIdx
;
2127 cu
->encodeIdx
= g_depthScanIdx
[yOffset
][xOffset
] * 4;
2128 cu
->numPartitions
= (NUM_CU_PARTITIONS
>> ((g_maxLog2CUSize
- cu
->log2CUSize
) * 2));
2129 cu
->depth
= g_log2Size
[maxCUSize
] - log2CUSize
;
2132 CU_SET_FLAG(cu
->flags
, CUGeom::PRESENT
, presentFlag
);
2133 CU_SET_FLAG(cu
->flags
, CUGeom::SPLIT_MANDATORY
| CUGeom::SPLIT
, splitMandatoryFlag
);
2134 CU_SET_FLAG(cu
->flags
, CUGeom::LEAF
, lastLevelFlag
);
2137 rangeCUIdx
+= sbWidth
* sbWidth
;