Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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
69.7M
{
37
69.7M
  logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0,
38
69.7M
           log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge);
39
40
69.7M
  int split_transform = img->get_split_transform_flag(x0,y0,trafoDepth);
41
69.7M
  if (split_transform) {
42
12.3M
    int x1 = x0 + ((1<<log2TrafoSize)>>1);
43
12.3M
    int y1 = y0 + ((1<<log2TrafoSize)>>1);
44
45
12.3M
    markTransformBlockBoundary(img,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   filterTopCbEdge);
46
12.3M
    markTransformBlockBoundary(img,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge);
47
12.3M
    markTransformBlockBoundary(img,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   DEBLOCK_FLAG_HORIZ);
48
12.3M
    markTransformBlockBoundary(img,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ);
49
12.3M
  }
50
57.4M
  else {
51
    // VER
52
53
131M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
54
74.2M
      img->set_deblk_flags(x0,y0+k, filterLeftCbEdge);
55
74.2M
    }
56
57
    // HOR
58
59
131M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
60
74.2M
      img->set_deblk_flags(x0+k,y0, filterTopCbEdge);
61
74.2M
    }
62
57.4M
  }
63
69.7M
}
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
20.3M
{
72
20.3M
  logtrace(LogDeblock,"markPredictionBlockBoundary(%d,%d, %d, %d,%d)\n",x0,y0,
73
20.3M
           log2CbSize, filterLeftCbEdge,filterTopCbEdge);
74
75
20.3M
  enum PartMode partMode = img->get_PartMode(x0,y0);
76
77
20.3M
  int cbSize = 1<<log2CbSize;
78
20.3M
  int cbSize2 = 1<<(log2CbSize-1);
79
20.3M
  int cbSize4 = 1<<(log2CbSize-2);
80
81
20.3M
  switch (partMode) {
82
8.61M
  case PART_NxN:
83
77.5M
    for (int k=0;k<cbSize;k++) {
84
68.9M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
85
68.9M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
86
68.9M
    }
87
8.61M
    break;
88
89
909k
  case PART_Nx2N:
90
9.96M
    for (int k=0;k<cbSize;k++) {
91
9.05M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
92
9.05M
    }
93
909k
    break;
94
95
662k
  case PART_2NxN:
96
7.67M
    for (int k=0;k<cbSize;k++) {
97
7.01M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
98
7.01M
    }
99
662k
    break;
100
101
38.8k
  case PART_nLx2N:
102
912k
    for (int k=0;k<cbSize;k++) {
103
873k
      img->set_deblk_flags(x0+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
104
873k
    }
105
38.8k
    break;
106
107
5.79k
  case PART_nRx2N:
108
151k
    for (int k=0;k<cbSize;k++) {
109
145k
      img->set_deblk_flags(x0+cbSize2+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
110
145k
    }
111
5.79k
    break;
112
113
23.9k
  case PART_2NxnU:
114
562k
    for (int k=0;k<cbSize;k++) {
115
538k
      img->set_deblk_flags(x0+k,y0+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
116
538k
    }
117
23.9k
    break;
118
119
6.03k
  case PART_2NxnD:
120
157k
    for (int k=0;k<cbSize;k++) {
121
151k
      img->set_deblk_flags(x0+k,y0+cbSize2+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
122
151k
    }
123
6.03k
    break;
124
125
10.1M
  case PART_2Nx2N:
126
    // NOP
127
10.1M
    break;
128
20.3M
  }
129
20.3M
}
130
131
132
bool derive_edgeFlags_CTBRow(de265_image* img, uint16_t ctby)
133
882k
{
134
882k
  const seq_parameter_set& sps = img->get_sps();
135
882k
  const pic_parameter_set& pps = img->get_pps();
136
137
882k
  const int minCbSize = sps.MinCbSizeY;
138
882k
  bool deblocking_enabled=false; // whether deblocking is enabled in some part of the image
139
140
882k
  int ctb_mask = (1<<sps.Log2CtbSizeY)-1;
141
882k
  int picWidthInCtbs = sps.PicWidthInCtbsY;
142
882k
  int ctbshift = sps.Log2CtbSizeY;
143
144
145
882k
  uint16_t cb_y_start = ( ctby    << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
146
882k
  uint16_t cb_y_end   = ((ctby+1) << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
147
148
882k
  cb_y_end = std::min(cb_y_end, sps.PicHeightInMinCbsY);
149
150
4.11M
  for (int cb_y=cb_y_start;cb_y<cb_y_end;cb_y++)
151
87.1M
    for (int cb_x=0;cb_x<img->get_sps().PicWidthInMinCbsY;cb_x++)
152
83.9M
      {
153
83.9M
        int log2CbSize = img->get_log2CbSize_cbUnits(cb_x,cb_y);
154
83.9M
        if (log2CbSize==0) {
155
61.3M
          continue;
156
61.3M
        }
157
158
        // we are now at the top corner of a CB
159
160
22.5M
        int x0 = cb_x * minCbSize;
161
22.5M
        int y0 = cb_y * minCbSize;
162
163
22.5M
        int x0ctb = x0 >> ctbshift;
164
22.5M
        int y0ctb = y0 >> ctbshift;
165
166
        // check for corrupted streams
167
22.5M
        if (img->is_SliceHeader_available(x0,y0)==false) {
168
0
          return false;
169
0
        }
170
171
        // check whether we should filter this slice
172
173
22.5M
        slice_segment_header* shdr = img->get_SliceHeader(x0,y0);
174
175
        // check whether to filter left and top edge
176
177
22.5M
        uint8_t filterLeftCbEdge = DEBLOCK_FLAG_VERTI;
178
22.5M
        uint8_t filterTopCbEdge  = DEBLOCK_FLAG_HORIZ;
179
22.5M
        if (x0 == 0) filterLeftCbEdge = 0;
180
22.5M
        if (y0 == 0) filterTopCbEdge  = 0;
181
182
        // check for slice and tile boundaries (8.7.2, step 2 in both processes)
183
184
22.5M
        if (x0 && ((x0 & ctb_mask) == 0)) { // left edge at CTB boundary
185
6.68M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
186
5.18M
              img->is_SliceHeader_available(x0-1,y0) && // for corrupted streams
187
5.18M
              shdr->SliceAddrRS != img->get_SliceHeader(x0-1,y0)->SliceAddrRS)
188
554
            {
189
554
              filterLeftCbEdge = 0;
190
554
            }
191
6.68M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
192
6.01M
                   pps.scan->TileIdRS[  x0ctb           +y0ctb*picWidthInCtbs] !=
193
6.01M
                   pps.scan->TileIdRS[((x0-1)>>ctbshift)+y0ctb*picWidthInCtbs]) {
194
2.87k
            filterLeftCbEdge = 0;
195
2.87k
          }
196
6.68M
        }
197
198
22.5M
        if (y0 && ((y0 & ctb_mask) == 0)) { // top edge at CTB boundary
199
5.63M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
200
4.16M
              img->is_SliceHeader_available(x0,y0-1) && // for corrupted streams
201
4.16M
              shdr->SliceAddrRS != img->get_SliceHeader(x0,y0-1)->SliceAddrRS)
202
3.01k
            {
203
3.01k
              filterTopCbEdge = 0;
204
3.01k
            }
205
5.62M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
206
4.85M
                   pps.scan->TileIdRS[x0ctb+  y0ctb           *picWidthInCtbs] !=
207
4.85M
                   pps.scan->TileIdRS[x0ctb+((y0-1)>>ctbshift)*picWidthInCtbs]) {
208
6.31k
            filterTopCbEdge = 0;
209
6.31k
          }
210
5.63M
        }
211
212
213
        // mark edges
214
215
22.5M
        if (shdr->slice_deblocking_filter_disabled_flag==0) {
216
20.3M
          deblocking_enabled=true;
217
218
20.3M
          markTransformBlockBoundary(img, x0,y0, log2CbSize,0,
219
20.3M
                                     filterLeftCbEdge, filterTopCbEdge);
220
221
20.3M
          markPredictionBlockBoundary(img, x0,y0, log2CbSize,
222
20.3M
                                      filterLeftCbEdge, filterTopCbEdge);
223
20.3M
        }
224
22.5M
      }
225
226
882k
  return deblocking_enabled;
227
882k
}
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
330k
{
246
330k
  int xIncr = vertical ? 2 : 1;
247
330k
  int yIncr = vertical ? 1 : 2;
248
330k
  int xOffs = vertical ? 1 : 0;
249
330k
  int yOffs = vertical ? 0 : 1;
250
330k
  int edgeMask = vertical ?
251
165k
    (DEBLOCK_FLAG_VERTI | DEBLOCK_PB_EDGE_VERTI) :
252
330k
    (DEBLOCK_FLAG_HORIZ | DEBLOCK_PB_EDGE_HORIZ);
253
330k
  int transformEdgeMask = vertical ? DEBLOCK_FLAG_VERTI : DEBLOCK_FLAG_HORIZ;
254
255
330k
  xEnd = std::min(xEnd,img->get_deblk_width());
256
330k
  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
2.02M
  for (int y=yStart;y<yEnd;y+=yIncr)
262
147M
    for (int x=xStart;x<xEnd;x+=xIncr) {
263
145M
      int xDi = x<<2;
264
145M
      int yDi = y<<2;
265
266
145M
      logtrace(LogDeblock,"%d %d %s = %s\n",xDi,yDi, vertical?"Vertical":"Horizontal",
267
145M
               (img->get_deblk_flags(xDi,yDi) & edgeMask) ? "edge" : "...");
268
269
145M
      uint8_t edgeFlags = img->get_deblk_flags(xDi,yDi);
270
271
145M
      if (edgeFlags & edgeMask) {
272
95.6M
        bool p_is_intra_pred = (img->get_pred_mode(xDi-xOffs, yDi-yOffs) == MODE_INTRA);
273
95.6M
        bool q_is_intra_pred = (img->get_pred_mode(xDi,       yDi      ) == MODE_INTRA);
274
275
95.6M
        int bS;
276
277
95.6M
        if (p_is_intra_pred || q_is_intra_pred) {
278
52.1M
          bS = 2;
279
52.1M
        }
280
43.4M
        else {
281
          // opposing site
282
43.4M
          int xDiOpp = xDi-xOffs;
283
43.4M
          int yDiOpp = yDi-yOffs;
284
285
43.4M
          if ((edgeFlags & transformEdgeMask) &&
286
42.4M
              (img->get_nonzero_coefficient(xDi   ,yDi) ||
287
36.5M
               img->get_nonzero_coefficient(xDiOpp,yDiOpp))) {
288
7.17M
            bS = 1;
289
7.17M
          }
290
36.2M
          else {
291
292
36.2M
            bS = 0;
293
294
36.2M
            const PBMotion& mviP = img->get_mv_info(xDiOpp,yDiOpp);
295
36.2M
            const PBMotion& mviQ = img->get_mv_info(xDi   ,yDi);
296
297
36.2M
            slice_segment_header* shdrP = img->get_SliceHeader(xDiOpp,yDiOpp);
298
36.2M
            slice_segment_header* shdrQ = img->get_SliceHeader(xDi   ,yDi);
299
300
36.2M
      if (shdrP && shdrQ) {
301
302
36.2M
        int refPicP0 = mviP.predFlag[0] ? shdrP->RefPicList[0][ mviP.refIdx[0] ] : -1;
303
36.2M
        int refPicP1 = mviP.predFlag[1] ? shdrP->RefPicList[1][ mviP.refIdx[1] ] : -1;
304
36.2M
        int refPicQ0 = mviQ.predFlag[0] ? shdrQ->RefPicList[0][ mviQ.refIdx[0] ] : -1;
305
36.2M
        int refPicQ1 = mviQ.predFlag[1] ? shdrQ->RefPicList[1][ mviQ.refIdx[1] ] : -1;
306
307
36.2M
        bool samePics = ((refPicP0==refPicQ0 && refPicP1==refPicQ1) ||
308
3.28M
             (refPicP0==refPicQ1 && refPicP1==refPicQ0));
309
310
36.2M
        if (!samePics) {
311
3.03M
    bS = 1;
312
3.03M
        }
313
33.2M
        else {
314
33.2M
    MotionVector mvP0 = mviP.mv[0]; if (!mviP.predFlag[0]) { mvP0.x=mvP0.y=0; }
315
33.2M
    MotionVector mvP1 = mviP.mv[1]; if (!mviP.predFlag[1]) { mvP1.x=mvP1.y=0; }
316
33.2M
    MotionVector mvQ0 = mviQ.mv[0]; if (!mviQ.predFlag[0]) { mvQ0.x=mvQ0.y=0; }
317
33.2M
    MotionVector mvQ1 = mviQ.mv[1]; if (!mviQ.predFlag[1]) { mvQ1.x=mvQ1.y=0; }
318
319
33.2M
    int numMV_P = mviP.predFlag[0] + mviP.predFlag[1];
320
33.2M
    int numMV_Q = mviQ.predFlag[0] + mviQ.predFlag[1];
321
322
33.2M
    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
33.2M
    if (refPicP0 != refPicP1) {
329
330
19.2M
      if (refPicP0 == refPicQ0) {
331
18.9M
        if (std::abs(mvP0.x-mvQ0.x) >= 4 ||
332
18.0M
      std::abs(mvP0.y-mvQ0.y) >= 4 ||
333
17.8M
      std::abs(mvP1.x-mvQ1.x) >= 4 ||
334
17.8M
      std::abs(mvP1.y-mvQ1.y) >= 4) {
335
1.17M
          bS = 1;
336
1.17M
        }
337
18.9M
      }
338
255k
      else {
339
255k
        if (std::abs(mvP0.x-mvQ1.x) >= 4 ||
340
234k
      std::abs(mvP0.y-mvQ1.y) >= 4 ||
341
215k
      std::abs(mvP1.x-mvQ0.x) >= 4 ||
342
192k
      std::abs(mvP1.y-mvQ0.y) >= 4) {
343
81.8k
          bS = 1;
344
81.8k
        }
345
255k
      }
346
19.2M
    }
347
14.0M
    else {
348
14.0M
      assert(refPicQ0==refPicQ1);
349
350
14.0M
      if ((std::abs(mvP0.x-mvQ0.x) >= 4 ||
351
13.6M
           std::abs(mvP0.y-mvQ0.y) >= 4 ||
352
13.5M
           std::abs(mvP1.x-mvQ1.x) >= 4 ||
353
13.4M
           std::abs(mvP1.y-mvQ1.y) >= 4)
354
576k
          &&
355
576k
          (std::abs(mvP0.x-mvQ1.x) >= 4 ||
356
232k
           std::abs(mvP0.y-mvQ1.y) >= 4 ||
357
124k
           std::abs(mvP1.x-mvQ0.x) >= 4 ||
358
567k
           std::abs(mvP1.y-mvQ0.y) >= 4)) {
359
567k
        bS = 1;
360
567k
      }
361
14.0M
    }
362
33.2M
        }
363
36.2M
      }
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
36.2M
          }
375
43.4M
        }
376
377
95.6M
        img->set_deblk_bS(xDi,yDi, bS);
378
95.6M
      }
379
49.8M
      else {
380
49.8M
        img->set_deblk_bS(xDi,yDi, 0);
381
49.8M
      }
382
145M
    }
383
330k
}
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
330k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
330k
  const seq_parameter_set& sps = img->get_sps();
419
420
330k
  int xIncr = vertical ? 2 : 1;
421
330k
  int yIncr = vertical ? 1 : 2;
422
423
330k
  const int stride = img->get_image_stride(0);
424
425
330k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
330k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
330k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
2.02M
  for (int y=yStart;y<yEnd;y+=yIncr)
431
146M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
145M
      int xDi = x<<2; // *4 -> pixel resolution
435
145M
      int yDi = y<<2; // *4 -> pixel resolution
436
145M
      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
145M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
145M
               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
145M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
64.0M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
64.0M
        pixel_t q[4][4], p[4][4];
481
319M
        for (int k=0;k<4;k++)
482
1.27G
          for (int i=0;i<4;i++)
483
1.02G
            {
484
1.02G
              if (vertical) {
485
520M
                q[k][i] = ptr[ i  +k*stride];
486
520M
                p[k][i] = ptr[-i-1+k*stride];
487
520M
              }
488
502M
              else {
489
502M
                q[k][i] = ptr[k + i   *stride];
490
502M
                p[k][i] = ptr[k -(i+1)*stride];
491
502M
              }
492
1.02G
            }
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
64.0M
        int QP_Q = img->get_QPY(xDi,yDi);
514
64.0M
        int QP_P = (vertical ?
515
32.6M
                    img->get_QPY(xDi-1,yDi) :
516
64.0M
                    img->get_QPY(xDi,yDi-1) );
517
64.0M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
64.0M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
64.0M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
64.0M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
64.0M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
64.0M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
64.0M
        int betaPrime = table_8_23_beta[Q_beta];
527
64.0M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
64.0M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
64.0M
        int tcPrime = table_8_23_tc[Q_tc];
531
64.0M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
64.0M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
64.0M
        int dE=0, dEp=0, dEq=0;
536
537
64.0M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
64.0M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
64.0M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
64.0M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
64.0M
        int dpq0 = dp0 + dq0;
543
64.0M
        int dpq3 = dp3 + dq3;
544
545
64.0M
        int dp = dp0 + dp3;
546
64.0M
        int dq = dq0 + dq3;
547
64.0M
        int d = dpq0 + dpq3;
548
549
64.0M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
26.2M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
21.8M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
19.1M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
26.2M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
21.8M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
19.2M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
26.2M
          if (dSam0 && dSam3) {
560
17.3M
            dE = 2;
561
17.3M
          }
562
8.94M
          else {
563
8.94M
            dE = 1;
564
8.94M
          }
565
566
26.2M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
26.2M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
26.2M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
26.2M
        }
571
572
573
        // 8.7.2.4.4
574
575
64.0M
        if (dE != 0) {
576
26.2M
          bool filterP = true;
577
26.2M
          bool filterQ = true;
578
579
26.2M
          if (vertical) {
580
13.0M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
13.0M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
13.0M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
13.0M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
13.0M
          }
586
13.2M
          else {
587
13.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
13.2M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
13.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
13.2M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
13.2M
          }
593
594
26.2M
          if constexpr (sizeof(pixel_t)==1) {
595
14.7M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
14.7M
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
11.5M
          else {
599
11.5M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
11.5M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
11.5M
          }
602
26.2M
        }
603
64.0M
      }
604
145M
    }
605
330k
}
void edge_filtering_luma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
51.2k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
51.2k
  const seq_parameter_set& sps = img->get_sps();
419
420
51.2k
  int xIncr = vertical ? 2 : 1;
421
51.2k
  int yIncr = vertical ? 1 : 2;
422
423
51.2k
  const int stride = img->get_image_stride(0);
424
425
51.2k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
51.2k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
51.2k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
365k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
50.3M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
49.9M
      int xDi = x<<2; // *4 -> pixel resolution
435
49.9M
      int yDi = y<<2; // *4 -> pixel resolution
436
49.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
49.9M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
49.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
49.9M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
20.7M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
20.7M
        pixel_t q[4][4], p[4][4];
481
103M
        for (int k=0;k<4;k++)
482
414M
          for (int i=0;i<4;i++)
483
331M
            {
484
331M
              if (vertical) {
485
167M
                q[k][i] = ptr[ i  +k*stride];
486
167M
                p[k][i] = ptr[-i-1+k*stride];
487
167M
              }
488
164M
              else {
489
164M
                q[k][i] = ptr[k + i   *stride];
490
164M
                p[k][i] = ptr[k -(i+1)*stride];
491
164M
              }
492
331M
            }
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
20.7M
        int QP_Q = img->get_QPY(xDi,yDi);
514
20.7M
        int QP_P = (vertical ?
515
10.4M
                    img->get_QPY(xDi-1,yDi) :
516
20.7M
                    img->get_QPY(xDi,yDi-1) );
517
20.7M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
20.7M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
20.7M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
20.7M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
20.7M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
20.7M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
20.7M
        int betaPrime = table_8_23_beta[Q_beta];
527
20.7M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
20.7M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
20.7M
        int tcPrime = table_8_23_tc[Q_tc];
531
20.7M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
20.7M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
20.7M
        int dE=0, dEp=0, dEq=0;
536
537
20.7M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
20.7M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
20.7M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
20.7M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
20.7M
        int dpq0 = dp0 + dq0;
543
20.7M
        int dpq3 = dp3 + dq3;
544
545
20.7M
        int dp = dp0 + dp3;
546
20.7M
        int dq = dq0 + dq3;
547
20.7M
        int d = dpq0 + dpq3;
548
549
20.7M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
11.5M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
9.87M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
9.21M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
11.5M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
9.63M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
8.92M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
11.5M
          if (dSam0 && dSam3) {
560
8.24M
            dE = 2;
561
8.24M
          }
562
3.29M
          else {
563
3.29M
            dE = 1;
564
3.29M
          }
565
566
11.5M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
11.5M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
11.5M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
11.5M
        }
571
572
573
        // 8.7.2.4.4
574
575
20.7M
        if (dE != 0) {
576
11.5M
          bool filterP = true;
577
11.5M
          bool filterQ = true;
578
579
11.5M
          if (vertical) {
580
5.53M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
5.53M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
5.53M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
5.53M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
5.53M
          }
586
6.00M
          else {
587
6.00M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
6.00M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
6.00M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
6.00M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
6.00M
          }
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
11.5M
          else {
599
11.5M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
11.5M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
11.5M
          }
602
11.5M
        }
603
20.7M
      }
604
49.9M
    }
605
51.2k
}
void edge_filtering_luma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
279k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
279k
  const seq_parameter_set& sps = img->get_sps();
419
420
279k
  int xIncr = vertical ? 2 : 1;
421
279k
  int yIncr = vertical ? 1 : 2;
422
423
279k
  const int stride = img->get_image_stride(0);
424
425
279k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
279k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
279k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
1.66M
  for (int y=yStart;y<yEnd;y+=yIncr)
431
96.6M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
95.2M
      int xDi = x<<2; // *4 -> pixel resolution
435
95.2M
      int yDi = y<<2; // *4 -> pixel resolution
436
95.2M
      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
95.2M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
95.2M
               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
95.2M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
43.3M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
43.3M
        pixel_t q[4][4], p[4][4];
481
216M
        for (int k=0;k<4;k++)
482
863M
          for (int i=0;i<4;i++)
483
690M
            {
484
690M
              if (vertical) {
485
353M
                q[k][i] = ptr[ i  +k*stride];
486
353M
                p[k][i] = ptr[-i-1+k*stride];
487
353M
              }
488
337M
              else {
489
337M
                q[k][i] = ptr[k + i   *stride];
490
337M
                p[k][i] = ptr[k -(i+1)*stride];
491
337M
              }
492
690M
            }
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
43.3M
        int QP_Q = img->get_QPY(xDi,yDi);
514
43.3M
        int QP_P = (vertical ?
515
22.1M
                    img->get_QPY(xDi-1,yDi) :
516
43.3M
                    img->get_QPY(xDi,yDi-1) );
517
43.3M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
43.3M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
43.3M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
43.3M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
43.3M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
43.3M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
43.3M
        int betaPrime = table_8_23_beta[Q_beta];
527
43.3M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
43.3M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
43.3M
        int tcPrime = table_8_23_tc[Q_tc];
531
43.3M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
43.3M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
43.3M
        int dE=0, dEp=0, dEq=0;
536
537
43.3M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
43.3M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
43.3M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
43.3M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
43.3M
        int dpq0 = dp0 + dq0;
543
43.3M
        int dpq3 = dp3 + dq3;
544
545
43.3M
        int dp = dp0 + dp3;
546
43.3M
        int dq = dq0 + dq3;
547
43.3M
        int d = dpq0 + dpq3;
548
549
43.3M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
14.7M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
11.9M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
9.95M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
14.7M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
12.2M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
10.2M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
14.7M
          if (dSam0 && dSam3) {
560
9.06M
            dE = 2;
561
9.06M
          }
562
5.64M
          else {
563
5.64M
            dE = 1;
564
5.64M
          }
565
566
14.7M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
14.7M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
14.7M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
14.7M
        }
571
572
573
        // 8.7.2.4.4
574
575
43.3M
        if (dE != 0) {
576
14.7M
          bool filterP = true;
577
14.7M
          bool filterQ = true;
578
579
14.7M
          if (vertical) {
580
7.47M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
7.47M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
7.47M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
7.47M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
7.47M
          }
586
7.23M
          else {
587
7.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
7.23M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
7.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
7.23M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
7.23M
          }
593
594
14.7M
          if constexpr (sizeof(pixel_t)==1) {
595
14.7M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
14.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
14.7M
        }
603
43.3M
      }
604
95.2M
    }
605
279k
}
606
607
608
void edge_filtering_luma(de265_image* img, bool vertical,
609
                         int yStart,int yEnd, int xStart,int xEnd)
610
330k
{
611
330k
  if (img->high_bit_depth(0)) {
612
51.2k
    edge_filtering_luma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
613
51.2k
  }
614
279k
  else {
615
279k
    edge_filtering_luma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
616
279k
  }
617
330k
}
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
329k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
329k
  const seq_parameter_set& sps = img->get_sps();
643
644
329k
  const int SubWidthC  = sps.SubWidthC;
645
329k
  const int SubHeightC = sps.SubHeightC;
646
647
329k
  int xIncr = vertical ? 2 : 1;
648
329k
  int yIncr = vertical ? 1 : 2;
649
650
329k
  xIncr *= SubWidthC;
651
329k
  yIncr *= SubHeightC;
652
653
329k
  const int stride = img->get_image_stride(1);
654
655
329k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
329k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
329k
  int bitDepth_C = sps.BitDepth_C;
659
660
1.26M
  for (int y=yStart;y<yEnd;y+=yIncr)
661
47.2M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
46.3M
      int xDi = x << (3-SubWidthC);
663
46.3M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
46.3M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
46.3M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
50.5M
        for (int cplane=0;cplane<2;cplane++) {
673
33.6M
          int cQpPicOffset = (cplane==0 ?
674
16.8M
                              img->get_pps().pic_cb_qp_offset :
675
33.6M
                              img->get_pps().pic_cr_qp_offset);
676
677
33.6M
          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
33.6M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
33.6M
          int QP_P = (vertical ?
700
18.5M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
33.6M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
33.6M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
33.6M
          int QP_C;
704
33.6M
          if (sps.ChromaArrayType == CHROMA_420) {
705
23.8M
            QP_C = table8_22(qP_i);
706
23.8M
          } else {
707
9.81M
            QP_C = std::min(qP_i, 51);
708
9.81M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
33.6M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
33.6M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
33.6M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
33.6M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
33.6M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
33.6M
          int tcPrime = table_8_23_tc[Q];
721
33.6M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
33.6M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
33.6M
          if (vertical) {
726
18.5M
            bool filterP = true;
727
18.5M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
18.5M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
18.5M
            bool filterQ = true;
731
18.5M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
18.5M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
18.5M
            if constexpr (sizeof(pixel_t)==1) {
736
12.4M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
6.11M
            else {
739
6.11M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
6.11M
            }
741
18.5M
          }
742
15.1M
          else {
743
15.1M
            bool filterP = true;
744
15.1M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
15.1M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
15.1M
            bool filterQ = true;
748
15.1M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
15.1M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
15.1M
            if constexpr (sizeof(pixel_t)==1) {
752
11.2M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
3.91M
            else {
755
3.91M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
3.91M
            }
757
15.1M
          }
758
33.6M
        }
759
16.8M
      }
760
46.3M
    }
761
329k
}
void edge_filtering_chroma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
63.8k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
63.8k
  const seq_parameter_set& sps = img->get_sps();
643
644
63.8k
  const int SubWidthC  = sps.SubWidthC;
645
63.8k
  const int SubHeightC = sps.SubHeightC;
646
647
63.8k
  int xIncr = vertical ? 2 : 1;
648
63.8k
  int yIncr = vertical ? 1 : 2;
649
650
63.8k
  xIncr *= SubWidthC;
651
63.8k
  yIncr *= SubHeightC;
652
653
63.8k
  const int stride = img->get_image_stride(1);
654
655
63.8k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
63.8k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
63.8k
  int bitDepth_C = sps.BitDepth_C;
659
660
272k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
18.0M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
17.8M
      int xDi = x << (3-SubWidthC);
663
17.8M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
17.8M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
17.8M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
15.0M
        for (int cplane=0;cplane<2;cplane++) {
673
10.0M
          int cQpPicOffset = (cplane==0 ?
674
5.01M
                              img->get_pps().pic_cb_qp_offset :
675
10.0M
                              img->get_pps().pic_cr_qp_offset);
676
677
10.0M
          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
10.0M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
10.0M
          int QP_P = (vertical ?
700
6.11M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
10.0M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
10.0M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
10.0M
          int QP_C;
704
10.0M
          if (sps.ChromaArrayType == CHROMA_420) {
705
2.52M
            QP_C = table8_22(qP_i);
706
7.49M
          } else {
707
7.49M
            QP_C = std::min(qP_i, 51);
708
7.49M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
10.0M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
10.0M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
10.0M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
10.0M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
10.0M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
10.0M
          int tcPrime = table_8_23_tc[Q];
721
10.0M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
10.0M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
10.0M
          if (vertical) {
726
6.11M
            bool filterP = true;
727
6.11M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
6.11M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
6.11M
            bool filterQ = true;
731
6.11M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
6.11M
            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
6.11M
            else {
739
6.11M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
6.11M
            }
741
6.11M
          }
742
3.91M
          else {
743
3.91M
            bool filterP = true;
744
3.91M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
3.91M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
3.91M
            bool filterQ = true;
748
3.91M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
3.91M
            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
3.91M
            else {
755
3.91M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
3.91M
            }
757
3.91M
          }
758
10.0M
        }
759
5.01M
      }
760
17.8M
    }
761
63.8k
}
void edge_filtering_chroma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
265k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
265k
  const seq_parameter_set& sps = img->get_sps();
643
644
265k
  const int SubWidthC  = sps.SubWidthC;
645
265k
  const int SubHeightC = sps.SubHeightC;
646
647
265k
  int xIncr = vertical ? 2 : 1;
648
265k
  int yIncr = vertical ? 1 : 2;
649
650
265k
  xIncr *= SubWidthC;
651
265k
  yIncr *= SubHeightC;
652
653
265k
  const int stride = img->get_image_stride(1);
654
655
265k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
265k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
265k
  int bitDepth_C = sps.BitDepth_C;
659
660
990k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
29.2M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
28.4M
      int xDi = x << (3-SubWidthC);
663
28.4M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
28.4M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
28.4M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
35.5M
        for (int cplane=0;cplane<2;cplane++) {
673
23.6M
          int cQpPicOffset = (cplane==0 ?
674
11.8M
                              img->get_pps().pic_cb_qp_offset :
675
23.6M
                              img->get_pps().pic_cr_qp_offset);
676
677
23.6M
          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
23.6M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
23.6M
          int QP_P = (vertical ?
700
12.4M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
23.6M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
23.6M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
23.6M
          int QP_C;
704
23.6M
          if (sps.ChromaArrayType == CHROMA_420) {
705
21.3M
            QP_C = table8_22(qP_i);
706
21.3M
          } else {
707
2.31M
            QP_C = std::min(qP_i, 51);
708
2.31M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
23.6M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
23.6M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
23.6M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
23.6M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
23.6M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
23.6M
          int tcPrime = table_8_23_tc[Q];
721
23.6M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
23.6M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
23.6M
          if (vertical) {
726
12.4M
            bool filterP = true;
727
12.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
12.4M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
12.4M
            bool filterQ = true;
731
12.4M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
12.4M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
12.4M
            if constexpr (sizeof(pixel_t)==1) {
736
12.4M
              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
12.4M
          }
742
11.2M
          else {
743
11.2M
            bool filterP = true;
744
11.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
11.2M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
11.2M
            bool filterQ = true;
748
11.2M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
11.2M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
11.2M
            if constexpr (sizeof(pixel_t)==1) {
752
11.2M
              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
11.2M
          }
758
23.6M
        }
759
11.8M
      }
760
28.4M
    }
761
265k
}
762
763
764
void edge_filtering_chroma(de265_image* img, bool vertical, int yStart,int yEnd,
765
                           int xStart,int xEnd)
766
329k
{
767
329k
  if (img->high_bit_depth(1)) {
768
63.8k
    edge_filtering_chroma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
769
63.8k
  }
770
265k
  else {
771
265k
    edge_filtering_chroma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
772
265k
  }
773
329k
}
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
1.76M
{
806
1.76M
  state = Running;
807
1.76M
  img->thread_run(this);
808
809
1.76M
  int xStart=0;
810
1.76M
  int xEnd = img->get_deblk_width();
811
812
1.76M
  int ctbSize = img->get_sps().CtbSizeY;
813
1.76M
  int deblkSize = ctbSize/4;
814
815
1.76M
  int first =  ctb_y    * deblkSize;
816
1.76M
  int last  = (ctb_y+1) * deblkSize;
817
1.76M
  if (last > img->get_deblk_height()) {
818
12.8k
    last = img->get_deblk_height();
819
12.8k
  }
820
821
1.76M
  int finalProgress = CTB_PROGRESS_DEBLK_V;
822
1.76M
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;
823
824
1.76M
  int rightCtb = img->get_sps().PicWidthInCtbsY-1;
825
826
1.76M
  if (vertical) {
827
    // pass 1: vertical
828
829
882k
    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
830
882k
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
831
882k
  }
832
882k
  else {
833
    // pass 2: horizontal
834
835
882k
    if (ctb_y>0) {
836
858k
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
837
858k
    }
838
839
882k
    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);
840
841
882k
    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
842
858k
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
843
858k
    }
844
882k
  }
845
846
  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);
847
848
1.76M
  bool deblocking_enabled;
849
850
  // first pass: check edge flags and whether we have to deblock
851
1.76M
  if (vertical) {
852
882k
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);
853
854
    //for (int x=0;x<=rightCtb;x++) {
855
882k
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
856
    //}
857
882k
  }
858
882k
  else {
859
882k
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
860
882k
  }
861
862
1.76M
  if (deblocking_enabled) {
863
330k
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);
864
865
330k
    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);
866
867
330k
    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
868
329k
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
869
329k
    }
870
330k
  }
871
872
16.3M
  for (int x=0;x<=rightCtb;x++) {
873
14.5M
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
874
14.5M
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
875
14.5M
  }
876
877
1.76M
  state = Finished;
878
1.76M
  img->thread_finishes(this);
879
1.76M
}
880
881
882
void add_deblocking_tasks(image_unit* imgunit)
883
24.3k
{
884
24.3k
  de265_image* img = imgunit->img;
885
24.3k
  decoder_context* ctx = img->decctx;
886
887
24.3k
  int nRows = img->get_sps().PicHeightInCtbsY;
888
889
24.3k
  img->thread_start(nRows*2);
890
891
73.1k
  for (int pass=0;pass<2;pass++)
892
48.7k
    {
893
1.81M
      for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++)
894
1.76M
        {
895
1.76M
          thread_task_deblock_CTBRow* task = new thread_task_deblock_CTBRow;
896
897
1.76M
          task->img   = img;
898
1.76M
          task->ctb_y = y;
899
1.76M
          task->vertical = (pass==0);
900
901
1.76M
          imgunit->tasks.push_back(task);
902
1.76M
          ctx->thread_pool_.add_task(task);
903
1.76M
        }
904
48.7k
    }
905
24.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
}