Coverage Report

Created: 2026-10-27 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}