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 "libavcodec/avcodec.h"
21 #include "mpeg2dec/mpeg2.h"
23 #define PP7_QP_DEFAULT 5
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 pv->buf_out = hb_video_buffer_init( width, height );
413 void hb_deblock_close( hb_filter_private_t * pv )
422 hb_buffer_close( &pv->buf_out );
428 int hb_deblock_work( const hb_buffer_t * buf_in,
429 hb_buffer_t ** buf_out,
433 hb_filter_private_t * pv )
436 pix_fmt != pv->pix_fmt ||
437 width != pv->width[0] ||
438 height != pv->height[0] )
440 return FILTER_FAILED;
443 avpicture_fill( &pv->pic_in, buf_in->data,
444 pix_fmt, width, height );
446 avpicture_fill( &pv->pic_out, pv->buf_out->data,
447 pix_fmt, width, height );
449 if( /*TODO: mpi->qscale ||*/ pv->pp7_qp )
456 NULL, /* TODO: mpi->qscale*/
457 0, /* TODO: mpi->qstride*/
465 NULL, /* TODO: mpi->qscale*/
466 0, /* TODO: mpi->qstride*/
474 NULL, /* TODO: mpi->qscale*/
475 0, /* TODO: mpi->qstride*/
480 memcpy( pv->buf_out->data, buf_in->data, buf_in->size );
483 hb_buffer_copy_settings( pv->buf_out, buf_in );
485 *buf_out = pv->buf_out;