Coverage Report

Created: 2026-07-16 06:32

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
32.5M
{
37
32.5M
  logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0,
38
32.5M
           log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge);
39
40
32.5M
  int split_transform = img->get_split_transform_flag(x0,y0,trafoDepth);
41
32.5M
  if (split_transform) {
42
6.10M
    int x1 = x0 + ((1<<log2TrafoSize)>>1);
43
6.10M
    int y1 = y0 + ((1<<log2TrafoSize)>>1);
44
45
6.10M
    markTransformBlockBoundary(img,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   filterTopCbEdge);
46
6.10M
    markTransformBlockBoundary(img,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge);
47
6.10M
    markTransformBlockBoundary(img,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   DEBLOCK_FLAG_HORIZ);
48
6.10M
    markTransformBlockBoundary(img,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ);
49
6.10M
  }
50
26.4M
  else {
51
    // VER
52
53
59.9M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
54
33.5M
      img->set_deblk_flags(x0,y0+k, filterLeftCbEdge);
55
33.5M
    }
56
57
    // HOR
58
59
59.9M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
60
33.5M
      img->set_deblk_flags(x0+k,y0, filterTopCbEdge);
61
33.5M
    }
62
26.4M
  }
63
32.5M
}
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
8.12M
{
72
8.12M
  logtrace(LogDeblock,"markPredictionBlockBoundary(%d,%d, %d, %d,%d)\n",x0,y0,
73
8.12M
           log2CbSize, filterLeftCbEdge,filterTopCbEdge);
74
75
8.12M
  enum PartMode partMode = img->get_PartMode(x0,y0);
76
77
8.12M
  int cbSize = 1<<log2CbSize;
78
8.12M
  int cbSize2 = 1<<(log2CbSize-1);
79
8.12M
  int cbSize4 = 1<<(log2CbSize-2);
80
81
8.12M
  switch (partMode) {
82
1.25M
  case PART_NxN:
83
11.3M
    for (int k=0;k<cbSize;k++) {
84
10.0M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
85
10.0M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
86
10.0M
    }
87
1.25M
    break;
88
89
557k
  case PART_Nx2N:
90
6.22M
    for (int k=0;k<cbSize;k++) {
91
5.66M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
92
5.66M
    }
93
557k
    break;
94
95
593k
  case PART_2NxN:
96
7.14M
    for (int k=0;k<cbSize;k++) {
97
6.55M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
98
6.55M
    }
99
593k
    break;
100
101
30.3k
  case PART_nLx2N:
102
693k
    for (int k=0;k<cbSize;k++) {
103
662k
      img->set_deblk_flags(x0+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
104
662k
    }
105
30.3k
    break;
106
107
2.83k
  case PART_nRx2N:
108
61.3k
    for (int k=0;k<cbSize;k++) {
109
58.4k
      img->set_deblk_flags(x0+cbSize2+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
110
58.4k
    }
111
2.83k
    break;
112
113
10.1k
  case PART_2NxnU:
114
231k
    for (int k=0;k<cbSize;k++) {
115
221k
      img->set_deblk_flags(x0+k,y0+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
116
221k
    }
117
10.1k
    break;
118
119
2.63k
  case PART_2NxnD:
120
56.2k
    for (int k=0;k<cbSize;k++) {
121
53.5k
      img->set_deblk_flags(x0+k,y0+cbSize2+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
122
53.5k
    }
123
2.63k
    break;
124
125
5.67M
  case PART_2Nx2N:
126
    // NOP
127
5.67M
    break;
128
8.12M
  }
129
8.12M
}
130
131
132
bool derive_edgeFlags_CTBRow(de265_image* img, uint16_t ctby)
133
46.6k
{
134
46.6k
  const seq_parameter_set& sps = img->get_sps();
135
46.6k
  const pic_parameter_set& pps = img->get_pps();
136
137
46.6k
  const int minCbSize = sps.MinCbSizeY;
138
46.6k
  bool deblocking_enabled=false; // whether deblocking is enabled in some part of the image
139
140
46.6k
  int ctb_mask = (1<<sps.Log2CtbSizeY)-1;
141
46.6k
  int picWidthInCtbs = sps.PicWidthInCtbsY;
142
46.6k
  int ctbshift = sps.Log2CtbSizeY;
143
144
145
46.6k
  uint16_t cb_y_start = ( ctby    << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
146
46.6k
  uint16_t cb_y_end   = ((ctby+1) << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
147
148
46.6k
  cb_y_end = std::min(cb_y_end, sps.PicHeightInMinCbsY);
149
150
180k
  for (int cb_y=cb_y_start;cb_y<cb_y_end;cb_y++)
151
16.7M
    for (int cb_x=0;cb_x<img->get_sps().PicWidthInMinCbsY;cb_x++)
152
16.6M
      {
153
16.6M
        int log2CbSize = img->get_log2CbSize_cbUnits(cb_x,cb_y);
154
16.6M
        if (log2CbSize==0) {
155
8.38M
          continue;
156
8.38M
        }
157
158
        // we are now at the top corner of a CB
159
160
8.23M
        int x0 = cb_x * minCbSize;
161
8.23M
        int y0 = cb_y * minCbSize;
162
163
8.23M
        int x0ctb = x0 >> ctbshift;
164
8.23M
        int y0ctb = y0 >> ctbshift;
165
166
        // check for corrupted streams
167
8.23M
        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
8.23M
        slice_segment_header* shdr = img->get_SliceHeader(x0,y0);
174
175
        // check whether to filter left and top edge
176
177
8.23M
        uint8_t filterLeftCbEdge = DEBLOCK_FLAG_VERTI;
178
8.23M
        uint8_t filterTopCbEdge  = DEBLOCK_FLAG_HORIZ;
179
8.23M
        if (x0 == 0) filterLeftCbEdge = 0;
180
8.23M
        if (y0 == 0) filterTopCbEdge  = 0;
181
182
        // check for slice and tile boundaries (8.7.2, step 2 in both processes)
183
184
8.23M
        if (x0 && ((x0 & ctb_mask) == 0)) { // left edge at CTB boundary
185
3.65M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
186
3.07M
              img->is_SliceHeader_available(x0-1,y0) && // for corrupted streams
187
3.07M
              shdr->SliceAddrRS != img->get_SliceHeader(x0-1,y0)->SliceAddrRS)
188
732
            {
189
732
              filterLeftCbEdge = 0;
190
732
            }
191
3.65M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
192
3.63M
                   pps.scan->TileIdRS[  x0ctb           +y0ctb*picWidthInCtbs] !=
193
3.63M
                   pps.scan->TileIdRS[((x0-1)>>ctbshift)+y0ctb*picWidthInCtbs]) {
194
1.61k
            filterLeftCbEdge = 0;
195
1.61k
          }
196
3.65M
        }
197
198
8.23M
        if (y0 && ((y0 & ctb_mask) == 0)) { // top edge at CTB boundary
199
2.76M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
200
2.24M
              img->is_SliceHeader_available(x0,y0-1) && // for corrupted streams
201
2.24M
              shdr->SliceAddrRS != img->get_SliceHeader(x0,y0-1)->SliceAddrRS)
202
2.81k
            {
203
2.81k
              filterTopCbEdge = 0;
204
2.81k
            }
205
2.76M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
206
2.73M
                   pps.scan->TileIdRS[x0ctb+  y0ctb           *picWidthInCtbs] !=
207
2.73M
                   pps.scan->TileIdRS[x0ctb+((y0-1)>>ctbshift)*picWidthInCtbs]) {
208
17.6k
            filterTopCbEdge = 0;
209
17.6k
          }
210
2.76M
        }
211
212
213
        // mark edges
214
215
8.23M
        if (shdr->slice_deblocking_filter_disabled_flag==0) {
216
8.12M
          deblocking_enabled=true;
217
218
8.12M
          markTransformBlockBoundary(img, x0,y0, log2CbSize,0,
219
8.12M
                                     filterLeftCbEdge, filterTopCbEdge);
220
221
8.12M
          markPredictionBlockBoundary(img, x0,y0, log2CbSize,
222
8.12M
                                      filterLeftCbEdge, filterTopCbEdge);
223
8.12M
        }
224
8.23M
      }
225
226
46.6k
  return deblocking_enabled;
227
46.6k
}
228
229
230
bool derive_edgeFlags(de265_image* img)
231
0
{
232
0
  bool deblocking_enabled=false;
233
234
0
  for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++) {
235
0
    deblocking_enabled |= derive_edgeFlags_CTBRow(img,y);
236
0
  }
237
238
0
  return deblocking_enabled;
239
0
}
240
241
242
// 8.7.2.3 (both, EDGE_VER and EDGE_HOR)
243
void derive_boundaryStrength(de265_image* img, bool vertical, int yStart,int yEnd,
244
                             int xStart,int xEnd)
245
79.2k
{
246
79.2k
  int xIncr = vertical ? 2 : 1;
247
79.2k
  int yIncr = vertical ? 1 : 2;
248
79.2k
  int xOffs = vertical ? 1 : 0;
249
79.2k
  int yOffs = vertical ? 0 : 1;
250
79.2k
  int edgeMask = vertical ?
251
39.6k
    (DEBLOCK_FLAG_VERTI | DEBLOCK_PB_EDGE_VERTI) :
252
79.2k
    (DEBLOCK_FLAG_HORIZ | DEBLOCK_PB_EDGE_HORIZ);
253
79.2k
  int transformEdgeMask = vertical ? DEBLOCK_FLAG_VERTI : DEBLOCK_FLAG_HORIZ;
254
255
79.2k
  xEnd = std::min(xEnd,img->get_deblk_width());
256
79.2k
  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
435k
  for (int y=yStart;y<yEnd;y+=yIncr)
262
60.9M
    for (int x=xStart;x<xEnd;x+=xIncr) {
263
60.6M
      int xDi = x<<2;
264
60.6M
      int yDi = y<<2;
265
266
60.6M
      logtrace(LogDeblock,"%d %d %s = %s\n",xDi,yDi, vertical?"Vertical":"Horizontal",
267
60.6M
               (img->get_deblk_flags(xDi,yDi) & edgeMask) ? "edge" : "...");
268
269
60.6M
      uint8_t edgeFlags = img->get_deblk_flags(xDi,yDi);
270
271
60.6M
      if (edgeFlags & edgeMask) {
272
42.3M
        bool p_is_intra_pred = (img->get_pred_mode(xDi-xOffs, yDi-yOffs) == MODE_INTRA);
273
42.3M
        bool q_is_intra_pred = (img->get_pred_mode(xDi,       yDi      ) == MODE_INTRA);
274
275
42.3M
        int bS;
276
277
42.3M
        if (p_is_intra_pred || q_is_intra_pred) {
278
14.5M
          bS = 2;
279
14.5M
        }
280
27.7M
        else {
281
          // opposing site
282
27.7M
          int xDiOpp = xDi-xOffs;
283
27.7M
          int yDiOpp = yDi-yOffs;
284
285
27.7M
          if ((edgeFlags & transformEdgeMask) &&
286
26.9M
              (img->get_nonzero_coefficient(xDi   ,yDi) ||
287
23.0M
               img->get_nonzero_coefficient(xDiOpp,yDiOpp))) {
288
5.09M
            bS = 1;
289
5.09M
          }
290
22.6M
          else {
291
292
22.6M
            bS = 0;
293
294
22.6M
            const PBMotion& mviP = img->get_mv_info(xDiOpp,yDiOpp);
295
22.6M
            const PBMotion& mviQ = img->get_mv_info(xDi   ,yDi);
296
297
22.6M
            slice_segment_header* shdrP = img->get_SliceHeader(xDiOpp,yDiOpp);
298
22.6M
            slice_segment_header* shdrQ = img->get_SliceHeader(xDi   ,yDi);
299
300
22.6M
      if (shdrP && shdrQ) {
301
302
22.6M
        int refPicP0 = mviP.predFlag[0] ? shdrP->RefPicList[0][ mviP.refIdx[0] ] : -1;
303
22.6M
        int refPicP1 = mviP.predFlag[1] ? shdrP->RefPicList[1][ mviP.refIdx[1] ] : -1;
304
22.6M
        int refPicQ0 = mviQ.predFlag[0] ? shdrQ->RefPicList[0][ mviQ.refIdx[0] ] : -1;
305
22.6M
        int refPicQ1 = mviQ.predFlag[1] ? shdrQ->RefPicList[1][ mviQ.refIdx[1] ] : -1;
306
307
22.6M
        bool samePics = ((refPicP0==refPicQ0 && refPicP1==refPicQ1) ||
308
2.61M
             (refPicP0==refPicQ1 && refPicP1==refPicQ0));
309
310
22.6M
        if (!samePics) {
311
2.42M
    bS = 1;
312
2.42M
        }
313
20.2M
        else {
314
20.2M
    MotionVector mvP0 = mviP.mv[0]; if (!mviP.predFlag[0]) { mvP0.x=mvP0.y=0; }
315
20.2M
    MotionVector mvP1 = mviP.mv[1]; if (!mviP.predFlag[1]) { mvP1.x=mvP1.y=0; }
316
20.2M
    MotionVector mvQ0 = mviQ.mv[0]; if (!mviQ.predFlag[0]) { mvQ0.x=mvQ0.y=0; }
317
20.2M
    MotionVector mvQ1 = mviQ.mv[1]; if (!mviQ.predFlag[1]) { mvQ1.x=mvQ1.y=0; }
318
319
20.2M
    int numMV_P = mviP.predFlag[0] + mviP.predFlag[1];
320
20.2M
    int numMV_Q = mviQ.predFlag[0] + mviQ.predFlag[1];
321
322
20.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
20.2M
    if (refPicP0 != refPicP1) {
329
330
9.72M
      if (refPicP0 == refPicQ0) {
331
9.53M
        if (std::abs(mvP0.x-mvQ0.x) >= 4 ||
332
9.14M
      std::abs(mvP0.y-mvQ0.y) >= 4 ||
333
8.98M
      std::abs(mvP1.x-mvQ1.x) >= 4 ||
334
8.94M
      std::abs(mvP1.y-mvQ1.y) >= 4) {
335
606k
          bS = 1;
336
606k
        }
337
9.53M
      }
338
189k
      else {
339
189k
        if (std::abs(mvP0.x-mvQ1.x) >= 4 ||
340
160k
      std::abs(mvP0.y-mvQ1.y) >= 4 ||
341
144k
      std::abs(mvP1.x-mvQ0.x) >= 4 ||
342
117k
      std::abs(mvP1.y-mvQ0.y) >= 4) {
343
86.1k
          bS = 1;
344
86.1k
        }
345
189k
      }
346
9.72M
    }
347
10.5M
    else {
348
10.5M
      assert(refPicQ0==refPicQ1);
349
350
10.5M
      if ((std::abs(mvP0.x-mvQ0.x) >= 4 ||
351
10.2M
           std::abs(mvP0.y-mvQ0.y) >= 4 ||
352
10.1M
           std::abs(mvP1.x-mvQ1.x) >= 4 ||
353
10.0M
           std::abs(mvP1.y-mvQ1.y) >= 4)
354
516k
          &&
355
516k
          (std::abs(mvP0.x-mvQ1.x) >= 4 ||
356
216k
           std::abs(mvP0.y-mvQ1.y) >= 4 ||
357
123k
           std::abs(mvP1.x-mvQ0.x) >= 4 ||
358
509k
           std::abs(mvP1.y-mvQ0.y) >= 4)) {
359
509k
        bS = 1;
360
509k
      }
361
10.5M
    }
362
20.2M
        }
363
22.6M
      }
364
0
      else {
365
0
        bS = 0; // if shdrP==nullptr or shdrQ==nullptr
366
0
      }
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
22.6M
          }
375
27.7M
        }
376
377
42.3M
        img->set_deblk_bS(xDi,yDi, bS);
378
42.3M
      }
379
18.2M
      else {
380
18.2M
        img->set_deblk_bS(xDi,yDi, 0);
381
18.2M
      }
382
60.6M
    }
383
79.2k
}
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
79.2k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
79.2k
  const seq_parameter_set& sps = img->get_sps();
419
420
79.2k
  int xIncr = vertical ? 2 : 1;
421
79.2k
  int yIncr = vertical ? 1 : 2;
422
423
79.2k
  const int stride = img->get_image_stride(0);
424
425
79.2k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
79.2k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
79.2k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
435k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
60.9M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
60.6M
      int xDi = x<<2; // *4 -> pixel resolution
435
60.6M
      int yDi = y<<2; // *4 -> pixel resolution
436
60.6M
      int bS = img->get_deblk_bS(xDi,yDi);
437
438
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
439
440
60.6M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
60.6M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
442
443
#if 0
444
      {
445
        uint8_t* ptr = img->y + stride*yDi + xDi;
446
447
        for (int dy=-4;dy<4;dy++) {
448
          for (int dx=-4;dx<4;dx++) {
449
            printf("%02x ", ptr[dy*stride + dx]);
450
            if (dx==-1) printf("| ");
451
          }
452
          printf("\n");
453
          if (dy==-1) printf("-------------------------\n");
454
        }
455
      }
456
#endif
457
458
#if 0
459
      if (!vertical)
460
        {
461
          uint8_t* ptr = img->y + stride*yDi + xDi;
462
463
          for (int dy=-4;dy<4;dy++) {
464
            for (int dx=0;dx<4;dx++) {
465
              printf("%02x ", ptr[dy*stride + dx]);
466
              if (dx==-1) printf("| ");
467
            }
468
            printf("\n");
469
            if (dy==-1) printf("-------------------------\n");
470
          }
471
        }
472
#endif
473
474
60.6M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
23.3M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
23.3M
        pixel_t q[4][4], p[4][4];
481
116M
        for (int k=0;k<4;k++)
482
466M
          for (int i=0;i<4;i++)
483
372M
            {
484
372M
              if (vertical) {
485
186M
                q[k][i] = ptr[ i  +k*stride];
486
186M
                p[k][i] = ptr[-i-1+k*stride];
487
186M
              }
488
186M
              else {
489
186M
                q[k][i] = ptr[k + i   *stride];
490
186M
                p[k][i] = ptr[k -(i+1)*stride];
491
186M
              }
492
372M
            }
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
23.3M
        int QP_Q = img->get_QPY(xDi,yDi);
514
23.3M
        int QP_P = (vertical ?
515
11.6M
                    img->get_QPY(xDi-1,yDi) :
516
23.3M
                    img->get_QPY(xDi,yDi-1) );
517
23.3M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
23.3M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
23.3M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
23.3M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
23.3M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
23.3M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
23.3M
        int betaPrime = table_8_23_beta[Q_beta];
527
23.3M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
23.3M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
23.3M
        int tcPrime = table_8_23_tc[Q_tc];
531
23.3M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
23.3M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
23.3M
        int dE=0, dEp=0, dEq=0;
536
537
23.3M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
23.3M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
23.3M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
23.3M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
23.3M
        int dpq0 = dp0 + dq0;
543
23.3M
        int dpq3 = dp3 + dq3;
544
545
23.3M
        int dp = dp0 + dp3;
546
23.3M
        int dq = dq0 + dq3;
547
23.3M
        int d = dpq0 + dpq3;
548
549
23.3M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
16.0M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
13.5M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
12.0M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
16.0M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
13.7M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
12.1M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
16.0M
          if (dSam0 && dSam3) {
560
10.9M
            dE = 2;
561
10.9M
          }
562
5.14M
          else {
563
5.14M
            dE = 1;
564
5.14M
          }
565
566
16.0M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
16.0M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
16.0M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
16.0M
        }
571
572
573
        // 8.7.2.4.4
574
575
23.3M
        if (dE != 0) {
576
16.0M
          bool filterP = true;
577
16.0M
          bool filterQ = true;
578
579
16.0M
          if (vertical) {
580
7.76M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
7.76M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
7.76M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
7.76M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
7.76M
          }
586
8.28M
          else {
587
8.28M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
8.28M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
8.28M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
8.28M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
8.28M
          }
593
594
16.0M
          if constexpr (sizeof(pixel_t)==1) {
595
8.32M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
8.32M
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
7.72M
          else {
599
7.72M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
7.72M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
7.72M
          }
602
16.0M
        }
603
23.3M
      }
604
60.6M
    }
605
79.2k
}
void edge_filtering_luma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
33.8k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
33.8k
  const seq_parameter_set& sps = img->get_sps();
419
420
33.8k
  int xIncr = vertical ? 2 : 1;
421
33.8k
  int yIncr = vertical ? 1 : 2;
422
423
33.8k
  const int stride = img->get_image_stride(0);
424
425
33.8k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
33.8k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
33.8k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
212k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
21.8M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
21.6M
      int xDi = x<<2; // *4 -> pixel resolution
435
21.6M
      int yDi = y<<2; // *4 -> pixel resolution
436
21.6M
      int bS = img->get_deblk_bS(xDi,yDi);
437
438
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
439
440
21.6M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
21.6M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
442
443
#if 0
444
      {
445
        uint8_t* ptr = img->y + stride*yDi + xDi;
446
447
        for (int dy=-4;dy<4;dy++) {
448
          for (int dx=-4;dx<4;dx++) {
449
            printf("%02x ", ptr[dy*stride + dx]);
450
            if (dx==-1) printf("| ");
451
          }
452
          printf("\n");
453
          if (dy==-1) printf("-------------------------\n");
454
        }
455
      }
456
#endif
457
458
#if 0
459
      if (!vertical)
460
        {
461
          uint8_t* ptr = img->y + stride*yDi + xDi;
462
463
          for (int dy=-4;dy<4;dy++) {
464
            for (int dx=0;dx<4;dx++) {
465
              printf("%02x ", ptr[dy*stride + dx]);
466
              if (dx==-1) printf("| ");
467
            }
468
            printf("\n");
469
            if (dy==-1) printf("-------------------------\n");
470
          }
471
        }
472
#endif
473
474
21.6M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
11.8M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
11.8M
        pixel_t q[4][4], p[4][4];
481
59.2M
        for (int k=0;k<4;k++)
482
237M
          for (int i=0;i<4;i++)
483
189M
            {
484
189M
              if (vertical) {
485
97.2M
                q[k][i] = ptr[ i  +k*stride];
486
97.2M
                p[k][i] = ptr[-i-1+k*stride];
487
97.2M
              }
488
92.4M
              else {
489
92.4M
                q[k][i] = ptr[k + i   *stride];
490
92.4M
                p[k][i] = ptr[k -(i+1)*stride];
491
92.4M
              }
492
189M
            }
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
11.8M
        int QP_Q = img->get_QPY(xDi,yDi);
514
11.8M
        int QP_P = (vertical ?
515
6.07M
                    img->get_QPY(xDi-1,yDi) :
516
11.8M
                    img->get_QPY(xDi,yDi-1) );
517
11.8M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
11.8M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
11.8M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
11.8M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
11.8M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
11.8M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
11.8M
        int betaPrime = table_8_23_beta[Q_beta];
527
11.8M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
11.8M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
11.8M
        int tcPrime = table_8_23_tc[Q_tc];
531
11.8M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
11.8M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
11.8M
        int dE=0, dEp=0, dEq=0;
536
537
11.8M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
11.8M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
11.8M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
11.8M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
11.8M
        int dpq0 = dp0 + dq0;
543
11.8M
        int dpq3 = dp3 + dq3;
544
545
11.8M
        int dp = dp0 + dp3;
546
11.8M
        int dq = dq0 + dq3;
547
11.8M
        int d = dpq0 + dpq3;
548
549
11.8M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
7.72M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
6.75M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
6.10M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
7.72M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
6.56M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
5.87M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
7.72M
          if (dSam0 && dSam3) {
560
5.38M
            dE = 2;
561
5.38M
          }
562
2.33M
          else {
563
2.33M
            dE = 1;
564
2.33M
          }
565
566
7.72M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
7.72M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
7.72M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
7.72M
        }
571
572
573
        // 8.7.2.4.4
574
575
11.8M
        if (dE != 0) {
576
7.72M
          bool filterP = true;
577
7.72M
          bool filterQ = true;
578
579
7.72M
          if (vertical) {
580
3.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
3.86M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
3.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
3.86M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
3.86M
          }
586
3.86M
          else {
587
3.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
3.86M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
3.86M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
3.86M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
3.86M
          }
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
7.72M
          else {
599
7.72M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
7.72M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
7.72M
          }
602
7.72M
        }
603
11.8M
      }
604
21.6M
    }
605
33.8k
}
void edge_filtering_luma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
45.3k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
45.3k
  const seq_parameter_set& sps = img->get_sps();
419
420
45.3k
  int xIncr = vertical ? 2 : 1;
421
45.3k
  int yIncr = vertical ? 1 : 2;
422
423
45.3k
  const int stride = img->get_image_stride(0);
424
425
45.3k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
45.3k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
45.3k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
222k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
39.1M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
38.9M
      int xDi = x<<2; // *4 -> pixel resolution
435
38.9M
      int yDi = y<<2; // *4 -> pixel resolution
436
38.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
38.9M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
38.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
38.9M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
11.4M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
11.4M
        pixel_t q[4][4], p[4][4];
481
57.2M
        for (int k=0;k<4;k++)
482
229M
          for (int i=0;i<4;i++)
483
183M
            {
484
183M
              if (vertical) {
485
89.1M
                q[k][i] = ptr[ i  +k*stride];
486
89.1M
                p[k][i] = ptr[-i-1+k*stride];
487
89.1M
              }
488
94.2M
              else {
489
94.2M
                q[k][i] = ptr[k + i   *stride];
490
94.2M
                p[k][i] = ptr[k -(i+1)*stride];
491
94.2M
              }
492
183M
            }
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
11.4M
        int QP_Q = img->get_QPY(xDi,yDi);
514
11.4M
        int QP_P = (vertical ?
515
5.56M
                    img->get_QPY(xDi-1,yDi) :
516
11.4M
                    img->get_QPY(xDi,yDi-1) );
517
11.4M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
11.4M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
11.4M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
11.4M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
11.4M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
11.4M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
11.4M
        int betaPrime = table_8_23_beta[Q_beta];
527
11.4M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
11.4M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
11.4M
        int tcPrime = table_8_23_tc[Q_tc];
531
11.4M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
11.4M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
11.4M
        int dE=0, dEp=0, dEq=0;
536
537
11.4M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
11.4M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
11.4M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
11.4M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
11.4M
        int dpq0 = dp0 + dq0;
543
11.4M
        int dpq3 = dp3 + dq3;
544
545
11.4M
        int dp = dp0 + dp3;
546
11.4M
        int dq = dq0 + dq3;
547
11.4M
        int d = dpq0 + dpq3;
548
549
11.4M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
8.32M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
6.77M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
5.95M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
8.32M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
7.14M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
6.32M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
8.32M
          if (dSam0 && dSam3) {
560
5.51M
            dE = 2;
561
5.51M
          }
562
2.81M
          else {
563
2.81M
            dE = 1;
564
2.81M
          }
565
566
8.32M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
8.32M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
8.32M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
8.32M
        }
571
572
573
        // 8.7.2.4.4
574
575
11.4M
        if (dE != 0) {
576
8.32M
          bool filterP = true;
577
8.32M
          bool filterQ = true;
578
579
8.32M
          if (vertical) {
580
3.89M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
3.89M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
3.89M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
3.89M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
3.89M
          }
586
4.42M
          else {
587
4.42M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
4.42M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
4.42M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
4.42M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
4.42M
          }
593
594
8.32M
          if constexpr (sizeof(pixel_t)==1) {
595
8.32M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
8.32M
                                                     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
8.32M
        }
603
11.4M
      }
604
38.9M
    }
605
45.3k
}
606
607
608
void edge_filtering_luma(de265_image* img, bool vertical,
609
                         int yStart,int yEnd, int xStart,int xEnd)
610
79.2k
{
611
79.2k
  if (img->high_bit_depth(0)) {
612
33.8k
    edge_filtering_luma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
613
33.8k
  }
614
45.3k
  else {
615
45.3k
    edge_filtering_luma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
616
45.3k
  }
617
79.2k
}
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
77.3k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
77.3k
  const seq_parameter_set& sps = img->get_sps();
643
644
77.3k
  const int SubWidthC  = sps.SubWidthC;
645
77.3k
  const int SubHeightC = sps.SubHeightC;
646
647
77.3k
  int xIncr = vertical ? 2 : 1;
648
77.3k
  int yIncr = vertical ? 1 : 2;
649
650
77.3k
  xIncr *= SubWidthC;
651
77.3k
  yIncr *= SubHeightC;
652
653
77.3k
  const int stride = img->get_image_stride(1);
654
655
77.3k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
77.3k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
77.3k
  int bitDepth_C = sps.BitDepth_C;
659
660
330k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
20.4M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
20.2M
      int xDi = x << (3-SubWidthC);
663
20.2M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
20.2M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
20.2M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
16.2M
        for (int cplane=0;cplane<2;cplane++) {
673
10.8M
          int cQpPicOffset = (cplane==0 ?
674
5.42M
                              img->get_pps().pic_cb_qp_offset :
675
10.8M
                              img->get_pps().pic_cr_qp_offset);
676
677
10.8M
          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.8M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
10.8M
          int QP_P = (vertical ?
700
5.78M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
10.8M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
10.8M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
10.8M
          int QP_C;
704
10.8M
          if (sps.ChromaArrayType == CHROMA_420) {
705
5.55M
            QP_C = table8_22(qP_i);
706
5.55M
          } else {
707
5.29M
            QP_C = std::min(qP_i, 51);
708
5.29M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
10.8M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
10.8M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
10.8M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
10.8M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
10.8M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
10.8M
          int tcPrime = table_8_23_tc[Q];
721
10.8M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
10.8M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
10.8M
          if (vertical) {
726
5.78M
            bool filterP = true;
727
5.78M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
5.78M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
5.78M
            bool filterQ = true;
731
5.78M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
5.78M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
5.78M
            if constexpr (sizeof(pixel_t)==1) {
736
4.41M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
1.36M
            else {
739
1.36M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
1.36M
            }
741
5.78M
          }
742
5.07M
          else {
743
5.07M
            bool filterP = true;
744
5.07M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
5.07M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
5.07M
            bool filterQ = true;
748
5.07M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
5.07M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
5.07M
            if constexpr (sizeof(pixel_t)==1) {
752
3.50M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
1.56M
            else {
755
1.56M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
1.56M
            }
757
5.07M
          }
758
10.8M
        }
759
5.42M
      }
760
20.2M
    }
761
77.3k
}
void edge_filtering_chroma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
19.8k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
19.8k
  const seq_parameter_set& sps = img->get_sps();
643
644
19.8k
  const int SubWidthC  = sps.SubWidthC;
645
19.8k
  const int SubHeightC = sps.SubHeightC;
646
647
19.8k
  int xIncr = vertical ? 2 : 1;
648
19.8k
  int yIncr = vertical ? 1 : 2;
649
650
19.8k
  xIncr *= SubWidthC;
651
19.8k
  yIncr *= SubHeightC;
652
653
19.8k
  const int stride = img->get_image_stride(1);
654
655
19.8k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
19.8k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
19.8k
  int bitDepth_C = sps.BitDepth_C;
659
660
106k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
5.32M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
5.23M
      int xDi = x << (3-SubWidthC);
663
5.23M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
5.23M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
5.23M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
4.39M
        for (int cplane=0;cplane<2;cplane++) {
673
2.93M
          int cQpPicOffset = (cplane==0 ?
674
1.46M
                              img->get_pps().pic_cb_qp_offset :
675
2.93M
                              img->get_pps().pic_cr_qp_offset);
676
677
2.93M
          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
2.93M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
2.93M
          int QP_P = (vertical ?
700
1.36M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
2.93M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
2.93M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
2.93M
          int QP_C;
704
2.93M
          if (sps.ChromaArrayType == CHROMA_420) {
705
1.23M
            QP_C = table8_22(qP_i);
706
1.70M
          } else {
707
1.70M
            QP_C = std::min(qP_i, 51);
708
1.70M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
2.93M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
2.93M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
2.93M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
2.93M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
2.93M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
2.93M
          int tcPrime = table_8_23_tc[Q];
721
2.93M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
2.93M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
2.93M
          if (vertical) {
726
1.36M
            bool filterP = true;
727
1.36M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
1.36M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
1.36M
            bool filterQ = true;
731
1.36M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
1.36M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
            if constexpr (sizeof(pixel_t)==1) {
736
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
1.36M
            else {
739
1.36M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
1.36M
            }
741
1.36M
          }
742
1.56M
          else {
743
1.56M
            bool filterP = true;
744
1.56M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
1.56M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
1.56M
            bool filterQ = true;
748
1.56M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
1.56M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
            if constexpr (sizeof(pixel_t)==1) {
752
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
1.56M
            else {
755
1.56M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
1.56M
            }
757
1.56M
          }
758
2.93M
        }
759
1.46M
      }
760
5.23M
    }
761
19.8k
}
void edge_filtering_chroma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
57.5k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
57.5k
  const seq_parameter_set& sps = img->get_sps();
643
644
57.5k
  const int SubWidthC  = sps.SubWidthC;
645
57.5k
  const int SubHeightC = sps.SubHeightC;
646
647
57.5k
  int xIncr = vertical ? 2 : 1;
648
57.5k
  int yIncr = vertical ? 1 : 2;
649
650
57.5k
  xIncr *= SubWidthC;
651
57.5k
  yIncr *= SubHeightC;
652
653
57.5k
  const int stride = img->get_image_stride(1);
654
655
57.5k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
57.5k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
57.5k
  int bitDepth_C = sps.BitDepth_C;
659
660
224k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
15.1M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
14.9M
      int xDi = x << (3-SubWidthC);
663
14.9M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
14.9M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
14.9M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
11.8M
        for (int cplane=0;cplane<2;cplane++) {
673
7.92M
          int cQpPicOffset = (cplane==0 ?
674
3.96M
                              img->get_pps().pic_cb_qp_offset :
675
7.92M
                              img->get_pps().pic_cr_qp_offset);
676
677
7.92M
          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
7.92M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
7.92M
          int QP_P = (vertical ?
700
4.41M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
7.92M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
7.92M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
7.92M
          int QP_C;
704
7.92M
          if (sps.ChromaArrayType == CHROMA_420) {
705
4.32M
            QP_C = table8_22(qP_i);
706
4.32M
          } else {
707
3.59M
            QP_C = std::min(qP_i, 51);
708
3.59M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
7.92M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
7.92M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
7.92M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
7.92M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
7.92M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
7.92M
          int tcPrime = table_8_23_tc[Q];
721
7.92M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
7.92M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
7.92M
          if (vertical) {
726
4.41M
            bool filterP = true;
727
4.41M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
4.41M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
4.41M
            bool filterQ = true;
731
4.41M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
4.41M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
4.41M
            if constexpr (sizeof(pixel_t)==1) {
736
4.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
4.41M
          }
742
3.50M
          else {
743
3.50M
            bool filterP = true;
744
3.50M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
3.50M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
3.50M
            bool filterQ = true;
748
3.50M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
3.50M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
3.50M
            if constexpr (sizeof(pixel_t)==1) {
752
3.50M
              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
3.50M
          }
758
7.92M
        }
759
3.96M
      }
760
14.9M
    }
761
57.5k
}
762
763
764
void edge_filtering_chroma(de265_image* img, bool vertical, int yStart,int yEnd,
765
                           int xStart,int xEnd)
766
77.3k
{
767
77.3k
  if (img->high_bit_depth(1)) {
768
19.8k
    edge_filtering_chroma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
769
19.8k
  }
770
57.5k
  else {
771
57.5k
    edge_filtering_chroma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
772
57.5k
  }
773
77.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
93.2k
{
806
93.2k
  state = Running;
807
93.2k
  img->thread_run(this);
808
809
93.2k
  int xStart=0;
810
93.2k
  int xEnd = img->get_deblk_width();
811
812
93.2k
  int ctbSize = img->get_sps().CtbSizeY;
813
93.2k
  int deblkSize = ctbSize/4;
814
815
93.2k
  int first =  ctb_y    * deblkSize;
816
93.2k
  int last  = (ctb_y+1) * deblkSize;
817
93.2k
  if (last > img->get_deblk_height()) {
818
9.04k
    last = img->get_deblk_height();
819
9.04k
  }
820
821
93.2k
  int finalProgress = CTB_PROGRESS_DEBLK_V;
822
93.2k
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;
823
824
93.2k
  int rightCtb = img->get_sps().PicWidthInCtbsY-1;
825
826
93.2k
  if (vertical) {
827
    // pass 1: vertical
828
829
46.6k
    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
830
46.6k
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
831
46.6k
  }
832
46.6k
  else {
833
    // pass 2: horizontal
834
835
46.6k
    if (ctb_y>0) {
836
34.0k
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
837
34.0k
    }
838
839
46.6k
    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);
840
841
46.6k
    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
842
34.0k
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
843
34.0k
    }
844
46.6k
  }
845
846
  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);
847
848
93.2k
  bool deblocking_enabled;
849
850
  // first pass: check edge flags and whether we have to deblock
851
93.2k
  if (vertical) {
852
46.6k
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);
853
854
    //for (int x=0;x<=rightCtb;x++) {
855
46.6k
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
856
    //}
857
46.6k
  }
858
46.6k
  else {
859
46.6k
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
860
46.6k
  }
861
862
93.2k
  if (deblocking_enabled) {
863
79.2k
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);
864
865
79.2k
    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);
866
867
79.2k
    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
868
77.3k
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
869
77.3k
    }
870
79.2k
  }
871
872
5.49M
  for (int x=0;x<=rightCtb;x++) {
873
5.40M
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
874
5.40M
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
875
5.40M
  }
876
877
93.2k
  state = Finished;
878
93.2k
  img->thread_finishes(this);
879
93.2k
}
880
881
882
void add_deblocking_tasks(image_unit* imgunit)
883
12.5k
{
884
12.5k
  de265_image* img = imgunit->img;
885
12.5k
  decoder_context* ctx = img->decctx;
886
887
12.5k
  int nRows = img->get_sps().PicHeightInCtbsY;
888
889
12.5k
  img->thread_start(nRows*2);
890
891
37.7k
  for (int pass=0;pass<2;pass++)
892
25.1k
    {
893
118k
      for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++)
894
93.2k
        {
895
93.2k
          thread_task_deblock_CTBRow* task = new thread_task_deblock_CTBRow;
896
897
93.2k
          task->img   = img;
898
93.2k
          task->ctb_y = y;
899
93.2k
          task->vertical = (pass==0);
900
901
93.2k
          imgunit->tasks.push_back(task);
902
93.2k
          ctx->thread_pool_.add_task(task);
903
93.2k
        }
904
25.1k
    }
905
12.5k
}
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
}