Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

scale.c

00001 /*****************************************************************************
00002  * resize.c: video scaling module for YUVP/A pictures
00003  *  Uses the low quality "nearest neighbour" algorithm.
00004  *****************************************************************************
00005  * Copyright (C) 2003 the VideoLAN team
00006  * $Id: scale.c 12516 2005-09-11 16:57:10Z gbazin $
00007  *
00008  * Author: Gildas Bazin <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <vlc/vlc.h>
00029 #include <vlc/decoder.h>
00030 #include "vlc_filter.h"
00031 
00032 /*****************************************************************************
00033  * filter_sys_t : filter descriptor
00034  *****************************************************************************/
00035 struct filter_sys_t
00036 {
00037     es_format_t fmt_in;
00038     es_format_t fmt_out;
00039 };
00040 
00041 /****************************************************************************
00042  * Local prototypes
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  * Module descriptor
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  * OpenFilter: probe the filter and return score
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     /* Allocate the memory needed to store the decoder's structure */
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  * CloseFilter: clean up the filter
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  * Filter: the whole thing
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     /* Request output picture */
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 }

Generated on Tue Dec 20 10:14:53 2005 for vlc-0.8.4a by  doxygen 1.4.2