~ubuntu-branches/debian/wheezy/vlc/wheezy

« back to all changes in this revision

Viewing changes to modules/codec/ffmpeg/postprocessing/postprocessing_c.c

Tags: upstream-0.7.2.final
ImportĀ upstreamĀ versionĀ 0.7.2.final

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 * postprocessing_c.c: Post Processing plugin in C
 
3
 *****************************************************************************
 
4
 * Copyright (C) 2001 VideoLAN
 
5
 * $Id: postprocessing_c.c 6961 2004-03-05 17:34:23Z sam $
 
6
 *
 
7
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 
22
 *****************************************************************************/
 
23
 
 
24
#include <vlc/vlc.h> /* only use uint8_t, uint32_t .... */
 
25
 
 
26
#include "postprocessing.h"
 
27
#include "postprocessing_common.h"
 
28
 
 
29
/*****************************************************************************
 
30
 *
 
31
 * Internals functions common to pp_deblock_V and pp_deblock_H
 
32
 *
 
33
 *****************************************************************************/
 
34
 
 
35
/****************************************************************************
 
36
 * pp_deblock_isDC_mode : Check if we will use DC mode or Default mode
 
37
 ****************************************************************************
 
38
 * Use constant PP_THR1 and PP_THR2 ( PP_2xTHR1 )
 
39
 *
 
40
 * Called for for each pixel on a boundary block when doing deblocking
 
41
 *  so need to be fast ...
 
42
 *
 
43
 ****************************************************************************/
 
44
static inline int pp_deblock_isDC_mode( uint8_t *p_v )
 
45
{
 
46
    unsigned int i_eq_cnt;
 
47
 
 
48
    /* algo :  if ( | v[i] -v[i+1] | <= PP_THR1 ) { i_eq_cnt++; } */
 
49
    i_eq_cnt = 0;
 
50
    if((  ( p_v[0] - p_v[1] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
51
    if((  ( p_v[1] - p_v[2] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
52
    if((  ( p_v[2] - p_v[3] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
53
    if((  ( p_v[3] - p_v[4] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
54
    if((  ( p_v[4] - p_v[5] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
55
    if((  ( p_v[5] - p_v[6] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
56
    if((  ( p_v[6] - p_v[7] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
57
    if((  ( p_v[7] - p_v[8] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
58
    if((  ( p_v[8] - p_v[9] + PP_THR1 )&0xffff )<= PP_2xTHR1 ) i_eq_cnt++;
 
59
 
 
60
#if 0
 
61
    int i;
 
62
    for( i =0; i < 9; i++ )
 
63
    {
 
64
        if((  ( p_v[i] - p_v[i+1] + PP_THR1 )&0xffff )<= PP_2xTHR1 )
 
65
        {
 
66
            i_eq_cnt++;
 
67
        }
 
68
    }
 
69
#endif
 
70
    return( (i_eq_cnt >= PP_THR2 ) ? 1 : 0 );
 
71
}
 
72
 
 
73
static inline int pp_deblock_isMinMaxOk( uint8_t *p_v, int i_QP )
 
74
{
 
75
    int i_max, i_min;
 
76
 
 
77
    i_min = i_max = p_v[1];
 
78
    if( i_max < p_v[1] ) i_max = p_v[1];
 
79
    if( i_min > p_v[1] ) i_min = p_v[1];
 
80
    if( i_max < p_v[2] ) i_max = p_v[2];
 
81
    if( i_min > p_v[2] ) i_min = p_v[2];
 
82
    if( i_max < p_v[3] ) i_max = p_v[3];
 
83
    if( i_min > p_v[3] ) i_min = p_v[3];
 
84
    if( i_max < p_v[4] ) i_max = p_v[4];
 
85
    if( i_min > p_v[4] ) i_min = p_v[4];
 
86
    if( i_max < p_v[5] ) i_max = p_v[5];
 
87
    if( i_min > p_v[5] ) i_min = p_v[5];
 
88
    if( i_max < p_v[6] ) i_max = p_v[6];
 
89
    if( i_min > p_v[6] ) i_min = p_v[6];
 
90
    if( i_max < p_v[7] ) i_max = p_v[7];
 
91
    if( i_min > p_v[7] ) i_min = p_v[7];
 
92
    if( i_max < p_v[8] ) i_max = p_v[8];
 
93
    if( i_min > p_v[8] ) i_min = p_v[8];
 
94
 
 
95
#if 0
 
96
    int i;
 
97
    int i_range;
 
98
    for( i = 2; i < 9; i++ )
 
99
    {
 
100
        if( i_max < p_v[i] ) i_max = p_v[i];
 
101
        if( i_min > p_v[i] ) i_min = p_v[i];
 
102
    }
 
103
    i_range = i_max - i_min;
 
104
#endif
 
105
    return( i_max - i_min < 2*i_QP ? 1 : 0 );
 
106
}
 
107
 
 
108
 
 
109
static inline void pp_deblock_DefaultMode( uint8_t i_v[10], int i_stride,
 
110
                                      int i_QP )
 
111
{
 
112
    int d, i_delta;
 
113
    int a3x0, a3x0_, a3x1, a3x2;
 
114
    int b_neg;
 
115
 
 
116
    /* d = CLIP( 5(a3x0' - a3x0)//8, 0, (v4-v5)/2 ).d( abs(a3x0) < QP ) */
 
117
 
 
118
    /* First calculate a3x0 */
 
119
    a3x0 = 2 * ( i_v[3] - i_v[6] ) + 5 *( i_v[5] - i_v[4] );
 
120
 
 
121
    if( a3x0 < 0 )
 
122
    {
 
123
        b_neg = 1;
 
124
        a3x0  = -a3x0;
 
125
    }
 
126
    else
 
127
    {
 
128
        b_neg = 0;
 
129
    }
 
130
    /* XXX Now a3x0 is abs( a3x0 ) */
 
131
    if( ( a3x0 < 8 * i_QP )&&( a3x0 != 0 ) ) /* |a3x0| < 8*i_QP */
 
132
    {
 
133
        /* calculate a3x1 et a3x2 */
 
134
        a3x1 = 2 * ( i_v[1] - i_v[4] ) + 5 * ( i_v[3] - i_v[2] );
 
135
        a3x2 = 2 * ( i_v[5] - i_v[8] ) + 5 * ( i_v[7] - i_v[6] );
 
136
 
 
137
        if( a3x1 < 0) a3x1 = -a3x1; /* abs( a3x1 ) */
 
138
        if( a3x2 < 0) a3x2 = -a3x2; /* abs( a3x2 ) */
 
139
 
 
140
        a3x0_ = PP_MIN3( a3x0, a3x1, a3x2 );
 
141
 
 
142
        d = 5 *( a3x0 - a3x0_ ) / 8; /* always > 0 */
 
143
 
 
144
        i_delta = ( i_v[4] - i_v[5] ) / 2;
 
145
        /* clip into [0, i_delta] or [i_delta, 0] */
 
146
        if( i_delta < 0 )
 
147
        {
 
148
            if( !b_neg ) /* since true d has sgn(d) = - sgn( a3x0 ) */
 
149
            {
 
150
                d = -d;
 
151
                if( d < i_delta ) d = i_delta;
 
152
                i_v[4] -= d;
 
153
                i_v[5] += d;
 
154
            }
 
155
        }
 
156
        else
 
157
        {
 
158
            if( b_neg )
 
159
            {
 
160
                if( d > i_delta ) d = i_delta;
 
161
                i_v[4] -= d;
 
162
                i_v[5] += d;
 
163
            }
 
164
        }
 
165
    }
 
166
}
 
167
 
 
168
 
 
169
 
 
170
static inline void pp_deblock_DCMode( uint8_t *p_v, /*  = int i_v[10] */
 
171
                                 int i_QP )
 
172
{
 
173
    int v[10];
 
174
 
 
175
    int i;
 
176
 
 
177
    int i_p0, i_p9;
 
178
    i_p0 = PP_ABS( p_v[1] - p_v[0] ) < i_QP ? p_v[0] : p_v[1];
 
179
    i_p9 = PP_ABS( p_v[8] - p_v[9] ) < i_QP ? p_v[9] : p_v[8];
 
180
 
 
181
    for( i = 1; i < 9; i++ )
 
182
    {
 
183
        v[i] = p_v[i]; /* save 8 pix that will be modified */
 
184
    }
 
185
 
 
186
    p_v[1] = ( 6 * i_p0                        + 4 * v[1]
 
187
                + 2 *( v[2] + v[3]) + v[4] + v[5]) >> 4;
 
188
 
 
189
    p_v[2] = ( 4 * i_p0    + 2 * v[1]          + 4 * v[2]
 
190
                + 2 *( v[3] + v[4]) + v[5] + v[6]) >> 4;
 
191
 
 
192
    p_v[3] = ( 2 * i_p0    + 2 * (v[1] + v[2]) + 4 * v[3]
 
193
                + 2 *( v[4] + v[5]) + v[6] + v[7]) >> 4;
 
194
 
 
195
    p_v[4] = ( i_p0 + v[1] + 2 * (v[2] + v[3]) + 4 * v[4]
 
196
                + 2 *( v[5] + v[6]) + v[7] + v[8]) >> 4;
 
197
 
 
198
    p_v[5] = ( v[1] + v[2] + 2 * (v[3] + v[4]) + 4 * v[5]
 
199
                + 2 *( v[6] + v[7]) + v[8] + i_p9) >> 4;
 
200
 
 
201
    p_v[6] = ( v[2] + v[3] + 2 * (v[4] + v[5]) + 4 * v[6]
 
202
            + 2 *( v[7] + v[8]) + 2 * i_p9) >> 4;
 
203
 
 
204
    p_v[7] = ( v[3] + v[4] + 2 * (v[5] + v[6]) + 4 * v[7]
 
205
                + 2 * v[8] + 4 * i_p9) >> 4;
 
206
 
 
207
    p_v[8] = ( v[4] + v[5] + 2 * (v[6] + v[7]) + 4 * v[8]
 
208
                                    + 6 * i_p9) >> 4;
 
209
 
 
210
}
 
211
 
 
212
 
 
213
 
 
214
/*****************************************************************************/
 
215
/*---------------------------------------------------------------------------*/
 
216
/*                                                                           */
 
217
/*    ---------- filter Vertical lines so follow horizontal edges --------   */
 
218
/*                                                                           */
 
219
/*---------------------------------------------------------------------------*/
 
220
/*****************************************************************************/
 
221
 
 
222
void E_( pp_deblock_V )( uint8_t *p_plane,
 
223
                         int i_width, int i_height, int i_stride,
 
224
                         QT_STORE_T *p_QP_store, int i_QP_stride,
 
225
                         int b_chroma )
 
226
{
 
227
    int x, y, i;
 
228
    uint8_t *p_v;
 
229
    int i_QP_scale; /* use to do ( ? >> i_QP_scale ) */
 
230
    int i_QP;
 
231
 
 
232
    uint8_t i_v[10];
 
233
 
 
234
    i_QP_scale = b_chroma ? 5 : 4 ;
 
235
 
 
236
    for( y = 8; y < i_height - 4; y += 8 )
 
237
    {
 
238
        p_v = p_plane + ( y - 5 )* i_stride;
 
239
        for( x = 0; x < i_width; x++ )
 
240
        {
 
241
            /* First get  10 vert pix to use them without i_stride */
 
242
            for( i = 0; i < 10; i++ )
 
243
            {
 
244
                i_v[i] = p_v[i*i_stride + x];
 
245
            }
 
246
 
 
247
            i_QP = p_QP_store[(y>>i_QP_scale)*i_QP_stride+
 
248
                                (x>>i_QP_scale)];
 
249
            /* XXX QP is for v5 */
 
250
            if( pp_deblock_isDC_mode( i_v ) )
 
251
            {
 
252
                if( pp_deblock_isMinMaxOk( i_v, i_QP ) )
 
253
                {
 
254
                    pp_deblock_DCMode( i_v, i_QP );
 
255
                }
 
256
            }
 
257
            else
 
258
            {
 
259
                pp_deblock_DefaultMode( i_v, i_stride, i_QP );
 
260
 
 
261
            }
 
262
            /* Copy back, XXX only 1-8 were modified */
 
263
            for( i = 1; i < 9; i++ )
 
264
            {
 
265
                p_v[i*i_stride + x] = i_v[i];
 
266
            }
 
267
 
 
268
        }
 
269
    }
 
270
 
 
271
    return;
 
272
}
 
273
/*****************************************************************************/
 
274
/*---------------------------------------------------------------------------*/
 
275
/*                                                                           */
 
276
/*     --------- filter Horizontal lines so follow vertical edges --------   */
 
277
/*                                                                           */
 
278
/*---------------------------------------------------------------------------*/
 
279
/*****************************************************************************/
 
280
 
 
281
void E_( pp_deblock_H )( uint8_t *p_plane,
 
282
                         int i_width, int i_height, int i_stride,
 
283
                         QT_STORE_T *p_QP_store, int i_QP_stride,
 
284
                         int b_chroma )
 
285
{
 
286
    int x, y;
 
287
    uint8_t *p_v;
 
288
    int i_QP_scale;
 
289
    int i_QP;
 
290
 
 
291
    i_QP_scale = b_chroma ? 5 : 4 ;
 
292
 
 
293
    for( y = 0; y < i_height; y++ )
 
294
    {
 
295
        p_v = p_plane + y * i_stride - 5;
 
296
        for( x = 8; x < i_width - 4; x += 8 )
 
297
        {
 
298
            /* p_v point 5 pix before a block boundary */
 
299
            /* XXX QP is for v5 */
 
300
            i_QP = p_QP_store[(y>>i_QP_scale)*i_QP_stride+
 
301
                                 (x>>i_QP_scale)];
 
302
            if( pp_deblock_isDC_mode( p_v + x ) )
 
303
            {
 
304
                if( pp_deblock_isMinMaxOk( p_v+ x, i_QP ) )
 
305
                {
 
306
                    pp_deblock_DCMode( p_v+x, i_QP );
 
307
                }
 
308
            }
 
309
            else
 
310
            {
 
311
                pp_deblock_DefaultMode( p_v+x, i_stride, i_QP );
 
312
            }
 
313
        }
 
314
    }
 
315
 
 
316
    return;
 
317
}
 
318
 
 
319
 
 
320
/*****************************************************************************
 
321
 *
 
322
 * Internals functions common to pp_Dering_Y pp_Dering_C
 
323
 *
 
324
 *****************************************************************************/
 
325
 
 
326
static inline void pp_dering_MinMax( uint8_t *p_block, int i_stride,
 
327
                                     int *pi_min, int *pi_max )
 
328
{
 
329
    int y;
 
330
    int i_min, i_max;
 
331
 
 
332
    i_min = 255; i_max = 0;
 
333
 
 
334
    for( y = 0; y < 8; y++ )
 
335
    {
 
336
        if( i_min > p_block[0] ) i_min = p_block[0];
 
337
        if( i_max < p_block[0] ) i_max = p_block[0];
 
338
        if( i_min > p_block[1] ) i_min = p_block[1];
 
339
        if( i_max < p_block[1] ) i_max = p_block[1];
 
340
        if( i_min > p_block[2] ) i_min = p_block[2];
 
341
        if( i_max < p_block[2] ) i_max = p_block[2];
 
342
        if( i_min > p_block[3] ) i_min = p_block[3];
 
343
        if( i_max < p_block[3] ) i_max = p_block[3];
 
344
        if( i_min > p_block[4] ) i_min = p_block[4];
 
345
        if( i_max < p_block[4] ) i_max = p_block[4];
 
346
        if( i_min > p_block[5] ) i_min = p_block[5];
 
347
        if( i_max < p_block[5] ) i_max = p_block[5];
 
348
        if( i_min > p_block[6] ) i_min = p_block[6];
 
349
        if( i_max < p_block[6] ) i_max = p_block[6];
 
350
        if( i_min > p_block[7] ) i_min = p_block[7];
 
351
        if( i_max < p_block[7] ) i_max = p_block[7];
 
352
#if 0
 
353
        int x;
 
354
        for( x = 0; x < 8; x++ )
 
355
        {
 
356
            if( i_min > p_block[x] ) i_min = p_block[x];
 
357
            if( i_max < p_block[x] ) i_max = p_block[x];
 
358
        }
 
359
#endif
 
360
        p_block += i_stride;
 
361
    }
 
362
 
 
363
    *pi_min = i_min;
 
364
    *pi_max = i_max;
 
365
}
 
366
 
 
367
 
 
368
static inline void pp_dering_BinIndex( uint8_t *p_block, int i_stride,
 
369
                                       int i_thr, uint32_t *p_bin )
 
370
{
 
371
    int x, y;
 
372
    uint32_t i_bin;
 
373
 
 
374
    for( y = 0; y < 10; y++ )
 
375
    {
 
376
        i_bin = 0;
 
377
        for( x = 0; x < 10; x++ )
 
378
        {
 
379
            if( p_block[x] > i_thr )
 
380
            {
 
381
                i_bin |= 1 << x;
 
382
            }
 
383
        }
 
384
        i_bin |= (~i_bin) << 16;  /* for detect also three 0 */
 
385
        *p_bin = i_bin&( i_bin >> 1 )&( i_bin << 1 );
 
386
 
 
387
        p_block += i_stride;
 
388
        p_bin++;
 
389
    }
 
390
}
 
391
 
 
392
static inline void pp_dering_Filter( uint8_t  *p_block, int i_stride,
 
393
                                     uint32_t *p_bin,
 
394
                                     int i_QP )
 
395
{
 
396
    int x, y;
 
397
    uint32_t i_bin;
 
398
    int i_flt[8][8];
 
399
    int i_f;
 
400
    uint8_t *p_sav;
 
401
    int i_QP_2;
 
402
 
 
403
    p_sav = p_block;
 
404
    i_QP_2 = i_QP >> 1;
 
405
 
 
406
    for( y = 0; y < 8; y++ )
 
407
    {
 
408
        i_bin = p_bin[y] & p_bin[y+1] & p_bin[y+2]; /* To be optimised */
 
409
        i_bin |= i_bin >> 16; /* detect 0 or 1 */
 
410
 
 
411
        for( x = 0; x < 8; x++ )
 
412
        {
 
413
            if( i_bin&0x02 ) /* 0x02 since 10 index but want 1-9 */
 
414
            {
 
415
                /* apply dering */
 
416
                /* 1 2 1
 
417
                   2 4 2   + (8)
 
418
                   1 2 1 */
 
419
                i_f =   p_block[x - i_stride - 1] +
 
420
                      ( p_block[x - i_stride    ] << 1)+
 
421
                        p_block[x - i_stride + 1] +
 
422
 
 
423
                      ( p_block[x - 1] << 1 )+
 
424
                      ( p_block[x    ] << 2 )+
 
425
                      ( p_block[x + 1] << 1 )+
 
426
 
 
427
                        p_block[x + i_stride - 1] +
 
428
                      ( p_block[x + i_stride    ] << 1 ) +
 
429
                        p_block[x + i_stride + 1];
 
430
 
 
431
                i_f = ( 8 + i_f ) >> 4;
 
432
 
 
433
                /* Clamp this value */
 
434
 
 
435
                if( i_f - p_block[x] > ( i_QP_2 ) )
 
436
                {
 
437
                    i_flt[y][x] = p_block[x] + i_QP_2;
 
438
                }
 
439
                else
 
440
                if( i_f - p_block[x] < -i_QP_2 )
 
441
                {
 
442
                    i_flt[y][x] = p_block[x] - i_QP_2;
 
443
                }
 
444
                else
 
445
                {
 
446
                    i_flt[y][x] = i_f ;
 
447
                }
 
448
            }
 
449
            else
 
450
            {
 
451
                i_flt[y][x] = p_block[x];
 
452
            }
 
453
            i_bin >>= 1;
 
454
 
 
455
        }
 
456
        p_block += i_stride;
 
457
    }
 
458
    for( y = 0; y < 8; y++ )
 
459
    {
 
460
        for( x = 0; x < 8; x++ )
 
461
        {
 
462
            p_sav[x] = i_flt[y][x];
 
463
        }
 
464
        p_sav+= i_stride;
 
465
    }
 
466
}
 
467
 
 
468
 
 
469
/*****************************************************************************/
 
470
/*---------------------------------------------------------------------------*/
 
471
/*                                                                           */
 
472
/*     ----------------- Dering filter on Y and C blocks -----------------   */
 
473
/*                                                                           */
 
474
/*---------------------------------------------------------------------------*/
 
475
/*****************************************************************************/
 
476
 
 
477
void E_( pp_dering_Y )( uint8_t *p_plane,
 
478
                        int i_width, int i_height, int i_stride,
 
479
                        QT_STORE_T *p_QP_store, int i_QP_stride )
 
480
{
 
481
    int x, y, k;
 
482
    int i_max[4], i_min[4], i_range[4];
 
483
    int i_thr[4];
 
484
    int i_max_range, i_kmax;
 
485
    uint32_t i_bin[4][10];
 
486
    uint8_t  *p_block[4];
 
487
    QT_STORE_T *p_QP;
 
488
 
 
489
    /* We process 4 blocks/loop*/
 
490
    for( y = 8; y < i_height-8; y += 16 )
 
491
    {
 
492
        /* +---+
 
493
           |0|1|
 
494
           +-+-+   :))
 
495
           |2|3|
 
496
           +-+-+ */
 
497
 
 
498
        p_block[0] = p_plane + y * i_stride + 8;
 
499
        p_block[1] = p_block[0] + 8;
 
500
        p_block[2] = p_block[0] + ( i_stride << 3 );
 
501
        p_block[3] = p_block[2] + 8;
 
502
 
 
503
        for( x = 8; x < i_width-8; x += 16 )
 
504
        {
 
505
            /* 1: Calculate threshold */
 
506
            /* Calculate max/min for each block */
 
507
            pp_dering_MinMax( p_block[0], i_stride, &i_min[0], &i_max[0] );
 
508
            pp_dering_MinMax( p_block[1], i_stride, &i_min[1], &i_max[1] );
 
509
            pp_dering_MinMax( p_block[2], i_stride, &i_min[2], &i_max[2] );
 
510
            pp_dering_MinMax( p_block[3], i_stride, &i_min[3], &i_max[3] );
 
511
            /* Calculate range, max_range and thr */
 
512
            i_max_range = 0; i_kmax = 0;
 
513
            for( k = 0; k <= 4; k++ )
 
514
            {
 
515
                i_range[k] = i_max[k] - i_min[k];
 
516
                i_thr[k] = ( i_max[k] + i_min[k] + 1 )/2;
 
517
                if( i_max_range < i_max[k])
 
518
                {
 
519
                    i_max_range = i_max[k];
 
520
                    i_kmax = k;
 
521
                }
 
522
            }
 
523
            /* Now rearrange thr */
 
524
            if(  i_max_range > 64 )
 
525
            {
 
526
                for( k = 1; k < 5; k++ )
 
527
                {
 
528
                    if( i_range[k] < 16 )
 
529
                    {
 
530
                        i_thr[k] = 0;
 
531
                    }
 
532
                    else
 
533
                    if( i_range[k] < 32 )
 
534
                    {
 
535
                        i_thr[k] = i_thr[i_kmax];
 
536
                    }
 
537
                }
 
538
            }
 
539
            else
 
540
            {
 
541
                for( k = 1; k < 5; k++ )
 
542
                {
 
543
                    if( i_range[k] < 16 )
 
544
                    {
 
545
                        i_thr[k] = 0;
 
546
                    }
 
547
                }
 
548
            }
 
549
            /* 2: Index acquisition 10x10 ! so " -i_stride - 1"*/
 
550
            pp_dering_BinIndex( p_block[0] - i_stride - 1, i_stride,
 
551
                                i_thr[0], i_bin[0] );
 
552
            pp_dering_BinIndex( p_block[1] - i_stride - 1, i_stride,
 
553
                                i_thr[1], i_bin[1] );
 
554
            pp_dering_BinIndex( p_block[2] - i_stride - 1, i_stride,
 
555
                                i_thr[2], i_bin[2] );
 
556
            pp_dering_BinIndex( p_block[3] - i_stride - 1, i_stride,
 
557
                                i_thr[3], i_bin[3] );
 
558
 
 
559
 
 
560
            /* 3: adaptive smoothing */
 
561
            /* since we begin at (8,8) QP can be different for each block */
 
562
            p_QP = &( p_QP_store[( y >> 4) * i_QP_stride + (x >> 4)] );
 
563
 
 
564
            pp_dering_Filter( p_block[0], i_stride,
 
565
                              i_bin[0], p_QP[0] );
 
566
 
 
567
            pp_dering_Filter( p_block[1], i_stride,
 
568
                              i_bin[1], p_QP[1] );
 
569
 
 
570
            pp_dering_Filter( p_block[2], i_stride,
 
571
                              i_bin[2], p_QP[i_QP_stride] );
 
572
 
 
573
            pp_dering_Filter( p_block[3], i_stride,
 
574
                              i_bin[3], p_QP[i_QP_stride+1] );
 
575
 
 
576
            p_block[0] += 8;
 
577
            p_block[1] += 8;
 
578
            p_block[2] += 8;
 
579
            p_block[3] += 8;
 
580
        }
 
581
    }
 
582
 
 
583
}
 
584
 
 
585
void E_( pp_dering_C )( uint8_t *p_plane,
 
586
                        int i_width, int i_height, int i_stride,
 
587
                        QT_STORE_T *p_QP_store, int i_QP_stride )
 
588
{
 
589
    int x, y;
 
590
    int i_max, i_min;
 
591
    int i_thr;
 
592
    uint32_t i_bin[10];
 
593
 
 
594
    uint8_t *p_block;
 
595
 
 
596
 
 
597
    for( y = 8; y < i_height-8; y += 8 )
 
598
    {
 
599
 
 
600
        p_block = p_plane + y * i_stride + 8;
 
601
        for( x = 8; x < i_width-8; x += 8 )
 
602
        {
 
603
 
 
604
            /* 1: Calculate threshold */
 
605
            /* Calculate max/min for each block */
 
606
            pp_dering_MinMax( p_block, i_stride,
 
607
                              &i_min, &i_max );
 
608
            /* Calculate thr*/
 
609
            i_thr = ( i_max + i_min + 1 )/2;
 
610
 
 
611
            /* 2: Index acquisition 10x10 */
 
612
            /* point on 10x10 in wich we have our 8x8 block */
 
613
            pp_dering_BinIndex( p_block - i_stride -1, i_stride,
 
614
                                i_thr,
 
615
                                i_bin );
 
616
 
 
617
            /* 3: adaptive smoothing */
 
618
            pp_dering_Filter( p_block, i_stride,
 
619
                              i_bin,
 
620
                              p_QP_store[(y>>5)*i_QP_stride+ (x>>5)]);
 
621
            p_block += 8;
 
622
        }
 
623
    }
 
624
 
 
625
}