X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_filter%2Fscale.c;h=388ce699b75d1c92940d8630c2e0bf8b84cecde7;hb=df507aa7f3649f100615e4578b283af1aa06da38;hp=d213d32a59a1aacb9c017a5eb67f0cd0b1dcf9cd;hpb=4f1a86baff4ba13e51adf7ad2b87aff62c20ad75;p=vlc diff --git a/modules/video_filter/scale.c b/modules/video_filter/scale.c index d213d32a59..388ce699b7 100644 --- a/modules/video_filter/scale.c +++ b/modules/video_filter/scale.c @@ -2,7 +2,7 @@ * resize.c: video scaling module for YUVP/A pictures * Uses the low quality "nearest neighbour" algorithm. ***************************************************************************** - * Copyright (C) 2003 VideoLAN + * Copyright (C) 2003 the VideoLAN team * $Id$ * * Author: Gildas Bazin @@ -19,14 +19,14 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ #include -#include +#include #include "vlc_filter.h" /***************************************************************************** @@ -52,6 +52,8 @@ static picture_t *Filter( filter_t *, picture_t * ); vlc_module_begin(); set_description( _("Video scaling filter") ); set_capability( "video filter2", 10000 ); +// set_category( CAT_VIDEO ); +// set_subcategory( SUBCAT_VIDEO_VFILTER2 ); set_callbacks( OpenFilter, CloseFilter ); vlc_module_end(); @@ -64,7 +66,8 @@ static int OpenFilter( vlc_object_t *p_this ) filter_sys_t *p_sys; if( ( p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','P') && - p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','A') ) || + p_filter->fmt_in.video.i_chroma != VLC_FOURCC('Y','U','V','A') && + p_filter->fmt_in.video.i_chroma != VLC_FOURCC('R','G','B','A') ) || p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma ) { return VLC_EGENERIC; @@ -103,38 +106,76 @@ static void CloseFilter( vlc_object_t *p_this ) ****************************************************************************/ static picture_t *Filter( filter_t *p_filter, picture_t *p_pic ) { - filter_sys_t *p_sys = p_filter->p_sys; picture_t *p_pic_dst; int i_plane, i, j, k, l; + if( !p_pic ) return NULL; + /* Request output picture */ p_pic_dst = p_filter->pf_vout_buffer_new( p_filter ); if( !p_pic_dst ) { msg_Warn( p_filter, "can't get output picture" ); + if( p_pic->pf_release ) + p_pic->pf_release( p_pic ); return NULL; } - for( i_plane = 0; i_plane < p_pic_dst->i_planes; i_plane++ ) + if( p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','U','V','P') || + p_filter->fmt_in.video.i_chroma == VLC_FOURCC('Y','U','V','A') ) { - uint8_t *p_src = p_pic->p[i_plane].p_pixels; - uint8_t *p_dst = p_pic_dst->p[i_plane].p_pixels; - int i_src_pitch = p_pic->p[i_plane].i_pitch; - int i_dst_pitch = p_pic_dst->p[i_plane].i_pitch; + for( i_plane = 0; i_plane < p_pic_dst->i_planes; i_plane++ ) + { + uint8_t *p_src = p_pic->p[i_plane].p_pixels; + uint8_t *p_dst = p_pic_dst->p[i_plane].p_pixels; + int i_src_pitch = p_pic->p[i_plane].i_pitch; + int i_dst_pitch = p_pic_dst->p[i_plane].i_pitch; + + for( i = 0; i < p_pic_dst->p[i_plane].i_visible_lines; i++ ) + { + l = ( p_filter->fmt_in.video.i_height * i + + p_filter->fmt_out.video.i_height / 2 ) / + p_filter->fmt_out.video.i_height; + + l = __MIN( (int)p_filter->fmt_in.video.i_height - 1, l ); + + for( j = 0; j < p_pic_dst->p[i_plane].i_visible_pitch; j++ ) + { + k = ( p_filter->fmt_in.video.i_width * j + + p_filter->fmt_out.video.i_width / 2 ) / + p_filter->fmt_out.video.i_width; - for( i = 0; i < p_pic_dst->p[i_plane].i_visible_lines; i++ ) + k = __MIN( (int)p_filter->fmt_in.video.i_width - 1, k ); + + p_dst[i * i_dst_pitch + j] = p_src[l * i_src_pitch + k]; + } + } + } + } + else /* RGBA */ + { + uint8_t *p_src = p_pic->p->p_pixels; + uint8_t *p_dst = p_pic_dst->p->p_pixels; + int i_src_pitch = p_pic->p->i_pitch; + int i_dst_pitch = p_pic_dst->p->i_pitch; + for( i = 0; i < p_pic_dst->p->i_visible_lines; i++ ) { l = ( p_filter->fmt_in.video.i_height * i + p_filter->fmt_out.video.i_height / 2 ) / p_filter->fmt_out.video.i_height; - for( j = 0; j < p_pic_dst->p[i_plane].i_visible_pitch; j++ ) + l = __MIN( (int)p_filter->fmt_in.video.i_height - 1, l ); + + for( j = 0; j < p_pic_dst->p->i_visible_pitch/4; j++ ) { k = ( p_filter->fmt_in.video.i_width * j + p_filter->fmt_out.video.i_width / 2 ) / p_filter->fmt_out.video.i_width; - p_dst[i * i_dst_pitch + j] = p_src[l * i_src_pitch + k]; + k = __MIN( (int)p_filter->fmt_in.video.i_width - 1, k ); + + *(uint32_t*)(&p_dst[i * i_dst_pitch + 4*j]) = + *(uint32_t*)(&p_src[l * i_src_pitch + 4*k]); } } }