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
20 #include "ffmpeg/avcodec.h"
21 #include "mpeg2dec/mpeg2.h"
23 #define PP7_QP_DEFAULT 0
24 #define PP7_MODE_DEFAULT 2
26 #define XMIN(a,b) ((a) < (b) ? (a) : (b))
27 #define XMAX(a,b) ((a) > (b) ? (a) : (b))
29 typedef short DCTELEM
;
31 //===========================================================================//
32 static const uint8_t __attribute__((aligned(8))) pp7_dither
[8][8] =
34 { 0, 48, 12, 60, 3, 51, 15, 63, },
35 { 32, 16, 44, 28, 35, 19, 47, 31, },
36 { 8, 56, 4, 52, 11, 59, 7, 55, },
37 { 40, 24, 36, 20, 43, 27, 39, 23, },
38 { 2, 50, 14, 62, 1, 49, 13, 61, },
39 { 34, 18, 46, 30, 33, 17, 45, 29, },
40 { 10, 58, 6, 54, 9, 57, 5, 53, },
41 { 42, 26, 38, 22, 41, 25, 37, 21, },
44 struct hb_filter_private_s
58 hb_buffer_t
* buf_out
;
61 hb_filter_private_t
* hb_deblock_init( int pix_fmt
,
66 int hb_deblock_work( const hb_buffer_t
* buf_in
,
67 hb_buffer_t
** buf_out
,
71 hb_filter_private_t
* pv
);
73 void hb_deblock_close( hb_filter_private_t
* pv
);
75 hb_filter_object_t hb_filter_deblock
=
85 static inline void pp7_dct_a( DCTELEM
* dst
, uint8_t * src
, int stride
)
89 for( i
= 0; i
< 4; i
++ )
91 int s0
= src
[0*stride
] + src
[6*stride
];
92 int s1
= src
[1*stride
] + src
[5*stride
];
93 int s2
= src
[2*stride
] + src
[4*stride
];
94 int s3
= src
[3*stride
];
112 static void pp7_dct_b( DCTELEM
* dst
, DCTELEM
* src
)
116 for( i
= 0; i
< 4; i
++ )
118 int s0
= src
[0*4] + src
[6*4];
119 int s1
= src
[1*4] + src
[5*4];
120 int s2
= src
[2*4] + src
[4*4];
131 dst
[1*4] = 2*s3
+ s2
;
132 dst
[3*4] = s3
- s2
*2;
144 #define SN1 2.2360679775
145 #define SN2 3.16227766017
147 static const int pp7_factor
[16] =
149 N
/(N0
*N0
), N
/(N0
*N1
), N
/(N0
*N0
),N
/(N0
*N2
),
150 N
/(N1
*N0
), N
/(N1
*N1
), N
/(N1
*N0
),N
/(N1
*N2
),
151 N
/(N0
*N0
), N
/(N0
*N1
), N
/(N0
*N0
),N
/(N0
*N2
),
152 N
/(N2
*N0
), N
/(N2
*N1
), N
/(N2
*N0
),N
/(N2
*N2
),
155 static int pp7_threshold
[99][16];
157 static void pp7_init_threshold( void )
162 for( qp
= 0; qp
< 99; qp
++ )
164 for( i
= 0; i
< 16; i
++ )
166 pp7_threshold
[qp
][i
] =
167 ((i
&1)?SN2
:SN0
) * ((i
&4)?SN2
:SN0
) *
168 XMAX(1,qp
) * (1<<2) - 1 - bias
;
173 static int pp7_hard_threshold( DCTELEM
* src
, int qp
)
178 a
= src
[0] * pp7_factor
[0];
179 for( i
= 1; i
< 16; i
++ )
181 unsigned int threshold1
= pp7_threshold
[qp
][i
];
182 unsigned int threshold2
= (threshold1
<<1);
184 if( ((unsigned)(level
+threshold1
)) > threshold2
)
186 a
+= level
* pp7_factor
[i
];
189 return (a
+ (1<<11)) >> 12;
192 static int pp7_medium_threshold( DCTELEM
* src
, int qp
)
197 a
= src
[0] * pp7_factor
[0];
198 for( i
= 1; i
< 16; i
++ )
200 unsigned int threshold1
= pp7_threshold
[qp
][i
];
201 unsigned int threshold2
= (threshold1
<<1);
203 if( ((unsigned)(level
+threshold1
)) > threshold2
)
205 if( ((unsigned)(level
+2*threshold1
)) > 2*threshold2
)
207 a
+= level
* pp7_factor
[i
];
213 a
+= 2*(level
- (int)threshold1
) * pp7_factor
[i
];
217 a
+= 2*(level
+ (int)threshold1
) * pp7_factor
[i
];
222 return (a
+ (1<<11)) >> 12;
225 static int pp7_soft_threshold( DCTELEM
* src
, int qp
)
230 a
= src
[0] * pp7_factor
[0];
231 for( i
= 1; i
< 16; i
++ )
233 unsigned int threshold1
= pp7_threshold
[qp
][i
];
234 unsigned int threshold2
= (threshold1
<<1);
236 if( ((unsigned)(level
+threshold1
))>threshold2
)
240 a
+= (level
- (int)threshold1
) * pp7_factor
[i
];
244 a
+= (level
+ (int)threshold1
) * pp7_factor
[i
];
248 return (a
+ (1<<11)) >> 12;
251 static int ( * pp7_requantize
)( DCTELEM
* src
, int qp
) = pp7_hard_threshold
;
253 static void pp7_filter( hb_filter_private_t
* pv
,
264 const int stride
= is_luma
? pv
->pp7_temp_stride
: ((width
+16+15)&(~15));
265 uint8_t * p_src
= pv
->pp7_src
+ 8*stride
;
266 DCTELEM
* block
= (DCTELEM
*)(pv
->pp7_src
);
267 DCTELEM
* temp
= (DCTELEM
*)(pv
->pp7_src
+ 32);
274 for( y
= 0; y
< height
; y
++ )
276 int index
= 8 + 8*stride
+ y
*stride
;
277 memcpy( p_src
+ index
, src
+ y
*width
, width
);
279 for( x
= 0; x
< 8; x
++ )
281 p_src
[index
- x
- 1] = p_src
[index
+ x
];
282 p_src
[index
+ width
+ x
] = p_src
[index
+ width
- x
- 1];
286 for( y
= 0; y
< 8; y
++ )
288 memcpy( p_src
+ ( 7-y
)*stride
,
289 p_src
+ ( y
+8)*stride
, stride
);
290 memcpy( p_src
+ (height
+8+y
)*stride
,
291 p_src
+ (height
-y
+7)*stride
, stride
);
294 for( y
= 0; y
< height
; y
++ )
296 for( x
= -8; x
< 0; x
+= 4 )
298 const int index
= x
+ y
*stride
+ (8-3)*(1+stride
) + 8;
299 uint8_t * src
= p_src
+ index
;
300 DCTELEM
* tp
= temp
+4*x
;
302 pp7_dct_a( tp
+4*8, src
, stride
);
305 for( x
= 0; x
< width
; )
307 const int qps
= 3 + is_luma
;
308 int end
= XMIN(x
+8, width
);
317 qp
= qp_store
[ (XMIN(x
, width
-1)>>qps
) +
318 (XMIN(y
, height
-1)>>qps
) * qp_stride
];
326 for( ; x
< end
; x
++ )
328 const int index
= x
+ y
*stride
+ (8-3)*(1+stride
) + 8;
329 uint8_t * src
= p_src
+ index
;
330 DCTELEM
* tp
= temp
+4*x
;
335 pp7_dct_a( tp
+4*8, src
, stride
);
338 pp7_dct_b( block
, tp
);
340 v
= pp7_requantize( block
, qp
);
341 v
= (v
+ pp7_dither
[y
&7][x
&7]) >> 6;
342 if( (unsigned)v
> 255 )
346 dst
[x
+ y
*width
] = v
;
352 hb_filter_private_t
* hb_deblock_init( int pix_fmt
,
357 if( pix_fmt
!= PIX_FMT_YUV420P
)
362 hb_filter_private_t
* pv
= malloc( sizeof(struct hb_filter_private_s
) );
364 pv
->pix_fmt
= pix_fmt
;
366 pv
->width
[0] = width
;
367 pv
->height
[0] = height
;
369 pv
->width
[1] = pv
->width
[2] = width
>> 1;
370 pv
->height
[1] = pv
->height
[2] = height
>> 1;
373 pv
->pp7_qp
= PP7_QP_DEFAULT
;
374 pv
->pp7_mode
= PP7_MODE_DEFAULT
;
375 pv
->pp7_mpeg2
= 1; /*mpi->qscale_type;*/
379 sscanf( settings
, "%d:%d", &pv
->pp7_qp
, &pv
->pp7_mode
);
387 pp7_init_threshold();
389 switch( pv
->pp7_mode
)
392 pp7_requantize
= pp7_hard_threshold
;
395 pp7_requantize
= pp7_soft_threshold
;
398 pp7_requantize
= pp7_medium_threshold
;
402 int h
= (height
+16+15)&(~15);
404 pv
->pp7_temp_stride
= (width
+16+15)&(~15);
406 pv
->pp7_src
= (uint8_t*)malloc( pv
->pp7_temp_stride
*(h
+8)*sizeof(uint8_t) );
408 int buf_size
= 3 * width
* height
/ 2;
409 pv
->buf_out
= hb_buffer_init( buf_size
);
414 void hb_deblock_close( hb_filter_private_t
* pv
)
423 hb_buffer_close( &pv
->buf_out
);
429 int hb_deblock_work( const hb_buffer_t
* buf_in
,
430 hb_buffer_t
** buf_out
,
434 hb_filter_private_t
* pv
)
437 pix_fmt
!= pv
->pix_fmt
||
438 width
!= pv
->width
[0] ||
439 height
!= pv
->height
[0] )
441 return FILTER_FAILED
;
444 avpicture_fill( &pv
->pic_in
, buf_in
->data
,
445 pix_fmt
, width
, height
);
447 avpicture_fill( &pv
->pic_out
, pv
->buf_out
->data
,
448 pix_fmt
, width
, height
);
450 if( /*TODO: mpi->qscale ||*/ pv
->pp7_qp
)
457 NULL
, /* TODO: mpi->qscale*/
458 0, /* TODO: mpi->qstride*/
466 NULL
, /* TODO: mpi->qscale*/
467 0, /* TODO: mpi->qstride*/
475 NULL
, /* TODO: mpi->qscale*/
476 0, /* TODO: mpi->qstride*/
481 memcpy( pv
->buf_out
->data
, buf_in
->data
, buf_in
->size
);
484 hb_buffer_copy_settings( pv
->buf_out
, buf_in
);
486 *buf_out
= pv
->buf_out
;