Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libde265/libde265/deblock.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 "deblock.h"
22
#include "util.h"
23
#include "transform.h"
24
#include "de265.h"
25
#include "decctx.h"
26
#include "fallback-deblk.h"
27
28
#include <assert.h>
29
30
31
32
// 8.7.2.1 for both EDGE_HOR and EDGE_VER at the same time
33
void markTransformBlockBoundary(de265_image* img, int x0,int y0,
34
                                int log2TrafoSize,int trafoDepth,
35
                                int filterLeftCbEdge, int filterTopCbEdge)
36
44.0M
{
37
44.0M
  logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0,
38
44.0M
           log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge);
39
40
44.0M
  int split_transform = img->get_split_transform_flag(x0,y0,trafoDepth);
41
44.0M
  if (split_transform) {
42
8.11M
    int x1 = x0 + ((1<<log2TrafoSize)>>1);
43
8.11M
    int y1 = y0 + ((1<<log2TrafoSize)>>1);
44
45
8.11M
    markTransformBlockBoundary(img,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   filterTopCbEdge);
46
8.11M
    markTransformBlockBoundary(img,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge);
47
8.11M
    markTransformBlockBoundary(img,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   DEBLOCK_FLAG_HORIZ);
48
8.11M
    markTransformBlockBoundary(img,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ);
49
8.11M
  }
50
35.9M
  else {
51
    // VER
52
53
84.1M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
54
48.2M
      img->set_deblk_flags(x0,y0+k, filterLeftCbEdge);
55
48.2M
    }
56
57
    // HOR
58
59
84.1M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
60
48.2M
      img->set_deblk_flags(x0+k,y0, filterTopCbEdge);
61
48.2M
    }
62
35.9M
  }
63
44.0M
}
64
65
66
67
// 8.7.2.2 for both EDGE_HOR and EDGE_VER at the same time
68
void markPredictionBlockBoundary(de265_image* img, int x0,int y0,
69
                                 int log2CbSize,
70
                                 int filterLeftCbEdge, int filterTopCbEdge)
71
11.5M
{
72
11.5M
  logtrace(LogDeblock,"markPredictionBlockBoundary(%d,%d, %d, %d,%d)\n",x0,y0,
73
11.5M
           log2CbSize, filterLeftCbEdge,filterTopCbEdge);
74
75
11.5M
  enum PartMode partMode = img->get_PartMode(x0,y0);
76
77
11.5M
  int cbSize = 1<<log2CbSize;
78
11.5M
  int cbSize2 = 1<<(log2CbSize-1);
79
11.5M
  int cbSize4 = 1<<(log2CbSize-2);
80
81
11.5M
  switch (partMode) {
82
5.76M
  case PART_NxN:
83
51.9M
    for (int k=0;k<cbSize;k++) {
84
46.1M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
85
46.1M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
86
46.1M
    }
87
5.76M
    break;
88
89
109k
  case PART_Nx2N:
90
1.19M
    for (int k=0;k<cbSize;k++) {
91
1.08M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
92
1.08M
    }
93
109k
    break;
94
95
77.6k
  case PART_2NxN:
96
851k
    for (int k=0;k<cbSize;k++) {
97
773k
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
98
773k
    }
99
77.6k
    break;
100
101
5.23k
  case PART_nLx2N:
102
145k
    for (int k=0;k<cbSize;k++) {
103
140k
      img->set_deblk_flags(x0+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
104
140k
    }
105
5.23k
    break;
106
107
2.09k
  case PART_nRx2N:
108
58.9k
    for (int k=0;k<cbSize;k++) {
109
56.8k
      img->set_deblk_flags(x0+cbSize2+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
110
56.8k
    }
111
2.09k
    break;
112
113
4.01k
  case PART_2NxnU:
114
116k
    for (int k=0;k<cbSize;k++) {
115
112k
      img->set_deblk_flags(x0+k,y0+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
116
112k
    }
117
4.01k
    break;
118
119
1.76k
  case PART_2NxnD:
120
47.7k
    for (int k=0;k<cbSize;k++) {
121
45.9k
      img->set_deblk_flags(x0+k,y0+cbSize2+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
122
45.9k
    }
123
1.76k
    break;
124
125
5.60M
  case PART_2Nx2N:
126
    // NOP
127
5.60M
    break;
128
11.5M
  }
129
11.5M
}
130
131
132
bool derive_edgeFlags_CTBRow(de265_image* img, uint16_t ctby)
133
59.6k
{
134
59.6k
  const seq_parameter_set& sps = img->get_sps();
135
59.6k
  const pic_parameter_set& pps = img->get_pps();
136
137
59.6k
  const int minCbSize = sps.MinCbSizeY;
138
59.6k
  bool deblocking_enabled=false; // whether deblocking is enabled in some part of the image
139
140
59.6k
  int ctb_mask = (1<<sps.Log2CtbSizeY)-1;
141
59.6k
  int picWidthInCtbs = sps.PicWidthInCtbsY;
142
59.6k
  int ctbshift = sps.Log2CtbSizeY;
143
144
145
59.6k
  uint16_t cb_y_start = ( ctby    << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
146
59.6k
  uint16_t cb_y_end   = ((ctby+1) << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
147
148
59.6k
  cb_y_end = std::min(cb_y_end, sps.PicHeightInMinCbsY);
149
150
408k
  for (int cb_y=cb_y_start;cb_y<cb_y_end;cb_y++)
151
33.6M
    for (int cb_x=0;cb_x<img->get_sps().PicWidthInMinCbsY;cb_x++)
152
33.3M
      {
153
33.3M
        int log2CbSize = img->get_log2CbSize_cbUnits(cb_x,cb_y);
154
33.3M
        if (log2CbSize==0) {
155
21.4M
          continue;
156
21.4M
        }
157
158
        // we are now at the top corner of a CB
159
160
11.8M
        int x0 = cb_x * minCbSize;
161
11.8M
        int y0 = cb_y * minCbSize;
162
163
11.8M
        int x0ctb = x0 >> ctbshift;
164
11.8M
        int y0ctb = y0 >> ctbshift;
165
166
        // check for corrupted streams
167
11.8M
        if (img->is_SliceHeader_available(x0,y0)==false) {
168
4
          return false;
169
4
        }
170
171
        // check whether we should filter this slice
172
173
11.8M
        slice_segment_header* shdr = img->get_SliceHeader(x0,y0);
174
175
        // check whether to filter left and top edge
176
177
11.8M
        uint8_t filterLeftCbEdge = DEBLOCK_FLAG_VERTI;
178
11.8M
        uint8_t filterTopCbEdge  = DEBLOCK_FLAG_HORIZ;
179
11.8M
        if (x0 == 0) filterLeftCbEdge = 0;
180
11.8M
        if (y0 == 0) filterTopCbEdge  = 0;
181
182
        // check for slice and tile boundaries (8.7.2, step 2 in both processes)
183
184
11.8M
        if (x0 && ((x0 & ctb_mask) == 0)) { // left edge at CTB boundary
185
1.83M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
186
185k
              img->is_SliceHeader_available(x0-1,y0) && // for corrupted streams
187
185k
              shdr->SliceAddrRS != img->get_SliceHeader(x0-1,y0)->SliceAddrRS)
188
542
            {
189
542
              filterLeftCbEdge = 0;
190
542
            }
191
1.83M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
192
1.82M
                   pps.scan->TileIdRS[  x0ctb           +y0ctb*picWidthInCtbs] !=
193
1.82M
                   pps.scan->TileIdRS[((x0-1)>>ctbshift)+y0ctb*picWidthInCtbs]) {
194
2.46k
            filterLeftCbEdge = 0;
195
2.46k
          }
196
1.83M
        }
197
198
11.8M
        if (y0 && ((y0 & ctb_mask) == 0)) { // top edge at CTB boundary
199
1.63M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
200
138k
              img->is_SliceHeader_available(x0,y0-1) && // for corrupted streams
201
138k
              shdr->SliceAddrRS != img->get_SliceHeader(x0,y0-1)->SliceAddrRS)
202
1.15k
            {
203
1.15k
              filterTopCbEdge = 0;
204
1.15k
            }
205
1.63M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
206
1.63M
                   pps.scan->TileIdRS[x0ctb+  y0ctb           *picWidthInCtbs] !=
207
1.63M
                   pps.scan->TileIdRS[x0ctb+((y0-1)>>ctbshift)*picWidthInCtbs]) {
208
0
            filterTopCbEdge = 0;
209
0
          }
210
1.63M
        }
211
212
213
        // mark edges
214
215
11.8M
        if (shdr->slice_deblocking_filter_disabled_flag==0) {
216
11.5M
          deblocking_enabled=true;
217
218
11.5M
          markTransformBlockBoundary(img, x0,y0, log2CbSize,0,
219
11.5M
                                     filterLeftCbEdge, filterTopCbEdge);
220
221
11.5M
          markPredictionBlockBoundary(img, x0,y0, log2CbSize,
222
11.5M
                                      filterLeftCbEdge, filterTopCbEdge);
223
11.5M
        }
224
11.8M
      }
225
226
59.6k
  return deblocking_enabled;
227
59.6k
}
228
229
230
bool derive_edgeFlags(de265_image* img)
231
0
{
232
0
  bool deblocking_enabled=false;
233
234
0
  for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++) {
235
0
    deblocking_enabled |= derive_edgeFlags_CTBRow(img,y);
236
0
  }
237
238
0
  return deblocking_enabled;
239
0
}
240
241
242
// 8.7.2.3 (both, EDGE_VER and EDGE_HOR)
243
void derive_boundaryStrength(de265_image* img, bool vertical, int yStart,int yEnd,
244
                             int xStart,int xEnd)
245
96.6k
{
246
96.6k
  int xIncr = vertical ? 2 : 1;
247
96.6k
  int yIncr = vertical ? 1 : 2;
248
96.6k
  int xOffs = vertical ? 1 : 0;
249
96.6k
  int yOffs = vertical ? 0 : 1;
250
96.6k
  int edgeMask = vertical ?
251
48.3k
    (DEBLOCK_FLAG_VERTI | DEBLOCK_PB_EDGE_VERTI) :
252
96.6k
    (DEBLOCK_FLAG_HORIZ | DEBLOCK_PB_EDGE_HORIZ);
253
96.6k
  int transformEdgeMask = vertical ? DEBLOCK_FLAG_VERTI : DEBLOCK_FLAG_HORIZ;
254
255
96.6k
  xEnd = std::min(xEnd,img->get_deblk_width());
256
96.6k
  yEnd = std::min(yEnd,img->get_deblk_height());
257
258
  //int TUShift = img->get_sps().Log2MinTrafoSize;
259
  //int TUStride= img->get_sps().PicWidthInTbsY;
260
261
968k
  for (int y=yStart;y<yEnd;y+=yIncr)
262
109M
    for (int x=xStart;x<xEnd;x+=xIncr) {
263
108M
      int xDi = x<<2;
264
108M
      int yDi = y<<2;
265
266
108M
      logtrace(LogDeblock,"%d %d %s = %s\n",xDi,yDi, vertical?"Vertical":"Horizontal",
267
108M
               (img->get_deblk_flags(xDi,yDi) & edgeMask) ? "edge" : "...");
268
269
108M
      uint8_t edgeFlags = img->get_deblk_flags(xDi,yDi);
270
271
108M
      if (edgeFlags & edgeMask) {
272
64.7M
        bool p_is_intra_pred = (img->get_pred_mode(xDi-xOffs, yDi-yOffs) == MODE_INTRA);
273
64.7M
        bool q_is_intra_pred = (img->get_pred_mode(xDi,       yDi      ) == MODE_INTRA);
274
275
64.7M
        int bS;
276
277
64.7M
        if (p_is_intra_pred || q_is_intra_pred) {
278
61.3M
          bS = 2;
279
61.3M
        }
280
3.40M
        else {
281
          // opposing site
282
3.40M
          int xDiOpp = xDi-xOffs;
283
3.40M
          int yDiOpp = yDi-yOffs;
284
285
3.40M
          if ((edgeFlags & transformEdgeMask) &&
286
3.27M
              (img->get_nonzero_coefficient(xDi   ,yDi) ||
287
2.44M
               img->get_nonzero_coefficient(xDiOpp,yDiOpp))) {
288
1.09M
            bS = 1;
289
1.09M
          }
290
2.30M
          else {
291
292
2.30M
            bS = 0;
293
294
2.30M
            const PBMotion& mviP = img->get_mv_info(xDiOpp,yDiOpp);
295
2.30M
            const PBMotion& mviQ = img->get_mv_info(xDi   ,yDi);
296
297
2.30M
            slice_segment_header* shdrP = img->get_SliceHeader(xDiOpp,yDiOpp);
298
2.30M
            slice_segment_header* shdrQ = img->get_SliceHeader(xDi   ,yDi);
299
300
2.30M
      if (shdrP && shdrQ) {
301
302
2.30M
        int refPicP0 = mviP.predFlag[0] ? shdrP->RefPicList[0][ mviP.refIdx[0] ] : -1;
303
2.30M
        int refPicP1 = mviP.predFlag[1] ? shdrP->RefPicList[1][ mviP.refIdx[1] ] : -1;
304
2.30M
        int refPicQ0 = mviQ.predFlag[0] ? shdrQ->RefPicList[0][ mviQ.refIdx[0] ] : -1;
305
2.30M
        int refPicQ1 = mviQ.predFlag[1] ? shdrQ->RefPicList[1][ mviQ.refIdx[1] ] : -1;
306
307
2.30M
        bool samePics = ((refPicP0==refPicQ0 && refPicP1==refPicQ1) ||
308
330k
             (refPicP0==refPicQ1 && refPicP1==refPicQ0));
309
310
2.30M
        if (!samePics) {
311
305k
    bS = 1;
312
305k
        }
313
2.00M
        else {
314
2.00M
    MotionVector mvP0 = mviP.mv[0]; if (!mviP.predFlag[0]) { mvP0.x=mvP0.y=0; }
315
2.00M
    MotionVector mvP1 = mviP.mv[1]; if (!mviP.predFlag[1]) { mvP1.x=mvP1.y=0; }
316
2.00M
    MotionVector mvQ0 = mviQ.mv[0]; if (!mviQ.predFlag[0]) { mvQ0.x=mvQ0.y=0; }
317
2.00M
    MotionVector mvQ1 = mviQ.mv[1]; if (!mviQ.predFlag[1]) { mvQ1.x=mvQ1.y=0; }
318
319
2.00M
    int numMV_P = mviP.predFlag[0] + mviP.predFlag[1];
320
2.00M
    int numMV_Q = mviQ.predFlag[0] + mviQ.predFlag[1];
321
322
2.00M
    if (numMV_P!=numMV_Q) {
323
0
      img->decctx->add_warning(DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ, false);
324
0
      img->integrity = INTEGRITY_DECODING_ERRORS;
325
0
    }
326
327
    // two different reference pictures or only one reference picture
328
2.00M
    if (refPicP0 != refPicP1) {
329
330
966k
      if (refPicP0 == refPicQ0) {
331
941k
        if (std::abs(mvP0.x-mvQ0.x) >= 4 ||
332
882k
      std::abs(mvP0.y-mvQ0.y) >= 4 ||
333
863k
      std::abs(mvP1.x-mvQ1.x) >= 4 ||
334
859k
      std::abs(mvP1.y-mvQ1.y) >= 4) {
335
83.2k
          bS = 1;
336
83.2k
        }
337
941k
      }
338
25.7k
      else {
339
25.7k
        if (std::abs(mvP0.x-mvQ1.x) >= 4 ||
340
21.9k
      std::abs(mvP0.y-mvQ1.y) >= 4 ||
341
19.7k
      std::abs(mvP1.x-mvQ0.x) >= 4 ||
342
15.9k
      std::abs(mvP1.y-mvQ0.y) >= 4) {
343
11.5k
          bS = 1;
344
11.5k
        }
345
25.7k
      }
346
966k
    }
347
1.03M
    else {
348
1.03M
      assert(refPicQ0==refPicQ1);
349
350
1.03M
      if ((std::abs(mvP0.x-mvQ0.x) >= 4 ||
351
1.00M
           std::abs(mvP0.y-mvQ0.y) >= 4 ||
352
989k
           std::abs(mvP1.x-mvQ1.x) >= 4 ||
353
981k
           std::abs(mvP1.y-mvQ1.y) >= 4)
354
60.2k
          &&
355
60.2k
          (std::abs(mvP0.x-mvQ1.x) >= 4 ||
356
32.8k
           std::abs(mvP0.y-mvQ1.y) >= 4 ||
357
19.9k
           std::abs(mvP1.x-mvQ0.x) >= 4 ||
358
58.8k
           std::abs(mvP1.y-mvQ0.y) >= 4)) {
359
58.8k
        bS = 1;
360
58.8k
      }
361
1.03M
    }
362
2.00M
        }
363
2.30M
      }
364
18.4E
      else {
365
18.4E
        bS = 0; // if shdrP==nullptr or shdrQ==nullptr
366
18.4E
      }
367
368
            /*
369
              printf("unimplemented deblocking code for CU at %d;%d\n",xDi,yDi);
370
371
              logerror(LogDeblock, "unimplemented code reached (file %s, line %d)\n",
372
              __FILE__, __LINE__);
373
            */
374
2.30M
          }
375
3.40M
        }
376
377
64.7M
        img->set_deblk_bS(xDi,yDi, bS);
378
64.7M
      }
379
44.1M
      else {
380
44.1M
        img->set_deblk_bS(xDi,yDi, 0);
381
44.1M
      }
382
108M
    }
383
96.6k
}
384
385
386
void derive_boundaryStrength_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
387
0
{
388
0
  int ctbSize = img->get_sps().CtbSizeY;
389
0
  int deblkSize = ctbSize/4;
390
391
0
  derive_boundaryStrength(img,vertical,
392
0
                          yCtb*deblkSize, (yCtb+1)*deblkSize,
393
0
                          xCtb*deblkSize, (xCtb+1)*deblkSize);
394
0
}
395
396
397
static uint8_t table_8_23_beta[52] = {
398
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8,
399
   9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,32,34,36,
400
  38,40,42,44,46,48,50,52,54,56,58,60,62,64
401
};
402
403
static uint8_t table_8_23_tc[54] = {
404
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
405
   1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
406
   5, 5, 6, 6, 7, 8, 9,10,11,13,14,16,18,20,22,24
407
};
408
409
410
411
// 8.7.2.4
412
template <class pixel_t>
413
void edge_filtering_luma_internal(de265_image* img, bool vertical,
414
                                  int yStart,int yEnd, int xStart,int xEnd)
415
96.6k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
96.6k
  const seq_parameter_set& sps = img->get_sps();
419
420
96.6k
  int xIncr = vertical ? 2 : 1;
421
96.6k
  int yIncr = vertical ? 1 : 2;
422
423
96.6k
  const int stride = img->get_image_stride(0);
424
425
96.6k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
96.6k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
96.6k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
968k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
109M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
108M
      int xDi = x<<2; // *4 -> pixel resolution
435
108M
      int yDi = y<<2; // *4 -> pixel resolution
436
108M
      int bS = img->get_deblk_bS(xDi,yDi);
437
438
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
439
440
108M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
108M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
442
443
#if 0
444
      {
445
        uint8_t* ptr = img->y + stride*yDi + xDi;
446
447
        for (int dy=-4;dy<4;dy++) {
448
          for (int dx=-4;dx<4;dx++) {
449
            printf("%02x ", ptr[dy*stride + dx]);
450
            if (dx==-1) printf("| ");
451
          }
452
          printf("\n");
453
          if (dy==-1) printf("-------------------------\n");
454
        }
455
      }
456
#endif
457
458
#if 0
459
      if (!vertical)
460
        {
461
          uint8_t* ptr = img->y + stride*yDi + xDi;
462
463
          for (int dy=-4;dy<4;dy++) {
464
            for (int dx=0;dx<4;dx++) {
465
              printf("%02x ", ptr[dy*stride + dx]);
466
              if (dx==-1) printf("| ");
467
            }
468
            printf("\n");
469
            if (dy==-1) printf("-------------------------\n");
470
          }
471
        }
472
#endif
473
474
108M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
62.7M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
62.7M
        pixel_t q[4][4], p[4][4];
481
311M
        for (int k=0;k<4;k++)
482
1.24G
          for (int i=0;i<4;i++)
483
995M
            {
484
995M
              if (vertical) {
485
505M
                q[k][i] = ptr[ i  +k*stride];
486
505M
                p[k][i] = ptr[-i-1+k*stride];
487
505M
              }
488
490M
              else {
489
490M
                q[k][i] = ptr[k + i   *stride];
490
490M
                p[k][i] = ptr[k -(i+1)*stride];
491
490M
              }
492
995M
            }
493
494
#if 0
495
        for (int k=0;k<4;k++)
496
          {
497
            for (int i=0;i<4;i++)
498
              {
499
                printf("%02x ", p[k][3-i]);
500
              }
501
502
            printf("| ");
503
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", q[k][i]);
507
              }
508
            printf("\n");
509
          }
510
#endif
511
512
513
62.7M
        int QP_Q = img->get_QPY(xDi,yDi);
514
62.7M
        int QP_P = (vertical ?
515
31.7M
                    img->get_QPY(xDi-1,yDi) :
516
62.7M
                    img->get_QPY(xDi,yDi-1) );
517
62.7M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
62.7M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
62.7M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
62.7M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
62.7M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
62.7M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
62.7M
        int betaPrime = table_8_23_beta[Q_beta];
527
62.7M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
62.7M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
62.7M
        int tcPrime = table_8_23_tc[Q_tc];
531
62.7M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
62.7M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
62.7M
        int dE=0, dEp=0, dEq=0;
536
537
62.7M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
62.7M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
62.7M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
62.7M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
62.7M
        int dpq0 = dp0 + dq0;
543
62.7M
        int dpq3 = dp3 + dq3;
544
545
62.7M
        int dp = dp0 + dp3;
546
62.7M
        int dq = dq0 + dq3;
547
62.7M
        int d = dpq0 + dpq3;
548
549
62.7M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
33.1M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
19.5M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
9.00M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
33.1M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
21.5M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
10.4M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
33.1M
          if (dSam0 && dSam3) {
560
6.82M
            dE = 2;
561
6.82M
          }
562
26.2M
          else {
563
26.2M
            dE = 1;
564
26.2M
          }
565
566
33.1M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
33.1M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
33.1M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
33.1M
        }
571
572
573
        // 8.7.2.4.4
574
575
62.7M
        if (dE != 0) {
576
33.1M
          bool filterP = true;
577
33.1M
          bool filterQ = true;
578
579
33.1M
          if (vertical) {
580
15.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
15.6M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
15.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
15.6M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
15.6M
          }
586
17.4M
          else {
587
17.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
17.4M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
17.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
17.4M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
17.4M
          }
593
594
33.1M
          if constexpr (sizeof(pixel_t)==1) {
595
30.7M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
30.7M
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
2.42M
          else {
599
2.42M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
2.42M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
2.42M
          }
602
33.1M
        }
603
62.7M
      }
604
108M
    }
605
96.6k
}
void edge_filtering_luma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
29.4k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
29.4k
  const seq_parameter_set& sps = img->get_sps();
419
420
29.4k
  int xIncr = vertical ? 2 : 1;
421
29.4k
  int yIncr = vertical ? 1 : 2;
422
423
29.4k
  const int stride = img->get_image_stride(0);
424
425
29.4k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
29.4k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
29.4k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
234k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
12.1M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
11.9M
      int xDi = x<<2; // *4 -> pixel resolution
435
11.9M
      int yDi = y<<2; // *4 -> pixel resolution
436
11.9M
      int bS = img->get_deblk_bS(xDi,yDi);
437
438
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
439
440
11.9M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
11.9M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
442
443
#if 0
444
      {
445
        uint8_t* ptr = img->y + stride*yDi + xDi;
446
447
        for (int dy=-4;dy<4;dy++) {
448
          for (int dx=-4;dx<4;dx++) {
449
            printf("%02x ", ptr[dy*stride + dx]);
450
            if (dx==-1) printf("| ");
451
          }
452
          printf("\n");
453
          if (dy==-1) printf("-------------------------\n");
454
        }
455
      }
456
#endif
457
458
#if 0
459
      if (!vertical)
460
        {
461
          uint8_t* ptr = img->y + stride*yDi + xDi;
462
463
          for (int dy=-4;dy<4;dy++) {
464
            for (int dx=0;dx<4;dx++) {
465
              printf("%02x ", ptr[dy*stride + dx]);
466
              if (dx==-1) printf("| ");
467
            }
468
            printf("\n");
469
            if (dy==-1) printf("-------------------------\n");
470
          }
471
        }
472
#endif
473
474
11.9M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
5.56M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
5.56M
        pixel_t q[4][4], p[4][4];
481
27.8M
        for (int k=0;k<4;k++)
482
111M
          for (int i=0;i<4;i++)
483
89.0M
            {
484
89.0M
              if (vertical) {
485
45.8M
                q[k][i] = ptr[ i  +k*stride];
486
45.8M
                p[k][i] = ptr[-i-1+k*stride];
487
45.8M
              }
488
43.1M
              else {
489
43.1M
                q[k][i] = ptr[k + i   *stride];
490
43.1M
                p[k][i] = ptr[k -(i+1)*stride];
491
43.1M
              }
492
89.0M
            }
493
494
#if 0
495
        for (int k=0;k<4;k++)
496
          {
497
            for (int i=0;i<4;i++)
498
              {
499
                printf("%02x ", p[k][3-i]);
500
              }
501
502
            printf("| ");
503
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", q[k][i]);
507
              }
508
            printf("\n");
509
          }
510
#endif
511
512
513
5.56M
        int QP_Q = img->get_QPY(xDi,yDi);
514
5.56M
        int QP_P = (vertical ?
515
2.86M
                    img->get_QPY(xDi-1,yDi) :
516
5.56M
                    img->get_QPY(xDi,yDi-1) );
517
5.56M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
5.56M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
5.56M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
5.56M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
5.56M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
5.56M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
5.56M
        int betaPrime = table_8_23_beta[Q_beta];
527
5.56M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
5.56M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
5.56M
        int tcPrime = table_8_23_tc[Q_tc];
531
5.56M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
5.56M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
5.56M
        int dE=0, dEp=0, dEq=0;
536
537
5.56M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
5.56M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
5.56M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
5.56M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
5.56M
        int dpq0 = dp0 + dq0;
543
5.56M
        int dpq3 = dp3 + dq3;
544
545
5.56M
        int dp = dp0 + dp3;
546
5.56M
        int dq = dq0 + dq3;
547
5.56M
        int d = dpq0 + dpq3;
548
549
5.56M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
2.42M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
1.53M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
1.28M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
2.42M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
1.86M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
1.59M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
2.42M
          if (dSam0 && dSam3) {
560
998k
            dE = 2;
561
998k
          }
562
1.42M
          else {
563
1.42M
            dE = 1;
564
1.42M
          }
565
566
2.42M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
2.42M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
2.42M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
2.42M
        }
571
572
573
        // 8.7.2.4.4
574
575
5.56M
        if (dE != 0) {
576
2.42M
          bool filterP = true;
577
2.42M
          bool filterQ = true;
578
579
2.42M
          if (vertical) {
580
1.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
1.19M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
1.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
1.19M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
1.19M
          }
586
1.23M
          else {
587
1.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
1.23M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
1.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
1.23M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
1.23M
          }
593
594
          if constexpr (sizeof(pixel_t)==1) {
595
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
2.42M
          else {
599
2.42M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
2.42M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
2.42M
          }
602
2.42M
        }
603
5.56M
      }
604
11.9M
    }
605
29.4k
}
void edge_filtering_luma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
67.2k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
67.2k
  const seq_parameter_set& sps = img->get_sps();
419
420
67.2k
  int xIncr = vertical ? 2 : 1;
421
67.2k
  int yIncr = vertical ? 1 : 2;
422
423
67.2k
  const int stride = img->get_image_stride(0);
424
425
67.2k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
67.2k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
67.2k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
734k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
97.2M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
96.6M
      int xDi = x<<2; // *4 -> pixel resolution
435
96.6M
      int yDi = y<<2; // *4 -> pixel resolution
436
96.6M
      int bS = img->get_deblk_bS(xDi,yDi);
437
438
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
439
440
96.6M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
96.6M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
442
443
#if 0
444
      {
445
        uint8_t* ptr = img->y + stride*yDi + xDi;
446
447
        for (int dy=-4;dy<4;dy++) {
448
          for (int dx=-4;dx<4;dx++) {
449
            printf("%02x ", ptr[dy*stride + dx]);
450
            if (dx==-1) printf("| ");
451
          }
452
          printf("\n");
453
          if (dy==-1) printf("-------------------------\n");
454
        }
455
      }
456
#endif
457
458
#if 0
459
      if (!vertical)
460
        {
461
          uint8_t* ptr = img->y + stride*yDi + xDi;
462
463
          for (int dy=-4;dy<4;dy++) {
464
            for (int dx=0;dx<4;dx++) {
465
              printf("%02x ", ptr[dy*stride + dx]);
466
              if (dx==-1) printf("| ");
467
            }
468
            printf("\n");
469
            if (dy==-1) printf("-------------------------\n");
470
          }
471
        }
472
#endif
473
474
96.6M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
57.1M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
57.1M
        pixel_t q[4][4], p[4][4];
481
283M
        for (int k=0;k<4;k++)
482
1.13G
          for (int i=0;i<4;i++)
483
906M
            {
484
906M
              if (vertical) {
485
459M
                q[k][i] = ptr[ i  +k*stride];
486
459M
                p[k][i] = ptr[-i-1+k*stride];
487
459M
              }
488
447M
              else {
489
447M
                q[k][i] = ptr[k + i   *stride];
490
447M
                p[k][i] = ptr[k -(i+1)*stride];
491
447M
              }
492
906M
            }
493
494
#if 0
495
        for (int k=0;k<4;k++)
496
          {
497
            for (int i=0;i<4;i++)
498
              {
499
                printf("%02x ", p[k][3-i]);
500
              }
501
502
            printf("| ");
503
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", q[k][i]);
507
              }
508
            printf("\n");
509
          }
510
#endif
511
512
513
57.1M
        int QP_Q = img->get_QPY(xDi,yDi);
514
57.1M
        int QP_P = (vertical ?
515
28.8M
                    img->get_QPY(xDi-1,yDi) :
516
57.1M
                    img->get_QPY(xDi,yDi-1) );
517
57.1M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
57.1M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
57.1M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
57.1M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
57.1M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
57.1M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
57.1M
        int betaPrime = table_8_23_beta[Q_beta];
527
57.1M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
57.1M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
57.1M
        int tcPrime = table_8_23_tc[Q_tc];
531
57.1M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
57.1M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
57.1M
        int dE=0, dEp=0, dEq=0;
536
537
57.1M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
57.1M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
57.1M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
57.1M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
57.1M
        int dpq0 = dp0 + dq0;
543
57.1M
        int dpq3 = dp3 + dq3;
544
545
57.1M
        int dp = dp0 + dp3;
546
57.1M
        int dq = dq0 + dq3;
547
57.1M
        int d = dpq0 + dpq3;
548
549
57.1M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
30.6M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
18.0M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
7.71M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
30.6M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
19.6M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
8.88M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
30.6M
          if (dSam0 && dSam3) {
560
5.82M
            dE = 2;
561
5.82M
          }
562
24.8M
          else {
563
24.8M
            dE = 1;
564
24.8M
          }
565
566
30.6M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
30.6M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
30.6M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
30.6M
        }
571
572
573
        // 8.7.2.4.4
574
575
57.1M
        if (dE != 0) {
576
30.7M
          bool filterP = true;
577
30.7M
          bool filterQ = true;
578
579
30.7M
          if (vertical) {
580
14.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
14.4M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
14.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
14.4M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
14.4M
          }
586
16.2M
          else {
587
16.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
16.2M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
16.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
16.2M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
16.2M
          }
593
594
30.7M
          if constexpr (sizeof(pixel_t)==1) {
595
30.7M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
30.7M
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
          else {
599
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
          }
602
30.7M
        }
603
57.1M
      }
604
96.6M
    }
605
67.2k
}
606
607
608
void edge_filtering_luma(de265_image* img, bool vertical,
609
                         int yStart,int yEnd, int xStart,int xEnd)
610
96.6k
{
611
96.6k
  if (img->high_bit_depth(0)) {
612
29.4k
    edge_filtering_luma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
613
29.4k
  }
614
67.2k
  else {
615
67.2k
    edge_filtering_luma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
616
67.2k
  }
617
96.6k
}
618
619
void edge_filtering_luma_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
620
0
{
621
0
  int ctbSize = img->get_sps().CtbSizeY;
622
0
  int deblkSize = ctbSize/4;
623
624
0
  edge_filtering_luma(img,vertical,
625
0
                      yCtb*deblkSize, (yCtb+1)*deblkSize,
626
0
                      xCtb*deblkSize, (xCtb+1)*deblkSize);
627
0
}
628
629
630
631
632
// 8.7.2.4
633
/** ?Start and ?End values in 4-luma pixels resolution.
634
 */
635
template <class pixel_t>
636
void edge_filtering_chroma_internal(de265_image* img, bool vertical,
637
                                    int yStart,int yEnd,
638
                                    int xStart,int xEnd)
639
86.4k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
86.4k
  const seq_parameter_set& sps = img->get_sps();
643
644
86.4k
  const int SubWidthC  = sps.SubWidthC;
645
86.4k
  const int SubHeightC = sps.SubHeightC;
646
647
86.4k
  int xIncr = vertical ? 2 : 1;
648
86.4k
  int yIncr = vertical ? 1 : 2;
649
650
86.4k
  xIncr *= SubWidthC;
651
86.4k
  yIncr *= SubHeightC;
652
653
86.4k
  const int stride = img->get_image_stride(1);
654
655
86.4k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
86.4k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
86.4k
  int bitDepth_C = sps.BitDepth_C;
659
660
647k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
36.8M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
36.3M
      int xDi = x << (3-SubWidthC);
663
36.3M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
36.3M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
36.3M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
72.3M
        for (int cplane=0;cplane<2;cplane++) {
673
48.2M
          int cQpPicOffset = (cplane==0 ?
674
24.1M
                              img->get_pps().pic_cb_qp_offset :
675
48.2M
                              img->get_pps().pic_cr_qp_offset);
676
677
48.2M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
678
679
680
#if 0
681
          for (int k=0;k<4;k++)
682
            {
683
              for (int i=0;i<2;i++)
684
                {
685
                  printf("%02x ", p[1-i][k]);
686
                }
687
688
              printf("| ");
689
690
              for (int i=0;i<2;i++)
691
                {
692
                  printf("%02x ", q[i][k]);
693
                }
694
              printf("\n");
695
            }
696
#endif
697
698
48.2M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
48.2M
          int QP_P = (vertical ?
700
24.6M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
48.2M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
48.2M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
48.2M
          int QP_C;
704
48.2M
          if (sps.ChromaArrayType == CHROMA_420) {
705
34.2M
            QP_C = table8_22(qP_i);
706
34.2M
          } else {
707
13.9M
            QP_C = std::min(qP_i, 51);
708
13.9M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
48.2M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
48.2M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
48.2M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
48.2M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
48.2M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
48.2M
          int tcPrime = table_8_23_tc[Q];
721
48.2M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
48.2M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
48.2M
          if (vertical) {
726
24.6M
            bool filterP = true;
727
24.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
24.6M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
24.6M
            bool filterQ = true;
731
24.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
24.6M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
24.6M
            if constexpr (sizeof(pixel_t)==1) {
736
22.7M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
1.86M
            else {
739
1.86M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
1.86M
            }
741
24.6M
          }
742
23.6M
          else {
743
23.6M
            bool filterP = true;
744
23.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
23.6M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
23.6M
            bool filterQ = true;
748
23.6M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
23.6M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
23.6M
            if constexpr (sizeof(pixel_t)==1) {
752
22.0M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
1.63M
            else {
755
1.63M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
1.63M
            }
757
23.6M
          }
758
48.2M
        }
759
24.1M
      }
760
36.3M
    }
761
86.4k
}
void edge_filtering_chroma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
16.5k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
16.5k
  const seq_parameter_set& sps = img->get_sps();
643
644
16.5k
  const int SubWidthC  = sps.SubWidthC;
645
16.5k
  const int SubHeightC = sps.SubHeightC;
646
647
16.5k
  int xIncr = vertical ? 2 : 1;
648
16.5k
  int yIncr = vertical ? 1 : 2;
649
650
16.5k
  xIncr *= SubWidthC;
651
16.5k
  yIncr *= SubHeightC;
652
653
16.5k
  const int stride = img->get_image_stride(1);
654
655
16.5k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
16.5k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
16.5k
  int bitDepth_C = sps.BitDepth_C;
659
660
124k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
4.15M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
4.04M
      int xDi = x << (3-SubWidthC);
663
4.04M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
4.04M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
4.04M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
5.25M
        for (int cplane=0;cplane<2;cplane++) {
673
3.50M
          int cQpPicOffset = (cplane==0 ?
674
1.75M
                              img->get_pps().pic_cb_qp_offset :
675
3.50M
                              img->get_pps().pic_cr_qp_offset);
676
677
3.50M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
678
679
680
#if 0
681
          for (int k=0;k<4;k++)
682
            {
683
              for (int i=0;i<2;i++)
684
                {
685
                  printf("%02x ", p[1-i][k]);
686
                }
687
688
              printf("| ");
689
690
              for (int i=0;i<2;i++)
691
                {
692
                  printf("%02x ", q[i][k]);
693
                }
694
              printf("\n");
695
            }
696
#endif
697
698
3.50M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
3.50M
          int QP_P = (vertical ?
700
1.86M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
3.50M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
3.50M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
3.50M
          int QP_C;
704
3.50M
          if (sps.ChromaArrayType == CHROMA_420) {
705
199k
            QP_C = table8_22(qP_i);
706
3.30M
          } else {
707
3.30M
            QP_C = std::min(qP_i, 51);
708
3.30M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
3.50M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
3.50M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
3.50M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
3.50M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
3.50M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
3.50M
          int tcPrime = table_8_23_tc[Q];
721
3.50M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
3.50M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
3.50M
          if (vertical) {
726
1.86M
            bool filterP = true;
727
1.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
1.86M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
1.86M
            bool filterQ = true;
731
1.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
1.86M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
            if constexpr (sizeof(pixel_t)==1) {
736
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
1.86M
            else {
739
1.86M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
1.86M
            }
741
1.86M
          }
742
1.63M
          else {
743
1.63M
            bool filterP = true;
744
1.63M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
1.63M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
1.63M
            bool filterQ = true;
748
1.63M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
1.63M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
            if constexpr (sizeof(pixel_t)==1) {
752
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
1.63M
            else {
755
1.63M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
1.63M
            }
757
1.63M
          }
758
3.50M
        }
759
1.75M
      }
760
4.04M
    }
761
16.5k
}
void edge_filtering_chroma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
69.8k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
69.8k
  const seq_parameter_set& sps = img->get_sps();
643
644
69.8k
  const int SubWidthC  = sps.SubWidthC;
645
69.8k
  const int SubHeightC = sps.SubHeightC;
646
647
69.8k
  int xIncr = vertical ? 2 : 1;
648
69.8k
  int yIncr = vertical ? 1 : 2;
649
650
69.8k
  xIncr *= SubWidthC;
651
69.8k
  yIncr *= SubHeightC;
652
653
69.8k
  const int stride = img->get_image_stride(1);
654
655
69.8k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
69.8k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
69.8k
  int bitDepth_C = sps.BitDepth_C;
659
660
522k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
32.7M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
32.2M
      int xDi = x << (3-SubWidthC);
663
32.2M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
32.2M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
32.2M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
67.1M
        for (int cplane=0;cplane<2;cplane++) {
673
44.7M
          int cQpPicOffset = (cplane==0 ?
674
22.3M
                              img->get_pps().pic_cb_qp_offset :
675
44.7M
                              img->get_pps().pic_cr_qp_offset);
676
677
44.7M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
678
679
680
#if 0
681
          for (int k=0;k<4;k++)
682
            {
683
              for (int i=0;i<2;i++)
684
                {
685
                  printf("%02x ", p[1-i][k]);
686
                }
687
688
              printf("| ");
689
690
              for (int i=0;i<2;i++)
691
                {
692
                  printf("%02x ", q[i][k]);
693
                }
694
              printf("\n");
695
            }
696
#endif
697
698
44.7M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
44.7M
          int QP_P = (vertical ?
700
22.7M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
44.7M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
44.7M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
44.7M
          int QP_C;
704
44.7M
          if (sps.ChromaArrayType == CHROMA_420) {
705
34.0M
            QP_C = table8_22(qP_i);
706
34.0M
          } else {
707
10.6M
            QP_C = std::min(qP_i, 51);
708
10.6M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
44.7M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
44.7M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
44.7M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
44.7M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
44.7M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
44.7M
          int tcPrime = table_8_23_tc[Q];
721
44.7M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
44.7M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
44.7M
          if (vertical) {
726
22.7M
            bool filterP = true;
727
22.7M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
22.7M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
22.7M
            bool filterQ = true;
731
22.7M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
22.7M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
22.7M
            if constexpr (sizeof(pixel_t)==1) {
736
22.7M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
            else {
739
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
            }
741
22.7M
          }
742
22.0M
          else {
743
22.0M
            bool filterP = true;
744
22.0M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
22.0M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
22.0M
            bool filterQ = true;
748
22.0M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
22.0M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
22.0M
            if constexpr (sizeof(pixel_t)==1) {
752
22.0M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
            else {
755
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
            }
757
22.0M
          }
758
44.7M
        }
759
22.3M
      }
760
32.2M
    }
761
69.8k
}
762
763
764
void edge_filtering_chroma(de265_image* img, bool vertical, int yStart,int yEnd,
765
                           int xStart,int xEnd)
766
86.4k
{
767
86.4k
  if (img->high_bit_depth(1)) {
768
16.5k
    edge_filtering_chroma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
769
16.5k
  }
770
69.8k
  else {
771
69.8k
    edge_filtering_chroma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
772
69.8k
  }
773
86.4k
}
774
775
776
void edge_filtering_chroma_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
777
0
{
778
0
  int ctbSize = img->get_sps().CtbSizeY;
779
0
  int deblkSize = ctbSize/4;
780
781
0
  edge_filtering_chroma(img,vertical,
782
0
                        yCtb*deblkSize, (yCtb+1)*deblkSize,
783
0
                        xCtb*deblkSize, (xCtb+1)*deblkSize);
784
0
}
785
786
787
788
class thread_task_deblock_CTBRow : public thread_task
789
{
790
public:
791
  struct de265_image* img;
792
  int  ctb_y;
793
  bool vertical;
794
795
  virtual void work();
796
0
  virtual std::string name() const {
797
0
    char buf[100];
798
0
    sprintf(buf,"deblock-%d",ctb_y);
799
0
    return buf;
800
0
  }
801
};
802
803
804
void thread_task_deblock_CTBRow::work()
805
119k
{
806
119k
  state = Running;
807
119k
  img->thread_run(this);
808
809
119k
  int xStart=0;
810
119k
  int xEnd = img->get_deblk_width();
811
812
119k
  int ctbSize = img->get_sps().CtbSizeY;
813
119k
  int deblkSize = ctbSize/4;
814
815
119k
  int first =  ctb_y    * deblkSize;
816
119k
  int last  = (ctb_y+1) * deblkSize;
817
119k
  if (last > img->get_deblk_height()) {
818
11.9k
    last = img->get_deblk_height();
819
11.9k
  }
820
821
119k
  int finalProgress = CTB_PROGRESS_DEBLK_V;
822
119k
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;
823
824
119k
  int rightCtb = img->get_sps().PicWidthInCtbsY-1;
825
826
119k
  if (vertical) {
827
    // pass 1: vertical
828
829
59.6k
    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
830
59.6k
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
831
59.6k
  }
832
59.6k
  else {
833
    // pass 2: horizontal
834
835
59.6k
    if (ctb_y>0) {
836
47.2k
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
837
47.2k
    }
838
839
59.6k
    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);
840
841
59.6k
    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
842
47.2k
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
843
47.2k
    }
844
59.6k
  }
845
846
  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);
847
848
119k
  bool deblocking_enabled;
849
850
  // first pass: check edge flags and whether we have to deblock
851
119k
  if (vertical) {
852
59.6k
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);
853
854
    //for (int x=0;x<=rightCtb;x++) {
855
59.6k
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
856
    //}
857
59.6k
  }
858
59.6k
  else {
859
59.6k
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
860
59.6k
  }
861
862
119k
  if (deblocking_enabled) {
863
96.6k
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);
864
865
96.6k
    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);
866
867
96.6k
    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
868
86.4k
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
869
86.4k
    }
870
96.6k
  }
871
872
1.61M
  for (int x=0;x<=rightCtb;x++) {
873
1.49M
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
874
1.49M
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
875
1.49M
  }
876
877
119k
  state = Finished;
878
119k
  img->thread_finishes(this);
879
119k
}
880
881
882
void add_deblocking_tasks(image_unit* imgunit)
883
12.3k
{
884
12.3k
  de265_image* img = imgunit->img;
885
12.3k
  decoder_context* ctx = img->decctx;
886
887
12.3k
  int nRows = img->get_sps().PicHeightInCtbsY;
888
889
12.3k
  img->thread_start(nRows*2);
890
891
37.1k
  for (int pass=0;pass<2;pass++)
892
24.7k
    {
893
143k
      for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++)
894
119k
        {
895
119k
          thread_task_deblock_CTBRow* task = new thread_task_deblock_CTBRow;
896
897
119k
          task->img   = img;
898
119k
          task->ctb_y = y;
899
119k
          task->vertical = (pass==0);
900
901
119k
          imgunit->tasks.push_back(task);
902
119k
          ctx->thread_pool_.add_task(task);
903
119k
        }
904
24.7k
    }
905
12.3k
}
906
907
908
void apply_deblocking_filter(de265_image* img) // decoder_context* ctx)
909
0
{
910
  //decoder_context* ctx = img->decctx;
911
912
0
  char enabled_deblocking = derive_edgeFlags(img);
913
914
0
  if (enabled_deblocking)
915
0
    {
916
      // vertical filtering
917
918
0
      logtrace(LogDeblock,"VERTICAL\n");
919
0
      derive_boundaryStrength(img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
920
0
      edge_filtering_luma    (img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
921
922
0
      if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
923
0
        edge_filtering_chroma  (img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
924
0
      }
925
#if 0
926
      char buf[1000];
927
      sprintf(buf,"lf-after-V-%05d.yuv", ctx->img->PicOrderCntVal);
928
      write_picture_to_file(ctx->img, buf);
929
#endif
930
931
      // horizontal filtering
932
933
0
      logtrace(LogDeblock,"HORIZONTAL\n");
934
0
      derive_boundaryStrength(img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
935
0
      edge_filtering_luma    (img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
936
937
0
      if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
938
0
        edge_filtering_chroma  (img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
939
0
      }
940
941
#if 0
942
      sprintf(buf,"lf-after-H-%05d.yuv", ctx->img->PicOrderCntVal);
943
      write_picture_to_file(ctx->img, buf);
944
#endif
945
0
    }
946
0
}