OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [test/] [decoder/] [ldecod/] [src/] [loopFilter.c] - Blame information for rev 100

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jamey.hick
 
2
/*!
3
 *************************************************************************************
4
 * \file loopFilter.c
5
 *
6
 * \brief
7
 *    Filter to reduce blocking artifacts on a macroblock level.
8
 *    The filter strength is QP dependent.
9
 *
10
 * \author
11
 *    Contributors:
12
 *    - Peter List       Peter.List@t-systems.de:  Original code                                 (13-Aug-2001)
13
 *    - Jani Lainema     Jani.Lainema@nokia.com:   Some bug fixing, removal of recusiveness      (16-Aug-2001)
14
 *    - Peter List       Peter.List@t-systems.de:  inplace filtering and various simplifications (10-Jan-2002)
15
 *    - Anthony Joch     anthony@ubvideo.com:      Simplified switching between filters and
16
 *                                                 non-recursive default filter.                 (08-Jul-2002)
17
 *    - Cristina Gomila  cristina.gomila@thomson.net: Simplification of the chroma deblocking
18
 *                                                    from JVT-E089                              (21-Nov-2002)
19
 *************************************************************************************
20
 */
21
#include <stdlib.h>
22
#include <string.h>
23
#include <assert.h>
24
#include "global.h"
25
#include "image.h"
26
#include "mb_access.h"
27
#include "loopfilter.h"
28
 
29
byte mixedModeEdgeFlag, fieldModeFilteringFlag;
30
 
31
/*********************************************************************************************************/
32
 
33
 
34
// NOTE: In principle, the alpha and beta tables are calculated with the formulas below
35
//       Alpha( qp ) = 0.8 * (2^(qp/6)  -  1)
36
//       Beta ( qp ) = 0.5 * qp  -  7
37
 
38
// The tables actually used have been "hand optimized" though (by Anthony Joch). So, the
39
// table values might be a little different to formula-generated values. Also, the first
40
// few values of both tables is set to zero to force the filter off at low qp’s
41
 
42
static const byte ALPHA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,4,4,5,6,  7,8,9,10,12,13,15,17,  20,22,25,28,32,36,40,45,  50,56,63,71,80,90,101,113,  127,144,162,182,203,226,255,255} ;
43
static const byte  BETA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,2,2,3,  3,3,3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9,10,10,  11,11,12,12,13,13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;
44
static const byte CLIP_TAB[52][5]  =
45
{
46
  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
47
  { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
48
  { 0, 0, 0, 0, 0},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 1, 1, 1, 1},
49
  { 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 2, 3, 3},
50
  { 0, 1, 2, 3, 3},{ 0, 2, 2, 3, 3},{ 0, 2, 2, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 3, 3, 5, 5},{ 0, 3, 4, 6, 6},{ 0, 3, 4, 6, 6},
51
  { 0, 4, 5, 7, 7},{ 0, 4, 5, 8, 8},{ 0, 4, 6, 9, 9},{ 0, 5, 7,10,10},{ 0, 6, 8,11,11},{ 0, 6, 8,13,13},{ 0, 7,10,14,14},{ 0, 8,11,16,16},
52
  { 0, 9,12,18,18},{ 0,10,13,20,20},{ 0,11,15,23,23},{ 0,13,17,25,25}
53
} ;
54
 
55
static const char chroma_edge[2][4][4] = //[dir][edge][yuv_format]
56
{ { {-1, 0, 0, 0},
57
    {-1,-1,-1, 1},
58
    {-1, 1, 1, 2},
59
    {-1,-1,-1, 3}},
60
 
61
  { {-1, 0, 0, 0},
62
    {-1,-1, 1, 1},
63
    {-1, 1, 2, 2},
64
    {-1,-1, 3, 3}}};
65
 
66
void GetStrength(byte Strength[16],struct img_par *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);
67
void EdgeLoop(imgpel** Img, byte Strength[16],struct img_par *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int yuv, int uv, StorablePicture *p);
68
void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr) ;
69
 
70
/*!
71
 *****************************************************************************************
72
 * \brief
73
 *    Filter all macroblocks in order of increasing macroblock address.
74
 *****************************************************************************************
75
 */
76
void DeblockPicture(ImageParameters *img, StorablePicture *p)
77
{
78
  unsigned i;
79
 
80
  for (i=0; i<p->PicSizeInMbs; i++)
81
  {
82
    DeblockMb( img, p, i ) ;
83
  }
84
}
85
 
86
 
87
/*!
88
 *****************************************************************************************
89
 * \brief
90
 *    Deblocking filter for one macroblock.
91
 *****************************************************************************************
92
 */
93
 
94
void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr)
95
{
96
  int           EdgeCondition;
97
  int           dir,edge;
98
  byte          Strength[16];
99
  int           mb_x, mb_y;
100
 
101
  int           filterNon8x8LumaEdgesFlag[4] = {1,1,1,1};
102
  int           filterLeftMbEdgeFlag;
103
  int           filterTopMbEdgeFlag;
104
  int           fieldModeMbFlag;
105
  int           mvlimit=4;
106
  int           i, StrengthSum;
107
  Macroblock    *MbQ;
108
  imgpel **imgY   = p->imgY;
109
  imgpel ***imgUV = p->imgUV;
110
 
111
  int           edge_cr;
112
 
113
  img->DeblockCall = 1;
114
  get_mb_pos (MbQAddr, &mb_x, &mb_y, IS_LUMA);
115
 
116
  filterLeftMbEdgeFlag  = (mb_x != 0);
117
  filterTopMbEdgeFlag   = (mb_y != 0);
118
 
119
  MbQ  = &(img->mb_data[MbQAddr]) ; // current Mb
120
 
121
  if (MbQ->mb_type == I8MB)
122
    assert(MbQ->luma_transform_size_8x8_flag);
123
 
124
  filterNon8x8LumaEdgesFlag[1] =
125
  filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag);
126
 
127
  if (p->MbaffFrameFlag && mb_y==16 && MbQ->mb_field)
128
    filterTopMbEdgeFlag = 0;
129
 
130
  fieldModeMbFlag       = (p->structure!=FRAME) || (p->MbaffFrameFlag && MbQ->mb_field);
131
  if (fieldModeMbFlag)
132
    mvlimit = 2;
133
 
134
  // return, if filter is disabled
135
  if (MbQ->LFDisableIdc==1) {
136
    img->DeblockCall = 0;
137
    return;
138
  }
139
 
140
  if (MbQ->LFDisableIdc==2)
141
  {
142
    // don't filter at slice boundaries
143
    filterLeftMbEdgeFlag = MbQ->mbAvailA;
144
    // if this the bottom of a frame macroblock pair then always filter the top edge
145
    if (p->MbaffFrameFlag && !MbQ->mb_field && (MbQAddr & 0x01))
146
      filterTopMbEdgeFlag  = 1;
147
    else
148
      filterTopMbEdgeFlag  = MbQ->mbAvailB;
149
  }
150
 
151
  img->current_mb_nr = MbQAddr;
152
  CheckAvailabilityOfNeighbors();
153
 
154
  for( dir=0 ; dir<2 ; dir++ )                                             // vertical edges, than horicontal edges
155
  {
156
    EdgeCondition = (dir && filterTopMbEdgeFlag) || (!dir && filterLeftMbEdgeFlag); // can not filter beyond picture boundaries
157
    for( edge=0 ; edge<4 ; edge++ )                                            // first 4 vertical strips of 16 pel
158
    {                                                                                         // then  4 horicontal
159
      if( edge || EdgeCondition )
160
      {
161
        edge_cr = chroma_edge[dir][edge][p->chroma_format_idc];
162
 
163
        GetStrength(Strength,img,MbQAddr,dir,edge, mvlimit, p); // Strength for 4 blks in 1 stripe
164
        StrengthSum = Strength[0];
165
        for (i = 1; i < 16; i++)
166
        {
167
          if (StrengthSum) break;
168
          StrengthSum += Strength[i];
169
        }
170
        if( StrengthSum )                      // only if one of the 16 Strength bytes is != 0
171
        {
172
          if (filterNon8x8LumaEdgesFlag[edge])
173
            EdgeLoop( imgY, Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge, p->size_x, 0, 0, p) ;
174
          if( (imgUV != NULL) && (edge_cr >= 0))
175
          {
176
            EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, p->size_x_cr, 1, 0, p) ;
177
            EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, edge_cr, p->size_x_cr, 1, 1, p) ;
178
          }
179
        }
180
 
181
        if (dir && !edge && !MbQ->mb_field && mixedModeEdgeFlag) {
182
          // this is the extra horizontal edge between a frame macroblock pair and a field above it
183
          img->DeblockCall = 2;
184
          GetStrength(Strength,img,MbQAddr,dir,4, mvlimit, p); // Strength for 4 blks in 1 stripe
185
          //if( *((int*)Strength) )                      // only if one of the 4 Strength bytes is != 0
186
          {
187
            if (filterNon8x8LumaEdgesFlag[edge])
188
              EdgeLoop( imgY, Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, p->size_x, 0, 0, p) ;
189
            if( (imgUV != NULL) && (edge_cr >= 0))
190
            {
191
              EdgeLoop( imgUV[0], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, p->size_x_cr, 1, 0, p) ;
192
              EdgeLoop( imgUV[1], Strength, img, MbQAddr, MbQ->LFAlphaC0Offset, MbQ->LFBetaOffset, dir, 4, p->size_x_cr, 1, 1, p) ;
193
            }
194
          }
195
          img->DeblockCall = 1;
196
        }
197
 
198
      }
199
    }//end edge
200
  }//end loop dir
201
  img->DeblockCall = 0;
202
 
203
}
204
 
205
  /*!
206
 *********************************************************************************************
207
 * \brief
208
 *    returns a buffer of 16 Strength values for one stripe in a mb (for different Frame types)
209
 *********************************************************************************************
210
 */
211
 
212
#define ANY_INTRA (MbP->mb_type==I4MB||MbP->mb_type==I16MB||MbP->mb_type==IPCM||MbQ->mb_type==I4MB||MbQ->mb_type==I16MB||MbQ->mb_type==IPCM)
213
 
214
void GetStrength(byte Strength[16],struct img_par *img,int MbQAddr,int dir,int edge, int mvlimit, StorablePicture *p)
215
{
216
  int    blkP, blkQ, idx;
217
  int    blk_x, blk_x2, blk_y, blk_y2 ;
218
  short  ***list0_mv = p->mv[LIST_0];
219
  short  ***list1_mv = p->mv[LIST_1];
220
  char   **list0_refIdxArr = p->ref_idx[LIST_0];
221
  char   **list1_refIdxArr = p->ref_idx[LIST_1];
222
  int64  **list0_refPicIdArr = p->ref_pic_id[LIST_0];
223
  int64  **list1_refPicIdArr = p->ref_pic_id[LIST_1];
224
  int64    ref_p0,ref_p1,ref_q0,ref_q1;
225
  int    xQ, xP, yQ, yP;
226
  int    mb_x, mb_y;
227
  Macroblock    *MbQ, *MbP;
228
  PixelPos pixP;
229
  int dir_m1 = (1 - dir);
230
 
231
  MbQ = &(img->mb_data[MbQAddr]);
232
 
233
  for( idx=0 ; idx<16 ; idx++ )
234
  {
235
    xQ = dir ? idx : edge << 2;
236
    yQ = dir ? (edge < 4 ? edge << 2 : 1) : idx;
237
    getNeighbour(MbQAddr, xQ - dir_m1, yQ - dir, IS_LUMA, &pixP);
238
    xP = pixP.x;
239
    yP = pixP.y;
240
    MbP = &(img->mb_data[pixP.mb_addr]);
241
    mixedModeEdgeFlag = (byte) (MbQ->mb_field != MbP->mb_field);
242
 
243
    blkQ = ((yQ>>2)<<2) + (xQ>>2);
244
    blkP = ((yP>>2)<<2) + (xP>>2);
245
 
246
    if ((p->slice_type==SP_SLICE)||(p->slice_type==SI_SLICE) )
247
    {
248
      Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
249
      (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
250
      ((p->MbaffFrameFlag || (p->structure != FRAME)) && !dir))) ? 4 : 3;
251
    }
252
    else
253
    {
254
      // Start with Strength=3. or Strength=4 for Mb-edge
255
      Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
256
        (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
257
        ((p->MbaffFrameFlag || (p->structure!=FRAME)) && !dir))) ? 4 : 3;
258
 
259
      if(  !(MbP->mb_type==I4MB || MbP->mb_type==I16MB || MbP->mb_type==I8MB || MbP->mb_type==IPCM)
260
        && !(MbQ->mb_type==I4MB || MbQ->mb_type==I16MB || MbQ->mb_type==I8MB || MbQ->mb_type==IPCM) )
261
      {
262
        if( ((MbQ->cbp_blk &  ((int64)1 << blkQ )) != 0) || ((MbP->cbp_blk &  ((int64)1 << blkP)) != 0) )
263
          Strength[idx] = 2 ;
264
        else
265
        {
266
          // if no coefs, but vector difference >= 1 set Strength=1
267
          // if this is a mixed mode edge then one set of reference pictures will be frame and the
268
          // other will be field
269
          if (mixedModeEdgeFlag)
270
          {
271
            (Strength[idx] = 1);
272
          }
273
          else
274
          {
275
            get_mb_block_pos (MbQAddr, &mb_x, &mb_y);
276
            blk_y  = (mb_y<<2) + (blkQ >> 2) ;
277
            blk_x  = (mb_x<<2) + (blkQ  & 3) ;
278
            blk_y2 = pixP.pos_y >> 2;
279
            blk_x2 = pixP.pos_x >> 2;
280
            {
281
              ref_p0 = list0_refIdxArr[blk_y] [blk_x] <0 ? INT64_MIN : list0_refPicIdArr[blk_y] [blk_x];
282
              ref_q0 = list0_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list0_refPicIdArr[blk_y2][blk_x2];
283
              ref_p1 = list1_refIdxArr[blk_y] [blk_x] <0 ? INT64_MIN : list1_refPicIdArr[blk_y] [blk_x];
284
              ref_q1 = list1_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list1_refPicIdArr[blk_y2][blk_x2];
285
              if ( ((ref_p0==ref_q0) && (ref_p1==ref_q1)) ||
286
                ((ref_p0==ref_q1) && (ref_p1==ref_q0)))
287
              {
288
                Strength[idx]=0;
289
                // L0 and L1 reference pictures of p0 are different; q0 as well
290
                if (ref_p0 != ref_p1)
291
                {
292
                  // compare MV for the same reference picture
293
                  if (ref_p0==ref_q0)
294
                  {
295
                    Strength[idx] =  (byte) (
296
                      (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
297
                      (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit) |
298
                      (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
299
                      (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
300
                  }
301
                  else
302
                  {
303
                    Strength[idx] =  (byte) (
304
                      (iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
305
                      (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
306
                      (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
307
                      (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
308
                  }
309
                }
310
                else
311
                { // L0 and L1 reference pictures of p0 are the same; q0 as well
312
 
313
                  Strength[idx] = (byte) (
314
                    ((iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
315
                    (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit ) |
316
                    (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
317
                    (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
318
                    &&
319
                    ((iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
320
                    (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
321
                    (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
322
                    (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)));
323
                }
324
              }
325
              else
326
              {
327
                Strength[idx] = 1;
328
              }
329
            }
330
          }
331
        }
332
      }
333
    }
334
  }
335
}
336
 
337
/*!
338
 *****************************************************************************************
339
 * \brief
340
 *    Filters one edge of 16 (luma) or 8 (chroma) pel
341
 *****************************************************************************************
342
 */
343
void EdgeLoop(imgpel** Img, byte Strength[16],struct img_par *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
344
              int dir, int edge, int width, int yuv, int uv, StorablePicture *p)
345
{
346
  int      pel, ap = 0, aq = 0, Strng ;
347
  int      incP, incQ;
348
  int      C0, c0, Delta, dif, AbsDelta ;
349
  int      L2 = 0, L1, L0, R0, R1, R2 = 0, RL0, L3, R3 ;
350
  int      Alpha = 0, Beta = 0 ;
351
  const byte* ClipTab = NULL;
352
  int      small_gap;
353
  int      indexA, indexB;
354
  int      PelNum;
355
  int      StrengthIdx;
356
  imgpel   *SrcPtrP, *SrcPtrQ;
357
  int      QP;
358
  int      xP, xQ, yP, yQ;
359
  Macroblock *MbQ, *MbP;
360
  PixelPos pixP, pixQ;
361
  int      bitdepth_scale;
362
  static const int pelnum_cr[2][4] =  {{0,8,16,16}, {0,8, 8,16}};  //[dir:0=vert, 1=hor.][yuv_format]
363
 
364
  if (!yuv)
365
    bitdepth_scale = 1<<(img->bitdepth_luma - 8);
366
  else
367
    bitdepth_scale = 1<<(img->bitdepth_chroma - 8);
368
 
369
  PelNum = yuv ? pelnum_cr[dir][p->chroma_format_idc] : 16 ;
370
 
371
  for( pel=0 ; pel<PelNum ; pel++ )
372
  {
373
    xQ = dir ? pel : edge << 2;
374
    yQ = dir ? (edge < 4 ? edge << 2 : 1) : pel;
375
    getNeighbour(MbQAddr, xQ, yQ, yuv, &pixQ);
376
    getNeighbour(MbQAddr, xQ - (1 - dir), yQ - dir, yuv, &pixP);
377
    xP = pixP.x;
378
    yP = pixP.y;
379
    MbQ = &(img->mb_data[MbQAddr]);
380
    MbP = &(img->mb_data[pixP.mb_addr]);
381
    fieldModeFilteringFlag = (byte) (MbQ->mb_field || MbP->mb_field);
382
    StrengthIdx = (yuv&&(PelNum==8)) ? ((MbQ->mb_field && !MbP->mb_field) ? pel<<1 :((pel>>1)<<2)+(pel&0x01)) : pel;
383
 
384
    if (pixP.available || (MbQ->LFDisableIdc== 0))
385
    {
386
      incQ = dir ? ((fieldModeFilteringFlag && !MbQ->mb_field) ? 2 * width : width) : 1;
387
      incP = dir ? ((fieldModeFilteringFlag && !MbP->mb_field) ? 2 * width : width) : 1;
388
      SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
389
      SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
390
 
391
      // Average QP of the two blocks
392
      QP = yuv ? (MbP->qpc[uv] + MbQ->qpc[uv] + 1) >> 1 : (MbP->qp + MbQ->qp + 1) >> 1;
393
 
394
      indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
395
      indexB = iClip3(0, MAX_QP, QP + BetaOffset);
396
 
397
      Alpha  =ALPHA_TABLE[indexA] * bitdepth_scale;
398
      Beta   =BETA_TABLE[indexB]  * bitdepth_scale;
399
      ClipTab=CLIP_TAB[indexA];
400
 
401
      L0  = SrcPtrP[0] ;
402
      R0  = SrcPtrQ[0] ;
403
      L1  = SrcPtrP[-incP] ;
404
      R1  = SrcPtrQ[ incQ] ;
405
      L2  = SrcPtrP[-incP*2] ;
406
      R2  = SrcPtrQ[ incQ*2] ;
407
      L3  = SrcPtrP[-incP*3] ;
408
      R3  = SrcPtrQ[ incQ*3] ;
409
 
410
      if( (Strng = Strength[StrengthIdx]) != 0)
411
      {
412
        AbsDelta  = iabs( Delta = R0 - L0 )  ;
413
 
414
        if( AbsDelta < Alpha )
415
        {
416
          C0  = ClipTab[ Strng ] * bitdepth_scale;
417
          if( ((iabs( R0 - R1) - Beta )  & (iabs(L0 - L1) - Beta )) < 0  )
418
          {
419
            if( !yuv)
420
            {
421
              aq  = (iabs( R0 - R2) - Beta ) < 0  ;
422
              ap  = (iabs( L0 - L2) - Beta ) < 0  ;
423
            }
424
 
425
            RL0             = L0 + R0 ;
426
 
427
            if(Strng == 4 )    // INTRA strong filtering
428
            {
429
              if( yuv)  // Chroma
430
              {
431
                SrcPtrQ[0] = (imgpel) (((R1 << 1) + R0 + L1 + 2) >> 2);
432
                SrcPtrP[0] = (imgpel) (((L1 << 1) + L0 + R1 + 2) >> 2);
433
              }
434
              else  // Luma
435
              {
436
                small_gap = (AbsDelta < ((Alpha >> 2) + 2));
437
 
438
                aq &= small_gap;
439
                ap &= small_gap;
440
 
441
                SrcPtrQ[0]   = (imgpel) (aq ? ( L1 + ((R1 + RL0) << 1) +  R2 + 4) >> 3 : ((R1 << 1) + R0 + L1 + 2) >> 2) ;
442
                SrcPtrP[0]   = (imgpel) (ap ? ( R1 + ((L1 + RL0) << 1) +  L2 + 4) >> 3 : ((L1 << 1) + L0 + R1 + 2) >> 2) ;
443
 
444
                SrcPtrQ[ incQ] =  (imgpel) (aq  ? ( R2 + R0 + R1 + L0 + 2) >> 2 : R1);
445
                SrcPtrP[-incP] =  (imgpel) (ap  ? ( L2 + L1 + L0 + R0 + 2) >> 2 : L1);
446
 
447
                SrcPtrQ[ incQ*2] = (imgpel) (aq ? (((R3 + R2) <<1) + R2 + R1 + RL0 + 4) >> 3 : R2);
448
                SrcPtrP[-incP*2] = (imgpel) (ap ? (((L3 + L2) <<1) + L2 + L1 + RL0 + 4) >> 3 : L2);
449
              }
450
            }
451
            else                                                     // normal filtering
452
            {
453
              c0  = yuv? (C0+1):(C0 + ap + aq) ;
454
              dif = iClip3( -c0, c0, ( (Delta << 2) + (L1 - R1) + 4) >> 3 ) ;
455
              if(!yuv)
456
              {
457
                SrcPtrP[0]  = (imgpel) iClip3(0, img->max_imgpel_value, L0 + dif) ;
458
                SrcPtrQ[0]  = (imgpel) iClip3(0, img->max_imgpel_value, R0 - dif) ;
459
                if( ap )
460
                  SrcPtrP[-incP] += iClip3( -C0,  C0, ( L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1 ) ;
461
                if( aq  )
462
                  SrcPtrQ[ incQ] += iClip3( -C0,  C0, ( R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1 ) ;
463
              }
464
              else
465
              {
466
                SrcPtrP[0]  = (imgpel) iClip3(0, img->max_imgpel_value_uv, L0 + dif) ;
467
                SrcPtrQ[0]  = (imgpel) iClip3(0, img->max_imgpel_value_uv, R0 - dif) ;
468
              }
469
            }
470
          }
471
        }
472
      }
473
    }
474
  }
475
}
476
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.