2 Copyright (C) 2005 Michael Niedermayer <michaelni@gmx.at>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #define PP7_QP_DEFAULT 5
23 #define PP7_MODE_DEFAULT 2
25 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
26 #define XMAX(a,b) ((a) > (b) ? (a) : (b))
28 typedef short DCTELEM
;
30 //===========================================================================//
31 static const uint8_t __attribute__((aligned(8))) pp7_dither
[8][8] =
33 { 0, 48, 12, 60, 3, 51, 15, 63, },
34 { 32, 16, 44, 28, 35, 19, 47, 31, },
35 { 8, 56, 4, 52, 11, 59, 7, 55, },
36 { 40, 24, 36, 20, 43, 27, 39, 23, },
37 { 2, 50, 14, 62, 1, 49, 13, 61, },
38 { 34, 18, 46, 30, 33, 17, 45, 29, },
39 { 10, 58, 6, 54, 9, 57, 5, 53, },
40 { 42, 26, 38, 22, 41, 25, 37, 21, },
43 struct hb_filter_private_s
52 static int hb_deblock_init( hb_filter_object_t
* filter
,
53 hb_filter_init_t
* init
);
55 static int hb_deblock_work( hb_filter_object_t
* filter
,
56 hb_buffer_t
** buf_in
,
57 hb_buffer_t
** buf_out
);
59 static void hb_deblock_close( hb_filter_object_t
* filter
);
61 hb_filter_object_t hb_filter_deblock
=
63 .id
= HB_FILTER_DEBLOCK
,
65 .name
= "Deblock (pp7)",
67 .init
= hb_deblock_init
,
68 .work
= hb_deblock_work
,
69 .close
= hb_deblock_close
,
72 static inline void pp7_dct_a( DCTELEM
* dst
, uint8_t * src
, int stride
)
76 for( i
= 0; i
< 4; i
++ )
78 int s0
= src
[0*stride
] + src
[6*stride
];
79 int s1
= src
[1*stride
] + src
[5*stride
];
80 int s2
= src
[2*stride
] + src
[4*stride
];
81 int s3
= src
[3*stride
];
99 static void pp7_dct_b( DCTELEM
* dst
, DCTELEM
* src
)
103 for( i
= 0; i
< 4; i
++ )
105 int s0
= src
[0*4] + src
[6*4];
106 int s1
= src
[1*4] + src
[5*4];
107 int s2
= src
[2*4] + src
[4*4];
118 dst
[1*4] = 2*s3
+ s2
;
119 dst
[3*4] = s3
- s2
*2;
131 #define SN1 2.2360679775
132 #define SN2 3.16227766017
134 static const int pp7_factor
[16] =
136 N
/(N0
*N0
), N
/(N0
*N1
), N
/(N0
*N0
),N
/(N0
*N2
),
137 N
/(N1
*N0
), N
/(N1
*N1
), N
/(N1
*N0
),N
/(N1
*N2
),
138 N
/(N0
*N0
), N
/(N0
*N1
), N
/(N0
*N0
),N
/(N0
*N2
),
139 N
/(N2
*N0
), N
/(N2
*N1
), N
/(N2
*N0
),N
/(N2
*N2
),
142 static int pp7_threshold
[99][16];
144 static void pp7_init_threshold( void )
149 for( qp
= 0; qp
< 99; qp
++ )
151 for( i
= 0; i
< 16; i
++ )
153 pp7_threshold
[qp
][i
] =
154 ((i
&1)?SN2
:SN0
) * ((i
&4)?SN2
:SN0
) *
155 XMAX(1,qp
) * (1<<2) - 1 - bias
;
160 static int pp7_hard_threshold( DCTELEM
* src
, int qp
)
165 a
= src
[0] * pp7_factor
[0];
166 for( i
= 1; i
< 16; i
++ )
168 unsigned int threshold1
= pp7_threshold
[qp
][i
];
169 unsigned int threshold2
= (threshold1
<<1);
171 if( ((unsigned)(level
+threshold1
)) > threshold2
)
173 a
+= level
* pp7_factor
[i
];
176 return (a
+ (1<<11)) >> 12;
179 static int pp7_medium_threshold( DCTELEM
* src
, int qp
)
184 a
= src
[0] * pp7_factor
[0];
185 for( i
= 1; i
< 16; i
++ )
187 unsigned int threshold1
= pp7_threshold
[qp
][i
];
188 unsigned int threshold2
= (threshold1
<<1);
190 if( ((unsigned)(level
+threshold1
)) > threshold2
)
192 if( ((unsigned)(level
+2*threshold1
)) > 2*threshold2
)
194 a
+= level
* pp7_factor
[i
];
200 a
+= 2*(level
- (int)threshold1
) * pp7_factor
[i
];
204 a
+= 2*(level
+ (int)threshold1
) * pp7_factor
[i
];
209 return (a
+ (1<<11)) >> 12;
212 static int pp7_soft_threshold( DCTELEM
* src
, int qp
)
217 a
= src
[0] * pp7_factor
[0];
218 for( i
= 1; i
< 16; i
++ )
220 unsigned int threshold1
= pp7_threshold
[qp
][i
];
221 unsigned int threshold2
= (threshold1
<<1);
223 if( ((unsigned)(level
+threshold1
))>threshold2
)
227 a
+= (level
- (int)threshold1
) * pp7_factor
[i
];
231 a
+= (level
+ (int)threshold1
) * pp7_factor
[i
];
235 return (a
+ (1<<11)) >> 12;
238 static int ( * pp7_requantize
)( DCTELEM
* src
, int qp
) = pp7_hard_threshold
;
240 static void pp7_filter( hb_filter_private_t
* pv
,
251 const int stride
= is_luma
? pv
->pp7_temp_stride
: ((width
+16+15)&(~15));
252 uint8_t * p_src
= pv
->pp7_src
+ 8*stride
;
253 DCTELEM
* block
= (DCTELEM
*)(pv
->pp7_src
);
254 DCTELEM
* temp
= (DCTELEM
*)(pv
->pp7_src
+ 32);
261 for( y
= 0; y
< height
; y
++ )
263 int index
= 8 + 8*stride
+ y
*stride
;
264 memcpy( p_src
+ index
, src
+ y
*width
, width
);
266 for( x
= 0; x
< 8; x
++ )
268 p_src
[index
- x
- 1] = p_src
[index
+ x
];
269 p_src
[index
+ width
+ x
] = p_src
[index
+ width
- x
- 1];
273 for( y
= 0; y
< 8; y
++ )
275 memcpy( p_src
+ ( 7-y
)*stride
,
276 p_src
+ ( y
+8)*stride
, stride
);
277 memcpy( p_src
+ (height
+8+y
)*stride
,
278 p_src
+ (height
-y
+7)*stride
, stride
);
281 for( y
= 0; y
< height
; y
++ )
283 for( x
= -8; x
< 0; x
+= 4 )
285 const int index
= x
+ y
*stride
+ (8-3)*(1+stride
) + 8;
286 uint8_t * src
= p_src
+ index
;
287 DCTELEM
* tp
= temp
+4*x
;
289 pp7_dct_a( tp
+4*8, src
, stride
);
292 for( x
= 0; x
< width
; )
294 const int qps
= 3 + is_luma
;
295 int end
= XMIN(x
+8, width
);
304 qp
= qp_store
[ (XMIN(x
, width
-1)>>qps
) +
305 (XMIN(y
, height
-1)>>qps
) * qp_stride
];
313 for( ; x
< end
; x
++ )
315 const int index
= x
+ y
*stride
+ (8-3)*(1+stride
) + 8;
316 uint8_t * src
= p_src
+ index
;
317 DCTELEM
* tp
= temp
+4*x
;
322 pp7_dct_a( tp
+4*8, src
, stride
);
325 pp7_dct_b( block
, tp
);
327 v
= pp7_requantize( block
, qp
);
328 v
= (v
+ pp7_dither
[y
&7][x
&7]) >> 6;
329 if( (unsigned)v
> 255 )
333 dst
[x
+ y
*width
] = v
;
339 static int hb_deblock_init( hb_filter_object_t
* filter
,
340 hb_filter_init_t
* init
)
342 filter
->private_data
= calloc( sizeof(struct hb_filter_private_s
), 1 );
343 hb_filter_private_t
* pv
= filter
->private_data
;
345 pv
->pp7_qp
= PP7_QP_DEFAULT
;
346 pv
->pp7_mode
= PP7_MODE_DEFAULT
;
347 pv
->pp7_mpeg2
= 1; /*mpi->qscale_type;*/
349 if( filter
->settings
)
351 sscanf( filter
->settings
, "%d:%d", &pv
->pp7_qp
, &pv
->pp7_mode
);
359 pp7_init_threshold();
361 switch( pv
->pp7_mode
)
364 pp7_requantize
= pp7_hard_threshold
;
367 pp7_requantize
= pp7_soft_threshold
;
370 pp7_requantize
= pp7_medium_threshold
;
374 int h
= (init
->geometry
.height
+ 16 + 15) & (~15);
376 pv
->pp7_temp_stride
= (init
->geometry
.width
+ 16 + 15) & (~15);
378 pv
->pp7_src
= (uint8_t*)malloc( pv
->pp7_temp_stride
*(h
+8)*sizeof(uint8_t) );
383 static void hb_deblock_close( hb_filter_object_t
* filter
)
385 hb_filter_private_t
* pv
= filter
->private_data
;
393 filter
->private_data
= NULL
;
396 static int hb_deblock_work( hb_filter_object_t
* filter
,
397 hb_buffer_t
** buf_in
,
398 hb_buffer_t
** buf_out
)
400 hb_filter_private_t
* pv
= filter
->private_data
;
401 hb_buffer_t
* in
= *buf_in
, * out
;
403 if (in
->s
.flags
& HB_BUF_FLAG_EOF
)
407 return HB_FILTER_DONE
;
410 if( /*TODO: mpi->qscale ||*/ pv
->pp7_qp
)
412 out
= hb_video_buffer_init( in
->f
.width
, in
->f
.height
);
419 NULL
, /* TODO: mpi->qscale*/
420 0, /* TODO: mpi->qstride*/
428 NULL
, /* TODO: mpi->qscale*/
429 0, /* TODO: mpi->qstride*/
437 NULL
, /* TODO: mpi->qscale*/
438 0, /* TODO: mpi->qstride*/
442 hb_buffer_move_subs( out
, in
);