Coverage Report

Created: 2026-10-28 06:15

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
34.0M
{
37
34.0M
  logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0,
38
34.0M
           log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge);
39
40
34.0M
  int split_transform = img->get_split_transform_flag(x0,y0,trafoDepth);
41
34.0M
  if (split_transform) {
42
5.95M
    int x1 = x0 + ((1<<log2TrafoSize)>>1);
43
5.95M
    int y1 = y0 + ((1<<log2TrafoSize)>>1);
44
45
5.95M
    markTransformBlockBoundary(img,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   filterTopCbEdge);
46
5.95M
    markTransformBlockBoundary(img,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge);
47
5.95M
    markTransformBlockBoundary(img,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   DEBLOCK_FLAG_HORIZ);
48
5.95M
    markTransformBlockBoundary(img,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ);
49
5.95M
  }
50
28.1M
  else {
51
    // VER
52
53
66.0M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
54
37.9M
      img->set_deblk_flags(x0,y0+k, filterLeftCbEdge);
55
37.9M
    }
56
57
    // HOR
58
59
66.0M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
60
37.9M
      img->set_deblk_flags(x0+k,y0, filterTopCbEdge);
61
37.9M
    }
62
28.1M
  }
63
34.0M
}
64
65
66
67
// 8.7.2.2 for both EDGE_HOR and EDGE_VER at the same time
68
void markPredictionBlockBoundary(de265_image* img, int x0,int y0,
69
                                 int log2CbSize,
70
                                 int filterLeftCbEdge, int filterTopCbEdge)
71
10.2M
{
72
10.2M
  logtrace(LogDeblock,"markPredictionBlockBoundary(%d,%d, %d, %d,%d)\n",x0,y0,
73
10.2M
           log2CbSize, filterLeftCbEdge,filterTopCbEdge);
74
75
10.2M
  enum PartMode partMode = img->get_PartMode(x0,y0);
76
77
10.2M
  int cbSize = 1<<log2CbSize;
78
10.2M
  int cbSize2 = 1<<(log2CbSize-1);
79
10.2M
  int cbSize4 = 1<<(log2CbSize-2);
80
81
10.2M
  switch (partMode) {
82
1.97M
  case PART_NxN:
83
17.8M
    for (int k=0;k<cbSize;k++) {
84
15.8M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
85
15.8M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
86
15.8M
    }
87
1.97M
    break;
88
89
683k
  case PART_Nx2N:
90
7.47M
    for (int k=0;k<cbSize;k++) {
91
6.79M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
92
6.79M
    }
93
683k
    break;
94
95
483k
  case PART_2NxN:
96
5.65M
    for (int k=0;k<cbSize;k++) {
97
5.17M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
98
5.17M
    }
99
483k
    break;
100
101
12.5k
  case PART_nLx2N:
102
335k
    for (int k=0;k<cbSize;k++) {
103
322k
      img->set_deblk_flags(x0+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
104
322k
    }
105
12.5k
    break;
106
107
2.38k
  case PART_nRx2N:
108
52.7k
    for (int k=0;k<cbSize;k++) {
109
50.4k
      img->set_deblk_flags(x0+cbSize2+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
110
50.4k
    }
111
2.38k
    break;
112
113
9.77k
  case PART_2NxnU:
114
221k
    for (int k=0;k<cbSize;k++) {
115
212k
      img->set_deblk_flags(x0+k,y0+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
116
212k
    }
117
9.77k
    break;
118
119
2.98k
  case PART_2NxnD:
120
64.6k
    for (int k=0;k<cbSize;k++) {
121
61.6k
      img->set_deblk_flags(x0+k,y0+cbSize2+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
122
61.6k
    }
123
2.98k
    break;
124
125
7.07M
  case PART_2Nx2N:
126
    // NOP
127
7.07M
    break;
128
10.2M
  }
129
10.2M
}
130
131
132
bool derive_edgeFlags_CTBRow(de265_image* img, uint16_t ctby)
133
790k
{
134
790k
  const seq_parameter_set& sps = img->get_sps();
135
790k
  const pic_parameter_set& pps = img->get_pps();
136
137
790k
  const int minCbSize = sps.MinCbSizeY;
138
790k
  bool deblocking_enabled=false; // whether deblocking is enabled in some part of the image
139
140
790k
  int ctb_mask = (1<<sps.Log2CtbSizeY)-1;
141
790k
  int picWidthInCtbs = sps.PicWidthInCtbsY;
142
790k
  int ctbshift = sps.Log2CtbSizeY;
143
144
145
790k
  uint16_t cb_y_start = ( ctby    << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
146
790k
  uint16_t cb_y_end   = ((ctby+1) << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
147
148
790k
  cb_y_end = std::min(cb_y_end, sps.PicHeightInMinCbsY);
149
150
3.67M
  for (int cb_y=cb_y_start;cb_y<cb_y_end;cb_y++)
151
64.2M
    for (int cb_x=0;cb_x<img->get_sps().PicWidthInMinCbsY;cb_x++)
152
61.3M
      {
153
61.3M
        int log2CbSize = img->get_log2CbSize_cbUnits(cb_x,cb_y);
154
61.3M
        if (log2CbSize==0) {
155
49.3M
          continue;
156
49.3M
        }
157
158
        // we are now at the top corner of a CB
159
160
12.0M
        int x0 = cb_x * minCbSize;
161
12.0M
        int y0 = cb_y * minCbSize;
162
163
12.0M
        int x0ctb = x0 >> ctbshift;
164
12.0M
        int y0ctb = y0 >> ctbshift;
165
166
        // check for corrupted streams
167
12.0M
        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
12.0M
        slice_segment_header* shdr = img->get_SliceHeader(x0,y0);
174
175
        // check whether to filter left and top edge
176
177
12.0M
        uint8_t filterLeftCbEdge = DEBLOCK_FLAG_VERTI;
178
12.0M
        uint8_t filterTopCbEdge  = DEBLOCK_FLAG_HORIZ;
179
12.0M
        if (x0 == 0) filterLeftCbEdge = 0;
180
12.0M
        if (y0 == 0) filterTopCbEdge  = 0;
181
182
        // check for slice and tile boundaries (8.7.2, step 2 in both processes)
183
184
12.0M
        if (x0 && ((x0 & ctb_mask) == 0)) { // left edge at CTB boundary
185
4.01M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
186
3.14M
              img->is_SliceHeader_available(x0-1,y0) && // for corrupted streams
187
3.14M
              shdr->SliceAddrRS != img->get_SliceHeader(x0-1,y0)->SliceAddrRS)
188
339
            {
189
339
              filterLeftCbEdge = 0;
190
339
            }
191
4.01M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
192
3.36M
                   pps.scan->TileIdRS[  x0ctb           +y0ctb*picWidthInCtbs] !=
193
3.36M
                   pps.scan->TileIdRS[((x0-1)>>ctbshift)+y0ctb*picWidthInCtbs]) {
194
1.65k
            filterLeftCbEdge = 0;
195
1.65k
          }
196
4.01M
        }
197
198
12.0M
        if (y0 && ((y0 & ctb_mask) == 0)) { // top edge at CTB boundary
199
3.16M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
200
2.22M
              img->is_SliceHeader_available(x0,y0-1) && // for corrupted streams
201
2.22M
              shdr->SliceAddrRS != img->get_SliceHeader(x0,y0-1)->SliceAddrRS)
202
1.56k
            {
203
1.56k
              filterTopCbEdge = 0;
204
1.56k
            }
205
3.16M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
206
2.40M
                   pps.scan->TileIdRS[x0ctb+  y0ctb           *picWidthInCtbs] !=
207
2.40M
                   pps.scan->TileIdRS[x0ctb+((y0-1)>>ctbshift)*picWidthInCtbs]) {
208
2.23k
            filterTopCbEdge = 0;
209
2.23k
          }
210
3.16M
        }
211
212
213
        // mark edges
214
215
12.0M
        if (shdr->slice_deblocking_filter_disabled_flag==0) {
216
10.2M
          deblocking_enabled=true;
217
218
10.2M
          markTransformBlockBoundary(img, x0,y0, log2CbSize,0,
219
10.2M
                                     filterLeftCbEdge, filterTopCbEdge);
220
221
10.2M
          markPredictionBlockBoundary(img, x0,y0, log2CbSize,
222
10.2M
                                      filterLeftCbEdge, filterTopCbEdge);
223
10.2M
        }
224
12.0M
      }
225
226
790k
  return deblocking_enabled;
227
790k
}
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
196k
{
246
196k
  int xIncr = vertical ? 2 : 1;
247
196k
  int yIncr = vertical ? 1 : 2;
248
196k
  int xOffs = vertical ? 1 : 0;
249
196k
  int yOffs = vertical ? 0 : 1;
250
196k
  int edgeMask = vertical ?
251
98.1k
    (DEBLOCK_FLAG_VERTI | DEBLOCK_PB_EDGE_VERTI) :
252
196k
    (DEBLOCK_FLAG_HORIZ | DEBLOCK_PB_EDGE_HORIZ);
253
196k
  int transformEdgeMask = vertical ? DEBLOCK_FLAG_VERTI : DEBLOCK_FLAG_HORIZ;
254
255
196k
  xEnd = std::min(xEnd,img->get_deblk_width());
256
196k
  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
1.11M
  for (int y=yStart;y<yEnd;y+=yIncr)
262
76.9M
    for (int x=xStart;x<xEnd;x+=xIncr) {
263
76.0M
      int xDi = x<<2;
264
76.0M
      int yDi = y<<2;
265
266
76.0M
      logtrace(LogDeblock,"%d %d %s = %s\n",xDi,yDi, vertical?"Vertical":"Horizontal",
267
76.0M
               (img->get_deblk_flags(xDi,yDi) & edgeMask) ? "edge" : "...");
268
269
76.0M
      uint8_t edgeFlags = img->get_deblk_flags(xDi,yDi);
270
271
76.0M
      if (edgeFlags & edgeMask) {
272
50.4M
        bool p_is_intra_pred = (img->get_pred_mode(xDi-xOffs, yDi-yOffs) == MODE_INTRA);
273
50.4M
        bool q_is_intra_pred = (img->get_pred_mode(xDi,       yDi      ) == MODE_INTRA);
274
275
50.4M
        int bS;
276
277
50.4M
        if (p_is_intra_pred || q_is_intra_pred) {
278
20.0M
          bS = 2;
279
20.0M
        }
280
30.3M
        else {
281
          // opposing site
282
30.3M
          int xDiOpp = xDi-xOffs;
283
30.3M
          int yDiOpp = yDi-yOffs;
284
285
30.3M
          if ((edgeFlags & transformEdgeMask) &&
286
29.6M
              (img->get_nonzero_coefficient(xDi   ,yDi) ||
287
25.4M
               img->get_nonzero_coefficient(xDiOpp,yDiOpp))) {
288
5.02M
            bS = 1;
289
5.02M
          }
290
25.3M
          else {
291
292
25.3M
            bS = 0;
293
294
25.3M
            const PBMotion& mviP = img->get_mv_info(xDiOpp,yDiOpp);
295
25.3M
            const PBMotion& mviQ = img->get_mv_info(xDi   ,yDi);
296
297
25.3M
            slice_segment_header* shdrP = img->get_SliceHeader(xDiOpp,yDiOpp);
298
25.3M
            slice_segment_header* shdrQ = img->get_SliceHeader(xDi   ,yDi);
299
300
25.3M
      if (shdrP && shdrQ) {
301
302
25.3M
        int refPicP0 = mviP.predFlag[0] ? shdrP->RefPicList[0][ mviP.refIdx[0] ] : -1;
303
25.3M
        int refPicP1 = mviP.predFlag[1] ? shdrP->RefPicList[1][ mviP.refIdx[1] ] : -1;
304
25.3M
        int refPicQ0 = mviQ.predFlag[0] ? shdrQ->RefPicList[0][ mviQ.refIdx[0] ] : -1;
305
25.3M
        int refPicQ1 = mviQ.predFlag[1] ? shdrQ->RefPicList[1][ mviQ.refIdx[1] ] : -1;
306
307
25.3M
        bool samePics = ((refPicP0==refPicQ0 && refPicP1==refPicQ1) ||
308
2.58M
             (refPicP0==refPicQ1 && refPicP1==refPicQ0));
309
310
25.3M
        if (!samePics) {
311
2.38M
    bS = 1;
312
2.38M
        }
313
22.9M
        else {
314
22.9M
    MotionVector mvP0 = mviP.mv[0]; if (!mviP.predFlag[0]) { mvP0.x=mvP0.y=0; }
315
22.9M
    MotionVector mvP1 = mviP.mv[1]; if (!mviP.predFlag[1]) { mvP1.x=mvP1.y=0; }
316
22.9M
    MotionVector mvQ0 = mviQ.mv[0]; if (!mviQ.predFlag[0]) { mvQ0.x=mvQ0.y=0; }
317
22.9M
    MotionVector mvQ1 = mviQ.mv[1]; if (!mviQ.predFlag[1]) { mvQ1.x=mvQ1.y=0; }
318
319
22.9M
    int numMV_P = mviP.predFlag[0] + mviP.predFlag[1];
320
22.9M
    int numMV_Q = mviQ.predFlag[0] + mviQ.predFlag[1];
321
322
22.9M
    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
22.9M
    if (refPicP0 != refPicP1) {
329
330
12.5M
      if (refPicP0 == refPicQ0) {
331
12.3M
        if (std::abs(mvP0.x-mvQ0.x) >= 4 ||
332
11.8M
      std::abs(mvP0.y-mvQ0.y) >= 4 ||
333
11.7M
      std::abs(mvP1.x-mvQ1.x) >= 4 ||
334
11.7M
      std::abs(mvP1.y-mvQ1.y) >= 4) {
335
590k
          bS = 1;
336
590k
        }
337
12.3M
      }
338
203k
      else {
339
203k
        if (std::abs(mvP0.x-mvQ1.x) >= 4 ||
340
187k
      std::abs(mvP0.y-mvQ1.y) >= 4 ||
341
176k
      std::abs(mvP1.x-mvQ0.x) >= 4 ||
342
158k
      std::abs(mvP1.y-mvQ0.y) >= 4) {
343
57.3k
          bS = 1;
344
57.3k
        }
345
203k
      }
346
12.5M
    }
347
10.4M
    else {
348
10.4M
      assert(refPicQ0==refPicQ1);
349
350
10.4M
      if ((std::abs(mvP0.x-mvQ0.x) >= 4 ||
351
10.1M
           std::abs(mvP0.y-mvQ0.y) >= 4 ||
352
10.0M
           std::abs(mvP1.x-mvQ1.x) >= 4 ||
353
10.0M
           std::abs(mvP1.y-mvQ1.y) >= 4)
354
389k
          &&
355
389k
          (std::abs(mvP0.x-mvQ1.x) >= 4 ||
356
181k
           std::abs(mvP0.y-mvQ1.y) >= 4 ||
357
97.1k
           std::abs(mvP1.x-mvQ0.x) >= 4 ||
358
382k
           std::abs(mvP1.y-mvQ0.y) >= 4)) {
359
382k
        bS = 1;
360
382k
      }
361
10.4M
    }
362
22.9M
        }
363
25.3M
      }
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
25.3M
          }
375
30.3M
        }
376
377
50.4M
        img->set_deblk_bS(xDi,yDi, bS);
378
50.4M
      }
379
25.6M
      else {
380
25.6M
        img->set_deblk_bS(xDi,yDi, 0);
381
25.6M
      }
382
76.0M
    }
383
196k
}
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
196k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
196k
  const seq_parameter_set& sps = img->get_sps();
419
420
196k
  int xIncr = vertical ? 2 : 1;
421
196k
  int yIncr = vertical ? 1 : 2;
422
423
196k
  const int stride = img->get_image_stride(0);
424
425
196k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
196k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
196k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
1.11M
  for (int y=yStart;y<yEnd;y+=yIncr)
431
76.9M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
76.0M
      int xDi = x<<2; // *4 -> pixel resolution
435
76.0M
      int yDi = y<<2; // *4 -> pixel resolution
436
76.0M
      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
76.0M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
76.0M
               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
76.0M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
28.5M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
28.5M
        pixel_t q[4][4], p[4][4];
481
142M
        for (int k=0;k<4;k++)
482
570M
          for (int i=0;i<4;i++)
483
456M
            {
484
456M
              if (vertical) {
485
236M
                q[k][i] = ptr[ i  +k*stride];
486
236M
                p[k][i] = ptr[-i-1+k*stride];
487
236M
              }
488
219M
              else {
489
219M
                q[k][i] = ptr[k + i   *stride];
490
219M
                p[k][i] = ptr[k -(i+1)*stride];
491
219M
              }
492
456M
            }
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
28.5M
        int QP_Q = img->get_QPY(xDi,yDi);
514
28.5M
        int QP_P = (vertical ?
515
14.7M
                    img->get_QPY(xDi-1,yDi) :
516
28.5M
                    img->get_QPY(xDi,yDi-1) );
517
28.5M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
28.5M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
28.5M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
28.5M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
28.5M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
28.5M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
28.5M
        int betaPrime = table_8_23_beta[Q_beta];
527
28.5M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
28.5M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
28.5M
        int tcPrime = table_8_23_tc[Q_tc];
531
28.5M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
28.5M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
28.5M
        int dE=0, dEp=0, dEq=0;
536
537
28.5M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
28.5M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
28.5M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
28.5M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
28.5M
        int dpq0 = dp0 + dq0;
543
28.5M
        int dpq3 = dp3 + dq3;
544
545
28.5M
        int dp = dp0 + dp3;
546
28.5M
        int dq = dq0 + dq3;
547
28.5M
        int d = dpq0 + dpq3;
548
549
28.5M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
18.3M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
15.4M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
13.9M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
18.3M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
15.3M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
13.7M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
18.3M
          if (dSam0 && dSam3) {
560
12.5M
            dE = 2;
561
12.5M
          }
562
5.80M
          else {
563
5.80M
            dE = 1;
564
5.80M
          }
565
566
18.3M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
18.3M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
18.3M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
18.3M
        }
571
572
573
        // 8.7.2.4.4
574
575
28.5M
        if (dE != 0) {
576
18.3M
          bool filterP = true;
577
18.3M
          bool filterQ = true;
578
579
18.3M
          if (vertical) {
580
9.15M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
9.15M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
9.15M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
9.15M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
9.15M
          }
586
9.14M
          else {
587
9.14M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
9.14M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
9.14M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
9.14M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
9.14M
          }
593
594
18.3M
          if constexpr (sizeof(pixel_t)==1) {
595
9.44M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
9.44M
                                                     dE,dEp,dEq,tc, filterP,filterQ);
597
          }
598
8.85M
          else {
599
8.85M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
8.85M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
8.85M
          }
602
18.3M
        }
603
28.5M
      }
604
76.0M
    }
605
196k
}
void edge_filtering_luma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
30.4k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
30.4k
  const seq_parameter_set& sps = img->get_sps();
419
420
30.4k
  int xIncr = vertical ? 2 : 1;
421
30.4k
  int yIncr = vertical ? 1 : 2;
422
423
30.4k
  const int stride = img->get_image_stride(0);
424
425
30.4k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
30.4k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
30.4k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
196k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
34.2M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
34.0M
      int xDi = x<<2; // *4 -> pixel resolution
435
34.0M
      int yDi = y<<2; // *4 -> pixel resolution
436
34.0M
      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
34.0M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
34.0M
               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
34.0M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
14.6M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
14.6M
        pixel_t q[4][4], p[4][4];
481
73.1M
        for (int k=0;k<4;k++)
482
292M
          for (int i=0;i<4;i++)
483
233M
            {
484
233M
              if (vertical) {
485
118M
                q[k][i] = ptr[ i  +k*stride];
486
118M
                p[k][i] = ptr[-i-1+k*stride];
487
118M
              }
488
115M
              else {
489
115M
                q[k][i] = ptr[k + i   *stride];
490
115M
                p[k][i] = ptr[k -(i+1)*stride];
491
115M
              }
492
233M
            }
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
14.6M
        int QP_Q = img->get_QPY(xDi,yDi);
514
14.6M
        int QP_P = (vertical ?
515
7.41M
                    img->get_QPY(xDi-1,yDi) :
516
14.6M
                    img->get_QPY(xDi,yDi-1) );
517
14.6M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
14.6M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
14.6M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
14.6M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
14.6M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
14.6M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
14.6M
        int betaPrime = table_8_23_beta[Q_beta];
527
14.6M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
14.6M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
14.6M
        int tcPrime = table_8_23_tc[Q_tc];
531
14.6M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
14.6M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
14.6M
        int dE=0, dEp=0, dEq=0;
536
537
14.6M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
14.6M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
14.6M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
14.6M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
14.6M
        int dpq0 = dp0 + dq0;
543
14.6M
        int dpq3 = dp3 + dq3;
544
545
14.6M
        int dp = dp0 + dp3;
546
14.6M
        int dq = dq0 + dq3;
547
14.6M
        int d = dpq0 + dpq3;
548
549
14.6M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
8.85M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
7.91M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
7.46M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
8.85M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
7.59M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
7.12M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
8.85M
          if (dSam0 && dSam3) {
560
6.68M
            dE = 2;
561
6.68M
          }
562
2.17M
          else {
563
2.17M
            dE = 1;
564
2.17M
          }
565
566
8.85M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
8.85M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
8.85M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
8.85M
        }
571
572
573
        // 8.7.2.4.4
574
575
14.6M
        if (dE != 0) {
576
8.85M
          bool filterP = true;
577
8.85M
          bool filterQ = true;
578
579
8.85M
          if (vertical) {
580
4.27M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
4.27M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
4.27M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
4.27M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
4.27M
          }
586
4.57M
          else {
587
4.57M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
4.57M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
4.57M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
4.57M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
4.57M
          }
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
8.85M
          else {
599
8.85M
            deblock_luma_kernel<pixel_t>(ptr, stride, vertical,
600
8.85M
                                         dE,dEp,dEq,tc, filterP,filterQ, bitDepth_Y);
601
8.85M
          }
602
8.85M
        }
603
14.6M
      }
604
34.0M
    }
605
30.4k
}
void edge_filtering_luma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
415
165k
{
416
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
417
418
165k
  const seq_parameter_set& sps = img->get_sps();
419
420
165k
  int xIncr = vertical ? 2 : 1;
421
165k
  int yIncr = vertical ? 1 : 2;
422
423
165k
  const int stride = img->get_image_stride(0);
424
425
165k
  int bitDepth_Y = sps.BitDepth_Y;
426
427
165k
  xEnd = std::min(xEnd,img->get_deblk_width());
428
165k
  yEnd = std::min(yEnd,img->get_deblk_height());
429
430
915k
  for (int y=yStart;y<yEnd;y+=yIncr)
431
42.7M
    for (int x=xStart;x<xEnd;x+=xIncr) {
432
      // x;y in deblocking units (4x4 pixels)
433
434
41.9M
      int xDi = x<<2; // *4 -> pixel resolution
435
41.9M
      int yDi = y<<2; // *4 -> pixel resolution
436
41.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
41.9M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
441
41.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
41.9M
      if (bS>0) {
475
476
        // 8.7.2.4.3
477
478
13.8M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
479
480
13.8M
        pixel_t q[4][4], p[4][4];
481
69.4M
        for (int k=0;k<4;k++)
482
277M
          for (int i=0;i<4;i++)
483
222M
            {
484
222M
              if (vertical) {
485
117M
                q[k][i] = ptr[ i  +k*stride];
486
117M
                p[k][i] = ptr[-i-1+k*stride];
487
117M
              }
488
104M
              else {
489
104M
                q[k][i] = ptr[k + i   *stride];
490
104M
                p[k][i] = ptr[k -(i+1)*stride];
491
104M
              }
492
222M
            }
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
13.8M
        int QP_Q = img->get_QPY(xDi,yDi);
514
13.8M
        int QP_P = (vertical ?
515
7.36M
                    img->get_QPY(xDi-1,yDi) :
516
13.8M
                    img->get_QPY(xDi,yDi-1) );
517
13.8M
        int qP_L = (QP_Q+QP_P+1)>>1;
518
519
13.8M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
520
521
13.8M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
522
13.8M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
523
13.8M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
524
525
13.8M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
526
13.8M
        int betaPrime = table_8_23_beta[Q_beta];
527
13.8M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
528
529
13.8M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
530
13.8M
        int tcPrime = table_8_23_tc[Q_tc];
531
13.8M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
532
533
13.8M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
534
535
13.8M
        int dE=0, dEp=0, dEq=0;
536
537
13.8M
        int dp0 = std::abs(p[0][2] - 2*p[0][1] + p[0][0]);
538
13.8M
        int dp3 = std::abs(p[3][2] - 2*p[3][1] + p[3][0]);
539
13.8M
        int dq0 = std::abs(q[0][2] - 2*q[0][1] + q[0][0]);
540
13.8M
        int dq3 = std::abs(q[3][2] - 2*q[3][1] + q[3][0]);
541
542
13.8M
        int dpq0 = dp0 + dq0;
543
13.8M
        int dpq3 = dp3 + dq3;
544
545
13.8M
        int dp = dp0 + dp3;
546
13.8M
        int dq = dq0 + dq3;
547
13.8M
        int d = dpq0 + dpq3;
548
549
13.8M
        if (d < beta) {
550
          //int dpq = 2*dpq0;
551
9.44M
          bool dSam0 = (2 * dpq0 < (beta >> 2) &&
552
7.54M
                        std::abs(p[0][3]-p[0][0]) + std::abs(q[0][0]-q[0][3]) < (beta >> 3) &&
553
6.43M
                        std::abs(p[0][0]-q[0][0]) < ((5 * tc + 1) >> 1));
554
555
9.44M
          bool dSam3 = (2 * dpq3 < (beta >> 2) &&
556
7.77M
                        std::abs(p[3][3]-p[3][0]) + std::abs(q[3][0]-q[3][3]) < (beta >> 3) &&
557
6.66M
                        std::abs(p[3][0]-q[3][0]) < ((5 * tc + 1) >> 1));
558
559
9.44M
          if (dSam0 && dSam3) {
560
5.81M
            dE = 2;
561
5.81M
          }
562
3.62M
          else {
563
3.62M
            dE = 1;
564
3.62M
          }
565
566
9.44M
          if (dp < ((beta + (beta >> 1)) >> 3)) { dEp = 1; }
567
9.44M
          if (dq < ((beta + (beta >> 1)) >> 3)) { dEq = 1; }
568
569
9.44M
          logtrace(LogDeblock, "dE:%d dEp:%d dEq:%d\n", dE, dEp, dEq);
570
9.44M
        }
571
572
573
        // 8.7.2.4.4
574
575
13.8M
        if (dE != 0) {
576
9.44M
          bool filterP = true;
577
9.44M
          bool filterQ = true;
578
579
9.44M
          if (vertical) {
580
4.87M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
581
4.87M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
582
583
4.87M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
584
4.87M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
585
4.87M
          }
586
4.57M
          else {
587
4.57M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
588
4.57M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
589
590
4.57M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
591
4.57M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
592
4.57M
          }
593
594
9.44M
          if constexpr (sizeof(pixel_t)==1) {
595
9.44M
            img->decctx->acceleration.deblock_luma_8((uint8_t*)ptr, stride, vertical,
596
9.44M
                                                     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
9.44M
        }
603
13.8M
      }
604
41.9M
    }
605
165k
}
606
607
608
void edge_filtering_luma(de265_image* img, bool vertical,
609
                         int yStart,int yEnd, int xStart,int xEnd)
610
196k
{
611
196k
  if (img->high_bit_depth(0)) {
612
30.4k
    edge_filtering_luma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
613
30.4k
  }
614
165k
  else {
615
165k
    edge_filtering_luma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
616
165k
  }
617
196k
}
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
195k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
195k
  const seq_parameter_set& sps = img->get_sps();
643
644
195k
  const int SubWidthC  = sps.SubWidthC;
645
195k
  const int SubHeightC = sps.SubHeightC;
646
647
195k
  int xIncr = vertical ? 2 : 1;
648
195k
  int yIncr = vertical ? 1 : 2;
649
650
195k
  xIncr *= SubWidthC;
651
195k
  yIncr *= SubHeightC;
652
653
195k
  const int stride = img->get_image_stride(1);
654
655
195k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
195k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
195k
  int bitDepth_C = sps.BitDepth_C;
659
660
725k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
28.3M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
27.8M
      int xDi = x << (3-SubWidthC);
663
27.8M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
27.8M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
27.8M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
23.1M
        for (int cplane=0;cplane<2;cplane++) {
673
15.4M
          int cQpPicOffset = (cplane==0 ?
674
7.71M
                              img->get_pps().pic_cb_qp_offset :
675
15.4M
                              img->get_pps().pic_cr_qp_offset);
676
677
15.4M
          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
15.4M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
15.4M
          int QP_P = (vertical ?
700
9.21M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
15.4M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
15.4M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
15.4M
          int QP_C;
704
15.4M
          if (sps.ChromaArrayType == CHROMA_420) {
705
7.60M
            QP_C = table8_22(qP_i);
706
7.83M
          } else {
707
7.83M
            QP_C = std::min(qP_i, 51);
708
7.83M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
15.4M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
15.4M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
15.4M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
15.4M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
15.4M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
15.4M
          int tcPrime = table_8_23_tc[Q];
721
15.4M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
15.4M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
15.4M
          if (vertical) {
726
9.21M
            bool filterP = true;
727
9.21M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
9.21M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
9.21M
            bool filterQ = true;
731
9.21M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
9.21M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
9.21M
            if constexpr (sizeof(pixel_t)==1) {
736
4.02M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 1, tc, filterP,filterQ);
737
            }
738
5.19M
            else {
739
5.19M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
5.19M
            }
741
9.21M
          }
742
6.22M
          else {
743
6.22M
            bool filterP = true;
744
6.22M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
6.22M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
6.22M
            bool filterQ = true;
748
6.22M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
6.22M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
6.22M
            if constexpr (sizeof(pixel_t)==1) {
752
3.02M
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
3.19M
            else {
755
3.19M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
3.19M
            }
757
6.22M
          }
758
15.4M
        }
759
7.71M
      }
760
27.8M
    }
761
195k
}
void edge_filtering_chroma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
20.3k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
20.3k
  const seq_parameter_set& sps = img->get_sps();
643
644
20.3k
  const int SubWidthC  = sps.SubWidthC;
645
20.3k
  const int SubHeightC = sps.SubHeightC;
646
647
20.3k
  int xIncr = vertical ? 2 : 1;
648
20.3k
  int yIncr = vertical ? 1 : 2;
649
650
20.3k
  xIncr *= SubWidthC;
651
20.3k
  yIncr *= SubHeightC;
652
653
20.3k
  const int stride = img->get_image_stride(1);
654
655
20.3k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
20.3k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
20.3k
  int bitDepth_C = sps.BitDepth_C;
659
660
116k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
13.6M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
13.5M
      int xDi = x << (3-SubWidthC);
663
13.5M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
13.5M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
13.5M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
12.5M
        for (int cplane=0;cplane<2;cplane++) {
673
8.38M
          int cQpPicOffset = (cplane==0 ?
674
4.19M
                              img->get_pps().pic_cb_qp_offset :
675
8.38M
                              img->get_pps().pic_cr_qp_offset);
676
677
8.38M
          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
8.38M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
8.38M
          int QP_P = (vertical ?
700
5.19M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
8.38M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
8.38M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
8.38M
          int QP_C;
704
8.38M
          if (sps.ChromaArrayType == CHROMA_420) {
705
2.19M
            QP_C = table8_22(qP_i);
706
6.19M
          } else {
707
6.19M
            QP_C = std::min(qP_i, 51);
708
6.19M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
8.38M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
8.38M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
8.38M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
8.38M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
8.38M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
8.38M
          int tcPrime = table_8_23_tc[Q];
721
8.38M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
8.38M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
8.38M
          if (vertical) {
726
5.19M
            bool filterP = true;
727
5.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
5.19M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
5.19M
            bool filterQ = true;
731
5.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
5.19M
            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
5.19M
            else {
739
5.19M
              deblock_chroma_kernel<pixel_t>(ptr, stride, true, tc, filterP,filterQ, bitDepth_C);
740
5.19M
            }
741
5.19M
          }
742
3.19M
          else {
743
3.19M
            bool filterP = true;
744
3.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
3.19M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
3.19M
            bool filterQ = true;
748
3.19M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
3.19M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
            if constexpr (sizeof(pixel_t)==1) {
752
              img->decctx->acceleration.deblock_chroma_8((uint8_t*)ptr, stride, 0, tc, filterP,filterQ);
753
            }
754
3.19M
            else {
755
3.19M
              deblock_chroma_kernel<pixel_t>(ptr, stride, false, tc, filterP,filterQ, bitDepth_C);
756
3.19M
            }
757
3.19M
          }
758
8.38M
        }
759
4.19M
      }
760
13.5M
    }
761
20.3k
}
void edge_filtering_chroma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
639
174k
{
640
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
641
642
174k
  const seq_parameter_set& sps = img->get_sps();
643
644
174k
  const int SubWidthC  = sps.SubWidthC;
645
174k
  const int SubHeightC = sps.SubHeightC;
646
647
174k
  int xIncr = vertical ? 2 : 1;
648
174k
  int yIncr = vertical ? 1 : 2;
649
650
174k
  xIncr *= SubWidthC;
651
174k
  yIncr *= SubHeightC;
652
653
174k
  const int stride = img->get_image_stride(1);
654
655
174k
  xEnd = std::min(xEnd,img->get_deblk_width());
656
174k
  yEnd = std::min(yEnd,img->get_deblk_height());
657
658
174k
  int bitDepth_C = sps.BitDepth_C;
659
660
608k
  for (int y=yStart;y<yEnd;y+=yIncr)
661
14.6M
    for (int x=xStart;x<xEnd;x+=xIncr) {
662
14.2M
      int xDi = x << (3-SubWidthC);
663
14.2M
      int yDi = y << (3-SubHeightC);
664
665
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
666
667
14.2M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
668
669
14.2M
      if (bS>1) {
670
        // 8.7.2.4.5
671
672
10.5M
        for (int cplane=0;cplane<2;cplane++) {
673
7.05M
          int cQpPicOffset = (cplane==0 ?
674
3.52M
                              img->get_pps().pic_cb_qp_offset :
675
7.05M
                              img->get_pps().pic_cr_qp_offset);
676
677
7.05M
          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.05M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
699
7.05M
          int QP_P = (vertical ?
700
4.02M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
701
7.05M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
702
7.05M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
703
7.05M
          int QP_C;
704
7.05M
          if (sps.ChromaArrayType == CHROMA_420) {
705
5.41M
            QP_C = table8_22(qP_i);
706
5.41M
          } else {
707
1.64M
            QP_C = std::min(qP_i, 51);
708
1.64M
          }
709
710
711
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
712
7.05M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
713
7.05M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
714
715
7.05M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
716
7.05M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
717
718
7.05M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
719
720
7.05M
          int tcPrime = table_8_23_tc[Q];
721
7.05M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
722
723
7.05M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
724
725
7.05M
          if (vertical) {
726
4.02M
            bool filterP = true;
727
4.02M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
728
4.02M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
729
730
4.02M
            bool filterQ = true;
731
4.02M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
732
4.02M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
733
734
735
4.02M
            if constexpr (sizeof(pixel_t)==1) {
736
4.02M
              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.02M
          }
742
3.02M
          else {
743
3.02M
            bool filterP = true;
744
3.02M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
745
3.02M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
746
747
3.02M
            bool filterQ = true;
748
3.02M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
749
3.02M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
750
751
3.02M
            if constexpr (sizeof(pixel_t)==1) {
752
3.02M
              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.02M
          }
758
7.05M
        }
759
3.52M
      }
760
14.2M
    }
761
174k
}
762
763
764
void edge_filtering_chroma(de265_image* img, bool vertical, int yStart,int yEnd,
765
                           int xStart,int xEnd)
766
195k
{
767
195k
  if (img->high_bit_depth(1)) {
768
20.3k
    edge_filtering_chroma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
769
20.3k
  }
770
174k
  else {
771
174k
    edge_filtering_chroma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
772
174k
  }
773
195k
}
774
775
776
void edge_filtering_chroma_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
777
0
{
778
0
  int ctbSize = img->get_sps().CtbSizeY;
779
0
  int deblkSize = ctbSize/4;
780
781
0
  edge_filtering_chroma(img,vertical,
782
0
                        yCtb*deblkSize, (yCtb+1)*deblkSize,
783
0
                        xCtb*deblkSize, (xCtb+1)*deblkSize);
784
0
}
785
786
787
788
class thread_task_deblock_CTBRow : public thread_task
789
{
790
public:
791
  struct de265_image* img;
792
  int  ctb_y;
793
  bool vertical;
794
795
  virtual void work();
796
0
  virtual std::string name() const {
797
0
    char buf[100];
798
0
    sprintf(buf,"deblock-%d",ctb_y);
799
0
    return buf;
800
0
  }
801
};
802
803
804
void thread_task_deblock_CTBRow::work()
805
1.58M
{
806
1.58M
  state = Running;
807
1.58M
  img->thread_run(this);
808
809
1.58M
  int xStart=0;
810
1.58M
  int xEnd = img->get_deblk_width();
811
812
1.58M
  int ctbSize = img->get_sps().CtbSizeY;
813
1.58M
  int deblkSize = ctbSize/4;
814
815
1.58M
  int first =  ctb_y    * deblkSize;
816
1.58M
  int last  = (ctb_y+1) * deblkSize;
817
1.58M
  if (last > img->get_deblk_height()) {
818
4.71k
    last = img->get_deblk_height();
819
4.71k
  }
820
821
1.58M
  int finalProgress = CTB_PROGRESS_DEBLK_V;
822
1.58M
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;
823
824
1.58M
  int rightCtb = img->get_sps().PicWidthInCtbsY-1;
825
826
1.58M
  if (vertical) {
827
    // pass 1: vertical
828
829
790k
    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
830
790k
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
831
790k
  }
832
790k
  else {
833
    // pass 2: horizontal
834
835
790k
    if (ctb_y>0) {
836
778k
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
837
778k
    }
838
839
790k
    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);
840
841
790k
    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
842
778k
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
843
778k
    }
844
790k
  }
845
846
  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);
847
848
1.58M
  bool deblocking_enabled;
849
850
  // first pass: check edge flags and whether we have to deblock
851
1.58M
  if (vertical) {
852
790k
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);
853
854
    //for (int x=0;x<=rightCtb;x++) {
855
790k
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
856
    //}
857
790k
  }
858
790k
  else {
859
790k
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
860
790k
  }
861
862
1.58M
  if (deblocking_enabled) {
863
196k
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);
864
865
196k
    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);
866
867
196k
    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
868
195k
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
869
195k
    }
870
196k
  }
871
872
13.1M
  for (int x=0;x<=rightCtb;x++) {
873
11.6M
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
874
11.6M
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
875
11.6M
  }
876
877
1.58M
  state = Finished;
878
1.58M
  img->thread_finishes(this);
879
1.58M
}
880
881
882
void add_deblocking_tasks(image_unit* imgunit)
883
12.2k
{
884
12.2k
  de265_image* img = imgunit->img;
885
12.2k
  decoder_context* ctx = img->decctx;
886
887
12.2k
  int nRows = img->get_sps().PicHeightInCtbsY;
888
889
12.2k
  img->thread_start(nRows*2);
890
891
36.7k
  for (int pass=0;pass<2;pass++)
892
24.4k
    {
893
1.60M
      for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++)
894
1.58M
        {
895
1.58M
          thread_task_deblock_CTBRow* task = new thread_task_deblock_CTBRow;
896
897
1.58M
          task->img   = img;
898
1.58M
          task->ctb_y = y;
899
1.58M
          task->vertical = (pass==0);
900
901
1.58M
          imgunit->tasks.push_back(task);
902
1.58M
          ctx->thread_pool_.add_task(task);
903
1.58M
        }
904
24.4k
    }
905
12.2k
}
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
}