00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <vlc/vlc.h>
00026 #include <vlc/vout.h>
00027 #include <vlc/decoder.h>
00028
00029
00030 #ifdef HAVE_FFMPEG_AVCODEC_H
00031 # include <ffmpeg/avcodec.h>
00032 #else
00033 # include <avcodec.h>
00034 #endif
00035
00036 #include "ffmpeg.h"
00037
00038 #ifdef LIBAVCODEC_PP
00039
00040 #ifdef HAVE_POSTPROC_POSTPROCESS_H
00041 # include <postproc/postprocess.h>
00042 #else
00043 # include <libpostproc/postprocess.h>
00044 #endif
00045
00046 #ifndef PP_CPU_CAPS_ALTIVEC
00047 # define PP_CPU_CAPS_ALTIVEC 0
00048 #endif
00049
00050
00051
00052
00053 typedef struct video_postproc_sys_t
00054 {
00055 pp_context_t *pp_context;
00056 pp_mode_t *pp_mode;
00057
00058 vlc_bool_t *pb_pp;
00059
00060 int i_width;
00061 int i_height;
00062
00063 } video_postproc_sys_t;
00064
00065 static int PPQCallback( vlc_object_t *p_this, char const *psz_cmd,
00066 vlc_value_t oldval, vlc_value_t newval, void *p_data );
00067
00068
00069
00070
00071 void *E_(OpenPostproc)( decoder_t *p_dec, vlc_bool_t *pb_pp )
00072 {
00073 video_postproc_sys_t *p_sys;
00074 vlc_value_t val, val_orig, text;
00075
00076 p_sys = malloc( sizeof(video_postproc_sys_t) );
00077 p_sys->pp_context = NULL;
00078 p_sys->pp_mode = NULL;
00079
00080 *pb_pp = VLC_FALSE;
00081 p_sys->pb_pp = pb_pp;
00082
00083
00084 if( var_Type( p_dec, "ffmpeg-pp-q" ) == 0 )
00085 {
00086 var_Create( p_dec, "ffmpeg-pp-q",
00087 VLC_VAR_INTEGER | VLC_VAR_HASCHOICE | VLC_VAR_DOINHERIT );
00088 text.psz_string = _("Post processing");
00089 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_SETTEXT, &text, NULL );
00090
00091 var_Get( p_dec, "ffmpeg-pp-q", &val_orig );
00092 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_DELCHOICE, &val_orig, NULL );
00093
00094 val.i_int = 0; text.psz_string = _("Disable");
00095 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
00096 val.i_int = 1; text.psz_string = _("1 (Lowest)");
00097 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
00098 val.i_int = 2;
00099 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
00100 val.i_int = 3;
00101 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
00102 val.i_int = 4;
00103 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
00104 val.i_int = 5;
00105 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, NULL );
00106 val.i_int = 6; text.psz_string = _("6 (Highest)");
00107 var_Change( p_dec, "ffmpeg-pp-q", VLC_VAR_ADDCHOICE, &val, &text );
00108 var_AddCallback( p_dec, "ffmpeg-pp-q", PPQCallback, p_sys );
00109 }
00110
00111
00112 var_Get( p_dec, "ffmpeg-pp-q", &val );
00113 var_Set( p_dec, "ffmpeg-pp-q", val_orig );
00114 if( val_orig.i_int )
00115 *pb_pp = VLC_TRUE;
00116
00117 return p_sys;
00118 }
00119
00120
00121
00122
00123 int E_(InitPostproc)( decoder_t *p_dec, void *p_data,
00124 int i_width, int i_height, int pix_fmt )
00125 {
00126 video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
00127 int32_t i_cpu = p_dec->p_libvlc->i_cpu;
00128 int i_flags = 0;
00129
00130
00131 if( i_cpu & CPU_CAPABILITY_MMX )
00132 {
00133 i_flags |= PP_CPU_CAPS_MMX;
00134 }
00135 if( i_cpu & CPU_CAPABILITY_MMXEXT )
00136 {
00137 i_flags |= PP_CPU_CAPS_MMX2;
00138 }
00139 if( i_cpu & CPU_CAPABILITY_3DNOW )
00140 {
00141 i_flags |= PP_CPU_CAPS_3DNOW;
00142 }
00143 if( i_cpu & CPU_CAPABILITY_ALTIVEC )
00144 {
00145 i_flags |= PP_CPU_CAPS_ALTIVEC;
00146 }
00147
00148 switch( pix_fmt )
00149 {
00150 case PIX_FMT_YUV444P:
00151 i_flags |= PP_FORMAT_444;
00152 break;
00153 case PIX_FMT_YUV422P:
00154 i_flags |= PP_FORMAT_422;
00155 break;
00156 case PIX_FMT_YUV411P:
00157 i_flags |= PP_FORMAT_411;
00158 break;
00159 default:
00160 i_flags |= PP_FORMAT_420;
00161 break;
00162 }
00163
00164 p_sys->pp_context = pp_get_context( i_width, i_height, i_flags );
00165 p_sys->i_width = i_width;
00166 p_sys->i_height = i_height;
00167
00168 return VLC_SUCCESS;
00169 }
00170
00171
00172
00173
00174 int E_(PostprocPict)( decoder_t *p_dec, void *p_data,
00175 picture_t *p_pic, AVFrame *p_ff_pic )
00176 {
00177 video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
00178
00179 uint8_t *src[3], *dst[3];
00180 int i_plane, i_src_stride[3], i_dst_stride[3];
00181
00182 for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ )
00183 {
00184 src[i_plane] = p_ff_pic->data[i_plane];
00185 dst[i_plane] = p_pic->p[i_plane].p_pixels;
00186
00187 i_src_stride[i_plane] = p_ff_pic->linesize[i_plane];
00188 i_dst_stride[i_plane] = p_pic->p[i_plane].i_pitch;
00189 }
00190
00191 pp_postprocess( src, i_src_stride, dst, i_dst_stride,
00192 p_sys->i_width, p_sys->i_height,
00193 p_ff_pic->qscale_table, p_ff_pic->qstride,
00194 p_sys->pp_mode, p_sys->pp_context,
00195 p_ff_pic->pict_type );
00196
00197 return VLC_SUCCESS;
00198 }
00199
00200
00201
00202
00203 void E_(ClosePostproc)( decoder_t *p_dec, void *p_data )
00204 {
00205 video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
00206
00207 if( p_sys && p_sys->pp_mode )
00208 {
00209 pp_free_mode( p_sys->pp_mode );
00210 if( p_sys->pp_context ) pp_free_context( p_sys->pp_context );
00211 }
00212
00213 var_DelCallback( p_dec, "ffmpeg-pp-q", PPQCallback, p_sys );
00214
00215 if( p_sys ) free( p_sys );
00216 }
00217
00218
00219
00220
00221
00222 static int PPQCallback( vlc_object_t *p_this, char const *psz_cmd,
00223 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00224 {
00225 decoder_t *p_dec = (decoder_t *)p_this;
00226 video_postproc_sys_t *p_sys = (video_postproc_sys_t *)p_data;
00227
00228 if( newval.i_int > 0 )
00229 {
00230 int i_quality = newval.i_int;
00231 char *psz_name = config_GetPsz( p_dec, "ffmpeg-pp-name" );
00232 pp_mode_t *pp_mode;
00233
00234 if( !psz_name )
00235 {
00236 psz_name = strdup( "default" );
00237 }
00238 else if( *psz_name == '\0' )
00239 {
00240 free( psz_name );
00241 psz_name = strdup( "default" );
00242 }
00243
00244 pp_mode = pp_get_mode_by_name_and_quality( psz_name, i_quality );
00245
00246 if( !pp_mode )
00247 {
00248 msg_Err( p_dec, "failed getting mode for postproc" );
00249 newval.i_int = 0;
00250 }
00251 else
00252 {
00253 msg_Dbg( p_dec, "postprocessing enabled" );
00254 }
00255 free( psz_name );
00256
00257 p_sys->pp_mode = pp_mode;
00258 }
00259 else
00260 {
00261 msg_Dbg( p_dec, "postprocessing disabled" );
00262 }
00263
00264 *p_sys->pb_pp = newval.i_int;
00265
00266 return VLC_SUCCESS;
00267 }
00268
00269 #endif