1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 1999-2001 VideoLAN
5 * $Id: postprocessing.c,v 1.2 2002/08/08 22:28:22 sam Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
33 #include "postprocessing.h"
34 #include "postprocessing_common.h"
37 static int Open ( vlc_object_t *p_this );
39 static u32 pp_getmode( int i_quality, int b_autolevel );
40 static int pp_postprocess( picture_t *,
41 QT_STORE_T *, unsigned int,
42 unsigned int i_mode );
44 /*****************************************************************************
46 *****************************************************************************/
48 #ifdef MODULE_NAME_IS_postprocessing_c
49 set_description( _("C Post Processing module") );
50 set_capability( "postprocessing", 50 );
52 #elif defined( MODULE_NAME_IS_postprocessing_mmx )
53 set_description( _("MMX Post Processing module") );
54 set_capability( "postprocessing", 100 );
55 add_requirement( MMX );
56 add_shortcut( "mmx" );
57 #elif defined( MODULE_NAME_IS_postprocessing_mmxext )
58 set_description( _("MMXEXT Post Processing module") );
59 set_capability( "postprocessing", 150 );
60 add_requirement( MMXEXT );
61 add_shortcut( "mmxext" );
62 add_shortcut( "mmx2" );
64 set_callbacks( Open, NULL );
67 /*****************************************************************************
69 *****************************************************************************/
70 static int Open ( vlc_object_t *p_this )
72 postprocessing_t *p_pp = (postprocessing_t *)p_this;
74 p_pp->pf_getmode = pp_getmode;
75 p_pp->pf_postprocess = pp_postprocess;
81 static u32 pp_getmode( int i_quality, int b_autolevel )
84 i_quality = i_quality < 0 ? 0 : i_quality;
85 i_quality = i_quality > 6 ? 6 : i_quality;
93 i_mode = PP_DEBLOCK_Y_H;
96 i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V;
99 i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
103 i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
104 PP_DEBLOCK_C_H|PP_DEBLOCK_C_V;
107 i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
108 PP_DEBLOCK_C_H|PP_DEBLOCK_C_V|
112 i_mode = PP_DEBLOCK_Y_H|PP_DEBLOCK_Y_V|
113 PP_DEBLOCK_C_H|PP_DEBLOCK_C_V|
114 PP_DERING_Y|PP_DERING_C;
121 i_mode |= PP_AUTOLEVEL;
127 /*****************************************************************************
128 * pp_postprocess : make post-filter as defined in MPEG4-ISO
129 *****************************************************************************
130 *****************************************************************************/
132 static int pp_postprocess( picture_t *p_pic,
133 QT_STORE_T *p_QP_store, unsigned int i_QP_stride,
134 unsigned int i_mode )
136 /* Some sanity checks */
137 /* if( ( p_pic->i_height&0x0f )||( p_pic->i_width&0x0f )||*/
138 if( ( p_pic->p_heap->i_chroma != VLC_FOURCC( 'I', '4', '2', '0' ) )&&
139 ( p_pic->p_heap->i_chroma != VLC_FOURCC( 'Y', 'V', '1', '2' ) ) )
141 return( PP_ERR_INVALID_PICTURE );
144 if( ( !p_QP_store )||( i_QP_stride < p_pic->p_heap->i_width >> 4 ) )
146 return( PP_ERR_INVALID_QP );
149 /* First do vertical deblocking and then horizontal */
152 if( i_mode&PP_DEBLOCK_Y_V )
154 E_( pp_deblock_V )( p_pic->Y_PIXELS,
155 p_pic->p_heap->i_width, p_pic->p_heap->i_height, p_pic->Y_PITCH,
156 p_QP_store, i_QP_stride,
159 if( i_mode&PP_DEBLOCK_Y_H )
161 E_( pp_deblock_H )( p_pic->Y_PIXELS,
162 p_pic->p_heap->i_width, p_pic->p_heap->i_height, p_pic->Y_PITCH,
163 p_QP_store, i_QP_stride,
168 if( i_mode&PP_DEBLOCK_C_V )
170 E_( pp_deblock_V )( p_pic->U_PIXELS,
171 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
173 p_QP_store, i_QP_stride,
175 E_( pp_deblock_V )( p_pic->V_PIXELS,
176 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
178 p_QP_store, i_QP_stride,
181 if( i_mode&PP_DEBLOCK_C_H )
183 E_( pp_deblock_H )( p_pic->U_PIXELS,
184 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
186 p_QP_store, i_QP_stride,
188 E_( pp_deblock_H )( p_pic->V_PIXELS,
189 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
191 p_QP_store, i_QP_stride,
195 /* After deblocking do dering */
196 /* TODO check for min size */
198 if( i_mode&PP_DERING_Y )
200 E_( pp_dering_Y )( p_pic->Y_PIXELS,
201 p_pic->p_heap->i_width, p_pic->p_heap->i_height,
203 p_QP_store, i_QP_stride );
205 if( i_mode&PP_DERING_C )
207 E_( pp_dering_C )( p_pic->U_PIXELS,
208 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
210 p_QP_store, i_QP_stride );
212 E_( pp_dering_C )( p_pic->V_PIXELS,
213 p_pic->p_heap->i_width >> 1, p_pic->p_heap->i_height >> 1,
215 p_QP_store, i_QP_stride );
218 #if defined( MODULE_NAME_IS_postprocessing_mmx )||defined( MODULE_NAME_IS_postprocessing_mmxext )
219 /* We have used MMX so return to safe FPU state */
220 __asm__ __volatile__ ( "emms" );