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
00026
00027
00028 #include <vlc/vlc.h>
00029 #include <vlc/decoder.h>
00030 #include "vlc_filter.h"
00031
00032
00033
00034
00035 struct filter_sys_t
00036 {
00037 es_format_t fmt_in;
00038 es_format_t fmt_out;
00039 };
00040
00041
00042
00043
00044 static int OpenFilter ( vlc_object_t * );
00045 static void CloseFilter( vlc_object_t * );
00046
00047 static picture_t *Filter( filter_t *, picture_t * );
00048
00049
00050
00051
00052 vlc_module_begin();
00053 set_description( _("Video scaling filter") );
00054 set_capability( "video filter2", 10000 );
00055 set_category( CAT_VIDEO );
00056 set_subcategory( SUBCAT_VIDEO_VFILTER );
00057 set_callbacks( OpenFilter, CloseFilter );
00058 vlc_module_end();
00059
00060
00061
00062
00063 static int OpenFilter( vlc_object_t *p_this )
00064 {
00065 filter_t *p_filter = (filter_t*)p_this;
00066 filter_sys_t *p_sys;
00067
00068 if( ( p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','P') &&
00069 p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','A') ) ||
00070 p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma )
00071 {
00072 return VLC_EGENERIC;
00073 }
00074
00075
00076 if( ( p_filter->p_sys = p_sys =
00077 (filter_sys_t *)malloc(sizeof(filter_sys_t)) ) == NULL )
00078 {
00079 msg_Err( p_filter, "out of memory" );
00080 return VLC_EGENERIC;
00081 }
00082
00083 p_filter->pf_video_filter = Filter;
00084
00085 msg_Dbg( p_filter, "%ix%i -> %ix%i", p_filter->fmt_in.video.i_width,
00086 p_filter->fmt_in.video.i_height, p_filter->fmt_out.video.i_width,
00087 p_filter->fmt_out.video.i_height );
00088
00089 return VLC_SUCCESS;
00090 }
00091
00092
00093
00094
00095 static void CloseFilter( vlc_object_t *p_this )
00096 {
00097 filter_t *p_filter = (filter_t*)p_this;
00098 filter_sys_t *p_sys = p_filter->p_sys;
00099
00100 free( p_sys );
00101 }
00102
00103
00104
00105
00106 static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
00107 {
00108 picture_t *p_pic_dst;
00109 int i_plane, i, j, k, l;
00110
00111 if( !p_pic ) return NULL;
00112
00113
00114 p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
00115 if( !p_pic_dst )
00116 {
00117 msg_Warn( p_filter, "can't get output picture" );
00118 if( p_pic->pf_release )
00119 p_pic->pf_release( p_pic );
00120 return NULL;
00121 }
00122
00123 for( i_plane = 0; i_plane < p_pic_dst->i_planes; i_plane++ )
00124 {
00125 uint8_t *p_src = p_pic->p[i_plane].p_pixels;
00126 uint8_t *p_dst = p_pic_dst->p[i_plane].p_pixels;
00127 int i_src_pitch = p_pic->p[i_plane].i_pitch;
00128 int i_dst_pitch = p_pic_dst->p[i_plane].i_pitch;
00129
00130 for( i = 0; i < p_pic_dst->p[i_plane].i_visible_lines; i++ )
00131 {
00132 l = ( p_filter->fmt_in.video.i_height * i +
00133 p_filter->fmt_out.video.i_height / 2 ) /
00134 p_filter->fmt_out.video.i_height;
00135
00136 l = __MIN( (int)p_filter->fmt_in.video.i_height - 1, l );
00137
00138 for( j = 0; j < p_pic_dst->p[i_plane].i_visible_pitch; j++ )
00139 {
00140 k = ( p_filter->fmt_in.video.i_width * j +
00141 p_filter->fmt_out.video.i_width / 2 ) /
00142 p_filter->fmt_out.video.i_width;
00143
00144 k = __MIN( (int)p_filter->fmt_in.video.i_width - 1, k );
00145
00146 p_dst[i * i_dst_pitch + j] = p_src[l * i_src_pitch + k];
00147 }
00148 }
00149 }
00150
00151 p_pic_dst->date = p_pic->date;
00152 p_pic_dst->b_force = p_pic->b_force;
00153 p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
00154 p_pic_dst->b_progressive = p_pic->b_progressive;
00155 p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
00156
00157 p_pic->pf_release( p_pic );
00158 return p_pic_dst;
00159 }