Coverage Report

Created: 2026-07-30 06:25

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