/src/libde265/libde265/transform.cc
Line | Count | Source |
1 | | /* |
2 | | * H.265 video codec. |
3 | | * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de> |
4 | | * |
5 | | * This file is part of libde265. |
6 | | * |
7 | | * libde265 is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as |
9 | | * published by the Free Software Foundation, either version 3 of |
10 | | * the License, or (at your option) any later version. |
11 | | * |
12 | | * libde265 is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libde265. If not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #include "transform.h" |
22 | | #include "util.h" |
23 | | |
24 | | #include <assert.h> |
25 | | |
26 | | |
27 | | const int tab8_22[] = { 29,30,31,32,33,33,34,34,35,35,36,36,37 /*,37*/ }; |
28 | | |
29 | | |
30 | | // (8.6.1) |
31 | | void decode_quantization_parameters(thread_context* tctx, int xC,int yC, |
32 | | int xCUBase, int yCUBase) |
33 | 7.73M | { |
34 | 7.73M | logtrace(LogTransform,">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> decode_quantization_parameters(int xC,int yC)=(%d,%d)\n", xC,yC); |
35 | | |
36 | 7.73M | const pic_parameter_set& pps = tctx->img->get_pps(); |
37 | 7.73M | const seq_parameter_set& sps = tctx->img->get_sps(); |
38 | 7.73M | slice_segment_header* shdr = tctx->shdr; |
39 | | |
40 | | // top left pixel position of current quantization group |
41 | 7.73M | int xQG = xCUBase - (xCUBase & ((1<<pps.Log2MinCuQpDeltaSize)-1)); |
42 | 7.73M | int yQG = yCUBase - (yCUBase & ((1<<pps.Log2MinCuQpDeltaSize)-1)); |
43 | | |
44 | 7.73M | logtrace(LogTransform,"QG: %d,%d\n",xQG,yQG); |
45 | | |
46 | | |
47 | | // we only have to set QP in the first call in a quantization-group |
48 | | |
49 | | /* TODO: check why this does not work with HoneyBee stream |
50 | | |
51 | | if (xQG == tctx->currentQG_x && |
52 | | yQG == tctx->currentQG_y) |
53 | | { |
54 | | return; |
55 | | } |
56 | | */ |
57 | | |
58 | | // if first QG in CU, remember last QPY of last CU previous QG |
59 | | |
60 | 7.73M | if (xQG != tctx->currentQG_x || |
61 | 6.49M | yQG != tctx->currentQG_y) |
62 | 1.24M | { |
63 | 1.24M | tctx->lastQPYinPreviousQG = tctx->currentQPY; |
64 | 1.24M | tctx->currentQG_x = xQG; |
65 | 1.24M | tctx->currentQG_y = yQG; |
66 | 1.24M | } |
67 | | |
68 | 7.73M | int qPY_PRED; |
69 | | |
70 | | // first QG in CTB row ? |
71 | | |
72 | 7.73M | int ctbLSBMask = ((1<<sps.Log2CtbSizeY)-1); |
73 | 7.73M | bool firstInCTBRow = (xQG == 0 && ((yQG & ctbLSBMask)==0)); |
74 | | |
75 | | // first QG in slice ? TODO: a "firstQG" flag in the thread context would be faster |
76 | | |
77 | 7.73M | int first_ctb_in_slice_RS = tctx->shdr->SliceAddrRS; |
78 | | |
79 | 7.73M | int SliceStartX = (first_ctb_in_slice_RS % sps.PicWidthInCtbsY) * sps.CtbSizeY; |
80 | 7.73M | int SliceStartY = (first_ctb_in_slice_RS / sps.PicWidthInCtbsY) * sps.CtbSizeY; |
81 | | |
82 | 7.73M | bool firstQGInSlice = (SliceStartX == xQG && SliceStartY == yQG); |
83 | | |
84 | | // first QG in tile ? |
85 | | |
86 | 7.73M | bool firstQGInTile = false; |
87 | 7.73M | if (pps.tiles_enabled_flag) { |
88 | 76.3k | if ((xQG & ((1 << sps.Log2CtbSizeY)-1)) == 0 && |
89 | 45.1k | (yQG & ((1 << sps.Log2CtbSizeY)-1)) == 0) |
90 | 32.5k | { |
91 | 32.5k | int ctbX = xQG >> sps.Log2CtbSizeY; |
92 | 32.5k | int ctbY = yQG >> sps.Log2CtbSizeY; |
93 | | |
94 | 32.5k | firstQGInTile = pps.is_tile_start_CTB(ctbX,ctbY); // TODO: this is slow |
95 | 32.5k | } |
96 | 76.3k | } |
97 | | |
98 | | |
99 | 7.73M | if (firstQGInSlice || firstQGInTile || |
100 | 7.65M | (firstInCTBRow && pps.entropy_coding_sync_enabled_flag)) { |
101 | 128k | qPY_PRED = tctx->shdr->SliceQPY; |
102 | 128k | } |
103 | 7.60M | else { |
104 | 7.60M | qPY_PRED = tctx->lastQPYinPreviousQG; |
105 | 7.60M | } |
106 | | |
107 | | |
108 | 7.73M | int qPYA,qPYB; |
109 | | |
110 | 7.73M | if (tctx->img->available_zscan(xQG,yQG, xQG-1,yQG)) { |
111 | 7.18M | int xTmp = (xQG-1) >> sps.Log2MinTrafoSize; |
112 | 7.18M | int yTmp = (yQG ) >> sps.Log2MinTrafoSize; |
113 | 7.18M | int minTbAddrA = pps.scan->MinTbAddrZS[xTmp + yTmp*sps.PicWidthInTbsY]; |
114 | 7.18M | uint32_t ctbAddrA = minTbAddrA >> (2 * (sps.Log2CtbSizeY-sps.Log2MinTrafoSize)); |
115 | 7.18M | if (ctbAddrA == tctx->CtbAddrInTS) { |
116 | 112k | qPYA = tctx->img->get_QPY(xQG-1,yQG); |
117 | 112k | } |
118 | 7.07M | else { |
119 | 7.07M | qPYA = qPY_PRED; |
120 | 7.07M | } |
121 | 7.18M | } |
122 | 549k | else { |
123 | 549k | qPYA = qPY_PRED; |
124 | 549k | } |
125 | | |
126 | 7.73M | if (tctx->img->available_zscan(xQG,yQG, xQG,yQG-1)) { |
127 | 7.13M | int xTmp = (xQG ) >> sps.Log2MinTrafoSize; |
128 | 7.13M | int yTmp = (yQG-1) >> sps.Log2MinTrafoSize; |
129 | 7.13M | uint32_t minTbAddrB = pps.scan->MinTbAddrZS[xTmp + yTmp*sps.PicWidthInTbsY]; |
130 | 7.13M | uint32_t ctbAddrB = minTbAddrB >> (2 * (sps.Log2CtbSizeY-sps.Log2MinTrafoSize)); |
131 | 7.13M | if (ctbAddrB == tctx->CtbAddrInTS) { |
132 | 126k | qPYB = tctx->img->get_QPY(xQG,yQG-1); |
133 | 126k | } |
134 | 7.00M | else { |
135 | 7.00M | qPYB = qPY_PRED; |
136 | 7.00M | } |
137 | 7.13M | } |
138 | 602k | else { |
139 | 602k | qPYB = qPY_PRED; |
140 | 602k | } |
141 | | |
142 | 7.73M | qPY_PRED = (qPYA + qPYB + 1)>>1; |
143 | | |
144 | 7.73M | logtrace(LogTransform,"qPY_PRED = %d (%d, %d)\n",qPY_PRED, qPYA, qPYB); |
145 | | |
146 | 7.73M | int QPY = ((qPY_PRED + tctx->CuQpDelta + 52+2*sps.QpBdOffset_Y) % |
147 | 7.73M | (52 + sps.QpBdOffset_Y)) - sps.QpBdOffset_Y; |
148 | | |
149 | 7.73M | assert(QPY >= -sps.QpBdOffset_Y && QPY <= 51); |
150 | | |
151 | 7.72M | tctx->qPYPrime = QPY + sps.QpBdOffset_Y; |
152 | | |
153 | 7.72M | int qPiCb = Clip3(-sps.QpBdOffset_C,57, QPY+pps.pic_cb_qp_offset + shdr->slice_cb_qp_offset + tctx->CuQpOffsetCb); |
154 | 7.72M | int qPiCr = Clip3(-sps.QpBdOffset_C,57, QPY+pps.pic_cr_qp_offset + shdr->slice_cr_qp_offset + tctx->CuQpOffsetCr); |
155 | | |
156 | 7.72M | logtrace(LogTransform,"qPiCb:%d (%d %d), qPiCr:%d (%d %d)\n", |
157 | 7.72M | qPiCb, pps.pic_cb_qp_offset, shdr->slice_cb_qp_offset, |
158 | 7.72M | qPiCr, pps.pic_cr_qp_offset, shdr->slice_cr_qp_offset); |
159 | | |
160 | 7.72M | int qPCb,qPCr; |
161 | | |
162 | 7.72M | if (sps.ChromaArrayType == CHROMA_420) { |
163 | 6.83M | qPCb = table8_22(qPiCb); |
164 | 6.83M | qPCr = table8_22(qPiCr); |
165 | 6.83M | } |
166 | 885k | else { |
167 | 885k | qPCb = qPiCb; |
168 | 885k | qPCr = qPiCr; |
169 | 885k | } |
170 | | |
171 | | //printf("q: %d %d\n",qPiCb, qPCb); |
172 | | |
173 | 7.72M | tctx->qPCbPrime = qPCb + sps.QpBdOffset_C; |
174 | 7.72M | if (tctx->qPCbPrime<0) { |
175 | 0 | tctx->qPCbPrime = 0; |
176 | 0 | } |
177 | | |
178 | 7.72M | tctx->qPCrPrime = qPCr + sps.QpBdOffset_C; |
179 | 7.72M | if (tctx->qPCrPrime<0) { |
180 | 0 | tctx->qPCrPrime = 0; |
181 | 0 | } |
182 | | |
183 | | /* |
184 | | printf("Q: %d (%d %d %d / %d %d) %d %d %d\n",QPY, |
185 | | sps->QpBdOffset_Y, |
186 | | pps->pic_cb_qp_offset + shdr->slice_cb_qp_offset, |
187 | | pps->pic_cr_qp_offset + shdr->slice_cr_qp_offset, |
188 | | sps->QpBdOffset_C, sps->QpBdOffset_C, |
189 | | tctx->qPYPrime, tctx->qPCbPrime, tctx->qPCrPrime); |
190 | | */ |
191 | | |
192 | 7.72M | int log2CbSize = tctx->img->get_log2CbSize(xCUBase, yCUBase); |
193 | | |
194 | | // TODO: On broken input, log2CbSize may be zero (multithreaded only). Not sure yet why. |
195 | | // Maybe another decoding thread is overwriting the value set in slice.cc:read_coding_unit. |
196 | | // id:000163,sig:06,src:002041,op:havoc,rep:16.bin |
197 | 7.72M | if (log2CbSize<3) { log2CbSize=3; } |
198 | | |
199 | 7.72M | tctx->img->set_QPY(xCUBase, yCUBase, log2CbSize, QPY); |
200 | 7.72M | tctx->currentQPY = QPY; |
201 | | |
202 | | /* |
203 | | printf("SET QPY POC=%d %d;%d-%d;%d = %d\n",ctx->img->PicOrderCntVal,xCUBase,yCUBase, |
204 | | xCUBase+(1<<log2CbSize),yCUBase+(1<<log2CbSize), QPY); |
205 | | */ |
206 | | |
207 | 7.72M | logtrace(LogTransform,"qPY(%d,%d,%d)= %d, qPYPrime=%d\n", |
208 | 7.72M | xCUBase,yCUBase,1<<log2CbSize,QPY,tctx->qPYPrime); |
209 | 7.72M | } |
210 | | |
211 | | |
212 | | |
213 | | template <class pixel_t> |
214 | | void transform_coefficients(acceleration_functions* acceleration, |
215 | | int16_t* coeff, int coeffStride, int nT, int trType, |
216 | | pixel_t* dst, int dstStride, int bit_depth) |
217 | 13.3M | { |
218 | 13.3M | logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); |
219 | | |
220 | | |
221 | 13.3M | if (trType==1) { |
222 | | |
223 | 4.23M | acceleration->transform_4x4_dst_add<pixel_t>(dst, coeff, dstStride, bit_depth); |
224 | | |
225 | 9.07M | } else { |
226 | | |
227 | 9.07M | /**/ if (nT==4) { acceleration->transform_add<pixel_t>(0,dst,coeff,dstStride, bit_depth); } |
228 | 5.49M | else if (nT==8) { acceleration->transform_add<pixel_t>(1,dst,coeff,dstStride, bit_depth); } |
229 | 2.53M | else if (nT==16) { acceleration->transform_add<pixel_t>(2,dst,coeff,dstStride, bit_depth); } |
230 | 294k | else { acceleration->transform_add<pixel_t>(3,dst,coeff,dstStride, bit_depth); } |
231 | 9.07M | } |
232 | | |
233 | | #if 0 |
234 | | printf("decoded pixels:\n"); |
235 | | for (int y=0;y<nT;y++,printf("\n")) |
236 | | for (int x=0;x<nT;x++) { |
237 | | printf("%02x ",dst[y*dstStride+x]); |
238 | | } |
239 | | #endif |
240 | 13.3M | } void transform_coefficients<unsigned short>(acceleration_functions*, short*, int, int, int, unsigned short*, int, int) Line | Count | Source | 217 | 514k | { | 218 | 514k | logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); | 219 | | | 220 | | | 221 | 514k | if (trType==1) { | 222 | | | 223 | 274k | acceleration->transform_4x4_dst_add<pixel_t>(dst, coeff, dstStride, bit_depth); | 224 | | | 225 | 274k | } else { | 226 | | | 227 | 239k | /**/ if (nT==4) { acceleration->transform_add<pixel_t>(0,dst,coeff,dstStride, bit_depth); } | 228 | 70.6k | else if (nT==8) { acceleration->transform_add<pixel_t>(1,dst,coeff,dstStride, bit_depth); } | 229 | 9.57k | else if (nT==16) { acceleration->transform_add<pixel_t>(2,dst,coeff,dstStride, bit_depth); } | 230 | 18.4E | else { acceleration->transform_add<pixel_t>(3,dst,coeff,dstStride, bit_depth); } | 231 | 239k | } | 232 | | | 233 | | #if 0 | 234 | | printf("decoded pixels:\n"); | 235 | | for (int y=0;y<nT;y++,printf("\n")) | 236 | | for (int x=0;x<nT;x++) { | 237 | | printf("%02x ",dst[y*dstStride+x]); | 238 | | } | 239 | | #endif | 240 | 514k | } |
void transform_coefficients<unsigned char>(acceleration_functions*, short*, int, int, int, unsigned char*, int, int) Line | Count | Source | 217 | 12.7M | { | 218 | 12.7M | logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); | 219 | | | 220 | | | 221 | 12.7M | if (trType==1) { | 222 | | | 223 | 3.96M | acceleration->transform_4x4_dst_add<pixel_t>(dst, coeff, dstStride, bit_depth); | 224 | | | 225 | 8.83M | } else { | 226 | | | 227 | 8.83M | /**/ if (nT==4) { acceleration->transform_add<pixel_t>(0,dst,coeff,dstStride, bit_depth); } | 228 | 5.42M | else if (nT==8) { acceleration->transform_add<pixel_t>(1,dst,coeff,dstStride, bit_depth); } | 229 | 2.52M | else if (nT==16) { acceleration->transform_add<pixel_t>(2,dst,coeff,dstStride, bit_depth); } | 230 | 295k | else { acceleration->transform_add<pixel_t>(3,dst,coeff,dstStride, bit_depth); } | 231 | 8.83M | } | 232 | | | 233 | | #if 0 | 234 | | printf("decoded pixels:\n"); | 235 | | for (int y=0;y<nT;y++,printf("\n")) | 236 | | for (int x=0;x<nT;x++) { | 237 | | printf("%02x ",dst[y*dstStride+x]); | 238 | | } | 239 | | #endif | 240 | 12.7M | } |
|
241 | | |
242 | | |
243 | | // TODO: make this an accelerated function |
244 | | void cross_comp_pred(const thread_context* tctx, int32_t* residual, int nT) |
245 | 0 | { |
246 | 0 | const int BitDepthC = tctx->img->get_sps().BitDepth_C; |
247 | 0 | const int BitDepthY = tctx->img->get_sps().BitDepth_Y; |
248 | 0 | const int ResScaleVal = tctx->ResScaleVal; |
249 | | |
250 | | /* (8.6.6): r[x][y] += ( ResScaleVal * ( ( rY[x][y] << BitDepthC ) >> BitDepthY ) ) >> 3 |
251 | | Both shifts operate on a signed value, so together they are a single signed rescaling |
252 | | by (BitDepthC - BitDepthY). It must not be evaluated on an unsigned type: the right |
253 | | shift would then be logical and turn every negative luma residual into a large |
254 | | positive value. Shifting left is expressed as a multiplication because shifting a |
255 | | negative value left is undefined behaviour before C++20. |
256 | | */ |
257 | |
|
258 | 0 | const int shift = BitDepthY - BitDepthC; |
259 | |
|
260 | 0 | if (shift >= 0) { |
261 | 0 | for (int y=0;y<nT;y++) |
262 | 0 | for (int x=0;x<nT;x++) { |
263 | 0 | residual[y*nT+x] += (ResScaleVal * (tctx->residual_luma[y*nT+x] >> shift)) >> 3; |
264 | 0 | } |
265 | 0 | } |
266 | 0 | else { |
267 | 0 | const int32_t factor = 1 << (-shift); |
268 | |
|
269 | 0 | for (int y=0;y<nT;y++) |
270 | 0 | for (int x=0;x<nT;x++) { |
271 | 0 | residual[y*nT+x] += (ResScaleVal * (tctx->residual_luma[y*nT+x] * factor)) >> 3; |
272 | 0 | } |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | | |
277 | | template <class pixel_t> |
278 | | void transform_coefficients_explicit(thread_context* tctx, |
279 | | int16_t* coeff, int coeffStride, int nT, int trType, |
280 | | pixel_t* dst, int dstStride, int bit_depth, int cIdx) |
281 | 0 | { |
282 | 0 | logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,nT); |
283 | |
|
284 | 0 | const acceleration_functions* acceleration = &tctx->decctx->acceleration; |
285 | |
|
286 | 0 | int32_t residual_buffer[32*32]; |
287 | 0 | int32_t* residual; |
288 | 0 | if (cIdx==0) { |
289 | 0 | residual = tctx->residual_luma; |
290 | 0 | } |
291 | 0 | else { |
292 | 0 | residual = residual_buffer; |
293 | 0 | } |
294 | | |
295 | | |
296 | | // TODO |
297 | 0 | int bdShift = 20 - bit_depth; |
298 | 0 | int max_coeff_bits = 15; |
299 | |
|
300 | 0 | if (trType==1) { |
301 | |
|
302 | 0 | acceleration->transform_idst_4x4(residual, coeff, bdShift, max_coeff_bits); |
303 | |
|
304 | 0 | } else { |
305 | | |
306 | 0 | /**/ if (nT==4) { acceleration->transform_idct_4x4(residual,coeff,bdShift,max_coeff_bits); } |
307 | 0 | else if (nT==8) { acceleration->transform_idct_8x8(residual,coeff,bdShift,max_coeff_bits); } |
308 | 0 | else if (nT==16) { acceleration->transform_idct_16x16(residual,coeff,bdShift,max_coeff_bits); } |
309 | 0 | else { acceleration->transform_idct_32x32(residual,coeff,bdShift,max_coeff_bits); } |
310 | 0 | } |
311 | | |
312 | | |
313 | | //printBlk("prediction",(uint8_t*)dst,nT,dstStride); |
314 | | //printBlk("residual",residual,nT,nT); |
315 | |
|
316 | 0 | if (cIdx != 0) { |
317 | 0 | if (tctx->ResScaleVal != 0) { |
318 | 0 | cross_comp_pred(tctx, residual, nT); |
319 | 0 | } |
320 | | |
321 | | //printBlk("cross-comp-pred modified residual",residual,nT,nT); |
322 | 0 | } |
323 | |
|
324 | 0 | acceleration->add_residual(dst,dstStride, residual,nT, bit_depth); |
325 | 0 | } Unexecuted instantiation: void transform_coefficients_explicit<unsigned short>(thread_context*, short*, int, int, int, unsigned short*, int, int, int) Unexecuted instantiation: void transform_coefficients_explicit<unsigned char>(thread_context*, short*, int, int, int, unsigned char*, int, int, int) |
326 | | |
327 | | |
328 | | void inv_transform(acceleration_functions* acceleration, |
329 | | uint8_t* dst, int dstStride, int16_t* coeff, |
330 | | int log2TbSize, int trType) |
331 | 0 | { |
332 | 0 | if (trType==1) { |
333 | 0 | assert(log2TbSize==2); |
334 | | |
335 | 0 | acceleration->transform_4x4_dst_add_8(dst, coeff, dstStride); |
336 | |
|
337 | 0 | } else { |
338 | 0 | acceleration->transform_add_8[log2TbSize-2](dst,coeff,dstStride); |
339 | 0 | } |
340 | | |
341 | |
|
342 | | #if 0 |
343 | | int nT = 1<<log2TbSize; |
344 | | printf("decoded pixels:\n"); |
345 | | for (int y=0;y<nT;y++,printf("\n")) |
346 | | for (int x=0;x<nT;x++) { |
347 | | printf("%02x ",dst[y*dstStride+x]); |
348 | | } |
349 | | #endif |
350 | 0 | } |
351 | | |
352 | | |
353 | | void fwd_transform(acceleration_functions* acceleration, |
354 | | int16_t* coeff, int coeffStride, int log2TbSize, int trType, |
355 | | const int16_t* src, int srcStride) |
356 | 0 | { |
357 | 0 | logtrace(LogTransform,"transform --- trType: %d nT: %d\n",trType,1<<log2TbSize); |
358 | |
|
359 | 0 | if (trType==1) { |
360 | | // DST 4x4 |
361 | |
|
362 | 0 | acceleration->fwd_transform_4x4_dst_8(coeff, src, srcStride); |
363 | 0 | } else { |
364 | | // DCT 4x4, 8x8, 16x16, 32x32 |
365 | |
|
366 | 0 | acceleration->fwd_transform_8[log2TbSize-2](coeff,src,srcStride); |
367 | 0 | } |
368 | 0 | } |
369 | | |
370 | | |
371 | | |
372 | | static const int levelScale[] = { 40,45,51,57,64,72 }; |
373 | | |
374 | | // (8.6.2) and (8.6.3) |
375 | | template <class pixel_t> |
376 | | void scale_coefficients_internal(thread_context* tctx, |
377 | | int xT,int yT, // position of TU in frame (chroma adapted) |
378 | | int x0,int y0, // position of CU in frame (chroma adapted) |
379 | | int nT, int cIdx, |
380 | | bool transform_skip_flag, bool intra, int rdpcmMode) |
381 | 14.5M | { |
382 | 14.5M | const seq_parameter_set& sps = tctx->img->get_sps(); |
383 | 14.5M | const pic_parameter_set& pps = tctx->img->get_pps(); |
384 | | |
385 | 14.5M | int qP; |
386 | 14.5M | switch (cIdx) { |
387 | 9.28M | case 0: qP = tctx->qPYPrime; break; |
388 | 2.76M | case 1: qP = tctx->qPCbPrime; break; |
389 | 2.52M | case 2: qP = tctx->qPCrPrime; break; |
390 | 0 | default: qP = 0; assert(0); break; // should never happen |
391 | 14.5M | } |
392 | | |
393 | 14.5M | logtrace(LogTransform,"qP: %d\n",qP); |
394 | | |
395 | | |
396 | 14.5M | int16_t* coeff; |
397 | 14.5M | int coeffStride; |
398 | | |
399 | 14.5M | coeff = tctx->coeffBuf; |
400 | 14.5M | coeffStride = nT; |
401 | | |
402 | | |
403 | | |
404 | | |
405 | | |
406 | 14.5M | pixel_t* pred; |
407 | 14.5M | int stride; |
408 | 14.5M | pred = tctx->img->get_image_plane_at_pos_NEW<pixel_t>(cIdx, xT,yT); |
409 | 14.5M | stride = tctx->img->get_image_stride(cIdx); |
410 | | |
411 | | // We explicitly include the case for sizeof(pixel_t)==1 so that the compiler |
412 | | // can optimize away a lot of code for 8-bit pixels. |
413 | 14.5M | const int bit_depth = ((sizeof(pixel_t)==1) ? 8 : sps.get_bit_depth(cIdx)); |
414 | | |
415 | | //assert(intra == (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA)); |
416 | 14.5M | int cuPredModeIntra = (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA); |
417 | | |
418 | 14.5M | bool rotateCoeffs = (sps.range_extension.transform_skip_rotation_enabled_flag && |
419 | 91.5k | nT == 4 && |
420 | 73.1k | cuPredModeIntra); |
421 | | |
422 | 14.5M | if (tctx->cu_transquant_bypass_flag) { |
423 | | |
424 | 1.04M | int32_t residual_buffer[32*32]; |
425 | | |
426 | 1.04M | int32_t* residual; |
427 | 1.04M | if (cIdx==0) residual = tctx->residual_luma; |
428 | 327k | else residual = residual_buffer; |
429 | | |
430 | | |
431 | | // TODO: we could fold the coefficient rotation into the coefficient expansion here: |
432 | 10.6M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { |
433 | 9.61M | int32_t currCoeff = tctx->coeffList[cIdx][i]; |
434 | 9.61M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; |
435 | 9.61M | } |
436 | | |
437 | 1.04M | if (rotateCoeffs) { |
438 | 7.92k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); |
439 | 7.92k | } |
440 | | |
441 | 1.04M | if (rdpcmMode) { |
442 | 27.6k | if (rdpcmMode==2) |
443 | 14.0k | tctx->decctx->acceleration.transform_bypass_rdpcm_v(residual, coeff, nT); |
444 | 13.5k | else |
445 | 13.5k | tctx->decctx->acceleration.transform_bypass_rdpcm_h(residual, coeff, nT); |
446 | 27.6k | } |
447 | 1.01M | else { |
448 | 1.01M | tctx->decctx->acceleration.transform_bypass(residual, coeff, nT); |
449 | 1.01M | } |
450 | | |
451 | 1.04M | if (cIdx != 0) { |
452 | 327k | if (tctx->ResScaleVal != 0) { |
453 | 0 | cross_comp_pred(tctx, residual, nT); |
454 | 0 | } |
455 | 327k | } |
456 | | |
457 | 1.04M | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); |
458 | | |
459 | 1.04M | if (rotateCoeffs) { |
460 | 7.92k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around |
461 | 7.92k | } |
462 | 1.04M | } |
463 | 13.4M | else { |
464 | | // (8.6.3) |
465 | | |
466 | 13.4M | int bdShift = (cIdx==0 ? sps.BitDepth_Y : sps.BitDepth_C) + Log2(nT) - 5; |
467 | | |
468 | 13.4M | logtrace(LogTransform,"bdShift=%d\n",bdShift); |
469 | | |
470 | 13.4M | logtrace(LogTransform,"dequant %d;%d cIdx=%d qp=%d\n",xT*(cIdx?2:1),yT*(cIdx?2:1),cIdx,qP); |
471 | | |
472 | | |
473 | | // --- inverse quantization --- |
474 | | |
475 | 13.4M | if (sps.scaling_list_enable_flag==0) { |
476 | | |
477 | | //const int m_x_y = 16; |
478 | 13.2M | const int m_x_y = 1; |
479 | 13.2M | bdShift -= 4; // this is equivalent to having a m_x_y of 16 and we can use 32bit integers |
480 | | |
481 | 13.2M | const int offset = (1<<(bdShift-1)); |
482 | 13.2M | const int fact = m_x_y * levelScale[qP%6] << (qP/6); |
483 | | |
484 | | // Fast path: when coeffList[i]*fact (|coeffList| <= 32767) fits in int32, |
485 | | // the dequant can run in int32 SIMD. Otherwise (very high QP, high bit |
486 | | // depth) fall back to the scalar int64 loop. |
487 | 13.2M | if (fact <= 32767) { |
488 | 13.1M | tctx->decctx->acceleration.dequant_coeff_block(tctx->coeffBuf, |
489 | 13.1M | tctx->coeffList[cIdx], |
490 | 13.1M | tctx->coeffPos[cIdx], |
491 | 13.1M | tctx->nCoeff[cIdx], |
492 | 13.1M | fact, offset, bdShift); |
493 | 13.1M | } |
494 | 42.2k | else { |
495 | 310k | for (int i=0;i<tctx->nCoeff[cIdx];i++) { |
496 | 268k | int64_t currCoeff = tctx->coeffList[cIdx][i]; |
497 | 268k | currCoeff = Clip3(-32768,32767, |
498 | 268k | ( (currCoeff * fact + offset ) >> bdShift)); |
499 | 268k | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; |
500 | 268k | } |
501 | 42.2k | } |
502 | 13.2M | } |
503 | 277k | else { |
504 | 277k | const int offset = (1<<(bdShift-1)); |
505 | | |
506 | 277k | const uint8_t* sclist; |
507 | 277k | int matrixID = cIdx; |
508 | | |
509 | 277k | if (nT==32) { |
510 | 848 | matrixID=0; |
511 | 848 | } |
512 | | |
513 | 277k | if (!intra) { |
514 | 981 | if (nT<32) { matrixID += 3; } |
515 | 3 | else { matrixID++; } |
516 | 981 | } |
517 | | |
518 | 277k | switch (nT) { |
519 | 185k | case 4: sclist = &pps.scaling_list.ScalingFactor_Size0[matrixID][0][0]; break; |
520 | 41.3k | case 8: sclist = &pps.scaling_list.ScalingFactor_Size1[matrixID][0][0]; break; |
521 | 1.71k | case 16: sclist = &pps.scaling_list.ScalingFactor_Size2[matrixID][0][0]; break; |
522 | 848 | case 32: sclist = &pps.scaling_list.ScalingFactor_Size3[matrixID][0][0]; break; |
523 | 0 | default: assert(0); sclist = nullptr; |
524 | 277k | } |
525 | | |
526 | 1.67M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { |
527 | 1.44M | int pos = tctx->coeffPos[cIdx][i]; |
528 | | |
529 | 1.44M | const int m_x_y = sclist[pos]; |
530 | 1.44M | const int fact = m_x_y * levelScale[qP%6] << (qP/6); |
531 | | |
532 | 1.44M | int64_t currCoeff = tctx->coeffList[cIdx][i]; |
533 | | |
534 | 1.44M | currCoeff = Clip3(-32768,32767, |
535 | 1.44M | ( (currCoeff * fact + offset ) >> bdShift)); |
536 | | |
537 | 1.44M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; |
538 | 1.44M | } |
539 | 229k | } |
540 | | |
541 | | |
542 | | // --- do transform or skip --- |
543 | | |
544 | 13.4M | logtrace(LogTransform,"coefficients OUT:\n"); |
545 | 116M | for (int y=0;y<nT;y++) { |
546 | 103M | logtrace(LogTransform," "); |
547 | 1.38G | for (int x=0;x<nT;x++) { |
548 | 1.28G | logtrace(LogTransform,"*%3d ", coeff[x+y*coeffStride]); |
549 | 1.28G | } |
550 | 103M | logtrace(LogTransform,"*\n"); |
551 | 103M | } |
552 | | |
553 | | #ifdef DE265_LOG_TRACE |
554 | | int bdShift2 = (cIdx==0) ? 20-sps.BitDepth_Y : 20-sps.BitDepth_C; |
555 | | #endif |
556 | | |
557 | 13.4M | logtrace(LogTransform,"bdShift2=%d\n",bdShift2); |
558 | | |
559 | 13.4M | logtrace(LogSlice,"get_transform_skip_flag(%d,%d, cIdx=%d)=%d\n",xT,yT,cIdx, |
560 | 13.4M | transform_skip_flag); |
561 | | |
562 | 13.4M | if (transform_skip_flag) { |
563 | | |
564 | 115k | int extended_precision_processing_flag = 0; |
565 | 115k | int Log2nTbS = Log2(nT); |
566 | 115k | int bdShift = std::max( 20 - bit_depth, extended_precision_processing_flag ? 11 : 0 ); |
567 | 115k | int tsShift = (extended_precision_processing_flag ? std::min( 5, bdShift - 2 ) : 5 ) |
568 | 115k | + Log2nTbS; |
569 | | |
570 | 115k | if (rotateCoeffs) { |
571 | 34.6k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); |
572 | 34.6k | } |
573 | | |
574 | 115k | int32_t residual_buffer[32*32]; |
575 | | |
576 | 115k | int32_t* residual; |
577 | 115k | if (cIdx==0) residual = tctx->residual_luma; |
578 | 56.8k | else residual = residual_buffer; |
579 | | |
580 | 115k | if (rdpcmMode) { |
581 | | /* |
582 | | if (rdpcmMode==2) |
583 | | tctx->decctx->acceleration.transform_skip_rdpcm_v(pred,coeff, Log2(nT), stride, bit_depth); |
584 | | else |
585 | | tctx->decctx->acceleration.transform_skip_rdpcm_h(pred,coeff, Log2(nT), stride, bit_depth); |
586 | | */ |
587 | | |
588 | 998 | if (rdpcmMode==2) |
589 | 756 | tctx->decctx->acceleration.rdpcm_v(residual, coeff,nT, tsShift,bdShift); |
590 | 242 | else |
591 | 242 | tctx->decctx->acceleration.rdpcm_h(residual, coeff,nT, tsShift,bdShift); |
592 | 998 | } |
593 | 114k | else { |
594 | | //tctx->decctx->acceleration.transform_skip(pred, coeff, stride, bit_depth); |
595 | | |
596 | 114k | tctx->decctx->acceleration.transform_skip_residual(residual, coeff, nT, tsShift, bdShift); |
597 | 114k | } |
598 | | |
599 | 115k | if (cIdx != 0) { |
600 | 56.8k | if (tctx->ResScaleVal != 0) { |
601 | 0 | cross_comp_pred(tctx, residual, nT); |
602 | 0 | } |
603 | 56.8k | } |
604 | | |
605 | 115k | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); |
606 | | |
607 | 115k | if (rotateCoeffs) { |
608 | 34.6k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around |
609 | 34.6k | } |
610 | 115k | } |
611 | 13.3M | else { |
612 | 13.3M | int trType; |
613 | | |
614 | | //if (nT==4 && cIdx==0 && tctx->img->get_pred_mode(xT,yT)==MODE_INTRA) { |
615 | 13.3M | if (nT==4 && cIdx==0 && cuPredModeIntra) { |
616 | 4.23M | trType=1; |
617 | 4.23M | } |
618 | 9.08M | else { |
619 | 9.08M | trType=0; |
620 | 9.08M | } |
621 | | |
622 | 13.3M | assert(rdpcmMode==0); |
623 | | |
624 | | |
625 | 13.3M | if (tctx->img->get_pps().range_extension.cross_component_prediction_enabled_flag) { |
626 | | // cross-component-prediction: transform to residual buffer and add in a separate step |
627 | |
|
628 | 0 | transform_coefficients_explicit(tctx, coeff, coeffStride, nT, trType, |
629 | 0 | pred, stride, bit_depth, cIdx); |
630 | 0 | } |
631 | 13.3M | else { |
632 | 13.3M | transform_coefficients(&tctx->decctx->acceleration, coeff, coeffStride, nT, trType, |
633 | 13.3M | pred, stride, bit_depth); |
634 | 13.3M | } |
635 | 13.3M | } |
636 | 13.4M | } |
637 | | |
638 | | |
639 | 14.4M | logtrace(LogTransform,"pixels (cIdx:%d), position %d %d:\n",cIdx, xT,yT); |
640 | | |
641 | 121M | for (int y=0;y<nT;y++) { |
642 | 107M | logtrace(LogTransform,"RECO-%3d-%3d-%d ",xT,yT+y,cIdx); |
643 | | |
644 | 1.40G | for (int x=0;x<nT;x++) { |
645 | 1.30G | logtrace(LogTransform,"*%03x ", pred[x+y*stride]); |
646 | 1.30G | } |
647 | | |
648 | 107M | logtrace(LogTransform,"*\n"); |
649 | 107M | } |
650 | | |
651 | | // zero out scrap coefficient buffer again |
652 | | |
653 | 126M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { |
654 | 112M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = 0; |
655 | 112M | } |
656 | 14.4M | } void scale_coefficients_internal<unsigned short>(thread_context*, int, int, int, int, int, int, bool, bool, int) Line | Count | Source | 381 | 676k | { | 382 | 676k | const seq_parameter_set& sps = tctx->img->get_sps(); | 383 | 676k | const pic_parameter_set& pps = tctx->img->get_pps(); | 384 | | | 385 | 676k | int qP; | 386 | 676k | switch (cIdx) { | 387 | 500k | case 0: qP = tctx->qPYPrime; break; | 388 | 89.4k | case 1: qP = tctx->qPCbPrime; break; | 389 | 88.7k | case 2: qP = tctx->qPCrPrime; break; | 390 | 0 | default: qP = 0; assert(0); break; // should never happen | 391 | 676k | } | 392 | | | 393 | 676k | logtrace(LogTransform,"qP: %d\n",qP); | 394 | | | 395 | | | 396 | 676k | int16_t* coeff; | 397 | 676k | int coeffStride; | 398 | | | 399 | 676k | coeff = tctx->coeffBuf; | 400 | 676k | coeffStride = nT; | 401 | | | 402 | | | 403 | | | 404 | | | 405 | | | 406 | 676k | pixel_t* pred; | 407 | 676k | int stride; | 408 | 676k | pred = tctx->img->get_image_plane_at_pos_NEW<pixel_t>(cIdx, xT,yT); | 409 | 676k | stride = tctx->img->get_image_stride(cIdx); | 410 | | | 411 | | // We explicitly include the case for sizeof(pixel_t)==1 so that the compiler | 412 | | // can optimize away a lot of code for 8-bit pixels. | 413 | 676k | const int bit_depth = ((sizeof(pixel_t)==1) ? 8 : sps.get_bit_depth(cIdx)); | 414 | | | 415 | | //assert(intra == (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA)); | 416 | 676k | int cuPredModeIntra = (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA); | 417 | | | 418 | 676k | bool rotateCoeffs = (sps.range_extension.transform_skip_rotation_enabled_flag && | 419 | 64.4k | nT == 4 && | 420 | 52.0k | cuPredModeIntra); | 421 | | | 422 | 676k | if (tctx->cu_transquant_bypass_flag) { | 423 | | | 424 | 130k | int32_t residual_buffer[32*32]; | 425 | | | 426 | 130k | int32_t* residual; | 427 | 130k | if (cIdx==0) residual = tctx->residual_luma; | 428 | 15.8k | else residual = residual_buffer; | 429 | | | 430 | | | 431 | | // TODO: we could fold the coefficient rotation into the coefficient expansion here: | 432 | 853k | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 433 | 722k | int32_t currCoeff = tctx->coeffList[cIdx][i]; | 434 | 722k | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 435 | 722k | } | 436 | | | 437 | 130k | if (rotateCoeffs) { | 438 | 2.15k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); | 439 | 2.15k | } | 440 | | | 441 | 130k | if (rdpcmMode) { | 442 | 23.8k | if (rdpcmMode==2) | 443 | 11.9k | tctx->decctx->acceleration.transform_bypass_rdpcm_v(residual, coeff, nT); | 444 | 11.8k | else | 445 | 11.8k | tctx->decctx->acceleration.transform_bypass_rdpcm_h(residual, coeff, nT); | 446 | 23.8k | } | 447 | 106k | else { | 448 | 106k | tctx->decctx->acceleration.transform_bypass(residual, coeff, nT); | 449 | 106k | } | 450 | | | 451 | 130k | if (cIdx != 0) { | 452 | 15.8k | if (tctx->ResScaleVal != 0) { | 453 | 0 | cross_comp_pred(tctx, residual, nT); | 454 | 0 | } | 455 | 15.8k | } | 456 | | | 457 | 130k | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); | 458 | | | 459 | 130k | if (rotateCoeffs) { | 460 | 2.15k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around | 461 | 2.15k | } | 462 | 130k | } | 463 | 545k | else { | 464 | | // (8.6.3) | 465 | | | 466 | 545k | int bdShift = (cIdx==0 ? sps.BitDepth_Y : sps.BitDepth_C) + Log2(nT) - 5; | 467 | | | 468 | 545k | logtrace(LogTransform,"bdShift=%d\n",bdShift); | 469 | | | 470 | 545k | logtrace(LogTransform,"dequant %d;%d cIdx=%d qp=%d\n",xT*(cIdx?2:1),yT*(cIdx?2:1),cIdx,qP); | 471 | | | 472 | | | 473 | | // --- inverse quantization --- | 474 | | | 475 | 545k | if (sps.scaling_list_enable_flag==0) { | 476 | | | 477 | | //const int m_x_y = 16; | 478 | 514k | const int m_x_y = 1; | 479 | 514k | bdShift -= 4; // this is equivalent to having a m_x_y of 16 and we can use 32bit integers | 480 | | | 481 | 514k | const int offset = (1<<(bdShift-1)); | 482 | 514k | const int fact = m_x_y * levelScale[qP%6] << (qP/6); | 483 | | | 484 | | // Fast path: when coeffList[i]*fact (|coeffList| <= 32767) fits in int32, | 485 | | // the dequant can run in int32 SIMD. Otherwise (very high QP, high bit | 486 | | // depth) fall back to the scalar int64 loop. | 487 | 514k | if (fact <= 32767) { | 488 | 471k | tctx->decctx->acceleration.dequant_coeff_block(tctx->coeffBuf, | 489 | 471k | tctx->coeffList[cIdx], | 490 | 471k | tctx->coeffPos[cIdx], | 491 | 471k | tctx->nCoeff[cIdx], | 492 | 471k | fact, offset, bdShift); | 493 | 471k | } | 494 | 42.7k | else { | 495 | 311k | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 496 | 268k | int64_t currCoeff = tctx->coeffList[cIdx][i]; | 497 | 268k | currCoeff = Clip3(-32768,32767, | 498 | 268k | ( (currCoeff * fact + offset ) >> bdShift)); | 499 | 268k | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 500 | 268k | } | 501 | 42.7k | } | 502 | 514k | } | 503 | 31.2k | else { | 504 | 31.2k | const int offset = (1<<(bdShift-1)); | 505 | | | 506 | 31.2k | const uint8_t* sclist; | 507 | 31.2k | int matrixID = cIdx; | 508 | | | 509 | 31.2k | if (nT==32) { | 510 | 194 | matrixID=0; | 511 | 194 | } | 512 | | | 513 | 31.2k | if (!intra) { | 514 | 880 | if (nT<32) { matrixID += 3; } | 515 | 0 | else { matrixID++; } | 516 | 880 | } | 517 | | | 518 | 31.2k | switch (nT) { | 519 | 23.6k | case 4: sclist = &pps.scaling_list.ScalingFactor_Size0[matrixID][0][0]; break; | 520 | 5.77k | case 8: sclist = &pps.scaling_list.ScalingFactor_Size1[matrixID][0][0]; break; | 521 | 870 | case 16: sclist = &pps.scaling_list.ScalingFactor_Size2[matrixID][0][0]; break; | 522 | 194 | case 32: sclist = &pps.scaling_list.ScalingFactor_Size3[matrixID][0][0]; break; | 523 | 0 | default: assert(0); sclist = nullptr; | 524 | 31.2k | } | 525 | | | 526 | 271k | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 527 | 241k | int pos = tctx->coeffPos[cIdx][i]; | 528 | | | 529 | 241k | const int m_x_y = sclist[pos]; | 530 | 241k | const int fact = m_x_y * levelScale[qP%6] << (qP/6); | 531 | | | 532 | 241k | int64_t currCoeff = tctx->coeffList[cIdx][i]; | 533 | | | 534 | 241k | currCoeff = Clip3(-32768,32767, | 535 | 241k | ( (currCoeff * fact + offset ) >> bdShift)); | 536 | | | 537 | 241k | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 538 | 241k | } | 539 | 30.5k | } | 540 | | | 541 | | | 542 | | // --- do transform or skip --- | 543 | | | 544 | 544k | logtrace(LogTransform,"coefficients OUT:\n"); | 545 | 3.16M | for (int y=0;y<nT;y++) { | 546 | 2.61M | logtrace(LogTransform," "); | 547 | 19.4M | for (int x=0;x<nT;x++) { | 548 | 16.8M | logtrace(LogTransform,"*%3d ", coeff[x+y*coeffStride]); | 549 | 16.8M | } | 550 | 2.61M | logtrace(LogTransform,"*\n"); | 551 | 2.61M | } | 552 | | | 553 | | #ifdef DE265_LOG_TRACE | 554 | | int bdShift2 = (cIdx==0) ? 20-sps.BitDepth_Y : 20-sps.BitDepth_C; | 555 | | #endif | 556 | | | 557 | 544k | logtrace(LogTransform,"bdShift2=%d\n",bdShift2); | 558 | | | 559 | 544k | logtrace(LogSlice,"get_transform_skip_flag(%d,%d, cIdx=%d)=%d\n",xT,yT,cIdx, | 560 | 544k | transform_skip_flag); | 561 | | | 562 | 544k | if (transform_skip_flag) { | 563 | | | 564 | 29.7k | int extended_precision_processing_flag = 0; | 565 | 29.7k | int Log2nTbS = Log2(nT); | 566 | 29.7k | int bdShift = std::max( 20 - bit_depth, extended_precision_processing_flag ? 11 : 0 ); | 567 | 29.7k | int tsShift = (extended_precision_processing_flag ? std::min( 5, bdShift - 2 ) : 5 ) | 568 | 29.7k | + Log2nTbS; | 569 | | | 570 | 29.7k | if (rotateCoeffs) { | 571 | 27.7k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); | 572 | 27.7k | } | 573 | | | 574 | 29.7k | int32_t residual_buffer[32*32]; | 575 | | | 576 | 29.7k | int32_t* residual; | 577 | 29.7k | if (cIdx==0) residual = tctx->residual_luma; | 578 | 21.0k | else residual = residual_buffer; | 579 | | | 580 | 29.7k | if (rdpcmMode) { | 581 | | /* | 582 | | if (rdpcmMode==2) | 583 | | tctx->decctx->acceleration.transform_skip_rdpcm_v(pred,coeff, Log2(nT), stride, bit_depth); | 584 | | else | 585 | | tctx->decctx->acceleration.transform_skip_rdpcm_h(pred,coeff, Log2(nT), stride, bit_depth); | 586 | | */ | 587 | | | 588 | 540 | if (rdpcmMode==2) | 589 | 392 | tctx->decctx->acceleration.rdpcm_v(residual, coeff,nT, tsShift,bdShift); | 590 | 148 | else | 591 | 148 | tctx->decctx->acceleration.rdpcm_h(residual, coeff,nT, tsShift,bdShift); | 592 | 540 | } | 593 | 29.2k | else { | 594 | | //tctx->decctx->acceleration.transform_skip(pred, coeff, stride, bit_depth); | 595 | | | 596 | 29.2k | tctx->decctx->acceleration.transform_skip_residual(residual, coeff, nT, tsShift, bdShift); | 597 | 29.2k | } | 598 | | | 599 | 29.7k | if (cIdx != 0) { | 600 | 21.0k | if (tctx->ResScaleVal != 0) { | 601 | 0 | cross_comp_pred(tctx, residual, nT); | 602 | 0 | } | 603 | 21.0k | } | 604 | | | 605 | 29.7k | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); | 606 | | | 607 | 29.7k | if (rotateCoeffs) { | 608 | 27.7k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around | 609 | 27.7k | } | 610 | 29.7k | } | 611 | 515k | else { | 612 | 515k | int trType; | 613 | | | 614 | | //if (nT==4 && cIdx==0 && tctx->img->get_pred_mode(xT,yT)==MODE_INTRA) { | 615 | 515k | if (nT==4 && cIdx==0 && cuPredModeIntra) { | 616 | 273k | trType=1; | 617 | 273k | } | 618 | 241k | else { | 619 | 241k | trType=0; | 620 | 241k | } | 621 | | | 622 | 515k | assert(rdpcmMode==0); | 623 | | | 624 | | | 625 | 513k | if (tctx->img->get_pps().range_extension.cross_component_prediction_enabled_flag) { | 626 | | // cross-component-prediction: transform to residual buffer and add in a separate step | 627 | |
| 628 | 0 | transform_coefficients_explicit(tctx, coeff, coeffStride, nT, trType, | 629 | 0 | pred, stride, bit_depth, cIdx); | 630 | 0 | } | 631 | 513k | else { | 632 | 513k | transform_coefficients(&tctx->decctx->acceleration, coeff, coeffStride, nT, trType, | 633 | 513k | pred, stride, bit_depth); | 634 | 513k | } | 635 | 513k | } | 636 | 544k | } | 637 | | | 638 | | | 639 | 674k | logtrace(LogTransform,"pixels (cIdx:%d), position %d %d:\n",cIdx, xT,yT); | 640 | | | 641 | 3.90M | for (int y=0;y<nT;y++) { | 642 | 3.22M | logtrace(LogTransform,"RECO-%3d-%3d-%d ",xT,yT+y,cIdx); | 643 | | | 644 | 23.6M | for (int x=0;x<nT;x++) { | 645 | 20.4M | logtrace(LogTransform,"*%03x ", pred[x+y*stride]); | 646 | 20.4M | } | 647 | | | 648 | 3.22M | logtrace(LogTransform,"*\n"); | 649 | 3.22M | } | 650 | | | 651 | | // zero out scrap coefficient buffer again | 652 | | | 653 | 4.53M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 654 | 3.85M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = 0; | 655 | 3.85M | } | 656 | 674k | } |
void scale_coefficients_internal<unsigned char>(thread_context*, int, int, int, int, int, int, bool, bool, int) Line | Count | Source | 381 | 13.8M | { | 382 | 13.8M | const seq_parameter_set& sps = tctx->img->get_sps(); | 383 | 13.8M | const pic_parameter_set& pps = tctx->img->get_pps(); | 384 | | | 385 | 13.8M | int qP; | 386 | 13.8M | switch (cIdx) { | 387 | 8.78M | case 0: qP = tctx->qPYPrime; break; | 388 | 2.67M | case 1: qP = tctx->qPCbPrime; break; | 389 | 2.44M | case 2: qP = tctx->qPCrPrime; break; | 390 | 0 | default: qP = 0; assert(0); break; // should never happen | 391 | 13.8M | } | 392 | | | 393 | 13.8M | logtrace(LogTransform,"qP: %d\n",qP); | 394 | | | 395 | | | 396 | 13.8M | int16_t* coeff; | 397 | 13.8M | int coeffStride; | 398 | | | 399 | 13.8M | coeff = tctx->coeffBuf; | 400 | 13.8M | coeffStride = nT; | 401 | | | 402 | | | 403 | | | 404 | | | 405 | | | 406 | 13.8M | pixel_t* pred; | 407 | 13.8M | int stride; | 408 | 13.8M | pred = tctx->img->get_image_plane_at_pos_NEW<pixel_t>(cIdx, xT,yT); | 409 | 13.8M | stride = tctx->img->get_image_stride(cIdx); | 410 | | | 411 | | // We explicitly include the case for sizeof(pixel_t)==1 so that the compiler | 412 | | // can optimize away a lot of code for 8-bit pixels. | 413 | 13.8M | const int bit_depth = ((sizeof(pixel_t)==1) ? 8 : sps.get_bit_depth(cIdx)); | 414 | | | 415 | | //assert(intra == (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA)); | 416 | 13.8M | int cuPredModeIntra = (tctx->img->get_pred_mode(xT,yT)==MODE_INTRA); | 417 | | | 418 | 13.8M | bool rotateCoeffs = (sps.range_extension.transform_skip_rotation_enabled_flag && | 419 | 27.0k | nT == 4 && | 420 | 21.0k | cuPredModeIntra); | 421 | | | 422 | 13.8M | if (tctx->cu_transquant_bypass_flag) { | 423 | | | 424 | 909k | int32_t residual_buffer[32*32]; | 425 | | | 426 | 909k | int32_t* residual; | 427 | 909k | if (cIdx==0) residual = tctx->residual_luma; | 428 | 311k | else residual = residual_buffer; | 429 | | | 430 | | | 431 | | // TODO: we could fold the coefficient rotation into the coefficient expansion here: | 432 | 9.80M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 433 | 8.89M | int32_t currCoeff = tctx->coeffList[cIdx][i]; | 434 | 8.89M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 435 | 8.89M | } | 436 | | | 437 | 909k | if (rotateCoeffs) { | 438 | 5.77k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); | 439 | 5.77k | } | 440 | | | 441 | 909k | if (rdpcmMode) { | 442 | 3.78k | if (rdpcmMode==2) | 443 | 2.08k | tctx->decctx->acceleration.transform_bypass_rdpcm_v(residual, coeff, nT); | 444 | 1.69k | else | 445 | 1.69k | tctx->decctx->acceleration.transform_bypass_rdpcm_h(residual, coeff, nT); | 446 | 3.78k | } | 447 | 906k | else { | 448 | 906k | tctx->decctx->acceleration.transform_bypass(residual, coeff, nT); | 449 | 906k | } | 450 | | | 451 | 909k | if (cIdx != 0) { | 452 | 311k | if (tctx->ResScaleVal != 0) { | 453 | 0 | cross_comp_pred(tctx, residual, nT); | 454 | 0 | } | 455 | 311k | } | 456 | | | 457 | 909k | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); | 458 | | | 459 | 909k | if (rotateCoeffs) { | 460 | 5.77k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around | 461 | 5.77k | } | 462 | 909k | } | 463 | 12.9M | else { | 464 | | // (8.6.3) | 465 | | | 466 | 12.9M | int bdShift = (cIdx==0 ? sps.BitDepth_Y : sps.BitDepth_C) + Log2(nT) - 5; | 467 | | | 468 | 12.9M | logtrace(LogTransform,"bdShift=%d\n",bdShift); | 469 | | | 470 | 12.9M | logtrace(LogTransform,"dequant %d;%d cIdx=%d qp=%d\n",xT*(cIdx?2:1),yT*(cIdx?2:1),cIdx,qP); | 471 | | | 472 | | | 473 | | // --- inverse quantization --- | 474 | | | 475 | 12.9M | if (sps.scaling_list_enable_flag==0) { | 476 | | | 477 | | //const int m_x_y = 16; | 478 | 12.6M | const int m_x_y = 1; | 479 | 12.6M | bdShift -= 4; // this is equivalent to having a m_x_y of 16 and we can use 32bit integers | 480 | | | 481 | 12.6M | const int offset = (1<<(bdShift-1)); | 482 | 12.6M | const int fact = m_x_y * levelScale[qP%6] << (qP/6); | 483 | | | 484 | | // Fast path: when coeffList[i]*fact (|coeffList| <= 32767) fits in int32, | 485 | | // the dequant can run in int32 SIMD. Otherwise (very high QP, high bit | 486 | | // depth) fall back to the scalar int64 loop. | 487 | 12.6M | if (fact <= 32767) { | 488 | 12.6M | tctx->decctx->acceleration.dequant_coeff_block(tctx->coeffBuf, | 489 | 12.6M | tctx->coeffList[cIdx], | 490 | 12.6M | tctx->coeffPos[cIdx], | 491 | 12.6M | tctx->nCoeff[cIdx], | 492 | 12.6M | fact, offset, bdShift); | 493 | 12.6M | } | 494 | 18.4E | else { | 495 | 18.4E | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 496 | 0 | int64_t currCoeff = tctx->coeffList[cIdx][i]; | 497 | 0 | currCoeff = Clip3(-32768,32767, | 498 | 0 | ( (currCoeff * fact + offset ) >> bdShift)); | 499 | 0 | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 500 | 0 | } | 501 | 18.4E | } | 502 | 12.6M | } | 503 | 246k | else { | 504 | 246k | const int offset = (1<<(bdShift-1)); | 505 | | | 506 | 246k | const uint8_t* sclist; | 507 | 246k | int matrixID = cIdx; | 508 | | | 509 | 246k | if (nT==32) { | 510 | 654 | matrixID=0; | 511 | 654 | } | 512 | | | 513 | 246k | if (!intra) { | 514 | 101 | if (nT<32) { matrixID += 3; } | 515 | 3 | else { matrixID++; } | 516 | 101 | } | 517 | | | 518 | 246k | switch (nT) { | 519 | 161k | case 4: sclist = &pps.scaling_list.ScalingFactor_Size0[matrixID][0][0]; break; | 520 | 35.5k | case 8: sclist = &pps.scaling_list.ScalingFactor_Size1[matrixID][0][0]; break; | 521 | 845 | case 16: sclist = &pps.scaling_list.ScalingFactor_Size2[matrixID][0][0]; break; | 522 | 654 | case 32: sclist = &pps.scaling_list.ScalingFactor_Size3[matrixID][0][0]; break; | 523 | 0 | default: assert(0); sclist = nullptr; | 524 | 246k | } | 525 | | | 526 | 1.40M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 527 | 1.20M | int pos = tctx->coeffPos[cIdx][i]; | 528 | | | 529 | 1.20M | const int m_x_y = sclist[pos]; | 530 | 1.20M | const int fact = m_x_y * levelScale[qP%6] << (qP/6); | 531 | | | 532 | 1.20M | int64_t currCoeff = tctx->coeffList[cIdx][i]; | 533 | | | 534 | 1.20M | currCoeff = Clip3(-32768,32767, | 535 | 1.20M | ( (currCoeff * fact + offset ) >> bdShift)); | 536 | | | 537 | 1.20M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = currCoeff; | 538 | 1.20M | } | 539 | 199k | } | 540 | | | 541 | | | 542 | | // --- do transform or skip --- | 543 | | | 544 | 12.8M | logtrace(LogTransform,"coefficients OUT:\n"); | 545 | 113M | for (int y=0;y<nT;y++) { | 546 | 100M | logtrace(LogTransform," "); | 547 | 1.36G | for (int x=0;x<nT;x++) { | 548 | 1.26G | logtrace(LogTransform,"*%3d ", coeff[x+y*coeffStride]); | 549 | 1.26G | } | 550 | 100M | logtrace(LogTransform,"*\n"); | 551 | 100M | } | 552 | | | 553 | | #ifdef DE265_LOG_TRACE | 554 | | int bdShift2 = (cIdx==0) ? 20-sps.BitDepth_Y : 20-sps.BitDepth_C; | 555 | | #endif | 556 | | | 557 | 12.8M | logtrace(LogTransform,"bdShift2=%d\n",bdShift2); | 558 | | | 559 | 12.8M | logtrace(LogSlice,"get_transform_skip_flag(%d,%d, cIdx=%d)=%d\n",xT,yT,cIdx, | 560 | 12.8M | transform_skip_flag); | 561 | | | 562 | 12.8M | if (transform_skip_flag) { | 563 | | | 564 | 86.0k | int extended_precision_processing_flag = 0; | 565 | 86.0k | int Log2nTbS = Log2(nT); | 566 | 86.0k | int bdShift = std::max( 20 - bit_depth, extended_precision_processing_flag ? 11 : 0 ); | 567 | 86.0k | int tsShift = (extended_precision_processing_flag ? std::min( 5, bdShift - 2 ) : 5 ) | 568 | 86.0k | + Log2nTbS; | 569 | | | 570 | 86.0k | if (rotateCoeffs) { | 571 | 6.82k | tctx->decctx->acceleration.rotate_coefficients(coeff, nT); | 572 | 6.82k | } | 573 | | | 574 | 86.0k | int32_t residual_buffer[32*32]; | 575 | | | 576 | 86.0k | int32_t* residual; | 577 | 86.0k | if (cIdx==0) residual = tctx->residual_luma; | 578 | 35.8k | else residual = residual_buffer; | 579 | | | 580 | 86.0k | if (rdpcmMode) { | 581 | | /* | 582 | | if (rdpcmMode==2) | 583 | | tctx->decctx->acceleration.transform_skip_rdpcm_v(pred,coeff, Log2(nT), stride, bit_depth); | 584 | | else | 585 | | tctx->decctx->acceleration.transform_skip_rdpcm_h(pred,coeff, Log2(nT), stride, bit_depth); | 586 | | */ | 587 | | | 588 | 458 | if (rdpcmMode==2) | 589 | 364 | tctx->decctx->acceleration.rdpcm_v(residual, coeff,nT, tsShift,bdShift); | 590 | 94 | else | 591 | 94 | tctx->decctx->acceleration.rdpcm_h(residual, coeff,nT, tsShift,bdShift); | 592 | 458 | } | 593 | 85.5k | else { | 594 | | //tctx->decctx->acceleration.transform_skip(pred, coeff, stride, bit_depth); | 595 | | | 596 | 85.5k | tctx->decctx->acceleration.transform_skip_residual(residual, coeff, nT, tsShift, bdShift); | 597 | 85.5k | } | 598 | | | 599 | 86.0k | if (cIdx != 0) { | 600 | 35.8k | if (tctx->ResScaleVal != 0) { | 601 | 0 | cross_comp_pred(tctx, residual, nT); | 602 | 0 | } | 603 | 35.8k | } | 604 | | | 605 | 86.0k | tctx->decctx->acceleration.add_residual(pred,stride, residual,nT, bit_depth); | 606 | | | 607 | 86.0k | if (rotateCoeffs) { | 608 | 6.82k | memset(coeff, 0, nT*nT*sizeof(int16_t)); // delete all, because we moved the coeffs around | 609 | 6.82k | } | 610 | 86.0k | } | 611 | 12.8M | else { | 612 | 12.8M | int trType; | 613 | | | 614 | | //if (nT==4 && cIdx==0 && tctx->img->get_pred_mode(xT,yT)==MODE_INTRA) { | 615 | 12.8M | if (nT==4 && cIdx==0 && cuPredModeIntra) { | 616 | 3.96M | trType=1; | 617 | 3.96M | } | 618 | 8.84M | else { | 619 | 8.84M | trType=0; | 620 | 8.84M | } | 621 | | | 622 | 12.8M | assert(rdpcmMode==0); | 623 | | | 624 | | | 625 | 12.7M | if (tctx->img->get_pps().range_extension.cross_component_prediction_enabled_flag) { | 626 | | // cross-component-prediction: transform to residual buffer and add in a separate step | 627 | |
| 628 | 0 | transform_coefficients_explicit(tctx, coeff, coeffStride, nT, trType, | 629 | 0 | pred, stride, bit_depth, cIdx); | 630 | 0 | } | 631 | 12.7M | else { | 632 | 12.7M | transform_coefficients(&tctx->decctx->acceleration, coeff, coeffStride, nT, trType, | 633 | 12.7M | pred, stride, bit_depth); | 634 | 12.7M | } | 635 | 12.7M | } | 636 | 12.8M | } | 637 | | | 638 | | | 639 | 13.7M | logtrace(LogTransform,"pixels (cIdx:%d), position %d %d:\n",cIdx, xT,yT); | 640 | | | 641 | 117M | for (int y=0;y<nT;y++) { | 642 | 103M | logtrace(LogTransform,"RECO-%3d-%3d-%d ",xT,yT+y,cIdx); | 643 | | | 644 | 1.38G | for (int x=0;x<nT;x++) { | 645 | 1.28G | logtrace(LogTransform,"*%03x ", pred[x+y*stride]); | 646 | 1.28G | } | 647 | | | 648 | 103M | logtrace(LogTransform,"*\n"); | 649 | 103M | } | 650 | | | 651 | | // zero out scrap coefficient buffer again | 652 | | | 653 | 122M | for (int i=0;i<tctx->nCoeff[cIdx];i++) { | 654 | 108M | tctx->coeffBuf[ tctx->coeffPos[cIdx][i] ] = 0; | 655 | 108M | } | 656 | 13.7M | } |
|
657 | | |
658 | | |
659 | | void scale_coefficients(thread_context* tctx, |
660 | | int xT,int yT, // position of TU in frame (chroma adapted) |
661 | | int x0,int y0, // position of CU in frame (chroma adapted) |
662 | | int nT, int cIdx, |
663 | | bool transform_skip_flag, bool intra, |
664 | | int rdpcmMode // 0 - off, 1 - Horizontal, 2 - Vertical |
665 | | ) |
666 | 14.5M | { |
667 | 14.5M | if (tctx->img->high_bit_depth(cIdx)) { |
668 | 676k | scale_coefficients_internal<uint16_t>(tctx, xT,yT, x0,y0, nT,cIdx, transform_skip_flag, intra, |
669 | 676k | rdpcmMode); |
670 | 13.8M | } else { |
671 | 13.8M | scale_coefficients_internal<uint8_t> (tctx, xT,yT, x0,y0, nT,cIdx, transform_skip_flag, intra, |
672 | 13.8M | rdpcmMode); |
673 | 13.8M | } |
674 | 14.5M | } |
675 | | |
676 | | |
677 | | //#define QUANT_IQUANT_SHIFT 20 // Q(QP%6) * IQ(QP%6) = 2^20 |
678 | 0 | #define QUANT_SHIFT 14 // Q(4) = 2^14 |
679 | | //#define SCALE_BITS 15 // Inherited from TMuC, presumably for fractional bit estimates in RDOQ |
680 | 0 | #define MAX_TR_DYNAMIC_RANGE 15 // Maximum transform dynamic range (excluding sign bit) |
681 | | |
682 | | |
683 | | const static uint16_t g_quantScales[6] = { |
684 | | 26214,23302,20560,18396,16384,14564 |
685 | | }; |
686 | | |
687 | | void quant_coefficients(//encoder_context* ectx, |
688 | | int16_t* out_coeff, |
689 | | const int16_t* in_coeff, |
690 | | int log2TrSize, int qp, |
691 | | bool intra) |
692 | 0 | { |
693 | 0 | const int qpDiv6 = qp / 6; |
694 | 0 | const int qpMod6 = qp % 6; |
695 | | |
696 | | //int uiLog2TrSize = xLog2( iWidth - 1); |
697 | |
|
698 | 0 | int uiQ = g_quantScales[qpMod6]; |
699 | 0 | int bitDepth = 8; |
700 | 0 | int transformShift = MAX_TR_DYNAMIC_RANGE - bitDepth - log2TrSize; // Represents scaling through forward transform |
701 | 0 | int qBits = QUANT_SHIFT + qpDiv6 + transformShift; |
702 | | |
703 | | /* TODO: originally, this was checking for intra slices, why not for intra mode ? |
704 | | */ |
705 | 0 | int rnd = (intra ? 171 : 85) << (qBits-9); |
706 | |
|
707 | 0 | int x, y; |
708 | |
|
709 | 0 | int nStride = (1<<log2TrSize); |
710 | |
|
711 | 0 | for (y=0; y < (1<<log2TrSize) ; y++) { |
712 | 0 | for (x=0; x < (1<<log2TrSize) ; x++) { |
713 | 0 | int level; |
714 | 0 | int sign; |
715 | 0 | int blockPos = y * nStride + x; |
716 | 0 | level = in_coeff[blockPos]; |
717 | | //logtrace(LogTransform,"(%d,%d) %d -> ", x,y,level); |
718 | 0 | sign = (level < 0 ? -1: 1); |
719 | |
|
720 | 0 | level = (std::abs(level) * uiQ + rnd ) >> qBits; |
721 | 0 | level *= sign; |
722 | 0 | out_coeff[blockPos] = Clip3(-32768, 32767, level); |
723 | | //logtrace(LogTransform,"%d\n", out_coeff[blockPos]); |
724 | 0 | } |
725 | 0 | } |
726 | 0 | } |
727 | | |
728 | | |
729 | | void dequant_coefficients(int16_t* out_coeff, |
730 | | const int16_t* in_coeff, |
731 | | int log2TrSize, int qP) |
732 | 0 | { |
733 | 0 | const int m_x_y = 1; |
734 | 0 | int bitDepth = 8; |
735 | 0 | int bdShift = bitDepth + log2TrSize - 5; |
736 | 0 | bdShift -= 4; // this is equivalent to having a m_x_y of 16 and we can use 32bit integers |
737 | |
|
738 | 0 | const int offset = (1<<(bdShift-1)); |
739 | 0 | const int fact = m_x_y * levelScale[qP%6] << (qP/6); |
740 | | |
741 | | //int blkSize = (1<<log2TrSize); |
742 | 0 | int nCoeff = (1<<(log2TrSize<<1)); |
743 | |
|
744 | 0 | for (int i=0;i<nCoeff;i++) { |
745 | | |
746 | | // usually, this needs to be 64bit, but because we modify the shift above, we can use 16 bit |
747 | 0 | int32_t currCoeff = in_coeff[i]; |
748 | | |
749 | | //logtrace(LogTransform,"coefficient[%d] = %d\n",i,currCoeff); |
750 | |
|
751 | 0 | currCoeff = Clip3(-32768,32767, |
752 | 0 | ( (currCoeff * fact + offset ) >> bdShift)); |
753 | | |
754 | | //logtrace(LogTransform," -> %d\n",currCoeff); |
755 | |
|
756 | 0 | out_coeff[i] = currCoeff; |
757 | 0 | } |
758 | 0 | } |