ffmpeg: targetos must now be in lower case.
[vlc.git] / modules / codec / fake.c
blobfdbd6c264838bc4a3e0f8ad7dc5ea100c2b6d049
1 /*****************************************************************************
2 * fake.c: decoder reading from a fake stream, outputting a fixed image
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
5 * $Id$
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc_codec.h>
30 #include <vlc_image.h>
31 #include <vlc_filter.h>
32 #include <vlc_charset.h>
34 /*****************************************************************************
35 * Local prototypes
36 *****************************************************************************/
37 static int OpenDecoder ( vlc_object_t * );
38 static void CloseDecoder ( vlc_object_t * );
40 static picture_t *DecodeBlock ( decoder_t *, block_t ** );
42 /*****************************************************************************
43 * Module descriptor
44 *****************************************************************************/
45 #define FILE_TEXT N_("Image file")
46 #define FILE_LONGTEXT N_( \
47 "Path of the image file for fake input." )
48 #define WIDTH_TEXT N_("Video width")
49 #define WIDTH_LONGTEXT N_( \
50 "Output video width." )
51 #define HEIGHT_TEXT N_("Video height")
52 #define HEIGHT_LONGTEXT N_( \
53 "Output video height." )
54 #define KEEP_AR_TEXT N_("Keep aspect ratio")
55 #define KEEP_AR_LONGTEXT N_( \
56 "Consider width and height as maximum values." )
57 #define ASPECT_RATIO_TEXT N_("Background aspect ratio")
58 #define ASPECT_RATIO_LONGTEXT N_( \
59 "Aspect ratio of the image file (4:3, 16:9). Default is square pixels." )
60 #define DEINTERLACE_TEXT N_("Deinterlace video")
61 #define DEINTERLACE_LONGTEXT N_( \
62 "Deinterlace the image after loading it." )
63 #define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")
64 #define DEINTERLACE_MODULE_LONGTEXT N_( \
65 "Deinterlace module to use." )
67 static const char *ppsz_deinterlace_type[] =
69 "deinterlace", "ffmpeg-deinterlace"
72 vlc_module_begin();
73 set_category( CAT_INPUT );
74 set_subcategory( SUBCAT_INPUT_VCODEC );
75 set_shortname( _("Fake") );
76 set_description( _("Fake video decoder") );
77 set_capability( "decoder", 1000 );
78 set_callbacks( OpenDecoder, CloseDecoder );
79 add_shortcut( "fake" );
81 add_file( "fake-file", "", NULL, FILE_TEXT,
82 FILE_LONGTEXT, VLC_FALSE );
83 add_integer( "fake-width", 0, NULL, WIDTH_TEXT,
84 WIDTH_LONGTEXT, VLC_TRUE );
85 add_integer( "fake-height", 0, NULL, HEIGHT_TEXT,
86 HEIGHT_LONGTEXT, VLC_TRUE );
87 add_bool( "fake-keep-ar", 0, NULL, KEEP_AR_TEXT, KEEP_AR_LONGTEXT,
88 VLC_TRUE );
89 add_string( "fake-aspect-ratio", "", NULL,
90 ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, VLC_TRUE );
91 add_bool( "fake-deinterlace", 0, NULL, DEINTERLACE_TEXT,
92 DEINTERLACE_LONGTEXT, VLC_FALSE );
93 add_string( "fake-deinterlace-module", "deinterlace", NULL,
94 DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT,
95 VLC_FALSE );
96 change_string_list( ppsz_deinterlace_type, 0, 0 );
97 vlc_module_end();
99 /*****************************************************************************
100 * OpenDecoder: probe the decoder and return score
101 *****************************************************************************/
102 static int OpenDecoder( vlc_object_t *p_this )
104 decoder_t *p_dec = (decoder_t*)p_this;
105 vlc_value_t val;
106 image_handler_t *p_handler;
107 video_format_t fmt_in, fmt_out;
108 picture_t *p_image;
109 char *psz_file;
110 vlc_bool_t b_keep_ar;
111 int i_aspect = 0;
113 if( p_dec->fmt_in.i_codec != VLC_FOURCC('f','a','k','e') )
115 return VLC_EGENERIC;
118 var_Create( p_dec, "fake-file", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
119 var_Get( p_dec, "fake-file", &val );
120 if( val.psz_string == NULL || !*val.psz_string )
122 if( val.psz_string ) free( val.psz_string );
123 msg_Err( p_dec, "specify a file with --fake-file=..." );
124 return VLC_EGENERIC;
126 psz_file = val.psz_string;
128 memset( &fmt_in, 0, sizeof(fmt_in) );
129 memset( &fmt_out, 0, sizeof(fmt_out) );
130 fmt_out.i_chroma = VLC_FOURCC('I','4','2','0');
132 var_Create( p_dec, "fake-keep-ar", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
133 var_Get( p_dec, "fake-keep-ar", &val );
134 b_keep_ar = val.b_bool;
136 var_Create( p_dec, "fake-width", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
137 var_Create( p_dec, "fake-height", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
138 var_Create( p_dec, "fake-aspect-ratio",
139 VLC_VAR_STRING | VLC_VAR_DOINHERIT );
141 var_Get( p_dec, "fake-aspect-ratio", &val );
142 if ( val.psz_string )
144 char *psz_parser = strchr( val.psz_string, ':' );
146 if( psz_parser )
148 *psz_parser++ = '\0';
149 i_aspect = atoi( val.psz_string )
150 * VOUT_ASPECT_FACTOR / atoi( psz_parser );
152 free( val.psz_string );
155 if ( !b_keep_ar )
157 var_Get( p_dec, "fake-width", &val );
158 fmt_out.i_width = val.i_int;
159 var_Get( p_dec, "fake-height", &val );
160 fmt_out.i_height = val.i_int;
163 p_handler = image_HandlerCreate( p_dec );
164 p_image = image_ReadUrl( p_handler, psz_file, &fmt_in, &fmt_out );
165 image_HandlerDelete( p_handler );
167 if ( p_image == NULL )
169 msg_Err( p_dec, "unable to read image file %s", psz_file );
170 return VLC_EGENERIC;
172 msg_Dbg( p_dec, "file %s loaded successfully", psz_file );
174 if ( psz_file ) free( psz_file );
176 if ( b_keep_ar )
178 picture_t *p_old = p_image;
179 int i_width, i_height;
181 var_Get( p_dec, "fake-width", &val );
182 i_width = val.i_int;
183 var_Get( p_dec, "fake-height", &val );
184 i_height = val.i_int;
186 if ( i_width && i_height )
188 int i_image_ar = fmt_out.i_width * VOUT_ASPECT_FACTOR
189 / fmt_out.i_height;
190 int i_region_ar = i_width * VOUT_ASPECT_FACTOR / i_height;
191 fmt_in = fmt_out;
193 if ( i_aspect == i_image_ar )
195 fmt_out.i_width = i_width;
196 fmt_out.i_height = i_height;
198 else if ( i_image_ar > i_region_ar )
200 fmt_out.i_width = i_width;
201 fmt_out.i_height = i_width * VOUT_ASPECT_FACTOR
202 / i_image_ar;
203 i_aspect = i_image_ar;
205 else
207 fmt_out.i_height = i_height;
208 fmt_out.i_width = i_height * i_image_ar
209 / VOUT_ASPECT_FACTOR;
210 i_aspect = i_image_ar;
213 p_handler = image_HandlerCreate( p_dec );
214 p_image = image_Convert( p_handler, p_old, &fmt_in, &fmt_out );
215 image_HandlerDelete( p_handler );
217 if ( p_image == NULL )
219 msg_Warn( p_dec, "couldn't load resizing module" );
220 p_image = p_old;
221 fmt_out = fmt_in;
223 else
225 p_old->pf_release( p_old );
230 if ( i_aspect )
232 fmt_out.i_aspect = i_aspect;
234 else
236 fmt_out.i_aspect = fmt_out.i_width
237 * VOUT_ASPECT_FACTOR / fmt_out.i_height;
240 var_Create( p_dec, "fake-deinterlace", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
241 var_Get( p_dec, "fake-deinterlace", &val );
242 if ( val.b_bool )
244 picture_t *p_old = p_image;
246 var_Create( p_dec, "fake-deinterlace-module",
247 VLC_VAR_STRING | VLC_VAR_DOINHERIT );
248 var_Get( p_dec, "fake-deinterlace-module", &val );
250 p_handler = image_HandlerCreate( p_dec );
251 p_image = image_Filter( p_handler, p_old, &fmt_out, val.psz_string );
252 image_HandlerDelete( p_handler );
253 if ( val.psz_string != NULL ) free( val.psz_string );
255 if ( p_image == NULL )
257 msg_Warn( p_dec, "couldn't load deinterlace module" );
258 p_image = p_old;
260 else
262 p_old->pf_release( p_old );
266 /* Set output properties */
267 p_dec->fmt_out.i_cat = VIDEO_ES;
268 p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0');
269 p_dec->fmt_out.video = fmt_out;
271 /* Set callbacks */
272 p_dec->pf_decode_video = DecodeBlock;
273 p_dec->p_sys = (decoder_sys_t *)p_image;
275 return VLC_SUCCESS;
278 /****************************************************************************
279 * DecodeBlock: the whole thing
280 ****************************************************************************/
281 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
283 picture_t *p_image = (picture_t *)p_dec->p_sys;
284 picture_t *p_pic;
286 if( pp_block == NULL || !*pp_block ) return NULL;
287 p_pic = p_dec->pf_vout_buffer_new( p_dec );
288 if( p_pic == NULL )
290 msg_Err( p_dec, "cannot get picture" );
291 goto error;
294 vout_CopyPicture( p_dec, p_pic, p_image );
295 p_pic->date = (*pp_block)->i_pts;
297 error:
298 block_Release( *pp_block );
299 *pp_block = NULL;
301 return p_pic;
304 /*****************************************************************************
305 * CloseDecoder: fake decoder destruction
306 *****************************************************************************/
307 static void CloseDecoder( vlc_object_t *p_this )
309 decoder_t *p_dec = (decoder_t *)p_this;
310 picture_t *p_image = (picture_t *)p_dec->p_sys;
312 if( p_image != NULL )
313 p_image->pf_release( p_image );