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

fake.c

00001 /*****************************************************************************
00002  * fake.c: decoder reading from a fake stream, outputting a fixed image
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  * $Id: fake.c 12447 2005-09-02 16:01:23Z massiot $
00006  *
00007  * Authors: Christophe Massiot <[email protected]>
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00022  *****************************************************************************/
00023 
00024 /*****************************************************************************
00025  * Preamble
00026  *****************************************************************************/
00027 #include <vlc/vlc.h>
00028 #include <vlc/decoder.h>
00029 
00030 #include "vlc_image.h"
00031 #include "vlc_filter.h"
00032 
00033 /*****************************************************************************
00034  * Local prototypes
00035  *****************************************************************************/
00036 static int  OpenDecoder   ( vlc_object_t * );
00037 static void CloseDecoder  ( vlc_object_t * );
00038 
00039 static picture_t *DecodeBlock  ( decoder_t *, block_t ** );
00040 
00041 /*****************************************************************************
00042  * Module descriptor
00043  *****************************************************************************/
00044 #define FILE_TEXT N_("Image file")
00045 #define FILE_LONGTEXT N_( \
00046     "Path of the image file when using the fake input." )
00047 #define WIDTH_TEXT N_("Video width")
00048 #define WIDTH_LONGTEXT N_( \
00049     "Allows you to specify the output video width." )
00050 #define HEIGHT_TEXT N_("Video height")
00051 #define HEIGHT_LONGTEXT N_( \
00052     "Allows you to specify the output video height." )
00053 #define KEEP_AR_TEXT N_("Keep aspect ratio")
00054 #define KEEP_AR_LONGTEXT N_( \
00055     "If selected, width and height will be considered as maximum values." )
00056 #define ASPECT_RATIO_TEXT N_("Background aspect ratio")
00057 #define ASPECT_RATIO_LONGTEXT N_( \
00058     "Aspect ratio of the image file (4:3, 16:9). Default is square pixels." )
00059 #define DEINTERLACE_TEXT N_("Deinterlace video")
00060 #define DEINTERLACE_LONGTEXT N_( \
00061     "Allows you to deinterlace the image after loading." )
00062 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
00063 #define DEINTERLACE_MODULE_LONGTEXT N_( \
00064     "Specifies the deinterlace module to use." )
00065 
00066 static char *ppsz_deinterlace_type[] =
00067 {
00068     "deinterlace", "ffmpeg-deinterlace"
00069 };
00070 
00071 vlc_module_begin();
00072     set_category( CAT_INPUT );
00073     set_subcategory( SUBCAT_INPUT_VCODEC );
00074     set_shortname( _("Fake") );
00075     set_description( _("Fake video decoder") );
00076     set_capability( "decoder", 1000 );
00077     set_callbacks( OpenDecoder, CloseDecoder );
00078     add_shortcut( "fake" );
00079 
00080     add_file( "fake-file", "", NULL, FILE_TEXT,
00081                 FILE_LONGTEXT, VLC_FALSE );
00082     add_integer( "fake-width", 0, NULL, WIDTH_TEXT,
00083                  WIDTH_LONGTEXT, VLC_TRUE );
00084     add_integer( "fake-height", 0, NULL, HEIGHT_TEXT,
00085                  HEIGHT_LONGTEXT, VLC_TRUE );
00086     add_bool( "fake-keep-ar", 0, NULL, KEEP_AR_TEXT, KEEP_AR_LONGTEXT,
00087               VLC_TRUE );
00088     add_string( "fake-aspect-ratio", "", NULL,
00089                 ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, VLC_TRUE );
00090     add_bool( "fake-deinterlace", 0, NULL, DEINTERLACE_TEXT,
00091               DEINTERLACE_LONGTEXT, VLC_FALSE );
00092     add_string( "fake-deinterlace-module", "deinterlace", NULL,
00093                 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
00094                 VLC_FALSE );
00095         change_string_list( ppsz_deinterlace_type, 0, 0 );
00096 vlc_module_end();
00097 
00098 /*****************************************************************************
00099  * OpenDecoder: probe the decoder and return score
00100  *****************************************************************************/
00101 static int OpenDecoder( vlc_object_t *p_this )
00102 {
00103     decoder_t *p_dec = (decoder_t*)p_this;
00104     vlc_value_t val;
00105     image_handler_t *p_handler;
00106     video_format_t fmt_in, fmt_out;
00107     picture_t *p_image;
00108     char *psz_file, *psz_local;
00109     vlc_bool_t b_keep_ar;
00110     int i_aspect = 0;
00111 
00112     if( p_dec->fmt_in.i_codec != VLC_FOURCC('f','a','k','e') )
00113     {
00114         return VLC_EGENERIC;
00115     }
00116 
00117     var_Create( p_dec, "fake-file", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00118     var_Get( p_dec, "fake-file", &val );
00119     if( val.psz_string == NULL || !*val.psz_string )
00120     {
00121         if( val.psz_string ) free( val.psz_string );
00122         msg_Err( p_dec, "specify a file with --fake-file=..." );
00123         return VLC_EGENERIC;
00124     }
00125     psz_file = val.psz_string;
00126 
00127     memset( &fmt_in, 0, sizeof(fmt_in) );
00128     memset( &fmt_out, 0, sizeof(fmt_out) );
00129     fmt_out.i_chroma = VLC_FOURCC('I','4','2','0');
00130 
00131     var_Create( p_dec, "fake-keep-ar", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00132     var_Get( p_dec, "fake-keep-ar", &val );
00133     b_keep_ar = val.b_bool;
00134 
00135     var_Create( p_dec, "fake-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00136     var_Create( p_dec, "fake-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00137     var_Create( p_dec, "fake-aspect-ratio",
00138                 VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00139 
00140     var_Get( p_dec, "fake-aspect-ratio", &val );
00141     if ( val.psz_string )
00142     {
00143         char *psz_parser = strchr( val.psz_string, ':' );
00144 
00145         if( psz_parser )
00146         {
00147             *psz_parser++ = '\0';
00148             i_aspect = atoi( val.psz_string )
00149                                    * VOUT_ASPECT_FACTOR / atoi( psz_parser );
00150         }
00151         free( val.psz_string );
00152     }
00153 
00154     if ( !b_keep_ar )
00155     {
00156         var_Get( p_dec, "fake-width", &val );
00157         fmt_out.i_width = val.i_int;
00158         var_Get( p_dec, "fake-height", &val );
00159         fmt_out.i_height = val.i_int;
00160     }
00161 
00162     p_handler = image_HandlerCreate( p_dec );
00163     psz_local = ToLocale( psz_file );
00164     p_image = image_ReadUrl( p_handler, psz_local, &fmt_in, &fmt_out );
00165     LocaleFree( psz_local );
00166     image_HandlerDelete( p_handler );
00167 
00168     if ( p_image == NULL )
00169     {
00170         msg_Err( p_dec, "unable to read image file %s", psz_file );
00171         return VLC_EGENERIC;
00172     }
00173     msg_Dbg( p_dec, "file %s loaded successfully", psz_file );
00174 
00175     if ( psz_file ) free( psz_file );
00176 
00177     if ( b_keep_ar )
00178     {
00179         picture_t *p_old = p_image;
00180         int i_width, i_height;
00181 
00182         var_Get( p_dec, "fake-width", &val );
00183         i_width = val.i_int;
00184         var_Get( p_dec, "fake-height", &val );
00185         i_height = val.i_int;
00186 
00187         if ( i_width && i_height )
00188         {
00189             int i_image_ar = fmt_out.i_width * VOUT_ASPECT_FACTOR
00190                               / fmt_out.i_height;
00191             int i_region_ar = i_width * VOUT_ASPECT_FACTOR / i_height;
00192             fmt_in = fmt_out;
00193 
00194             if ( i_aspect == i_image_ar )
00195             {
00196                 fmt_out.i_width = i_width;
00197                 fmt_out.i_height = i_height;
00198             }
00199             else if ( i_image_ar > i_region_ar )
00200             {
00201                 fmt_out.i_width = i_width;
00202                 fmt_out.i_height = i_width * VOUT_ASPECT_FACTOR
00203                                     / i_image_ar;
00204                 i_aspect = i_image_ar;
00205             }
00206             else
00207             {
00208                 fmt_out.i_height = i_height;
00209                 fmt_out.i_width = i_height * i_image_ar
00210                                     / VOUT_ASPECT_FACTOR;
00211                 i_aspect = i_image_ar;
00212             }
00213 
00214             p_handler = image_HandlerCreate( p_dec );
00215             p_image = image_Convert( p_handler, p_old, &fmt_in, &fmt_out );
00216             image_HandlerDelete( p_handler );
00217 
00218             if ( p_image == NULL )
00219             {
00220                 msg_Warn( p_dec, "couldn't load resizing module" );
00221                 p_image = p_old;
00222                 fmt_out = fmt_in;
00223             }
00224             else
00225             {
00226                 p_old->pf_release( p_old );
00227             }
00228         }
00229     }
00230 
00231     if ( i_aspect )
00232     {
00233         fmt_out.i_aspect = i_aspect;
00234     }
00235     else
00236     {
00237         fmt_out.i_aspect = fmt_out.i_width
00238                             * VOUT_ASPECT_FACTOR / fmt_out.i_height;
00239     }
00240 
00241     var_Create( p_dec, "fake-deinterlace", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
00242     var_Get( p_dec, "fake-deinterlace", &val );
00243     if ( val.b_bool )
00244     {
00245         picture_t *p_old = p_image;
00246 
00247         var_Create( p_dec, "fake-deinterlace-module",
00248                     VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00249         var_Get( p_dec, "fake-deinterlace-module", &val );
00250 
00251         p_handler = image_HandlerCreate( p_dec );
00252         p_image = image_Filter( p_handler, p_old, &fmt_out, val.psz_string );
00253         image_HandlerDelete( p_handler );
00254         if ( val.psz_string != NULL ) free( val.psz_string );
00255 
00256         if ( p_image == NULL )
00257         {
00258             msg_Warn( p_dec, "couldn't load deinterlace module" );
00259             p_image = p_old;
00260         }
00261         else
00262         {
00263             p_old->pf_release( p_old );
00264         }
00265     }
00266 
00267     /* Set output properties */
00268     p_dec->fmt_out.i_cat = VIDEO_ES;
00269     p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
00270     p_dec->fmt_out.video = fmt_out;
00271 
00272     /* Set callbacks */
00273     p_dec->pf_decode_video = DecodeBlock;
00274     p_dec->p_sys = (decoder_sys_t *)p_image;
00275 
00276     return VLC_SUCCESS;
00277 }
00278 
00279 /****************************************************************************
00280  * DecodeBlock: the whole thing
00281  ****************************************************************************/
00282 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00283 {
00284     picture_t *p_image = (picture_t *)p_dec->p_sys;
00285     picture_t *p_pic;
00286 
00287     if( pp_block == NULL || !*pp_block ) return NULL;
00288     p_pic = p_dec->pf_vout_buffer_new( p_dec );
00289     if( p_pic == NULL )
00290     {
00291         msg_Err( p_dec, "cannot get picture" );
00292         goto error;
00293     }
00294 
00295     vout_CopyPicture( p_dec, p_pic, p_image );
00296     p_pic->date = (*pp_block)->i_pts;
00297 
00298 error:
00299     block_Release( *pp_block );
00300     *pp_block = NULL;
00301 
00302     return p_pic;
00303 }
00304 
00305 /*****************************************************************************
00306  * CloseDecoder: fake decoder destruction
00307  *****************************************************************************/
00308 static void CloseDecoder( vlc_object_t *p_this )
00309 {
00310     decoder_t *p_dec = (decoder_t *)p_this;
00311     picture_t *p_image = (picture_t *)p_dec->p_sys;
00312 
00313     if( p_image != NULL )
00314         p_image->pf_release( p_image );
00315 }

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