Coverage Report

Created: 2025-08-11 08:01

/src/libde265/libde265/deblock.cc
Line
Count
Source (jump to first uncovered line)
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
26
#include <assert.h>
27
28
29
30
// 8.7.2.1 for both EDGE_HOR and EDGE_VER at the same time
31
void markTransformBlockBoundary(de265_image* img, int x0,int y0,
32
                                int log2TrafoSize,int trafoDepth,
33
                                int filterLeftCbEdge, int filterTopCbEdge)
34
14.0M
{
35
14.0M
  logtrace(LogDeblock,"markTransformBlockBoundary(%d,%d, %d,%d, %d,%d)\n",x0,y0,
36
14.0M
           log2TrafoSize,trafoDepth, filterLeftCbEdge,filterTopCbEdge);
37
38
14.0M
  int split_transform = img->get_split_transform_flag(x0,y0,trafoDepth);
39
14.0M
  if (split_transform) {
40
2.59M
    int x1 = x0 + ((1<<log2TrafoSize)>>1);
41
2.59M
    int y1 = y0 + ((1<<log2TrafoSize)>>1);
42
43
2.59M
    markTransformBlockBoundary(img,x0,y0,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   filterTopCbEdge);
44
2.59M
    markTransformBlockBoundary(img,x1,y0,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, filterTopCbEdge);
45
2.59M
    markTransformBlockBoundary(img,x0,y1,log2TrafoSize-1,trafoDepth+1, filterLeftCbEdge,   DEBLOCK_FLAG_HORIZ);
46
2.59M
    markTransformBlockBoundary(img,x1,y1,log2TrafoSize-1,trafoDepth+1, DEBLOCK_FLAG_VERTI, DEBLOCK_FLAG_HORIZ);
47
2.59M
  }
48
11.4M
  else {
49
    // VER
50
51
25.8M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
52
14.4M
      img->set_deblk_flags(x0,y0+k, filterLeftCbEdge);
53
14.4M
    }
54
55
    // HOR
56
57
25.8M
    for (int k=0;k<(1<<log2TrafoSize);k+=4) {
58
14.4M
      img->set_deblk_flags(x0+k,y0, filterTopCbEdge);
59
14.4M
    }
60
11.4M
  }
61
14.0M
}
62
63
64
65
// 8.7.2.2 for both EDGE_HOR and EDGE_VER at the same time
66
void markPredictionBlockBoundary(de265_image* img, int x0,int y0,
67
                                 int log2CbSize,
68
                                 int filterLeftCbEdge, int filterTopCbEdge)
69
3.63M
{
70
3.63M
  logtrace(LogDeblock,"markPredictionBlockBoundary(%d,%d, %d, %d,%d)\n",x0,y0,
71
3.63M
           log2CbSize, filterLeftCbEdge,filterTopCbEdge);
72
73
3.63M
  enum PartMode partMode = img->get_PartMode(x0,y0);
74
75
3.63M
  int cbSize = 1<<log2CbSize;
76
3.63M
  int cbSize2 = 1<<(log2CbSize-1);
77
3.63M
  int cbSize4 = 1<<(log2CbSize-2);
78
79
3.63M
  switch (partMode) {
80
762k
  case PART_NxN:
81
6.94M
    for (int k=0;k<cbSize;k++) {
82
6.18M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
83
6.18M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
84
6.18M
    }
85
762k
    break;
86
87
212k
  case PART_Nx2N:
88
2.17M
    for (int k=0;k<cbSize;k++) {
89
1.96M
      img->set_deblk_flags(x0+cbSize2,y0+k, DEBLOCK_PB_EDGE_VERTI);
90
1.96M
    }
91
212k
    break;
92
93
304k
  case PART_2NxN:
94
3.04M
    for (int k=0;k<cbSize;k++) {
95
2.74M
      img->set_deblk_flags(x0+k,y0+cbSize2, DEBLOCK_PB_EDGE_HORIZ);
96
2.74M
    }
97
304k
    break;
98
99
22.2k
  case PART_nLx2N:
100
468k
    for (int k=0;k<cbSize;k++) {
101
446k
      img->set_deblk_flags(x0+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
102
446k
    }
103
22.2k
    break;
104
105
2.02k
  case PART_nRx2N:
106
50.8k
    for (int k=0;k<cbSize;k++) {
107
48.8k
      img->set_deblk_flags(x0+cbSize2+cbSize4,y0+k, DEBLOCK_PB_EDGE_VERTI);
108
48.8k
    }
109
2.02k
    break;
110
111
14.1k
  case PART_2NxnU:
112
313k
    for (int k=0;k<cbSize;k++) {
113
299k
      img->set_deblk_flags(x0+k,y0+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
114
299k
    }
115
14.1k
    break;
116
117
2.35k
  case PART_2NxnD:
118
56.6k
    for (int k=0;k<cbSize;k++) {
119
54.3k
      img->set_deblk_flags(x0+k,y0+cbSize2+cbSize4, DEBLOCK_PB_EDGE_HORIZ);
120
54.3k
    }
121
2.35k
    break;
122
123
2.31M
  case PART_2Nx2N:
124
    // NOP
125
2.31M
    break;
126
3.63M
  }
127
3.63M
}
128
129
130
bool derive_edgeFlags_CTBRow(de265_image* img, int ctby)
131
274k
{
132
274k
  const seq_parameter_set& sps = img->get_sps();
133
274k
  const pic_parameter_set& pps = img->get_pps();
134
135
274k
  const int minCbSize = sps.MinCbSizeY;
136
274k
  bool deblocking_enabled=false; // whether deblocking is enabled in some part of the image
137
138
274k
  int ctb_mask = (1<<sps.Log2CtbSizeY)-1;
139
274k
  int picWidthInCtbs = sps.PicWidthInCtbsY;
140
274k
  int ctbshift = sps.Log2CtbSizeY;
141
142
143
274k
  int cb_y_start = ( ctby    << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
144
274k
  int cb_y_end   = ((ctby+1) << sps.Log2CtbSizeY) >> sps.Log2MinCbSizeY;
145
146
274k
  cb_y_end = std::min(cb_y_end, sps.PicHeightInMinCbsY);
147
148
927k
  for (int cb_y=cb_y_start;cb_y<cb_y_end;cb_y++)
149
9.51M
    for (int cb_x=0;cb_x<img->get_sps().PicWidthInMinCbsY;cb_x++)
150
8.86M
      {
151
8.86M
        int log2CbSize = img->get_log2CbSize_cbUnits(cb_x,cb_y);
152
8.86M
        if (log2CbSize==0) {
153
5.03M
          continue;
154
5.03M
        }
155
156
        // we are now at the top corner of a CB
157
158
3.82M
        int x0 = cb_x * minCbSize;
159
3.82M
        int y0 = cb_y * minCbSize;
160
161
3.82M
        int x0ctb = x0 >> ctbshift;
162
3.82M
        int y0ctb = y0 >> ctbshift;
163
164
        // check for corrupted streams
165
3.82M
        if (img->is_SliceHeader_available(x0,y0)==false) {
166
0
          return false;
167
0
        }
168
169
        // check whether we should filter this slice
170
171
3.82M
        slice_segment_header* shdr = img->get_SliceHeader(x0,y0);
172
173
        // check whether to filter left and top edge
174
175
3.82M
        uint8_t filterLeftCbEdge = DEBLOCK_FLAG_VERTI;
176
3.82M
        uint8_t filterTopCbEdge  = DEBLOCK_FLAG_HORIZ;
177
3.82M
        if (x0 == 0) filterLeftCbEdge = 0;
178
3.82M
        if (y0 == 0) filterTopCbEdge  = 0;
179
180
        // check for slice and tile boundaries (8.7.2, step 2 in both processes)
181
182
3.82M
        if (x0 && ((x0 & ctb_mask) == 0)) { // left edge at CTB boundary
183
1.35M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
184
1.35M
              img->is_SliceHeader_available(x0-1,y0) && // for corrupted streams
185
1.35M
              shdr->SliceAddrRS != img->get_SliceHeader(x0-1,y0)->SliceAddrRS)
186
80
            {
187
80
              filterLeftCbEdge = 0;
188
80
            }
189
1.35M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
190
1.35M
                   pps.TileIdRS[  x0ctb           +y0ctb*picWidthInCtbs] !=
191
1.28M
                   pps.TileIdRS[((x0-1)>>ctbshift)+y0ctb*picWidthInCtbs]) {
192
992
            filterLeftCbEdge = 0;
193
992
          }
194
1.35M
        }
195
196
3.82M
        if (y0 && ((y0 & ctb_mask) == 0)) { // top edge at CTB boundary
197
1.21M
          if (shdr->slice_loop_filter_across_slices_enabled_flag == 0 &&
198
1.21M
              img->is_SliceHeader_available(x0,y0-1) && // for corrupted streams
199
1.21M
              shdr->SliceAddrRS != img->get_SliceHeader(x0,y0-1)->SliceAddrRS)
200
1.63k
            {
201
1.63k
              filterTopCbEdge = 0;
202
1.63k
            }
203
1.21M
          else if (pps.loop_filter_across_tiles_enabled_flag == 0 &&
204
1.21M
                   pps.TileIdRS[x0ctb+  y0ctb           *picWidthInCtbs] !=
205
1.14M
                   pps.TileIdRS[x0ctb+((y0-1)>>ctbshift)*picWidthInCtbs]) {
206
6.87k
            filterTopCbEdge = 0;
207
6.87k
          }
208
1.21M
        }
209
210
211
        // mark edges
212
213
3.82M
        if (shdr->slice_deblocking_filter_disabled_flag==0) {
214
3.63M
          deblocking_enabled=true;
215
216
3.63M
          markTransformBlockBoundary(img, x0,y0, log2CbSize,0,
217
3.63M
                                     filterLeftCbEdge, filterTopCbEdge);
218
219
3.63M
          markPredictionBlockBoundary(img, x0,y0, log2CbSize,
220
3.63M
                                      filterLeftCbEdge, filterTopCbEdge);
221
3.63M
        }
222
3.82M
      }
223
224
274k
  return deblocking_enabled;
225
274k
}
226
227
228
bool derive_edgeFlags(de265_image* img)
229
0
{
230
0
  bool deblocking_enabled=false;
231
232
0
  for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++) {
233
0
    deblocking_enabled |= derive_edgeFlags_CTBRow(img,y);
234
0
  }
235
236
0
  return deblocking_enabled;
237
0
}
238
239
240
// 8.7.2.3 (both, EDGE_VER and EDGE_HOR)
241
void derive_boundaryStrength(de265_image* img, bool vertical, int yStart,int yEnd,
242
                             int xStart,int xEnd)
243
347k
{
244
347k
  int xIncr = vertical ? 2 : 1;
245
347k
  int yIncr = vertical ? 1 : 2;
246
347k
  int xOffs = vertical ? 1 : 0;
247
347k
  int yOffs = vertical ? 0 : 1;
248
347k
  int edgeMask = vertical ?
249
173k
    (DEBLOCK_FLAG_VERTI | DEBLOCK_PB_EDGE_VERTI) :
250
347k
    (DEBLOCK_FLAG_HORIZ | DEBLOCK_PB_EDGE_HORIZ);
251
347k
  int transformEdgeMask = vertical ? DEBLOCK_FLAG_VERTI : DEBLOCK_FLAG_HORIZ;
252
253
347k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
254
347k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
255
256
347k
  int TUShift = img->get_sps().Log2MinTrafoSize;
257
347k
  int TUStride= img->get_sps().PicWidthInTbsY;
258
259
1.48M
  for (int y=yStart;y<yEnd;y+=yIncr)
260
27.3M
    for (int x=xStart;x<xEnd;x+=xIncr) {
261
26.2M
      int xDi = x<<2;
262
26.2M
      int yDi = y<<2;
263
264
26.2M
      logtrace(LogDeblock,"%d %d %s = %s\n",xDi,yDi, vertical?"Vertical":"Horizontal",
265
26.2M
               (img->get_deblk_flags(xDi,yDi) & edgeMask) ? "edge" : "...");
266
267
26.2M
      uint8_t edgeFlags = img->get_deblk_flags(xDi,yDi);
268
269
26.2M
      if (edgeFlags & edgeMask) {
270
17.6M
        bool p_is_intra_pred = (img->get_pred_mode(xDi-xOffs, yDi-yOffs) == MODE_INTRA);
271
17.6M
        bool q_is_intra_pred = (img->get_pred_mode(xDi,       yDi      ) == MODE_INTRA);
272
273
17.6M
        int bS;
274
275
17.6M
        if (p_is_intra_pred || q_is_intra_pred) {
276
7.17M
          bS = 2;
277
7.17M
        }
278
10.4M
        else {
279
          // opposing site
280
10.4M
          int xDiOpp = xDi-xOffs;
281
10.4M
          int yDiOpp = yDi-yOffs;
282
283
10.4M
          if ((edgeFlags & transformEdgeMask) &&
284
10.4M
              (img->get_nonzero_coefficient(xDi   ,yDi) ||
285
10.2M
               img->get_nonzero_coefficient(xDiOpp,yDiOpp))) {
286
1.90M
            bS = 1;
287
1.90M
          }
288
8.55M
          else {
289
290
8.55M
            bS = 0;
291
292
8.55M
            const PBMotion& mviP = img->get_mv_info(xDiOpp,yDiOpp);
293
8.55M
            const PBMotion& mviQ = img->get_mv_info(xDi   ,yDi);
294
295
8.55M
            slice_segment_header* shdrP = img->get_SliceHeader(xDiOpp,yDiOpp);
296
8.55M
            slice_segment_header* shdrQ = img->get_SliceHeader(xDi   ,yDi);
297
298
8.55M
      if (shdrP && shdrQ) {
299
300
8.55M
        if (mviP.refIdx[0] > MAX_NUM_REF_PICS ||
301
8.55M
            mviP.refIdx[1] > MAX_NUM_REF_PICS ||
302
8.55M
            mviQ.refIdx[0] > MAX_NUM_REF_PICS ||
303
8.55M
            mviQ.refIdx[1] > MAX_NUM_REF_PICS) {
304
          // we cannot return an error from here, so just set a valid boundaryStrength value and continue;
305
0
          img->set_deblk_bS(xDi, yDi, 0);
306
0
          continue;
307
0
        }
308
309
8.55M
        int refPicP0 = mviP.predFlag[0] ? shdrP->RefPicList[0][ mviP.refIdx[0] ] : -1;
310
8.55M
        int refPicP1 = mviP.predFlag[1] ? shdrP->RefPicList[1][ mviP.refIdx[1] ] : -1;
311
8.55M
        int refPicQ0 = mviQ.predFlag[0] ? shdrQ->RefPicList[0][ mviQ.refIdx[0] ] : -1;
312
8.55M
        int refPicQ1 = mviQ.predFlag[1] ? shdrQ->RefPicList[1][ mviQ.refIdx[1] ] : -1;
313
314
8.55M
        bool samePics = ((refPicP0==refPicQ0 && refPicP1==refPicQ1) ||
315
8.55M
             (refPicP0==refPicQ1 && refPicP1==refPicQ0));
316
317
8.55M
        if (!samePics) {
318
670k
    bS = 1;
319
670k
        }
320
7.87M
        else {
321
7.87M
    MotionVector mvP0 = mviP.mv[0]; if (!mviP.predFlag[0]) { mvP0.x=mvP0.y=0; }
322
7.87M
    MotionVector mvP1 = mviP.mv[1]; if (!mviP.predFlag[1]) { mvP1.x=mvP1.y=0; }
323
7.87M
    MotionVector mvQ0 = mviQ.mv[0]; if (!mviQ.predFlag[0]) { mvQ0.x=mvQ0.y=0; }
324
7.87M
    MotionVector mvQ1 = mviQ.mv[1]; if (!mviQ.predFlag[1]) { mvQ1.x=mvQ1.y=0; }
325
326
7.87M
    int numMV_P = mviP.predFlag[0] + mviP.predFlag[1];
327
7.87M
    int numMV_Q = mviQ.predFlag[0] + mviQ.predFlag[1];
328
329
7.87M
    if (numMV_P!=numMV_Q) {
330
0
      img->decctx->add_warning(DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ, false);
331
0
      img->integrity = INTEGRITY_DECODING_ERRORS;
332
0
    }
333
334
    // two different reference pictures or only one reference picture
335
7.87M
    if (refPicP0 != refPicP1) {
336
337
4.22M
      if (refPicP0 == refPicQ0) {
338
4.16M
        if (abs_value(mvP0.x-mvQ0.x) >= 4 ||
339
4.16M
      abs_value(mvP0.y-mvQ0.y) >= 4 ||
340
4.16M
      abs_value(mvP1.x-mvQ1.x) >= 4 ||
341
4.16M
      abs_value(mvP1.y-mvQ1.y) >= 4) {
342
194k
          bS = 1;
343
194k
        }
344
4.16M
      }
345
59.6k
      else {
346
59.6k
        if (abs_value(mvP0.x-mvQ1.x) >= 4 ||
347
59.6k
      abs_value(mvP0.y-mvQ1.y) >= 4 ||
348
59.6k
      abs_value(mvP1.x-mvQ0.x) >= 4 ||
349
59.6k
      abs_value(mvP1.y-mvQ0.y) >= 4) {
350
20.7k
          bS = 1;
351
20.7k
        }
352
59.6k
      }
353
4.22M
    }
354
3.65M
    else {
355
3.65M
      assert(refPicQ0==refPicQ1);
356
357
3.65M
      if ((abs_value(mvP0.x-mvQ0.x) >= 4 ||
358
3.65M
           abs_value(mvP0.y-mvQ0.y) >= 4 ||
359
3.65M
           abs_value(mvP1.x-mvQ1.x) >= 4 ||
360
3.65M
           abs_value(mvP1.y-mvQ1.y) >= 4)
361
3.65M
          &&
362
3.65M
          (abs_value(mvP0.x-mvQ1.x) >= 4 ||
363
137k
           abs_value(mvP0.y-mvQ1.y) >= 4 ||
364
137k
           abs_value(mvP1.x-mvQ0.x) >= 4 ||
365
137k
           abs_value(mvP1.y-mvQ0.y) >= 4)) {
366
135k
        bS = 1;
367
135k
      }
368
3.65M
    }
369
7.87M
        }
370
8.55M
      }
371
0
      else {
372
0
        bS = 0; // if shdrP==NULL or shdrQ==NULL
373
0
      }
374
375
            /*
376
              printf("unimplemented deblocking code for CU at %d;%d\n",xDi,yDi);
377
378
              logerror(LogDeblock, "unimplemented code reached (file %s, line %d)\n",
379
              __FILE__, __LINE__);
380
            */
381
8.55M
          }
382
10.4M
        }
383
384
17.6M
        img->set_deblk_bS(xDi,yDi, bS);
385
17.6M
      }
386
8.62M
      else {
387
8.62M
        img->set_deblk_bS(xDi,yDi, 0);
388
8.62M
      }
389
26.2M
    }
390
347k
}
391
392
393
void derive_boundaryStrength_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
394
0
{
395
0
  int ctbSize = img->get_sps().CtbSizeY;
396
0
  int deblkSize = ctbSize/4;
397
398
0
  derive_boundaryStrength(img,vertical,
399
0
                          yCtb*deblkSize, (yCtb+1)*deblkSize,
400
0
                          xCtb*deblkSize, (xCtb+1)*deblkSize);
401
0
}
402
403
404
static uint8_t table_8_23_beta[52] = {
405
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8,
406
   9,10,11,12,13,14,15,16,17,18,20,22,24,26,28,30,32,34,36,
407
  38,40,42,44,46,48,50,52,54,56,58,60,62,64
408
};
409
410
static uint8_t table_8_23_tc[54] = {
411
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
412
   1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
413
   5, 5, 6, 6, 7, 8, 9,10,11,13,14,16,18,20,22,24
414
};
415
416
417
418
// 8.7.2.4
419
template <class pixel_t>
420
void edge_filtering_luma_internal(de265_image* img, bool vertical,
421
                                  int yStart,int yEnd, int xStart,int xEnd)
422
347k
{
423
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
424
425
347k
  const seq_parameter_set& sps = img->get_sps();
426
427
347k
  int xIncr = vertical ? 2 : 1;
428
347k
  int yIncr = vertical ? 1 : 2;
429
430
347k
  const int stride = img->get_image_stride(0);
431
432
347k
  int bitDepth_Y = sps.BitDepth_Y;
433
434
347k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
435
347k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
436
437
1.48M
  for (int y=yStart;y<yEnd;y+=yIncr)
438
27.3M
    for (int x=xStart;x<xEnd;x+=xIncr) {
439
      // x;y in deblocking units (4x4 pixels)
440
441
26.2M
      int xDi = x<<2; // *4 -> pixel resolution
442
26.2M
      int yDi = y<<2; // *4 -> pixel resolution
443
26.2M
      int bS = img->get_deblk_bS(xDi,yDi);
444
445
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
446
447
26.2M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
448
26.2M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
449
450
#if 0
451
      {
452
        uint8_t* ptr = img->y + stride*yDi + xDi;
453
454
        for (int dy=-4;dy<4;dy++) {
455
          for (int dx=-4;dx<4;dx++) {
456
            printf("%02x ", ptr[dy*stride + dx]);
457
            if (dx==-1) printf("| ");
458
          }
459
          printf("\n");
460
          if (dy==-1) printf("-------------------------\n");
461
        }
462
      }
463
#endif
464
465
#if 0
466
      if (!vertical)
467
        {
468
          uint8_t* ptr = img->y + stride*yDi + xDi;
469
470
          for (int dy=-4;dy<4;dy++) {
471
            for (int dx=0;dx<4;dx++) {
472
              printf("%02x ", ptr[dy*stride + dx]);
473
              if (dx==-1) printf("| ");
474
            }
475
            printf("\n");
476
            if (dy==-1) printf("-------------------------\n");
477
          }
478
        }
479
#endif
480
481
26.2M
      if (bS>0) {
482
483
        // 8.7.2.4.3
484
485
10.0M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
486
487
10.0M
        pixel_t q[4][4], p[4][4];
488
50.4M
        for (int k=0;k<4;k++)
489
201M
          for (int i=0;i<4;i++)
490
161M
            {
491
161M
              if (vertical) {
492
79.9M
                q[k][i] = ptr[ i  +k*stride];
493
79.9M
                p[k][i] = ptr[-i-1+k*stride];
494
79.9M
              }
495
81.5M
              else {
496
81.5M
                q[k][i] = ptr[k + i   *stride];
497
81.5M
                p[k][i] = ptr[k -(i+1)*stride];
498
81.5M
              }
499
161M
            }
500
501
#if 0
502
        for (int k=0;k<4;k++)
503
          {
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", p[k][3-i]);
507
              }
508
509
            printf("| ");
510
511
            for (int i=0;i<4;i++)
512
              {
513
                printf("%02x ", q[k][i]);
514
              }
515
            printf("\n");
516
          }
517
#endif
518
519
520
10.0M
        int QP_Q = img->get_QPY(xDi,yDi);
521
10.0M
        int QP_P = (vertical ?
522
4.99M
                    img->get_QPY(xDi-1,yDi) :
523
10.0M
                    img->get_QPY(xDi,yDi-1) );
524
10.0M
        int qP_L = (QP_Q+QP_P+1)>>1;
525
526
10.0M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
527
528
10.0M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
529
10.0M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
530
10.0M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
531
532
10.0M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
533
10.0M
        int betaPrime = table_8_23_beta[Q_beta];
534
10.0M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
535
536
10.0M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
537
10.0M
        int tcPrime = table_8_23_tc[Q_tc];
538
10.0M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
539
540
10.0M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
541
542
10.0M
        int dE=0, dEp=0, dEq=0;
543
544
10.0M
        if (vertical || !vertical) {
545
10.0M
          int dp0 = abs_value(p[0][2] - 2*p[0][1] + p[0][0]);
546
10.0M
          int dp3 = abs_value(p[3][2] - 2*p[3][1] + p[3][0]);
547
10.0M
          int dq0 = abs_value(q[0][2] - 2*q[0][1] + q[0][0]);
548
10.0M
          int dq3 = abs_value(q[3][2] - 2*q[3][1] + q[3][0]);
549
550
10.0M
          int dpq0 = dp0 + dq0;
551
10.0M
          int dpq3 = dp3 + dq3;
552
553
10.0M
          int dp = dp0 + dp3;
554
10.0M
          int dq = dq0 + dq3;
555
10.0M
          int d  = dpq0+ dpq3;
556
557
10.0M
          if (d<beta) {
558
            //int dpq = 2*dpq0;
559
5.14M
            bool dSam0 = (2*dpq0 < (beta>>2) &&
560
5.14M
                          abs_value(p[0][3]-p[0][0])+abs_value(q[0][0]-q[0][3]) < (beta>>3) &&
561
5.14M
                          abs_value(p[0][0]-q[0][0]) < ((5*tc+1)>>1));
562
563
5.14M
            bool dSam3 = (2*dpq3 < (beta>>2) &&
564
5.14M
                          abs_value(p[3][3]-p[3][0])+abs_value(q[3][0]-q[3][3]) < (beta>>3) &&
565
5.14M
                          abs_value(p[3][0]-q[3][0]) < ((5*tc+1)>>1));
566
567
5.14M
            if (dSam0 && dSam3) {
568
3.21M
              dE=2;
569
3.21M
            }
570
1.92M
            else {
571
1.92M
              dE=1;
572
1.92M
            }
573
574
5.14M
            if (dp < ((beta + (beta>>1))>>3)) { dEp=1; }
575
5.14M
            if (dq < ((beta + (beta>>1))>>3)) { dEq=1; }
576
577
5.14M
            logtrace(LogDeblock,"dE:%d dEp:%d dEq:%d\n",dE,dEp,dEq);
578
5.14M
          }
579
10.0M
        }
580
0
        else {
581
          // TODO
582
0
          assert(0);
583
0
        }
584
585
586
        // 8.7.2.4.4
587
588
10.0M
        if (dE != 0) {
589
5.14M
          bool filterP = true;
590
5.14M
          bool filterQ = true;
591
592
5.14M
          if (vertical) {
593
2.35M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
594
2.35M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
595
596
2.35M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
597
2.35M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
598
2.35M
          }
599
2.78M
          else {
600
2.78M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
601
2.78M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
602
603
2.78M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
604
2.78M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
605
2.78M
          }
606
607
25.7M
          for (int k=0;k<4;k++) {
608
            //int nDp,nDq;
609
610
20.5M
            logtrace(LogDeblock,"line:%d\n",k);
611
612
20.5M
            const pixel_t p0 = p[k][0];
613
20.5M
            const pixel_t p1 = p[k][1];
614
20.5M
            const pixel_t p2 = p[k][2];
615
20.5M
            const pixel_t p3 = p[k][3];
616
20.5M
            const pixel_t q0 = q[k][0];
617
20.5M
            const pixel_t q1 = q[k][1];
618
20.5M
            const pixel_t q2 = q[k][2];
619
20.5M
            const pixel_t q3 = q[k][3];
620
621
20.5M
            if (dE==2) {
622
              // strong filtering
623
624
              //nDp=nDq=3;
625
626
12.8M
              pixel_t pnew[3],qnew[3];
627
12.8M
              pnew[0] = Clip3(p0-2*tc,p0+2*tc, (p2 + 2*p1 + 2*p0 + 2*q0 + q1 +4)>>3);
628
12.8M
              pnew[1] = Clip3(p1-2*tc,p1+2*tc, (p2 + p1 + p0 + q0+2)>>2);
629
12.8M
              pnew[2] = Clip3(p2-2*tc,p2+2*tc, (2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3);
630
12.8M
              qnew[0] = Clip3(q0-2*tc,q0+2*tc, (p1+2*p0+2*q0+2*q1+q2+4)>>3);
631
12.8M
              qnew[1] = Clip3(q1-2*tc,q1+2*tc, (p0+q0+q1+q2+2)>>2);
632
12.8M
              qnew[2] = Clip3(q2-2*tc,q2+2*tc, (p0+q0+q1+3*q2+2*q3+4)>>3);
633
634
12.8M
              logtrace(LogDeblock,"strong filtering\n");
635
636
12.8M
              if (vertical) {
637
22.6M
                for (int i=0;i<3;i++) {
638
17.0M
                  if (filterP) { ptr[-i-1+k*stride] = pnew[i]; }
639
17.0M
                  if (filterQ) { ptr[ i + k*stride] = qnew[i]; }
640
17.0M
                }
641
642
                // ptr[-1+k*stride] = ptr[ 0+k*stride] = 200;
643
5.67M
              }
644
7.18M
              else {
645
28.7M
                for (int i=0;i<3;i++) {
646
21.5M
                  if (filterP) { ptr[ k -(i+1)*stride] = pnew[i]; }
647
21.5M
                  if (filterQ) { ptr[ k + i   *stride] = qnew[i]; }
648
21.5M
                }
649
7.18M
              }
650
12.8M
            }
651
7.70M
            else {
652
              // weak filtering
653
654
              //nDp=nDq=0;
655
656
7.70M
              int delta = (9*(q0-p0) - 3*(q1-p1) + 8)>>4;
657
7.70M
              logtrace(LogDeblock,"delta=%d, tc=%d\n",delta,tc);
658
659
7.70M
              if (abs_value(delta) < tc*10) {
660
661
7.00M
                delta = Clip3(-tc,tc,delta);
662
7.00M
                logtrace(LogDeblock," deblk + %d;%d [%02x->%02x]  - %d;%d [%02x->%02x] delta:%d\n",
663
7.00M
                         vertical ? xDi-1 : xDi+k,
664
7.00M
                         vertical ? yDi+k : yDi-1, p0,Clip_BitDepth(p0+delta, bitDepth_Y),
665
7.00M
                         vertical ? xDi   : xDi+k,
666
7.00M
                         vertical ? yDi+k : yDi,   q0,Clip_BitDepth(q0-delta, bitDepth_Y),
667
7.00M
                         delta);
668
669
7.00M
                if (vertical) {
670
3.46M
                  if (filterP) { ptr[-0-1+k*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
671
3.46M
                  if (filterQ) { ptr[ 0  +k*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
672
3.46M
                }
673
3.53M
                else {
674
3.53M
                  if (filterP) { ptr[ k -1*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
675
3.53M
                  if (filterQ) { ptr[ k +0*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
676
3.53M
                }
677
678
                //ptr[ 0+k*stride] = 200;
679
680
7.00M
                if (dEp==1 && filterP) {
681
2.73M
                  int delta_p = Clip3(-(tc>>1), tc>>1, (((p2+p0+1)>>1)-p1+delta)>>1);
682
683
2.73M
                  logtrace(LogDeblock," deblk dEp %d;%d delta:%d\n",
684
2.73M
                           vertical ? xDi-2 : xDi+k,
685
2.73M
                           vertical ? yDi+k : yDi-2,
686
2.73M
                           delta_p);
687
688
2.73M
                  if (vertical) { ptr[-1-1+k*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
689
1.30M
                  else          { ptr[ k  -2*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
690
2.73M
                }
691
692
7.00M
                if (dEq==1 && filterQ) {
693
2.51M
                  int delta_q = Clip3(-(tc>>1), tc>>1, (((q2+q0+1)>>1)-q1-delta)>>1);
694
695
2.51M
                  logtrace(LogDeblock," delkb dEq %d;%d delta:%d\n",
696
2.51M
                           vertical ? xDi+1 : xDi+k,
697
2.51M
                           vertical ? yDi+k : yDi+1,
698
2.51M
                           delta_q);
699
700
2.51M
                  if (vertical) { ptr[ 1  +k*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
701
1.44M
                  else          { ptr[ k  +1*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
702
2.51M
                }
703
704
                //nDp = dEp+1;
705
                //nDq = dEq+1;
706
707
                //logtrace(LogDeblock,"weak filtering (%d:%d)\n",nDp,nDq);
708
7.00M
              }
709
7.70M
            }
710
20.5M
          }
711
5.14M
        }
712
10.0M
      }
713
26.2M
    }
714
347k
}
void edge_filtering_luma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
422
303k
{
423
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
424
425
303k
  const seq_parameter_set& sps = img->get_sps();
426
427
303k
  int xIncr = vertical ? 2 : 1;
428
303k
  int yIncr = vertical ? 1 : 2;
429
430
303k
  const int stride = img->get_image_stride(0);
431
432
303k
  int bitDepth_Y = sps.BitDepth_Y;
433
434
303k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
435
303k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
436
437
1.20M
  for (int y=yStart;y<yEnd;y+=yIncr)
438
12.6M
    for (int x=xStart;x<xEnd;x+=xIncr) {
439
      // x;y in deblocking units (4x4 pixels)
440
441
11.7M
      int xDi = x<<2; // *4 -> pixel resolution
442
11.7M
      int yDi = y<<2; // *4 -> pixel resolution
443
11.7M
      int bS = img->get_deblk_bS(xDi,yDi);
444
445
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
446
447
11.7M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
448
11.7M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
449
450
#if 0
451
      {
452
        uint8_t* ptr = img->y + stride*yDi + xDi;
453
454
        for (int dy=-4;dy<4;dy++) {
455
          for (int dx=-4;dx<4;dx++) {
456
            printf("%02x ", ptr[dy*stride + dx]);
457
            if (dx==-1) printf("| ");
458
          }
459
          printf("\n");
460
          if (dy==-1) printf("-------------------------\n");
461
        }
462
      }
463
#endif
464
465
#if 0
466
      if (!vertical)
467
        {
468
          uint8_t* ptr = img->y + stride*yDi + xDi;
469
470
          for (int dy=-4;dy<4;dy++) {
471
            for (int dx=0;dx<4;dx++) {
472
              printf("%02x ", ptr[dy*stride + dx]);
473
              if (dx==-1) printf("| ");
474
            }
475
            printf("\n");
476
            if (dy==-1) printf("-------------------------\n");
477
          }
478
        }
479
#endif
480
481
11.7M
      if (bS>0) {
482
483
        // 8.7.2.4.3
484
485
4.49M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
486
487
4.49M
        pixel_t q[4][4], p[4][4];
488
22.4M
        for (int k=0;k<4;k++)
489
89.9M
          for (int i=0;i<4;i++)
490
71.9M
            {
491
71.9M
              if (vertical) {
492
35.7M
                q[k][i] = ptr[ i  +k*stride];
493
35.7M
                p[k][i] = ptr[-i-1+k*stride];
494
35.7M
              }
495
36.2M
              else {
496
36.2M
                q[k][i] = ptr[k + i   *stride];
497
36.2M
                p[k][i] = ptr[k -(i+1)*stride];
498
36.2M
              }
499
71.9M
            }
500
501
#if 0
502
        for (int k=0;k<4;k++)
503
          {
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", p[k][3-i]);
507
              }
508
509
            printf("| ");
510
511
            for (int i=0;i<4;i++)
512
              {
513
                printf("%02x ", q[k][i]);
514
              }
515
            printf("\n");
516
          }
517
#endif
518
519
520
4.49M
        int QP_Q = img->get_QPY(xDi,yDi);
521
4.49M
        int QP_P = (vertical ?
522
2.23M
                    img->get_QPY(xDi-1,yDi) :
523
4.49M
                    img->get_QPY(xDi,yDi-1) );
524
4.49M
        int qP_L = (QP_Q+QP_P+1)>>1;
525
526
4.49M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
527
528
4.49M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
529
4.49M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
530
4.49M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
531
532
4.49M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
533
4.49M
        int betaPrime = table_8_23_beta[Q_beta];
534
4.49M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
535
536
4.49M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
537
4.49M
        int tcPrime = table_8_23_tc[Q_tc];
538
4.49M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
539
540
4.49M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
541
542
4.49M
        int dE=0, dEp=0, dEq=0;
543
544
4.49M
        if (vertical || !vertical) {
545
4.49M
          int dp0 = abs_value(p[0][2] - 2*p[0][1] + p[0][0]);
546
4.49M
          int dp3 = abs_value(p[3][2] - 2*p[3][1] + p[3][0]);
547
4.49M
          int dq0 = abs_value(q[0][2] - 2*q[0][1] + q[0][0]);
548
4.49M
          int dq3 = abs_value(q[3][2] - 2*q[3][1] + q[3][0]);
549
550
4.49M
          int dpq0 = dp0 + dq0;
551
4.49M
          int dpq3 = dp3 + dq3;
552
553
4.49M
          int dp = dp0 + dp3;
554
4.49M
          int dq = dq0 + dq3;
555
4.49M
          int d  = dpq0+ dpq3;
556
557
4.49M
          if (d<beta) {
558
            //int dpq = 2*dpq0;
559
2.36M
            bool dSam0 = (2*dpq0 < (beta>>2) &&
560
2.36M
                          abs_value(p[0][3]-p[0][0])+abs_value(q[0][0]-q[0][3]) < (beta>>3) &&
561
2.36M
                          abs_value(p[0][0]-q[0][0]) < ((5*tc+1)>>1));
562
563
2.36M
            bool dSam3 = (2*dpq3 < (beta>>2) &&
564
2.36M
                          abs_value(p[3][3]-p[3][0])+abs_value(q[3][0]-q[3][3]) < (beta>>3) &&
565
2.36M
                          abs_value(p[3][0]-q[3][0]) < ((5*tc+1)>>1));
566
567
2.36M
            if (dSam0 && dSam3) {
568
1.61M
              dE=2;
569
1.61M
            }
570
749k
            else {
571
749k
              dE=1;
572
749k
            }
573
574
2.36M
            if (dp < ((beta + (beta>>1))>>3)) { dEp=1; }
575
2.36M
            if (dq < ((beta + (beta>>1))>>3)) { dEq=1; }
576
577
2.36M
            logtrace(LogDeblock,"dE:%d dEp:%d dEq:%d\n",dE,dEp,dEq);
578
2.36M
          }
579
4.49M
        }
580
0
        else {
581
          // TODO
582
0
          assert(0);
583
0
        }
584
585
586
        // 8.7.2.4.4
587
588
4.49M
        if (dE != 0) {
589
2.36M
          bool filterP = true;
590
2.36M
          bool filterQ = true;
591
592
2.36M
          if (vertical) {
593
1.09M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
594
1.09M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
595
596
1.09M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
597
1.09M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
598
1.09M
          }
599
1.26M
          else {
600
1.26M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
601
1.26M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
602
603
1.26M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
604
1.26M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
605
1.26M
          }
606
607
11.8M
          for (int k=0;k<4;k++) {
608
            //int nDp,nDq;
609
610
9.47M
            logtrace(LogDeblock,"line:%d\n",k);
611
612
9.47M
            const pixel_t p0 = p[k][0];
613
9.47M
            const pixel_t p1 = p[k][1];
614
9.47M
            const pixel_t p2 = p[k][2];
615
9.47M
            const pixel_t p3 = p[k][3];
616
9.47M
            const pixel_t q0 = q[k][0];
617
9.47M
            const pixel_t q1 = q[k][1];
618
9.47M
            const pixel_t q2 = q[k][2];
619
9.47M
            const pixel_t q3 = q[k][3];
620
621
9.47M
            if (dE==2) {
622
              // strong filtering
623
624
              //nDp=nDq=3;
625
626
6.47M
              pixel_t pnew[3],qnew[3];
627
6.47M
              pnew[0] = Clip3(p0-2*tc,p0+2*tc, (p2 + 2*p1 + 2*p0 + 2*q0 + q1 +4)>>3);
628
6.47M
              pnew[1] = Clip3(p1-2*tc,p1+2*tc, (p2 + p1 + p0 + q0+2)>>2);
629
6.47M
              pnew[2] = Clip3(p2-2*tc,p2+2*tc, (2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3);
630
6.47M
              qnew[0] = Clip3(q0-2*tc,q0+2*tc, (p1+2*p0+2*q0+2*q1+q2+4)>>3);
631
6.47M
              qnew[1] = Clip3(q1-2*tc,q1+2*tc, (p0+q0+q1+q2+2)>>2);
632
6.47M
              qnew[2] = Clip3(q2-2*tc,q2+2*tc, (p0+q0+q1+3*q2+2*q3+4)>>3);
633
634
6.47M
              logtrace(LogDeblock,"strong filtering\n");
635
636
6.47M
              if (vertical) {
637
11.6M
                for (int i=0;i<3;i++) {
638
8.70M
                  if (filterP) { ptr[-i-1+k*stride] = pnew[i]; }
639
8.70M
                  if (filterQ) { ptr[ i + k*stride] = qnew[i]; }
640
8.70M
                }
641
642
                // ptr[-1+k*stride] = ptr[ 0+k*stride] = 200;
643
2.90M
              }
644
3.56M
              else {
645
14.2M
                for (int i=0;i<3;i++) {
646
10.7M
                  if (filterP) { ptr[ k -(i+1)*stride] = pnew[i]; }
647
10.7M
                  if (filterQ) { ptr[ k + i   *stride] = qnew[i]; }
648
10.7M
                }
649
3.56M
              }
650
6.47M
            }
651
2.99M
            else {
652
              // weak filtering
653
654
              //nDp=nDq=0;
655
656
2.99M
              int delta = (9*(q0-p0) - 3*(q1-p1) + 8)>>4;
657
2.99M
              logtrace(LogDeblock,"delta=%d, tc=%d\n",delta,tc);
658
659
2.99M
              if (abs_value(delta) < tc*10) {
660
661
2.79M
                delta = Clip3(-tc,tc,delta);
662
2.79M
                logtrace(LogDeblock," deblk + %d;%d [%02x->%02x]  - %d;%d [%02x->%02x] delta:%d\n",
663
2.79M
                         vertical ? xDi-1 : xDi+k,
664
2.79M
                         vertical ? yDi+k : yDi-1, p0,Clip_BitDepth(p0+delta, bitDepth_Y),
665
2.79M
                         vertical ? xDi   : xDi+k,
666
2.79M
                         vertical ? yDi+k : yDi,   q0,Clip_BitDepth(q0-delta, bitDepth_Y),
667
2.79M
                         delta);
668
669
2.79M
                if (vertical) {
670
1.40M
                  if (filterP) { ptr[-0-1+k*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
671
1.40M
                  if (filterQ) { ptr[ 0  +k*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
672
1.40M
                }
673
1.39M
                else {
674
1.39M
                  if (filterP) { ptr[ k -1*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
675
1.39M
                  if (filterQ) { ptr[ k +0*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
676
1.39M
                }
677
678
                //ptr[ 0+k*stride] = 200;
679
680
2.79M
                if (dEp==1 && filterP) {
681
1.25M
                  int delta_p = Clip3(-(tc>>1), tc>>1, (((p2+p0+1)>>1)-p1+delta)>>1);
682
683
1.25M
                  logtrace(LogDeblock," deblk dEp %d;%d delta:%d\n",
684
1.25M
                           vertical ? xDi-2 : xDi+k,
685
1.25M
                           vertical ? yDi+k : yDi-2,
686
1.25M
                           delta_p);
687
688
1.25M
                  if (vertical) { ptr[-1-1+k*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
689
573k
                  else          { ptr[ k  -2*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
690
1.25M
                }
691
692
2.79M
                if (dEq==1 && filterQ) {
693
1.09M
                  int delta_q = Clip3(-(tc>>1), tc>>1, (((q2+q0+1)>>1)-q1-delta)>>1);
694
695
1.09M
                  logtrace(LogDeblock," delkb dEq %d;%d delta:%d\n",
696
1.09M
                           vertical ? xDi+1 : xDi+k,
697
1.09M
                           vertical ? yDi+k : yDi+1,
698
1.09M
                           delta_q);
699
700
1.09M
                  if (vertical) { ptr[ 1  +k*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
701
585k
                  else          { ptr[ k  +1*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
702
1.09M
                }
703
704
                //nDp = dEp+1;
705
                //nDq = dEq+1;
706
707
                //logtrace(LogDeblock,"weak filtering (%d:%d)\n",nDp,nDq);
708
2.79M
              }
709
2.99M
            }
710
9.47M
          }
711
2.36M
        }
712
4.49M
      }
713
11.7M
    }
714
303k
}
void edge_filtering_luma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
422
43.6k
{
423
  //printf("luma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
424
425
43.6k
  const seq_parameter_set& sps = img->get_sps();
426
427
43.6k
  int xIncr = vertical ? 2 : 1;
428
43.6k
  int yIncr = vertical ? 1 : 2;
429
430
43.6k
  const int stride = img->get_image_stride(0);
431
432
43.6k
  int bitDepth_Y = sps.BitDepth_Y;
433
434
43.6k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
435
43.6k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
436
437
277k
  for (int y=yStart;y<yEnd;y+=yIncr)
438
14.7M
    for (int x=xStart;x<xEnd;x+=xIncr) {
439
      // x;y in deblocking units (4x4 pixels)
440
441
14.5M
      int xDi = x<<2; // *4 -> pixel resolution
442
14.5M
      int yDi = y<<2; // *4 -> pixel resolution
443
14.5M
      int bS = img->get_deblk_bS(xDi,yDi);
444
445
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
446
447
14.5M
      logtrace(LogDeblock,"deblock POC=%d %c --- x:%d y:%d bS:%d---\n",
448
14.5M
               img->PicOrderCntVal,vertical ? 'V':'H',xDi,yDi,bS);
449
450
#if 0
451
      {
452
        uint8_t* ptr = img->y + stride*yDi + xDi;
453
454
        for (int dy=-4;dy<4;dy++) {
455
          for (int dx=-4;dx<4;dx++) {
456
            printf("%02x ", ptr[dy*stride + dx]);
457
            if (dx==-1) printf("| ");
458
          }
459
          printf("\n");
460
          if (dy==-1) printf("-------------------------\n");
461
        }
462
      }
463
#endif
464
465
#if 0
466
      if (!vertical)
467
        {
468
          uint8_t* ptr = img->y + stride*yDi + xDi;
469
470
          for (int dy=-4;dy<4;dy++) {
471
            for (int dx=0;dx<4;dx++) {
472
              printf("%02x ", ptr[dy*stride + dx]);
473
              if (dx==-1) printf("| ");
474
            }
475
            printf("\n");
476
            if (dy==-1) printf("-------------------------\n");
477
          }
478
        }
479
#endif
480
481
14.5M
      if (bS>0) {
482
483
        // 8.7.2.4.3
484
485
5.59M
        pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(0, xDi,yDi);
486
487
5.59M
        pixel_t q[4][4], p[4][4];
488
27.9M
        for (int k=0;k<4;k++)
489
111M
          for (int i=0;i<4;i++)
490
89.5M
            {
491
89.5M
              if (vertical) {
492
44.1M
                q[k][i] = ptr[ i  +k*stride];
493
44.1M
                p[k][i] = ptr[-i-1+k*stride];
494
44.1M
              }
495
45.3M
              else {
496
45.3M
                q[k][i] = ptr[k + i   *stride];
497
45.3M
                p[k][i] = ptr[k -(i+1)*stride];
498
45.3M
              }
499
89.5M
            }
500
501
#if 0
502
        for (int k=0;k<4;k++)
503
          {
504
            for (int i=0;i<4;i++)
505
              {
506
                printf("%02x ", p[k][3-i]);
507
              }
508
509
            printf("| ");
510
511
            for (int i=0;i<4;i++)
512
              {
513
                printf("%02x ", q[k][i]);
514
              }
515
            printf("\n");
516
          }
517
#endif
518
519
520
5.59M
        int QP_Q = img->get_QPY(xDi,yDi);
521
5.59M
        int QP_P = (vertical ?
522
2.76M
                    img->get_QPY(xDi-1,yDi) :
523
5.59M
                    img->get_QPY(xDi,yDi-1) );
524
5.59M
        int qP_L = (QP_Q+QP_P+1)>>1;
525
526
5.59M
        logtrace(LogDeblock,"QP: %d & %d -> %d\n",QP_Q,QP_P,qP_L);
527
528
5.59M
        int sliceIndexQ00 = img->get_SliceHeaderIndex(xDi,yDi);
529
5.59M
        int beta_offset = img->slices[sliceIndexQ00]->slice_beta_offset;
530
5.59M
        int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
531
532
5.59M
        int Q_beta = Clip3(0,51, qP_L + beta_offset);
533
5.59M
        int betaPrime = table_8_23_beta[Q_beta];
534
5.59M
        int beta = betaPrime * (1<<(bitDepth_Y - 8));
535
536
5.59M
        int Q_tc = Clip3(0,53, qP_L + 2*(bS-1) + tc_offset);
537
5.59M
        int tcPrime = table_8_23_tc[Q_tc];
538
5.59M
        int tc = tcPrime * (1<<(bitDepth_Y - 8));
539
540
5.59M
        logtrace(LogDeblock,"beta: %d (%d)  tc: %d (%d)\n",beta,beta_offset, tc,tc_offset);
541
542
5.59M
        int dE=0, dEp=0, dEq=0;
543
544
5.59M
        if (vertical || !vertical) {
545
5.59M
          int dp0 = abs_value(p[0][2] - 2*p[0][1] + p[0][0]);
546
5.59M
          int dp3 = abs_value(p[3][2] - 2*p[3][1] + p[3][0]);
547
5.59M
          int dq0 = abs_value(q[0][2] - 2*q[0][1] + q[0][0]);
548
5.59M
          int dq3 = abs_value(q[3][2] - 2*q[3][1] + q[3][0]);
549
550
5.59M
          int dpq0 = dp0 + dq0;
551
5.59M
          int dpq3 = dp3 + dq3;
552
553
5.59M
          int dp = dp0 + dp3;
554
5.59M
          int dq = dq0 + dq3;
555
5.59M
          int d  = dpq0+ dpq3;
556
557
5.59M
          if (d<beta) {
558
            //int dpq = 2*dpq0;
559
2.77M
            bool dSam0 = (2*dpq0 < (beta>>2) &&
560
2.77M
                          abs_value(p[0][3]-p[0][0])+abs_value(q[0][0]-q[0][3]) < (beta>>3) &&
561
2.77M
                          abs_value(p[0][0]-q[0][0]) < ((5*tc+1)>>1));
562
563
2.77M
            bool dSam3 = (2*dpq3 < (beta>>2) &&
564
2.77M
                          abs_value(p[3][3]-p[3][0])+abs_value(q[3][0]-q[3][3]) < (beta>>3) &&
565
2.77M
                          abs_value(p[3][0]-q[3][0]) < ((5*tc+1)>>1));
566
567
2.77M
            if (dSam0 && dSam3) {
568
1.59M
              dE=2;
569
1.59M
            }
570
1.17M
            else {
571
1.17M
              dE=1;
572
1.17M
            }
573
574
2.77M
            if (dp < ((beta + (beta>>1))>>3)) { dEp=1; }
575
2.77M
            if (dq < ((beta + (beta>>1))>>3)) { dEq=1; }
576
577
2.77M
            logtrace(LogDeblock,"dE:%d dEp:%d dEq:%d\n",dE,dEp,dEq);
578
2.77M
          }
579
5.59M
        }
580
0
        else {
581
          // TODO
582
0
          assert(0);
583
0
        }
584
585
586
        // 8.7.2.4.4
587
588
5.59M
        if (dE != 0) {
589
2.77M
          bool filterP = true;
590
2.77M
          bool filterQ = true;
591
592
2.77M
          if (vertical) {
593
1.25M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi-1,yDi)) filterP=false;
594
1.25M
            if (img->get_cu_transquant_bypass(xDi-1,yDi)) filterP=false;
595
596
1.25M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
597
1.25M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
598
1.25M
          }
599
1.51M
          else {
600
1.51M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi-1)) filterP=false;
601
1.51M
            if (img->get_cu_transquant_bypass(xDi,yDi-1)) filterP=false;
602
603
1.51M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(xDi,yDi)) filterQ=false;
604
1.51M
            if (img->get_cu_transquant_bypass(xDi,yDi)) filterQ=false;
605
1.51M
          }
606
607
13.8M
          for (int k=0;k<4;k++) {
608
            //int nDp,nDq;
609
610
11.0M
            logtrace(LogDeblock,"line:%d\n",k);
611
612
11.0M
            const pixel_t p0 = p[k][0];
613
11.0M
            const pixel_t p1 = p[k][1];
614
11.0M
            const pixel_t p2 = p[k][2];
615
11.0M
            const pixel_t p3 = p[k][3];
616
11.0M
            const pixel_t q0 = q[k][0];
617
11.0M
            const pixel_t q1 = q[k][1];
618
11.0M
            const pixel_t q2 = q[k][2];
619
11.0M
            const pixel_t q3 = q[k][3];
620
621
11.0M
            if (dE==2) {
622
              // strong filtering
623
624
              //nDp=nDq=3;
625
626
6.38M
              pixel_t pnew[3],qnew[3];
627
6.38M
              pnew[0] = Clip3(p0-2*tc,p0+2*tc, (p2 + 2*p1 + 2*p0 + 2*q0 + q1 +4)>>3);
628
6.38M
              pnew[1] = Clip3(p1-2*tc,p1+2*tc, (p2 + p1 + p0 + q0+2)>>2);
629
6.38M
              pnew[2] = Clip3(p2-2*tc,p2+2*tc, (2*p3 + 3*p2 + p1 + p0 + q0 + 4)>>3);
630
6.38M
              qnew[0] = Clip3(q0-2*tc,q0+2*tc, (p1+2*p0+2*q0+2*q1+q2+4)>>3);
631
6.38M
              qnew[1] = Clip3(q1-2*tc,q1+2*tc, (p0+q0+q1+q2+2)>>2);
632
6.38M
              qnew[2] = Clip3(q2-2*tc,q2+2*tc, (p0+q0+q1+3*q2+2*q3+4)>>3);
633
634
6.38M
              logtrace(LogDeblock,"strong filtering\n");
635
636
6.38M
              if (vertical) {
637
11.0M
                for (int i=0;i<3;i++) {
638
8.31M
                  if (filterP) { ptr[-i-1+k*stride] = pnew[i]; }
639
8.31M
                  if (filterQ) { ptr[ i + k*stride] = qnew[i]; }
640
8.31M
                }
641
642
                // ptr[-1+k*stride] = ptr[ 0+k*stride] = 200;
643
2.77M
              }
644
3.61M
              else {
645
14.4M
                for (int i=0;i<3;i++) {
646
10.8M
                  if (filterP) { ptr[ k -(i+1)*stride] = pnew[i]; }
647
10.8M
                  if (filterQ) { ptr[ k + i   *stride] = qnew[i]; }
648
10.8M
                }
649
3.61M
              }
650
6.38M
            }
651
4.70M
            else {
652
              // weak filtering
653
654
              //nDp=nDq=0;
655
656
4.70M
              int delta = (9*(q0-p0) - 3*(q1-p1) + 8)>>4;
657
4.70M
              logtrace(LogDeblock,"delta=%d, tc=%d\n",delta,tc);
658
659
4.70M
              if (abs_value(delta) < tc*10) {
660
661
4.20M
                delta = Clip3(-tc,tc,delta);
662
4.20M
                logtrace(LogDeblock," deblk + %d;%d [%02x->%02x]  - %d;%d [%02x->%02x] delta:%d\n",
663
4.20M
                         vertical ? xDi-1 : xDi+k,
664
4.20M
                         vertical ? yDi+k : yDi-1, p0,Clip_BitDepth(p0+delta, bitDepth_Y),
665
4.20M
                         vertical ? xDi   : xDi+k,
666
4.20M
                         vertical ? yDi+k : yDi,   q0,Clip_BitDepth(q0-delta, bitDepth_Y),
667
4.20M
                         delta);
668
669
4.20M
                if (vertical) {
670
2.05M
                  if (filterP) { ptr[-0-1+k*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
671
2.05M
                  if (filterQ) { ptr[ 0  +k*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
672
2.05M
                }
673
2.14M
                else {
674
2.14M
                  if (filterP) { ptr[ k -1*stride] = Clip_BitDepth(p0+delta, bitDepth_Y); }
675
2.14M
                  if (filterQ) { ptr[ k +0*stride] = Clip_BitDepth(q0-delta, bitDepth_Y); }
676
2.14M
                }
677
678
                //ptr[ 0+k*stride] = 200;
679
680
4.20M
                if (dEp==1 && filterP) {
681
1.48M
                  int delta_p = Clip3(-(tc>>1), tc>>1, (((p2+p0+1)>>1)-p1+delta)>>1);
682
683
1.48M
                  logtrace(LogDeblock," deblk dEp %d;%d delta:%d\n",
684
1.48M
                           vertical ? xDi-2 : xDi+k,
685
1.48M
                           vertical ? yDi+k : yDi-2,
686
1.48M
                           delta_p);
687
688
1.48M
                  if (vertical) { ptr[-1-1+k*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
689
735k
                  else          { ptr[ k  -2*stride] = Clip_BitDepth(p1+delta_p, bitDepth_Y); }
690
1.48M
                }
691
692
4.20M
                if (dEq==1 && filterQ) {
693
1.42M
                  int delta_q = Clip3(-(tc>>1), tc>>1, (((q2+q0+1)>>1)-q1-delta)>>1);
694
695
1.42M
                  logtrace(LogDeblock," delkb dEq %d;%d delta:%d\n",
696
1.42M
                           vertical ? xDi+1 : xDi+k,
697
1.42M
                           vertical ? yDi+k : yDi+1,
698
1.42M
                           delta_q);
699
700
1.42M
                  if (vertical) { ptr[ 1  +k*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
701
862k
                  else          { ptr[ k  +1*stride] = Clip_BitDepth(q1+delta_q, bitDepth_Y); }
702
1.42M
                }
703
704
                //nDp = dEp+1;
705
                //nDq = dEq+1;
706
707
                //logtrace(LogDeblock,"weak filtering (%d:%d)\n",nDp,nDq);
708
4.20M
              }
709
4.70M
            }
710
11.0M
          }
711
2.77M
        }
712
5.59M
      }
713
14.5M
    }
714
43.6k
}
715
716
717
void edge_filtering_luma(de265_image* img, bool vertical,
718
                         int yStart,int yEnd, int xStart,int xEnd)
719
347k
{
720
347k
  if (img->high_bit_depth(0)) {
721
303k
    edge_filtering_luma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
722
303k
  }
723
43.6k
  else {
724
43.6k
    edge_filtering_luma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
725
43.6k
  }
726
347k
}
727
728
void edge_filtering_luma_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
729
0
{
730
0
  int ctbSize = img->get_sps().CtbSizeY;
731
0
  int deblkSize = ctbSize/4;
732
733
0
  edge_filtering_luma(img,vertical,
734
0
                      yCtb*deblkSize, (yCtb+1)*deblkSize,
735
0
                      xCtb*deblkSize, (xCtb+1)*deblkSize);
736
0
}
737
738
739
740
741
// 8.7.2.4
742
/** ?Start and ?End values in 4-luma pixels resolution.
743
 */
744
template <class pixel_t>
745
void edge_filtering_chroma_internal(de265_image* img, bool vertical,
746
                                    int yStart,int yEnd,
747
                                    int xStart,int xEnd)
748
258k
{
749
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
750
751
258k
  const seq_parameter_set& sps = img->get_sps();
752
753
258k
  const int SubWidthC  = sps.SubWidthC;
754
258k
  const int SubHeightC = sps.SubHeightC;
755
756
258k
  int xIncr = vertical ? 2 : 1;
757
258k
  int yIncr = vertical ? 1 : 2;
758
759
258k
  xIncr *= SubWidthC;
760
258k
  yIncr *= SubHeightC;
761
762
258k
  const int stride = img->get_image_stride(1);
763
764
258k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
765
258k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
766
767
258k
  int bitDepth_C = sps.BitDepth_C;
768
769
783k
  for (int y=yStart;y<yEnd;y+=yIncr)
770
11.1M
    for (int x=xStart;x<xEnd;x+=xIncr) {
771
10.6M
      int xDi = x << (3-SubWidthC);
772
10.6M
      int yDi = y << (3-SubHeightC);
773
774
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
775
776
10.6M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
777
778
10.6M
      if (bS>1) {
779
        // 8.7.2.4.5
780
781
10.6M
        for (int cplane=0;cplane<2;cplane++) {
782
7.07M
          int cQpPicOffset = (cplane==0 ?
783
3.53M
                              img->get_pps().pic_cb_qp_offset :
784
7.07M
                              img->get_pps().pic_cr_qp_offset);
785
786
7.07M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
787
788
7.07M
          pixel_t p[2][4];
789
7.07M
          pixel_t q[2][4];
790
791
7.07M
          logtrace(LogDeblock,"-%s- %d %d\n",cplane==0 ? "Cb" : "Cr",xDi,yDi);
792
793
21.2M
          for (int i=0;i<2;i++)
794
70.7M
            for (int k=0;k<4;k++)
795
56.5M
              {
796
56.5M
                if (vertical) {
797
30.6M
                  q[i][k] = ptr[ i  +k*stride];
798
30.6M
                  p[i][k] = ptr[-i-1+k*stride];
799
30.6M
                }
800
25.8M
                else {
801
25.8M
                  q[i][k] = ptr[k + i   *stride];
802
25.8M
                  p[i][k] = ptr[k -(i+1)*stride];
803
25.8M
                }
804
56.5M
              }
805
806
#if 0
807
          for (int k=0;k<4;k++)
808
            {
809
              for (int i=0;i<2;i++)
810
                {
811
                  printf("%02x ", p[1-i][k]);
812
                }
813
814
              printf("| ");
815
816
              for (int i=0;i<2;i++)
817
                {
818
                  printf("%02x ", q[i][k]);
819
                }
820
              printf("\n");
821
            }
822
#endif
823
824
7.07M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
825
7.07M
          int QP_P = (vertical ?
826
3.83M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
827
7.07M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
828
7.07M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
829
7.07M
          int QP_C;
830
7.07M
          if (sps.ChromaArrayType == CHROMA_420) {
831
1.10M
            QP_C = table8_22(qP_i);
832
5.96M
          } else {
833
5.96M
            QP_C = libde265_min(qP_i, 51);
834
5.96M
          }
835
836
837
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
838
7.07M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
839
7.07M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
840
841
7.07M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
842
7.07M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
843
844
7.07M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
845
846
7.07M
          int tcPrime = table_8_23_tc[Q];
847
7.07M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
848
849
7.07M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
850
851
7.07M
          if (vertical) {
852
3.83M
            bool filterP = true;
853
3.83M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
854
3.83M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
855
856
3.83M
            bool filterQ = true;
857
3.83M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
858
3.83M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
859
860
861
19.1M
            for (int k=0;k<4;k++) {
862
15.3M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2 in eq. (8-356), but the value can also be negative
863
15.3M
              logtrace(LogDeblock,"delta=%d\n",delta);
864
15.3M
              if (filterP) { ptr[-1+k*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
865
15.3M
              if (filterQ) { ptr[ 0+k*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
866
15.3M
            }
867
3.83M
          }
868
3.23M
          else {
869
3.23M
            bool filterP = true;
870
3.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
871
3.23M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
872
873
3.23M
            bool filterQ = true;
874
3.23M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
875
3.23M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
876
877
16.1M
            for (int k=0;k<4;k++) {
878
12.9M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2, but the value can also be negative
879
12.9M
              if (filterP) { ptr[ k-1*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
880
12.9M
              if (filterQ) { ptr[ k+0*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
881
12.9M
            }
882
3.23M
          }
883
7.07M
        }
884
3.53M
      }
885
10.6M
    }
886
258k
}
void edge_filtering_chroma_internal<unsigned short>(de265_image*, bool, int, int, int, int)
Line
Count
Source
748
214k
{
749
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
750
751
214k
  const seq_parameter_set& sps = img->get_sps();
752
753
214k
  const int SubWidthC  = sps.SubWidthC;
754
214k
  const int SubHeightC = sps.SubHeightC;
755
756
214k
  int xIncr = vertical ? 2 : 1;
757
214k
  int yIncr = vertical ? 1 : 2;
758
759
214k
  xIncr *= SubWidthC;
760
214k
  yIncr *= SubHeightC;
761
762
214k
  const int stride = img->get_image_stride(1);
763
764
214k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
765
214k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
766
767
214k
  int bitDepth_C = sps.BitDepth_C;
768
769
584k
  for (int y=yStart;y<yEnd;y+=yIncr)
770
4.40M
    for (int x=xStart;x<xEnd;x+=xIncr) {
771
4.03M
      int xDi = x << (3-SubWidthC);
772
4.03M
      int yDi = y << (3-SubHeightC);
773
774
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
775
776
4.03M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
777
778
4.03M
      if (bS>1) {
779
        // 8.7.2.4.5
780
781
4.47M
        for (int cplane=0;cplane<2;cplane++) {
782
2.98M
          int cQpPicOffset = (cplane==0 ?
783
1.49M
                              img->get_pps().pic_cb_qp_offset :
784
2.98M
                              img->get_pps().pic_cr_qp_offset);
785
786
2.98M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
787
788
2.98M
          pixel_t p[2][4];
789
2.98M
          pixel_t q[2][4];
790
791
2.98M
          logtrace(LogDeblock,"-%s- %d %d\n",cplane==0 ? "Cb" : "Cr",xDi,yDi);
792
793
8.94M
          for (int i=0;i<2;i++)
794
29.8M
            for (int k=0;k<4;k++)
795
23.8M
              {
796
23.8M
                if (vertical) {
797
13.0M
                  q[i][k] = ptr[ i  +k*stride];
798
13.0M
                  p[i][k] = ptr[-i-1+k*stride];
799
13.0M
                }
800
10.8M
                else {
801
10.8M
                  q[i][k] = ptr[k + i   *stride];
802
10.8M
                  p[i][k] = ptr[k -(i+1)*stride];
803
10.8M
                }
804
23.8M
              }
805
806
#if 0
807
          for (int k=0;k<4;k++)
808
            {
809
              for (int i=0;i<2;i++)
810
                {
811
                  printf("%02x ", p[1-i][k]);
812
                }
813
814
              printf("| ");
815
816
              for (int i=0;i<2;i++)
817
                {
818
                  printf("%02x ", q[i][k]);
819
                }
820
              printf("\n");
821
            }
822
#endif
823
824
2.98M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
825
2.98M
          int QP_P = (vertical ?
826
1.62M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
827
2.98M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
828
2.98M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
829
2.98M
          int QP_C;
830
2.98M
          if (sps.ChromaArrayType == CHROMA_420) {
831
659k
            QP_C = table8_22(qP_i);
832
2.32M
          } else {
833
2.32M
            QP_C = libde265_min(qP_i, 51);
834
2.32M
          }
835
836
837
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
838
2.98M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
839
2.98M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
840
841
2.98M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
842
2.98M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
843
844
2.98M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
845
846
2.98M
          int tcPrime = table_8_23_tc[Q];
847
2.98M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
848
849
2.98M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
850
851
2.98M
          if (vertical) {
852
1.62M
            bool filterP = true;
853
1.62M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
854
1.62M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
855
856
1.62M
            bool filterQ = true;
857
1.62M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
858
1.62M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
859
860
861
8.12M
            for (int k=0;k<4;k++) {
862
6.50M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2 in eq. (8-356), but the value can also be negative
863
6.50M
              logtrace(LogDeblock,"delta=%d\n",delta);
864
6.50M
              if (filterP) { ptr[-1+k*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
865
6.50M
              if (filterQ) { ptr[ 0+k*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
866
6.50M
            }
867
1.62M
          }
868
1.35M
          else {
869
1.35M
            bool filterP = true;
870
1.35M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
871
1.35M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
872
873
1.35M
            bool filterQ = true;
874
1.35M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
875
1.35M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
876
877
6.78M
            for (int k=0;k<4;k++) {
878
5.42M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2, but the value can also be negative
879
5.42M
              if (filterP) { ptr[ k-1*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
880
5.42M
              if (filterQ) { ptr[ k+0*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
881
5.42M
            }
882
1.35M
          }
883
2.98M
        }
884
1.49M
      }
885
4.03M
    }
886
214k
}
void edge_filtering_chroma_internal<unsigned char>(de265_image*, bool, int, int, int, int)
Line
Count
Source
748
43.9k
{
749
  //printf("chroma %d-%d %d-%d\n",xStart,xEnd,yStart,yEnd);
750
751
43.9k
  const seq_parameter_set& sps = img->get_sps();
752
753
43.9k
  const int SubWidthC  = sps.SubWidthC;
754
43.9k
  const int SubHeightC = sps.SubHeightC;
755
756
43.9k
  int xIncr = vertical ? 2 : 1;
757
43.9k
  int yIncr = vertical ? 1 : 2;
758
759
43.9k
  xIncr *= SubWidthC;
760
43.9k
  yIncr *= SubHeightC;
761
762
43.9k
  const int stride = img->get_image_stride(1);
763
764
43.9k
  xEnd = libde265_min(xEnd,img->get_deblk_width());
765
43.9k
  yEnd = libde265_min(yEnd,img->get_deblk_height());
766
767
43.9k
  int bitDepth_C = sps.BitDepth_C;
768
769
199k
  for (int y=yStart;y<yEnd;y+=yIncr)
770
6.75M
    for (int x=xStart;x<xEnd;x+=xIncr) {
771
6.60M
      int xDi = x << (3-SubWidthC);
772
6.60M
      int yDi = y << (3-SubHeightC);
773
774
      //printf("x,y:%d,%d  xDi,yDi:%d,%d\n",x,y,xDi,yDi);
775
776
6.60M
      int bS = img->get_deblk_bS(xDi*SubWidthC,yDi*SubHeightC);
777
778
6.60M
      if (bS>1) {
779
        // 8.7.2.4.5
780
781
6.13M
        for (int cplane=0;cplane<2;cplane++) {
782
4.08M
          int cQpPicOffset = (cplane==0 ?
783
2.04M
                              img->get_pps().pic_cb_qp_offset :
784
4.08M
                              img->get_pps().pic_cr_qp_offset);
785
786
4.08M
          pixel_t* ptr = img->get_image_plane_at_pos_NEW<pixel_t>(cplane+1, xDi,yDi);
787
788
4.08M
          pixel_t p[2][4];
789
4.08M
          pixel_t q[2][4];
790
791
4.08M
          logtrace(LogDeblock,"-%s- %d %d\n",cplane==0 ? "Cb" : "Cr",xDi,yDi);
792
793
12.2M
          for (int i=0;i<2;i++)
794
40.8M
            for (int k=0;k<4;k++)
795
32.7M
              {
796
32.7M
                if (vertical) {
797
17.6M
                  q[i][k] = ptr[ i  +k*stride];
798
17.6M
                  p[i][k] = ptr[-i-1+k*stride];
799
17.6M
                }
800
15.0M
                else {
801
15.0M
                  q[i][k] = ptr[k + i   *stride];
802
15.0M
                  p[i][k] = ptr[k -(i+1)*stride];
803
15.0M
                }
804
32.7M
              }
805
806
#if 0
807
          for (int k=0;k<4;k++)
808
            {
809
              for (int i=0;i<2;i++)
810
                {
811
                  printf("%02x ", p[1-i][k]);
812
                }
813
814
              printf("| ");
815
816
              for (int i=0;i<2;i++)
817
                {
818
                  printf("%02x ", q[i][k]);
819
                }
820
              printf("\n");
821
            }
822
#endif
823
824
4.08M
          int QP_Q = img->get_QPY(SubWidthC*xDi,SubHeightC*yDi);
825
4.08M
          int QP_P = (vertical ?
826
2.20M
                      img->get_QPY(SubWidthC*xDi-1,SubHeightC*yDi) :
827
4.08M
                      img->get_QPY(SubWidthC*xDi,SubHeightC*yDi-1));
828
4.08M
          int qP_i = ((QP_Q+QP_P+1)>>1) + cQpPicOffset;
829
4.08M
          int QP_C;
830
4.08M
          if (sps.ChromaArrayType == CHROMA_420) {
831
445k
            QP_C = table8_22(qP_i);
832
3.64M
          } else {
833
3.64M
            QP_C = libde265_min(qP_i, 51);
834
3.64M
          }
835
836
837
          //printf("POC=%d\n",ctx->img->PicOrderCntVal);
838
4.08M
          logtrace(LogDeblock,"%d %d: ((%d+%d+1)>>1) + %d = qP_i=%d  (QP_C=%d)\n",
839
4.08M
                   SubWidthC*xDi,SubHeightC*yDi, QP_Q,QP_P,cQpPicOffset,qP_i,QP_C);
840
841
4.08M
          int sliceIndexQ00 = img->get_SliceHeaderIndex(SubWidthC*xDi,SubHeightC*yDi);
842
4.08M
          int tc_offset   = img->slices[sliceIndexQ00]->slice_tc_offset;
843
844
4.08M
          int Q = Clip3(0,53, QP_C + 2*(bS-1) + tc_offset);
845
846
4.08M
          int tcPrime = table_8_23_tc[Q];
847
4.08M
          int tc = tcPrime * (1<<(sps.BitDepth_C - 8));
848
849
4.08M
          logtrace(LogDeblock,"tc_offset=%d Q=%d tc'=%d tc=%d\n",tc_offset,Q,tcPrime,tc);
850
851
4.08M
          if (vertical) {
852
2.20M
            bool filterP = true;
853
2.20M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
854
2.20M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi-1,SubHeightC*yDi)) filterP=false;
855
856
2.20M
            bool filterQ = true;
857
2.20M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
858
2.20M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
859
860
861
11.0M
            for (int k=0;k<4;k++) {
862
8.83M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2 in eq. (8-356), but the value can also be negative
863
8.83M
              logtrace(LogDeblock,"delta=%d\n",delta);
864
8.83M
              if (filterP) { ptr[-1+k*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
865
8.83M
              if (filterQ) { ptr[ 0+k*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
866
8.83M
            }
867
2.20M
          }
868
1.87M
          else {
869
1.87M
            bool filterP = true;
870
1.87M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
871
1.87M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi-1)) filterP=false;
872
873
1.87M
            bool filterQ = true;
874
1.87M
            if (sps.pcm_loop_filter_disable_flag && img->get_pcm_flag(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
875
1.87M
            if (img->get_cu_transquant_bypass(SubWidthC*xDi,SubHeightC*yDi)) filterQ=false;
876
877
9.39M
            for (int k=0;k<4;k++) {
878
7.51M
              int delta = Clip3(-tc,tc, ((((q[0][k]-p[0][k])*4)+p[1][k]-q[1][k]+4)>>3)); // standard says <<2, but the value can also be negative
879
7.51M
              if (filterP) { ptr[ k-1*stride] = Clip_BitDepth(p[0][k]+delta, bitDepth_C); }
880
7.51M
              if (filterQ) { ptr[ k+0*stride] = Clip_BitDepth(q[0][k]-delta, bitDepth_C); }
881
7.51M
            }
882
1.87M
          }
883
4.08M
        }
884
2.04M
      }
885
6.60M
    }
886
43.9k
}
887
888
889
void edge_filtering_chroma(de265_image* img, bool vertical, int yStart,int yEnd,
890
                           int xStart,int xEnd)
891
258k
{
892
258k
  if (img->high_bit_depth(1)) {
893
214k
    edge_filtering_chroma_internal<uint16_t>(img,vertical,yStart,yEnd,xStart,xEnd);
894
214k
  }
895
43.9k
  else {
896
43.9k
    edge_filtering_chroma_internal<uint8_t>(img,vertical,yStart,yEnd,xStart,xEnd);
897
43.9k
  }
898
258k
}
899
900
901
void edge_filtering_chroma_CTB(de265_image* img, bool vertical, int xCtb,int yCtb)
902
0
{
903
0
  int ctbSize = img->get_sps().CtbSizeY;
904
0
  int deblkSize = ctbSize/4;
905
906
0
  edge_filtering_chroma(img,vertical,
907
0
                        yCtb*deblkSize, (yCtb+1)*deblkSize,
908
0
                        xCtb*deblkSize, (xCtb+1)*deblkSize);
909
0
}
910
911
912
913
class thread_task_deblock_CTBRow : public thread_task
914
{
915
public:
916
  struct de265_image* img;
917
  int  ctb_y;
918
  bool vertical;
919
920
  virtual void work();
921
0
  virtual std::string name() const {
922
0
    char buf[100];
923
0
    sprintf(buf,"deblock-%d",ctb_y);
924
0
    return buf;
925
0
  }
926
};
927
928
929
void thread_task_deblock_CTBRow::work()
930
549k
{
931
549k
  state = Running;
932
549k
  img->thread_run(this);
933
934
549k
  int xStart=0;
935
549k
  int xEnd = img->get_deblk_width();
936
937
549k
  int ctbSize = img->get_sps().CtbSizeY;
938
549k
  int deblkSize = ctbSize/4;
939
940
549k
  int first =  ctb_y    * deblkSize;
941
549k
  int last  = (ctb_y+1) * deblkSize;
942
549k
  if (last > img->get_deblk_height()) {
943
7.78k
    last = img->get_deblk_height();
944
7.78k
  }
945
946
549k
  int finalProgress = CTB_PROGRESS_DEBLK_V;
947
549k
  if (!vertical) finalProgress = CTB_PROGRESS_DEBLK_H;
948
949
549k
  int rightCtb = img->get_sps().PicWidthInCtbsY-1;
950
951
549k
  if (vertical) {
952
    // pass 1: vertical
953
954
274k
    int CtbRow = std::min(ctb_y+1 , img->get_sps().PicHeightInCtbsY-1);
955
274k
    img->wait_for_progress(this, rightCtb,CtbRow, CTB_PROGRESS_PREFILTER);
956
274k
  }
957
274k
  else {
958
    // pass 2: horizontal
959
960
274k
    if (ctb_y>0) {
961
267k
      img->wait_for_progress(this, rightCtb,ctb_y-1, CTB_PROGRESS_DEBLK_V);
962
267k
    }
963
964
274k
    img->wait_for_progress(this, rightCtb,ctb_y,  CTB_PROGRESS_DEBLK_V);
965
966
274k
    if (ctb_y+1<img->get_sps().PicHeightInCtbsY) {
967
267k
      img->wait_for_progress(this, rightCtb,ctb_y+1, CTB_PROGRESS_DEBLK_V);
968
267k
    }
969
274k
  }
970
971
  //printf("deblock %d to %d orientation: %d\n",first,last,vertical);
972
973
549k
  bool deblocking_enabled;
974
975
  // first pass: check edge flags and whether we have to deblock
976
549k
  if (vertical) {
977
274k
    deblocking_enabled = derive_edgeFlags_CTBRow(img, ctb_y);
978
979
    //for (int x=0;x<=rightCtb;x++) {
980
274k
    int x=0; img->set_CtbDeblockFlag(x,ctb_y, deblocking_enabled);
981
    //}
982
274k
  }
983
274k
  else {
984
274k
    int x=0; deblocking_enabled=img->get_CtbDeblockFlag(x,ctb_y);
985
274k
  }
986
987
549k
  if (deblocking_enabled) {
988
347k
    derive_boundaryStrength(img, vertical, first,last, xStart,xEnd);
989
990
347k
    edge_filtering_luma(img, vertical, first,last, xStart,xEnd);
991
992
347k
    if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
993
258k
      edge_filtering_chroma(img, vertical, first,last, xStart,xEnd);
994
258k
    }
995
347k
  }
996
997
3.78M
  for (int x=0;x<=rightCtb;x++) {
998
3.23M
    const int CtbWidth = img->get_sps().PicWidthInCtbsY;
999
3.23M
    img->ctb_progress[x+ctb_y*CtbWidth].set_progress(finalProgress);
1000
3.23M
  }
1001
1002
549k
  state = Finished;
1003
549k
  img->thread_finishes(this);
1004
549k
}
1005
1006
1007
void add_deblocking_tasks(image_unit* imgunit)
1008
6.93k
{
1009
6.93k
  de265_image* img = imgunit->img;
1010
6.93k
  decoder_context* ctx = img->decctx;
1011
1012
6.93k
  int nRows = img->get_sps().PicHeightInCtbsY;
1013
1014
6.93k
  int n=0;
1015
6.93k
  img->thread_start(nRows*2);
1016
1017
20.8k
  for (int pass=0;pass<2;pass++)
1018
13.8k
    {
1019
562k
      for (int y=0;y<img->get_sps().PicHeightInCtbsY;y++)
1020
549k
        {
1021
549k
          thread_task_deblock_CTBRow* task = new thread_task_deblock_CTBRow;
1022
1023
549k
          task->img   = img;
1024
549k
          task->ctb_y = y;
1025
549k
          task->vertical = (pass==0);
1026
1027
549k
          imgunit->tasks.push_back(task);
1028
549k
          add_task(&ctx->thread_pool_, task);
1029
549k
          n++;
1030
549k
        }
1031
13.8k
    }
1032
6.93k
}
1033
1034
1035
void apply_deblocking_filter(de265_image* img) // decoder_context* ctx)
1036
0
{
1037
0
  decoder_context* ctx = img->decctx;
1038
1039
0
  char enabled_deblocking = derive_edgeFlags(img);
1040
1041
0
  if (enabled_deblocking)
1042
0
    {
1043
      // vertical filtering
1044
1045
0
      logtrace(LogDeblock,"VERTICAL\n");
1046
0
      derive_boundaryStrength(img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
1047
0
      edge_filtering_luma    (img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
1048
1049
0
      if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
1050
0
        edge_filtering_chroma  (img, true ,0,img->get_deblk_height(),0,img->get_deblk_width());
1051
0
      }
1052
#if 0
1053
      char buf[1000];
1054
      sprintf(buf,"lf-after-V-%05d.yuv", ctx->img->PicOrderCntVal);
1055
      write_picture_to_file(ctx->img, buf);
1056
#endif
1057
1058
      // horizontal filtering
1059
1060
0
      logtrace(LogDeblock,"HORIZONTAL\n");
1061
0
      derive_boundaryStrength(img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
1062
0
      edge_filtering_luma    (img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
1063
1064
0
      if (img->get_sps().ChromaArrayType != CHROMA_MONO) {
1065
0
        edge_filtering_chroma  (img, false ,0,img->get_deblk_height(),0,img->get_deblk_width());
1066
0
      }
1067
1068
#if 0
1069
      sprintf(buf,"lf-after-H-%05d.yuv", ctx->img->PicOrderCntVal);
1070
      write_picture_to_file(ctx->img, buf);
1071
#endif
1072
0
    }
1073
0
}