Mercurial > hg > forks > libbpg
comparison jctvc/TLibCommon/TComPattern.cpp @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:772086c29cc7 |
---|---|
1 /* The copyright in this software is being made available under the BSD | |
2 * License, included below. This software may be subject to other third party | |
3 * and contributor rights, including patent rights, and no such rights are | |
4 * granted under this license. | |
5 * | |
6 * Copyright (c) 2010-2014, ITU/ISO/IEC | |
7 * All rights reserved. | |
8 * | |
9 * Redistribution and use in source and binary forms, with or without | |
10 * modification, are permitted provided that the following conditions are met: | |
11 * | |
12 * * Redistributions of source code must retain the above copyright notice, | |
13 * this list of conditions and the following disclaimer. | |
14 * * Redistributions in binary form must reproduce the above copyright notice, | |
15 * this list of conditions and the following disclaimer in the documentation | |
16 * and/or other materials provided with the distribution. | |
17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may | |
18 * be used to endorse or promote products derived from this software without | |
19 * specific prior written permission. | |
20 * | |
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS | |
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
31 * THE POSSIBILITY OF SUCH DAMAGE. | |
32 */ | |
33 | |
34 /** \file TComPattern.cpp | |
35 \brief neighbouring pixel access classes | |
36 */ | |
37 | |
38 #include "TComPic.h" | |
39 #include "TComPattern.h" | |
40 #include "TComDataCU.h" | |
41 #include "TComTU.h" | |
42 #include "Debug.h" | |
43 #include "TComPrediction.h" | |
44 | |
45 //! \ingroup TLibCommon | |
46 //! \{ | |
47 | |
48 // Forward declarations | |
49 | |
50 /// padding of unavailable reference samples for intra prediction | |
51 #if O0043_BEST_EFFORT_DECODING | |
52 Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, | |
53 #else | |
54 Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, | |
55 #endif | |
56 const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits, | |
57 const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride, | |
58 const ChannelType chType, const ChromaFormat chFmt ); | |
59 | |
60 /// constrained intra prediction | |
61 Bool isAboveLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT ); | |
62 Int isAboveAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags ); | |
63 Int isLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags ); | |
64 Int isAboveRightAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags ); | |
65 Int isBelowLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags ); | |
66 | |
67 | |
68 // ==================================================================================================================== | |
69 // Public member functions (TComPatternParam) | |
70 // ==================================================================================================================== | |
71 | |
72 /** \param piTexture pixel data | |
73 \param iRoiWidth pattern width | |
74 \param iRoiHeight pattern height | |
75 \param iStride buffer stride | |
76 \param iOffsetLeft neighbour offset (left) | |
77 \param iOffsetRight neighbour offset (right) | |
78 \param iOffsetAbove neighbour offset (above) | |
79 \param iOffsetBottom neighbour offset (bottom) | |
80 */ | |
81 Void TComPatternParam::setPatternParamPel ( Pel* piTexture, | |
82 Int iRoiWidth, | |
83 Int iRoiHeight, | |
84 Int iStride | |
85 ) | |
86 { | |
87 m_piROIOrigin = piTexture; | |
88 m_iROIWidth = iRoiWidth; | |
89 m_iROIHeight = iRoiHeight; | |
90 m_iPatternStride = iStride; | |
91 } | |
92 | |
93 // ==================================================================================================================== | |
94 // Public member functions (TComPattern) | |
95 // ==================================================================================================================== | |
96 | |
97 Void TComPattern::initPattern (Pel* piY, | |
98 Int iRoiWidth, | |
99 Int iRoiHeight, | |
100 Int iStride) | |
101 { | |
102 m_cPatternY. setPatternParamPel( piY, iRoiWidth, iRoiHeight, iStride); | |
103 } | |
104 | |
105 | |
106 // TODO: move this function to TComPrediction.cpp. | |
107 Void TComPrediction::initAdiPatternChType( TComTU &rTu, Bool& bAbove, Bool& bLeft, const ComponentID compID, const Bool bFilterRefSamples DEBUG_STRING_FN_DECLARE(sDebug)) | |
108 { | |
109 const ChannelType chType = toChannelType(compID); | |
110 | |
111 TComDataCU *pcCU=rTu.getCU(); | |
112 const UInt uiZorderIdxInPart=rTu.GetAbsPartIdxTU(); | |
113 const UInt uiTuWidth = rTu.getRect(compID).width; | |
114 const UInt uiTuHeight = rTu.getRect(compID).height; | |
115 const UInt uiTuWidth2 = uiTuWidth << 1; | |
116 const UInt uiTuHeight2 = uiTuHeight << 1; | |
117 | |
118 const Int iBaseUnitSize = g_uiMaxCUWidth >> g_uiMaxCUDepth; | |
119 const Int iUnitWidth = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleX(compID); | |
120 const Int iUnitHeight = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleY(compID); | |
121 const Int iTUWidthInUnits = uiTuWidth / iUnitWidth; | |
122 const Int iTUHeightInUnits = uiTuHeight / iUnitHeight; | |
123 const Int iAboveUnits = iTUWidthInUnits << 1; | |
124 const Int iLeftUnits = iTUHeightInUnits << 1; | |
125 | |
126 assert(iTUHeightInUnits > 0 && iTUWidthInUnits > 0); | |
127 | |
128 const Int iPartIdxStride = pcCU->getPic()->getNumPartInCtuWidth(); | |
129 const UInt uiPartIdxLT = pcCU->getZorderIdxInCtu() + uiZorderIdxInPart; | |
130 const UInt uiPartIdxRT = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + iTUWidthInUnits - 1 ]; | |
131 const UInt uiPartIdxLB = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + ((iTUHeightInUnits - 1) * iPartIdxStride)]; | |
132 | |
133 Int iPicStride = pcCU->getPic()->getStride(compID); | |
134 Bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; | |
135 Int iNumIntraNeighbor = 0; | |
136 | |
137 bNeighborFlags[iLeftUnits] = isAboveLeftAvailable( pcCU, uiPartIdxLT ); | |
138 iNumIntraNeighbor += bNeighborFlags[iLeftUnits] ? 1 : 0; | |
139 iNumIntraNeighbor += isAboveAvailable ( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1) ); | |
140 iNumIntraNeighbor += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1 + iTUWidthInUnits ) ); | |
141 iNumIntraNeighbor += isLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1) ); | |
142 iNumIntraNeighbor += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1 - iTUHeightInUnits) ); | |
143 | |
144 bAbove = true; | |
145 bLeft = true; | |
146 | |
147 const ChromaFormat chFmt = rTu.GetChromaFormat(); | |
148 const UInt uiROIWidth = uiTuWidth2+1; | |
149 const UInt uiROIHeight = uiTuHeight2+1; | |
150 | |
151 assert(uiROIWidth*uiROIHeight <= m_iYuvExtSize); | |
152 | |
153 #ifdef DEBUG_STRING | |
154 std::stringstream ss(stringstream::out); | |
155 #endif | |
156 | |
157 { | |
158 Pel *piAdiTemp = m_piYuvExt[compID][PRED_BUF_UNFILTERED]; | |
159 Pel *piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu()+uiZorderIdxInPart); | |
160 #if O0043_BEST_EFFORT_DECODING | |
161 fillReferenceSamples (g_bitDepthInStream[chType], g_bitDepthInStream[chType] - g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits, | |
162 #else | |
163 fillReferenceSamples (g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits, | |
164 #endif | |
165 uiTuWidth, uiTuHeight, uiROIWidth, uiROIHeight, iPicStride, toChannelType(compID), chFmt); | |
166 | |
167 | |
168 #ifdef DEBUG_STRING | |
169 if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA)) | |
170 { | |
171 ss << "###: generating Ref Samples for channel " << compID << " and " << rTu.getRect(compID).width << " x " << rTu.getRect(compID).height << "\n"; | |
172 for (UInt y=0; y<uiROIHeight; y++) | |
173 { | |
174 ss << "###: - "; | |
175 for (UInt x=0; x<uiROIWidth; x++) | |
176 { | |
177 if (x==0 || y==0) | |
178 ss << piAdiTemp[y*uiROIWidth + x] << ", "; | |
179 // if (x%16==15) ss << "\nPart size: ~ "; | |
180 } | |
181 ss << "\n"; | |
182 } | |
183 } | |
184 #endif | |
185 | |
186 if (bFilterRefSamples) | |
187 { | |
188 // generate filtered intra prediction samples | |
189 | |
190 Int stride = uiROIWidth; | |
191 const Pel *piSrcPtr = piAdiTemp + (stride * uiTuHeight2); // bottom left | |
192 Pel *piDestPtr = m_piYuvExt[compID][PRED_BUF_FILTERED] + (stride * uiTuHeight2); // bottom left | |
193 | |
194 //------------------------------------------------ | |
195 | |
196 Bool useStrongIntraSmoothing = isLuma(chType) && pcCU->getSlice()->getSPS()->getUseStrongIntraSmoothing(); | |
197 | |
198 const Pel bottomLeft = piAdiTemp[stride * uiTuHeight2]; | |
199 const Pel topLeft = piAdiTemp[0]; | |
200 const Pel topRight = piAdiTemp[uiTuWidth2]; | |
201 | |
202 if (useStrongIntraSmoothing) | |
203 { | |
204 #if O0043_BEST_EFFORT_DECODING | |
205 const Int threshold = 1 << (g_bitDepthInStream[chType] - 5); | |
206 #else | |
207 const Int threshold = 1 << (g_bitDepth[chType] - 5); | |
208 #endif | |
209 const Bool bilinearLeft = abs((bottomLeft + topLeft ) - (2 * piAdiTemp[stride * uiTuHeight])) < threshold; //difference between the | |
210 const Bool bilinearAbove = abs((topLeft + topRight) - (2 * piAdiTemp[ uiTuWidth ])) < threshold; //ends and the middle | |
211 if ((uiTuWidth < 32) || (!bilinearLeft) || (!bilinearAbove)) | |
212 useStrongIntraSmoothing = false; | |
213 } | |
214 | |
215 *piDestPtr = *piSrcPtr; // bottom left is not filtered | |
216 piDestPtr -= stride; | |
217 piSrcPtr -= stride; | |
218 | |
219 //------------------------------------------------ | |
220 | |
221 //left column (bottom to top) | |
222 | |
223 if (useStrongIntraSmoothing) | |
224 { | |
225 const Int shift = g_aucConvertToBit[uiTuHeight] + 3; //log2(uiTuHeight2) | |
226 | |
227 for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride) | |
228 { | |
229 *piDestPtr = (((uiTuHeight2 - i) * bottomLeft) + (i * topLeft) + uiTuHeight) >> shift; | |
230 } | |
231 | |
232 piSrcPtr -= stride * (uiTuHeight2 - 1); | |
233 } | |
234 else | |
235 { | |
236 for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride, piSrcPtr-=stride) | |
237 { | |
238 *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[-stride] + 2 ) >> 2; | |
239 } | |
240 } | |
241 | |
242 //------------------------------------------------ | |
243 | |
244 //top-left | |
245 | |
246 if (useStrongIntraSmoothing) | |
247 { | |
248 *piDestPtr = piSrcPtr[0]; | |
249 } | |
250 else | |
251 { | |
252 *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[1] + 2 ) >> 2; | |
253 } | |
254 piDestPtr += 1; | |
255 piSrcPtr += 1; | |
256 | |
257 //------------------------------------------------ | |
258 | |
259 //top row (left-to-right) | |
260 | |
261 if (useStrongIntraSmoothing) | |
262 { | |
263 const Int shift = g_aucConvertToBit[uiTuWidth] + 3; //log2(uiTuWidth2) | |
264 | |
265 for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++) | |
266 { | |
267 *piDestPtr = (((uiTuWidth2 - i) * topLeft) + (i * topRight) + uiTuWidth) >> shift; | |
268 } | |
269 | |
270 piSrcPtr += uiTuWidth2 - 1; | |
271 } | |
272 else | |
273 { | |
274 for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++, piSrcPtr++) | |
275 { | |
276 *piDestPtr = ( piSrcPtr[1] + 2*piSrcPtr[0] + piSrcPtr[-1] + 2 ) >> 2; | |
277 } | |
278 } | |
279 | |
280 //------------------------------------------------ | |
281 | |
282 *piDestPtr=*piSrcPtr; // far right is not filtered | |
283 | |
284 #ifdef DEBUG_STRING | |
285 if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA)) | |
286 { | |
287 ss << "###: filtered result for channel " << compID <<"\n"; | |
288 for (UInt y=0; y<uiROIHeight; y++) | |
289 { | |
290 ss << "###: - "; | |
291 for (UInt x=0; x<uiROIWidth; x++) | |
292 { | |
293 if (x==0 || y==0) | |
294 ss << m_piYuvExt[compID][PRED_BUF_FILTERED][y*uiROIWidth + x] << ", "; | |
295 // if (x%16==15) ss << "\nPart size: ~ "; | |
296 } | |
297 ss << "\n"; | |
298 } | |
299 } | |
300 #endif | |
301 | |
302 | |
303 } | |
304 } | |
305 DEBUG_STRING_APPEND(sDebug, ss.str()) | |
306 } | |
307 | |
308 #if O0043_BEST_EFFORT_DECODING | |
309 Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, | |
310 #else | |
311 Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, | |
312 #endif | |
313 const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits, | |
314 const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride, | |
315 const ChannelType chType, const ChromaFormat chFmt ) | |
316 { | |
317 const Pel* piRoiTemp; | |
318 Int i, j; | |
319 Int iDCValue = 1 << (bitDepth - 1); | |
320 const Int iTotalUnits = iAboveUnits + iLeftUnits + 1; //+1 for top-left | |
321 | |
322 if (iNumIntraNeighbor == 0) | |
323 { | |
324 // Fill border with DC value | |
325 for (i=0; i<uiWidth; i++) | |
326 { | |
327 piAdiTemp[i] = iDCValue; | |
328 } | |
329 for (i=1; i<uiHeight; i++) | |
330 { | |
331 piAdiTemp[i*uiWidth] = iDCValue; | |
332 } | |
333 } | |
334 else if (iNumIntraNeighbor == iTotalUnits) | |
335 { | |
336 // Fill top-left border and top and top right with rec. samples | |
337 piRoiTemp = piRoiOrigin - iPicStride - 1; | |
338 | |
339 for (i=0; i<uiWidth; i++) | |
340 { | |
341 #if O0043_BEST_EFFORT_DECODING | |
342 piAdiTemp[i] = piRoiTemp[i] << bitDepthDelta; | |
343 #else | |
344 piAdiTemp[i] = piRoiTemp[i]; | |
345 #endif | |
346 } | |
347 | |
348 // Fill left and below left border with rec. samples | |
349 piRoiTemp = piRoiOrigin - 1; | |
350 | |
351 for (i=1; i<uiHeight; i++) | |
352 { | |
353 #if O0043_BEST_EFFORT_DECODING | |
354 piAdiTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta; | |
355 #else | |
356 piAdiTemp[i*uiWidth] = *(piRoiTemp); | |
357 #endif | |
358 piRoiTemp += iPicStride; | |
359 } | |
360 } | |
361 else // reference samples are partially available | |
362 { | |
363 // all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each | |
364 const Int iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + 1) * unitWidth); | |
365 Pel piAdiLine[5 * MAX_CU_SIZE]; | |
366 Pel *piAdiLineTemp; | |
367 const Bool *pbNeighborFlags; | |
368 | |
369 | |
370 // Initialize | |
371 for (i=0; i<iTotalSamples; i++) | |
372 { | |
373 piAdiLine[i] = iDCValue; | |
374 } | |
375 | |
376 // Fill top-left sample | |
377 piRoiTemp = piRoiOrigin - iPicStride - 1; | |
378 piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight); | |
379 pbNeighborFlags = bNeighborFlags + iLeftUnits; | |
380 if (*pbNeighborFlags) | |
381 { | |
382 #if O0043_BEST_EFFORT_DECODING | |
383 Pel topLeftVal=piRoiTemp[0] << bitDepthDelta; | |
384 #else | |
385 Pel topLeftVal=piRoiTemp[0]; | |
386 #endif | |
387 for (i=0; i<unitWidth; i++) | |
388 { | |
389 piAdiLineTemp[i] = topLeftVal; | |
390 } | |
391 } | |
392 | |
393 // Fill left & below-left samples (downwards) | |
394 piRoiTemp += iPicStride; | |
395 piAdiLineTemp--; | |
396 pbNeighborFlags--; | |
397 | |
398 for (j=0; j<iLeftUnits; j++) | |
399 { | |
400 if (*pbNeighborFlags) | |
401 { | |
402 for (i=0; i<unitHeight; i++) | |
403 { | |
404 #if O0043_BEST_EFFORT_DECODING | |
405 piAdiLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta; | |
406 #else | |
407 piAdiLineTemp[-i] = piRoiTemp[i*iPicStride]; | |
408 #endif | |
409 } | |
410 } | |
411 piRoiTemp += unitHeight*iPicStride; | |
412 piAdiLineTemp -= unitHeight; | |
413 pbNeighborFlags--; | |
414 } | |
415 | |
416 // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples) | |
417 piRoiTemp = piRoiOrigin - iPicStride; | |
418 // offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left) | |
419 piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight) + unitWidth; | |
420 pbNeighborFlags = bNeighborFlags + iLeftUnits + 1; | |
421 for (j=0; j<iAboveUnits; j++) | |
422 { | |
423 if (*pbNeighborFlags) | |
424 { | |
425 for (i=0; i<unitWidth; i++) | |
426 { | |
427 #if O0043_BEST_EFFORT_DECODING | |
428 piAdiLineTemp[i] = piRoiTemp[i] << bitDepthDelta; | |
429 #else | |
430 piAdiLineTemp[i] = piRoiTemp[i]; | |
431 #endif | |
432 } | |
433 } | |
434 piRoiTemp += unitWidth; | |
435 piAdiLineTemp += unitWidth; | |
436 pbNeighborFlags++; | |
437 } | |
438 | |
439 // Pad reference samples when necessary | |
440 Int iCurrJnit = 0; | |
441 Pel *piAdiLineCur = piAdiLine; | |
442 const UInt piAdiLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth); | |
443 | |
444 if (!bNeighborFlags[0]) | |
445 { | |
446 // very bottom unit of bottom-left; at least one unit will be valid. | |
447 { | |
448 Int iNext = 1; | |
449 while (iNext < iTotalUnits && !bNeighborFlags[iNext]) | |
450 { | |
451 iNext++; | |
452 } | |
453 Pel *piAdiLineNext = piAdiLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piAdiLineTopRowOffset + (iNext * unitWidth))); | |
454 const Pel refSample = *piAdiLineNext; | |
455 // Pad unavailable samples with new value | |
456 Int iNextOrTop = std::min<Int>(iNext, iLeftUnits); | |
457 // fill left column | |
458 while (iCurrJnit < iNextOrTop) | |
459 { | |
460 for (i=0; i<unitHeight; i++) | |
461 { | |
462 piAdiLineCur[i] = refSample; | |
463 } | |
464 piAdiLineCur += unitHeight; | |
465 iCurrJnit++; | |
466 } | |
467 // fill top row | |
468 while (iCurrJnit < iNext) | |
469 { | |
470 for (i=0; i<unitWidth; i++) | |
471 { | |
472 piAdiLineCur[i] = refSample; | |
473 } | |
474 piAdiLineCur += unitWidth; | |
475 iCurrJnit++; | |
476 } | |
477 } | |
478 } | |
479 | |
480 // pad all other reference samples. | |
481 while (iCurrJnit < iTotalUnits) | |
482 { | |
483 if (!bNeighborFlags[iCurrJnit]) // samples not available | |
484 { | |
485 { | |
486 const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight; | |
487 const Pel refSample = *(piAdiLineCur-1); | |
488 for (i=0; i<numSamplesInCurrUnit; i++) | |
489 { | |
490 piAdiLineCur[i] = refSample; | |
491 } | |
492 piAdiLineCur += numSamplesInCurrUnit; | |
493 iCurrJnit++; | |
494 } | |
495 } | |
496 else | |
497 { | |
498 piAdiLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight; | |
499 iCurrJnit++; | |
500 } | |
501 } | |
502 | |
503 // Copy processed samples | |
504 | |
505 piAdiLineTemp = piAdiLine + uiHeight + unitWidth - 2; | |
506 // top left, top and top right samples | |
507 for (i=0; i<uiWidth; i++) | |
508 { | |
509 piAdiTemp[i] = piAdiLineTemp[i]; | |
510 } | |
511 | |
512 piAdiLineTemp = piAdiLine + uiHeight - 1; | |
513 for (i=1; i<uiHeight; i++) | |
514 { | |
515 piAdiTemp[i*uiWidth] = piAdiLineTemp[-i]; | |
516 } | |
517 } | |
518 } | |
519 | |
520 /** Get pointer to reference samples for intra prediction | |
521 * \param uiDirMode prediction mode index | |
522 * \param log2BlkSize size of block (2 = 4x4, 3 = 8x8, 4 = 16x16, 5 = 32x32, 6 = 64x64) | |
523 * \param piAdiBuf pointer to unfiltered reference samples | |
524 * \return pointer to (possibly filtered) reference samples | |
525 * | |
526 * The prediction mode index is used to determine whether a smoothed reference sample buffer is returned. | |
527 */ | |
528 | |
529 Bool TComPrediction::filteringIntraReferenceSamples(const ComponentID compID, UInt uiDirMode, UInt uiTuChWidth, UInt uiTuChHeight, const ChromaFormat chFmt, const Bool intraReferenceSmoothingDisabled) | |
530 { | |
531 Bool bFilter; | |
532 | |
533 if (!filterIntraReferenceSamples(toChannelType(compID), chFmt, intraReferenceSmoothingDisabled)) | |
534 { | |
535 bFilter=false; | |
536 } | |
537 else | |
538 { | |
539 assert(uiTuChWidth>=4 && uiTuChHeight>=4 && uiTuChWidth<128 && uiTuChHeight<128); | |
540 | |
541 if (uiDirMode == DC_IDX) | |
542 { | |
543 bFilter=false; //no smoothing for DC or LM chroma | |
544 } | |
545 else | |
546 { | |
547 Int diff = min<Int>(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX)); | |
548 UInt sizeIndex=g_aucConvertToBit[uiTuChWidth]; | |
549 assert(sizeIndex < MAX_INTRA_FILTER_DEPTHS); | |
550 bFilter = diff > m_aucIntraFilter[toChannelType(compID)][sizeIndex]; | |
551 } | |
552 } | |
553 return bFilter; | |
554 } | |
555 | |
556 Bool isAboveLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT ) | |
557 { | |
558 Bool bAboveLeftFlag; | |
559 UInt uiPartAboveLeft; | |
560 TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT ); | |
561 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) | |
562 { | |
563 bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->isIntra( uiPartAboveLeft ) ); | |
564 } | |
565 else | |
566 { | |
567 bAboveLeftFlag = (pcCUAboveLeft ? true : false); | |
568 } | |
569 return bAboveLeftFlag; | |
570 } | |
571 | |
572 Int isAboveAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) | |
573 { | |
574 const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; | |
575 const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1; | |
576 const UInt uiIdxStep = 1; | |
577 Bool *pbValidFlags = bValidFlags; | |
578 Int iNumIntra = 0; | |
579 | |
580 for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) | |
581 { | |
582 UInt uiPartAbove; | |
583 TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart] ); | |
584 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) | |
585 { | |
586 if ( pcCUAbove && pcCUAbove->isIntra( uiPartAbove ) ) | |
587 { | |
588 iNumIntra++; | |
589 *pbValidFlags = true; | |
590 } | |
591 else | |
592 { | |
593 *pbValidFlags = false; | |
594 } | |
595 } | |
596 else | |
597 { | |
598 if (pcCUAbove) | |
599 { | |
600 iNumIntra++; | |
601 *pbValidFlags = true; | |
602 } | |
603 else | |
604 { | |
605 *pbValidFlags = false; | |
606 } | |
607 } | |
608 pbValidFlags++; | |
609 } | |
610 return iNumIntra; | |
611 } | |
612 | |
613 Int isLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) | |
614 { | |
615 const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; | |
616 const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1; | |
617 const UInt uiIdxStep = pcCU->getPic()->getNumPartInCtuWidth(); | |
618 Bool *pbValidFlags = bValidFlags; | |
619 Int iNumIntra = 0; | |
620 | |
621 for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) | |
622 { | |
623 UInt uiPartLeft; | |
624 TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart] ); | |
625 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) | |
626 { | |
627 if ( pcCULeft && pcCULeft->isIntra( uiPartLeft ) ) | |
628 { | |
629 iNumIntra++; | |
630 *pbValidFlags = true; | |
631 } | |
632 else | |
633 { | |
634 *pbValidFlags = false; | |
635 } | |
636 } | |
637 else | |
638 { | |
639 if ( pcCULeft ) | |
640 { | |
641 iNumIntra++; | |
642 *pbValidFlags = true; | |
643 } | |
644 else | |
645 { | |
646 *pbValidFlags = false; | |
647 } | |
648 } | |
649 pbValidFlags--; // opposite direction | |
650 } | |
651 | |
652 return iNumIntra; | |
653 } | |
654 | |
655 Int isAboveRightAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) | |
656 { | |
657 const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1; | |
658 Bool *pbValidFlags = bValidFlags; | |
659 Int iNumIntra = 0; | |
660 | |
661 for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) | |
662 { | |
663 UInt uiPartAboveRight; | |
664 TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPartIdxRT, uiOffset ); | |
665 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) | |
666 { | |
667 if ( pcCUAboveRight && pcCUAboveRight->isIntra( uiPartAboveRight ) ) | |
668 { | |
669 iNumIntra++; | |
670 *pbValidFlags = true; | |
671 } | |
672 else | |
673 { | |
674 *pbValidFlags = false; | |
675 } | |
676 } | |
677 else | |
678 { | |
679 if ( pcCUAboveRight ) | |
680 { | |
681 iNumIntra++; | |
682 *pbValidFlags = true; | |
683 } | |
684 else | |
685 { | |
686 *pbValidFlags = false; | |
687 } | |
688 } | |
689 pbValidFlags++; | |
690 } | |
691 | |
692 return iNumIntra; | |
693 } | |
694 | |
695 Int isBelowLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) | |
696 { | |
697 const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInCtuWidth() + 1; | |
698 Bool *pbValidFlags = bValidFlags; | |
699 Int iNumIntra = 0; | |
700 | |
701 for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) | |
702 { | |
703 UInt uiPartBelowLeft; | |
704 TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPartIdxLB, uiOffset ); | |
705 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) | |
706 { | |
707 if ( pcCUBelowLeft && pcCUBelowLeft->isIntra( uiPartBelowLeft ) ) | |
708 { | |
709 iNumIntra++; | |
710 *pbValidFlags = true; | |
711 } | |
712 else | |
713 { | |
714 *pbValidFlags = false; | |
715 } | |
716 } | |
717 else | |
718 { | |
719 if ( pcCUBelowLeft ) | |
720 { | |
721 iNumIntra++; | |
722 *pbValidFlags = true; | |
723 } | |
724 else | |
725 { | |
726 *pbValidFlags = false; | |
727 } | |
728 } | |
729 pbValidFlags--; // opposite direction | |
730 } | |
731 | |
732 return iNumIntra; | |
733 } | |
734 //! \} |